How to convert from lat/lng to eastings/northings?

Jan 18, 2011 at 1:05 PM

Hi, I'm sorry to ask what is probably a stupid question. I've read the docs and examined the source code but I can't work out how to do this simple task.

I need to convert points for which I have the latitude and longitude to eastings and northings.

With the Franson library I would do this:
var query = from line in File.ReadAllLines(openFileDialog1.FileName)                        let record = line.Split(',')                        select new GpsToolsNET.Position { Grid = GpsToolsNET.Grid.BRITISH_GRID, Latitude = double.Parse(record[0]), Longitude = double.Parse(record[1]) };

and then access the .Easting and .Northing properties.

How can I (can I?) do something like this with DotSpatial?

Developer
Jan 18, 2011 at 4:36 PM

this is off the top of my head, so I'm not sure exactly where the british grid is, but I bet you can browse for it.

ProjectionInfo source = KnownCoordinateSystems.Geographic.World.WGS1984;
ProjectionInfo dest = KnownCoordinateSystems.Projected...;

// If you have a shapefile do it like this:
FeatureSet fs = new FeatureSet();
fs.Open("yourshapefile.shp");
fs.Reproject(dest);
Map1.Layers.Add(fs);

// If you have a list of coordinates for instance, you can
// convert the coordinates into an array of doubles like
// x1, y1, x2, y2, ... , xn, yn
double[] vertices = new double[mylist.Count*2];
for(int i = 0; i < mylist.Count; i++)
{
  vertices[i*2] = mylist[i].X;
  vertices[i*2+1] = mylist[i].Y;
}
DotSpatial.Projections.Reproject.ReprojectPoints(vertices, source, dest);


The above code is an approximation.  There may be other parameters in the ReprojectPoints like a progress handler which can be null.  Source and dest may be in the wrong order, but just match them with the parameter definitions.  Just remember, if you have no other definition, it is probably ok to assume your lat long are WGS84.  I know little about british grids, so you may have to hunt for that projection in the KnownCoordinateSystems.  Easting is just X and Northing is just Y.  So when you use the ReprojectPoints method and get an output array, the X1, Y1 are effectively Easting1, Northing1 and so on.

Ted

Jan 18, 2011 at 5:54 PM

Thanks Ted.

I guess I need KnownCoordinateSystems.Projected.NationalGrids.BritishNationalGridOSGB36.

The signature of ReprojectPoints is double[] xy, double[] z, ProjectionInfo source, ProjectionInfo dest, int startIndex, int numPoints. What do I need to supply for z, and how do I get the output?

Developer
Jan 18, 2011 at 6:11 PM

you can make z an empty array of doubles that has the same number of doubles as you have coordinates.  The values can all be zero.  I can't remember if it will be happy if you pass null, so you might want to just pass an empty array of double values.

Ted

 

Jan 19, 2011 at 3:14 PM

Thanks Ted. I've done this with Franson now and checked the results in MapPoint, but I'd still like to be able to use DotSpatial to do it.

Condensed code:

                var xy = new List<double>();
                var z = new List<double>();

                ProjectionInfo source = KnownCoordinateSystems.Geographic.World.WGS1984;
                ProjectionInfo dest = KnownCoordinateSystems.Projected.NationalGrids.BritishNationalGridOSGB36;

foreach (var record in File.ReadAllLines(openFileDialog1.FileName).Select(line => line.Split(',')))
                {
                    // Parse lat and lng from text file:
                    double lat = double.Parse(record[0]);
                    double lng = double.Parse(record[1]);
                    xy.Add(lat);
                    xy.Add(lng);
                    z.Add(0);
                }
                
                var xyA = xy.ToArray();
                var zA = z.ToArray();
                Reproject.ReprojectPoints(xyA, zA, source, dest, 0, z.Count);

Sample data:

51.48832038825232,-0.128364230253154751.48866340951659,-0.129145641237840951.48876113338547,-0.1295026564268653

Expected return values:

530042 178263529987 178300529962 178310

Actual return values:

xyA is full of NaNs. zA is full of very low numbers (-6m or less).

Steve

Developer
Jan 19, 2011 at 4:26 PM

You are almost there.  But the values should be in X, Y order, which is Long, Lat.  You added lat, lng, which is Y, X order.

Ted

 

Jan 19, 2011 at 5:13 PM

Unfortunately I'd already tried reversing the lat/lng. I've just tried again but xyA is still full of NaNs. Could it be a bug?

Developer
Jan 19, 2011 at 5:59 PM

It could be.  There are a few hundred coordinate systems out of the 3200 or so total in our test kit that don't work yet.  Maybe this is one?  I'm not sure.  Returning NaN values is typical if your values are outside of the range for what will be accepted by a transform.  So a UTM for the wrong side of the world, for instance, will return NAN values.  In your case, that is not likely, as long as you are entering the values in long, lat order.  If it is still not working, this could be a bug somewhere.  If you want, you can post this as an issue instead, and it might get looked at sooner by Mathew.  Also, he has been working on fixing some content related to projections, so it might help if you download the source code from the repository (preferably using mercurial) and build from the source.  I am planning on a release build Sunday, but until then, building from source might fix things that are broken in the December release.

Jan 19, 2011 at 6:08 PM

The coordinates are for the London congestion charging zone, and they convert with the Franson library and the resulting map looks fine in MapPoint.

I'm using a source code dump downloaded yesterday.

In a way I have what I need, as I was able to use Franson and verify with MapPoint, and these values will now be stored in a database. However, the Franson kit is closed source and now discontinued so I'd rather use something open source going forward.

 

Developer
Jan 20, 2011 at 5:52 AM

The Lat Long coordinates look right for London in WGS84.

I've had success in transforming UTM (Easting, Northing) coordinates to WGS84 and back using Proj4 stings and known coordinate systems with something like this:

        internal static void Wgs84ToUTMProjection(ref double[] xy, ref double[] z)
        {
            var pStart = KnownCoordinateSystems.Geographic.World.WGS1984;
            var pEnd = new ProjectionInfo("+proj=utm +zone=50 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs");
            Reproject.ReprojectPoints(xy, z, pStart, pEnd, 0, z.Length);
        }
Jan 21, 2011 at 9:55 AM

Posted as an issue per Ted's advice - http://dotspatial.codeplex.com/workitem/218.

Thanks again for your help Ted!

Jun 30, 2011 at 10:56 PM
Edited Jun 30, 2011 at 10:58 PM

Hello friends, i is develop one application, i work with MaWindows ActiveX, now i migrate to DotSpatial. My contry is in Two UTM Zone (16 and 17) with MapWindowGeoproc this is my code for reproject

 LBLUTM.Text = "Zona " & MapWinGeoProc.SpatialReference.GetUTMZone(PTCOORDX)
                If LBLUTM.Text = "Zona 16" Then
                    MapWinGeoProc.SpatialReference.ProjectPoint(PTCOORDX, PTCOORDY, "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs", "+proj=utm +zone=16 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
                    LBLUTM.Text &= " X:" & CInt(PTCOORDX) & " Y:" & CInt(PTCOORDY)

                ElseIf LBLUTM.Text = "Zona 17" Then
                    MapWinGeoProc.SpatialReference.ProjectPoint(PTCOORDX, PTCOORDY, "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs", "+proj=utm +zone=17 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
                    LBLUTM.Text &= " X:" & CInt(PTCOORDX) & " Y:" & CInt(PTCOORDY)
                End If

What is the equivalent in DotSpatial?