4

I have this data gathered using a GPS device

No.     Time       Longitude    Latitude Speed(Km/h)   Compass point      Direction (deg)
1   10/20/15 1:34   40.11724    -3.21032     11        Northwest by north  341   
2   10/20/15 1:34   40.11714    -3.20999      6        Northwest by north  334   
3   10/20/15 1:34   40.11713    -3.2098      10        North               352  

My question is, how can I know the compass point given only the longitude, latitude and direction in degrees?

  • You would be comparing the direction in degrees with a table of the cardinal points, e.g. from wikipedia. But it is strange that the values from your example do not correlate. Do you have another example? Are you sure the last is the direction in degrees (gons don't correlate either)? Is the degree or the compass point somehow depending on previous points? – bennos Oct 22 '15 at 9:36
  • @bennos I have included more data. – Le Qs Oct 22 '15 at 14:20
  • 3
    It should be pointed out (excuse the pun) that time, long, lat and speed are all irrelevant to the problem, which, essentially, is to convert 0-360 degs to 0-32 points. – Martin F Oct 22 '15 at 15:28
  • Please check the documentation of your gps device what it says about the direction and the degrees because they obgiously dont correlate. – bennos Oct 22 '15 at 15:45
  • Are you sure those sample points and degrees are what you actually received? If there were some consistency in the errors, i'd be tempted to contradict what i said above: the discrepancy -- if consistent at 0.8 deg -- may be equal to the magnetic declination at your location (lat, long)! I.E. the difference between magnetic and geodetic north. See geomag.nrcan.gc.ca/calc/… – Martin F Oct 24 '15 at 18:56
2

This is one solution to your problem (though your example is wrong according to wikipedia, as @bennos points out).

package com.ianturton;

import java.util.ArrayList;

/**
 * given a direction in degrees (from North) return the Compass Point on a 32
 * element compass rose.
 * 
 * @author ian
 */

public class CompassRose {
    private static final int SIZE = 32;
    static final float STEP = 360f / SIZE;
    static final float HALF_STEP = STEP / 2.0f;

    static final String points[] = { "N", "NbE", "NNE", "NEbN", "NE", "NEbE", "ENE", "EbN", "E", "EbS", "ESE", "SEbE",
        "SE", "SEbS", "SSE", "SbE", "S", "SbW", "SSW", "SWbS", "SW", "SWbW", "WSW", "WbS", "W", "WbN", "WNW", "NWbW",
        "NW", "NWbN", "NNW", "NbW" };
    static ArrayList<Direction> directions = new ArrayList<>();

    static {
        int k = 0;
        for (float i = 0; i < 360; i += (360.0 / SIZE), k++) {
            Direction d = new Direction(points[k], i);
            directions.add(d);
        }
    }

    public static String getDirection(float heading) {
        while (heading < 0) {
            heading += 360;
        }
        while (heading > 360) {
            heading -= 360;
        }
        for (Direction d : directions) {
            if (d.contains(heading)) {
                return d.name;
            }
        }
        return "bad heading " + heading;
    }

    public static void main(String[] args) {

        for (int i = 0; i < 360; i += 10) {
            System.out.println(i + " " + CompassRose.getDirection(i));
        }
    }

    static public class Direction {
        private float start;
        private float end;
        private float centre;
        final String name;

        Direction(String name, float centre) {
            this.name = name;
            this.centre = centre;
            start = this.centre - HALF_STEP;
            end = this.centre + HALF_STEP;
        }

        public boolean contains(float degree) {
            return (start < degree && end > degree);
        }
    }

  }
1

A simpler solution

static final String points[] = { "N", "NbE", "NNE", "NEbN", "NE", "NEbE", "ENE", "EbN", "E", "EbS", "ESE", "SEbE",
    "SE", "SEbS", "SSE", "SbE", "S", "SbW", "SSW", "SWbS", "SW", "SWbW", "WSW", "WbS", "W", "WbN", "WNW", "NWbW",
    "NW", "NWbN", "NNW", "NbW" };

public static String getDirection(int degrees) {
    int point = Math.floor(degrees / 360 * 32);
    return points[point];
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.