convert coordinate system (Latitude longitude) to SphericalMercator (epsg:3785)

Dec 8, 2009 at 12:01 PM

Hi...
i'm newbie in 'GIS' and i want using "Proj.Net" in my project
i need to convert coordinate system (Latitude longitude) to SphericalMercator (epsg:3785) .

if anyone  have a sample please let me know how can i have it.

Dec 16, 2009 at 9:53 AM

In the FAQ there's a page explaining how to reproject between two coordinate systems, here:

http://projnet.codeplex.com/wikipage?title=CreateProjection

 

And if you want to know the WKT for EPSG:4326 (which I assume is what you mean by latitude longitude) and EPSG:3785 systems, then you can see those here:

http://projnet.codeplex.com/wikipage?title=CommonWellKnownText

Coordinator
Dec 16, 2009 at 12:57 PM

here's my code:

 

        private const string Srid4326 = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]]";

        public double[] MercatorToWgs84LatLon(double[] values)
        {
            var mercator = GetMercatorProjection();
            var latlon = (IGeographicCoordinateSystem)CoordinateSystemWktReader.Parse(Srid4326);
            var ctfac = new CoordinateTransformationFactory();
            var transformation = ctfac.CreateFromCoordinateSystems(mercator, latlon);
            var transform = transformation;
            var converted = transform.MathTransform.Transform(values);
            return converted;
        }

        public double[] Wgs84LatLonToMercator(double[] values)
        {
            var mercator = GetMercatorProjection();
            var latlon = (IGeographicCoordinateSystem)CoordinateSystemWktReader.Parse(Srid4326);
            var ctfac = new CoordinateTransformationFactory();
            var transformation = ctfac.CreateFromCoordinateSystems(latlon, mercator);
            var transform = transformation;
            var converted = transform.MathTransform.Transform(values);
            return converted;
        }

        private static ICoordinateSystem GetMercatorProjection()
        {
            var factory = new CoordinateSystemFactory();
            
            var wgs84 = factory.CreateGeographicCoordinateSystem("WGS 84", 
                AngularUnit.Degrees, HorizontalDatum.WGS84, PrimeMeridian.Greenwich,
                new AxisInfo("north", AxisOrientationEnum.North), new
                AxisInfo("east", AxisOrientationEnum.East));

            var parameters = new List<ProjectionParameter>
            {
                new ProjectionParameter("semi_major", 6371000), // 6378137
                new ProjectionParameter("semi_minor", 6371000), // 6378137
                new ProjectionParameter("latitude_of_origin", 0.0),
                new ProjectionParameter("central_meridian", 0.0),
                new ProjectionParameter("scale_factor", 1.0),
                new ProjectionParameter("false_easting", 0.0),
                new ProjectionParameter("false_northing", 0.0)
            };
            var projection = factory.CreateProjection("Mercator", "mercator_1sp", parameters);
            var mercator = factory.CreateProjectedCoordinateSystem("Mercator",
                wgs84, projection, LinearUnit.Metre,
                new AxisInfo("East", AxisOrientationEnum.East), 
                new AxisInfo("North", AxisOrientationEnum.North));
            return mercator;
        }

 

 

Mar 5, 2010 at 3:15 PM

Hi,

Thanks for the code. I need to do the same thing, I'm working with Bing Maps Silverlight Control and it uses Longitude/Latitude most of the time except
for tile layers, which need to be in WGS84 Easting/Northing (I don't know the exact SRID or even terms for these systems). I've done something similar
using SharpGIS binaries (non-Silverlight).

I tried your code above but I get an exception at

var latlon = (IGeographicCoordinateSystem)CoordinateSystemWktReader.Parse(Srid4326);

which says: "'G' is not recognized." I presume this has something to do with ASCII/Unicode - any ideas?

Thanks,
John 

Apr 15, 2010 at 6:50 AM

I suggest this one:

        double[] toMercator(double lon, double lat)
        {
            double x = lon * 20037508.34 / 180;
            double y = Math.Log(Math.Tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
            y = y * 20037508.34 / 180;
            return new double[] {x, y};
        }
        double[] inverseMercator (double x, double y) {
            double lon = (x / 20037508.34) * 180;
            double lat = (y / 20037508.34) * 180;

            lat = 180/Math.PI * (2 * Math.Atan(Math.Exp(lat * Math.PI / 180)) - Math.PI / 2);
            return new double[] {lon, lat};
        }

It's a pure mathematical implementation. If you create a ICoordinateSystem from the provided WKT in faq or the one from abow you will see a .25 shift in y axis.

Apr 15, 2010 at 9:51 AM
Hi irezax, Thanks for that looks like it would have worked well - I had the problem some time ago however so in order to fix I just implemented the conversion on the webservice side (i.e. not in Silverlight) and that worked for me. Cheers, John
Jul 30, 2011 at 8:32 PM

Hello!

Eventually, I decided to use the pure mathematical method  to convert Mercator Sphere coordinates to latitude and longitude. I needed it in JavaScript and implemented it in the following way:

function MercatorToLatLon(mercX, mercY) {
 
    var rMajor = 6378137; //Equatorial Radius, WGS84
    var shift  = Math.PI * rMajor;
    var lon    = mercX / shift * 180.0;
    var lat    = mercY / shift * 180.0;
    lat = 180 / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180.0)) - Math.PI / 2.0);
 
    return { 'Lon': lon, 'Lat': lat };
}

You can read it up in my blog at greater length.

Thanks!

Sep 22, 2011 at 9:30 AM

How to convert  to Mercator lon=-180, lat=-90 ( min of bounding box in wgs84 of the world map)?

Sep 22, 2011 at 10:24 AM

Follow me should to be change to :

double[] toMercator(double lon, double lat) 
{
double
x = lon * 20037508.34 / 180; double y = -180; if(lat>-90) y = Math.Log(Math.Tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180); y = y * 20037508.34 / 180;
return new double[] {x, y};
 }

Regards,
TrieuVy

Feb 22, 2012 at 1:02 PM
Edited Feb 22, 2012 at 2:19 PM

I have the following NAD83 UTM coordinate:

Easting: 686029.702258

Northing: 3581213.621173

zone: 15

Using the pure math solution from irezax above, calling the function as 

inverseMercator (686029.702258, 3581213.621173)

 

I get the following result:

lat: 30.602349476368449

long: 6.1627096689832594

I get similar results using the Proj.Net solution provided by D_Guidi.

Using an online converter, I was able to get something closer to what I am expecting: 

lat: 32.35238307052292

long: -91.0230710652583

Can anyone shed any light on what I am doing wrong?

Coordinator
Mar 15, 2012 at 9:24 AM

take a look here: http://alastaira.wordpress.com/2011/01/23/the-google-maps-bing-maps-spherical-mercator-projection/