[GIS] Getting the compass point given longitude, latitude and direction in degrees

bearingcompassdirectiongps

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?

Best Answer

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);
        }
    }

  }
Related Question