Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am working with the ESRI Silverlight API. I found THIS post in the ESRI forums and THIS OTHER which show how to convert between WGS84 geographic coordinates and WebMercator coordinates. I want to do the same thing but from NAD27 Geographic coordinates to WebMercator. I found the spatial reference for NAD27 at the spatialreference website with the WKID 4267 and changed the code accordingly with the radius of 6378206.4 and degree 0.01745329251994328 respectively. I ended up with this function (in c#):

private MapPoint GeographicToWebMercator(MapPoint point)
{
        double a = point.Y * 0.01745329251994328;
        double y = (6378206.4/2) * Math.Log((1.0 + Math.Sin(a)) / (1.0 - Math.Sin(a)));

        double x = 6378206.4 * (point.X * 0.01745329251994328);
        return new MapPoint(x, y);
}

Unfortunately, my dots are displaced from where they should be. So, this is not working as intended. I was wondering if someone can take a look at it and tell me what is wrong... or if I can do this projection this way to begin with. The function, as is, is not checking for null "point" or any other data just yet. But, please, don't focus on that. I am just interested in the calculation per se. Thanks!

share|improve this question
3  
Displaced in what directions and by how much? How do you know where they "should" be? (It's possible the reference points are wrong, after all.) Please note that your equations are not correct for either WGS84 nor NAD27, both of which use ellipsoids with flattenings near 1/300: these equations are for a sphere only. (One way to tell that is to notice that the only parameter entering into the calculations is a radius; there is nothing indicating the flattening.) –  whuber Nov 27 '12 at 22:28
    
Thanks for your comment. I know my markers are off because my reference layer has been thoroughly tested. We can also simply add a World Imagery layer to our map and see the physical locations we are referring on our own layer and the markers are off from those points. So, I don't think it gets any better than that to know we are off. How off are the markers, not much. I don't have them in front of me at the moment; but speculating I'd say anything between 200 and 500 meters and if I remember well, they all seem to be shifted in a north-west direction. –  Luis Garcia Nov 30 '12 at 15:57
    
Also, if I were to add the flattening how would I do that? any ideas? Thanks! –  Luis Garcia Nov 30 '12 at 15:58
1  
The discrepancies due to confusing ellipsoidal and spherical datums will amount to tens of kilometers, typically, so that is not the explanation. The displacements you note are consistent with (although a bit large) for the shift between the NAD83 and NAD27 datums. This shift cannot be programmed with any simple formula, because it occurs irregularly throughout the US: you need to look up the amount of shift on a grid and interpolate. This is done with NADCON. If your area of interest is very small, a constant vector translation will do. –  whuber Nov 30 '12 at 17:05
1  
Re the flattening: it sounds like you don't need it, but for the record the y formula is corrected to y = (R/2) [log((1 + sin(phi)) / (1 - sin(phi))) - e log((1 + e sin(phi)) / (1 - e sin(phi)))] where e, the eccentricity, equals sqrt(2f-f^2) = 0.081819190842621 and R is the semi-major axis, 6378137.0 m. As before, phi is the (geodetic) latitude. The x formula uses the same value of R as the y formula. –  whuber Nov 30 '12 at 17:14

2 Answers 2

If you don't mind making a round trip to the server, and you have a 10.1 geometry service available to you, you can use the Esri Rest API Project Geometries operation.

If Transformation is not specified, a search is made through a set of default GeoTransformations. Currently, the following default transformations are used when applicable:

esriSRGeoTransformation_NAD_1927_TO_NAD_1983_NADCON, forward and reverse, WKID=1241

esriSRGeoTransformation_NAD1983_To_WGS1984_1, forward and reverse, WKID=1188

esriSRGeoTransformation_NAD1927_To_WGS1984_4, forward and reverse, WKID=1173

share|improve this answer
    
Thanks for your reply! I tried this solution already and because of the amount of data our application handles dynamically (adds and deletes markers on the fly per user's demand) it is a little slow and (this may be something with our server) it seems to shut the operation after many continuous hits with 3000+ projections. That is why I like this solution doing the projections locally better. –  Luis Garcia Nov 30 '12 at 16:01

I'd recommend you try the Proj.NET library (a Proj4 implementation for .Net) in your application and let Proj.NET do the coordinate transformations for you. It should be compatible with Silverlight by way of C#.

Here's a blog post with a C# example showing implementation.

I took a crack at it in a simple Windows Form app. Here's a screenshot of it..

enter image description here

And this is the C# code I used, of course you will need to have referenced the ProjNet.dll in your project..

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

//using ProjNet.Converters; // didn't need this one
using ProjNet.Converters.WellKnownText;
using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;

namespace ProjNetTest
{
    public partial class projNetTestForm : Form
    {
        public projNetTestForm()
        {
            InitializeComponent();

            // BassPro, Springfield MO
            // long: -93.29592962, lat: 37.18069720
            xTB.Text = "-93.29592962";
            yTB.Text = "37.18069720";
        }

        private void convertButton_Click(object sender, EventArgs e)
        {
            // Get the NAD27 Point Coords as X(long) Y(Lat)..
            double fromX = Convert.ToDouble(xTB.Text);
            double fromY = Convert.ToDouble(yTB.Text);
            double[] nad27Point = new double[] { fromX, fromY };

            // To begin with, I tested against WGS84 coords.
            // Init the WGS84 rules..
            // ICoordinateSystem gcs_WGS84 = GeographicCoordinateSystem.WGS84;

            // Init the NAD27 rules..
            string epsg4267 = "GEOGCS[\"NAD27\",DATUM[\"North_American_Datum_1927\",SPHEROID[\"Clarke 1866\",6378206.4,294.9786982138982,AUTHORITY[\"EPSG\",\"7008\"]],AUTHORITY[\"EPSG\",\"6267\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4267\"]]";
            ICoordinateSystem gcs_NAD27 = CoordinateSystemWktReader.Parse(epsg4267) as ICoordinateSystem;

            // Init the WebMerc rules, and note the "gotchas!" at that link (this was eating me alive at first)..
            // READ THIS:
            // http://alastaira.wordpress.com/2011/01/23/the-google-maps-bing-maps-spherical-mercator-projection/
            string epsg3857_HACK = "PROJCS[\"Popular Visualisation CRS / Mercator\",GEOGCS[\"Popular Visualisation CRS\",DATUM[\"WGS84\",SPHEROID[\"WGS84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7059\"]],AUTHORITY[\"EPSG\",\"6055\"]],PRIMEM[\"Greenwich\", 0, AUTHORITY[\"EPSG\", \"8901\"]],UNIT[\"degree\", 0.0174532925199433, AUTHORITY[\"EPSG\", \"9102\"]],AXIS[\"E\", EAST], AXIS[\"N\", NORTH], AUTHORITY[\"EPSG\",\"4055\"]],PROJECTION[\"Mercator\"],PARAMETER[\"semi_minor\",6378137],PARAMETER[\"False_Easting\", 0],PARAMETER[\"False_Northing\", 0],PARAMETER[\"Central_Meridian\", 0],PARAMETER[\"Latitude_of_origin\", 0],UNIT[\"metre\", 1, AUTHORITY[\"EPSG\", \"9001\"]],AXIS[\"East\", EAST], AXIS[\"North\", NORTH],AUTHORITY[\"EPSG\",\"3785\"]]";
            IProjectedCoordinateSystem gsc_WebMerc = CoordinateSystemWktReader.Parse(epsg3857_HACK) as IProjectedCoordinateSystem;

            // Perform the coordinate transformation between these systems.
            CoordinateTransformationFactory transformer = new CoordinateTransformationFactory();
            ICoordinateTransformation coordTransform = transformer.CreateFromCoordinateSystems(gcs_NAD27, gsc_WebMerc as ICoordinateSystem);

            double[] webMercPoint = coordTransform.MathTransform.Transform(nad27Point);

            double webMercX = (double)webMercPoint[0];
            double webMercY = (double)webMercPoint[1];

            resultTB.Text = "X: " + webMercX.ToString() + "\r\nY: " + webMercY.ToString();
        }
    }
}

And finally, here is where QGIS, with the Bing aerial (OpenLayers plugin) shows my point computation. I hovered my mouse over the position in question so it appears in the status area, below:

enter image description here

If you want to compare it with where Google places that Lat/Long, this is the link: http://maps.google.com/?ll=37.18069720,-93.29592962

share|improve this answer
    
thanks for all your efforts! this is awesome! I will try this and see how it works. –  Luis Garcia Nov 30 '12 at 16:06
    
NP, Luis. Admittedly, I'm still curious whether or not this approach will side-step datum shift issues. I'll be interested to know the outcome. –  elrobis Nov 30 '12 at 19:30
    
Thanks again. It does project; but south of the actual position. I measured the shift and they are off roughly 14 miles south from where they are supposed to be. So, I guess there is something going on with the 3857 projections that is not projecting the latitude correctly. I need to work on something else; but I will go back to this in a couple of days or so. Thanks for your help! Much appreciated. –  Luis Garcia Dec 3 '12 at 18:58
    
Quick question, Is that application on the screen shot created with the ESRI toolkit? Or is it google maps? The reason I ask is because, in reading the ESRi documentation, I found that for 102100 they have a unit of ESRImeters... whatever that is. So, I guess they came up with their own unit for projections?? I may have misunderstood the documentation, so don't trust my statement completely. –  Luis Garcia Dec 3 '12 at 19:07
    
Nope, my first screenshot is the little test form I created just to get a button that would run the routine---the second is QGIS showing Bing aerials projected to 3857. I just needed some way to test whether or no my C# code was converting coordinates and getting "in the ballpark". The part that should interest you the most is the convertButton_Click() function in the code sample, which is what you would want to implement into your silverlight client, and drive using some form of mouse_move event. –  elrobis Dec 3 '12 at 19:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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