This project is read-only.

Confused about projections: GPS to map

May 26, 2013 at 4:42 AM
Have searched, but at a loss about how to show GPS derived location on a map.

I'm setting up a dotspatial map with:
DotSpatial.Controls.Map dotSpatialMap.Projection = KnownCoordinateSystems.Geographic.World.WGS1984;
I can load layers (raster and vector) into the map, and it basically seems fine. My task is to show a line on the map, indicating the path of some travel. That works fine, when I use my "travel simulator", which is based on values taken from the map:
dotSpatialMap.ViewExtents.Center.X and dotSpatialMap.ViewExtents.Center.Y
A simple routine uses sin/cos to "drive" in a circle around those initial (e.g. 1973076.10935, 5773630.8284) x,y points.

The line is drawn in a layer defined this way:
gpsFeatures = new FeatureSet(FeatureType.Line);
gpsFeatures.Projection = dotSpatialMap.Projection;
gpsLayer = (MapLineLayer)dotSpatialMap.Layers.Add(gpsFeatures);
gpsLayer.LegendText = "Path";
LineSymbolizer symbol = new LineSymbolizer(System.Drawing.Color.Blue, 2);
gpsLayer.Symbolizer = symbol;
And new points are added to the (latest) line:
IFeature latestLineFeature = gpsFeatures.Features[gpsFeatures.Features.Count - 1];
latestLineFeature.Coordinates.Add(newCoordinate);
The trick is that "newCoordinate". (It's just a dotspatial Coordinate object.)

It works fine for my simulation using numbers derived from the map, but I need to show latitude/longitude as supplied by the Windows.Devices.Geolocation class. It supplies values as lat/long (e.g. -41, 174), and I can't figure out how to project those to numbers that map would want. I thought those were WGS1984 values, which is why I set the map to that projection, but then I don't know what values to use in my conversion routine to project...
private void LatLonToMap(double lat, double lon, double? alt, out double x, out double y, out double z)
{
  double[] convert_xy = new double[2];
  double[] convert_z = new double[1];
  ProjectionInfo source = ???
  ProjectionInfo dest = ???
  convert_xy[0] = lat;
  convert_xy[1] = lon;
  convert_z[0] = alt ?? 0;
  Reproject.ReprojectPoints(convert_xy, convert_z, source, dest, 0, 1);
  x = convert_xy[0];
  y = convert_xy[1];
  z = convert_z[0];
}
Any advice greatly appreciated.
Jun 9, 2013 at 10:39 AM
Well, much further along, and I'll answer myself in case it helps anyone.

My main issue was I was confused about which projection to use where., It turned out I should have been setting the map control to the projection used for the maps, and converting the GPS values to that.

So at the start of my class I now set these standards:
        // Standard projections
        ProjectionInfo projMap = DotSpatial.Projections.KnownCoordinateSystems.Projected.NationalGridsNewZealand.NZGD2000NewZealandTransverseMercator;
        ProjectionInfo projGps = DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984;
And use where required, e.g.:
        private void SetupMap()
        {
            // Define the standard projection
            dotSpatialMap.Projection = projMap;
            ...
This conversion routine successfully takes the GPS supplied values (from a Windows.Devices.Geolocation.Geolocator object) and projects them to the maps co-ords:
        private void LatLonToMap(double lat, double lon, double? alt, out double x, out double y, out double z)
        {
            double[] convert_xy = new double[2];
            double[] convert_z = new double[1];
            convert_xy[0] = lon; // x
            convert_xy[1] = lat; // y
            convert_z[0] = alt ?? 0;
            Reproject.ReprojectPoints(convert_xy, convert_z, projGps, projMap, 0, 1);
            x = convert_xy[0];
            y = convert_xy[1];
            z = convert_z[0];
        }
Sep 9, 2013 at 3:10 PM
Thank you, this was a great help for me!