3

I have a project with C# that contains a CEFSharp viewer showing a webpage with a map that I've created.I'm trying to add a marker in the map sending the parameters from C# to a function in the webpage javascript.

The problem appears when I try to transform the coordinates of the marker with the ProjNet library in C#. I have followed this post to make the transformation and the code works, but for the Y coordinate, I get a deviation always.

The original coordinates are in EPSG:25831 CRS.

x = 589721.77, y = 44221978.1

And I want them in EPSG:3857, according to epsg.io the coordinates in EPSG:3857 should be:

x = 450868.62, y = 4857687.93

and that is correct for me, but when I do it through the ProjNet library I get an incorrect Y coordinate, the coordinates I get are:

x = 450868.61766004807, y = 4830249.5985677531

so the transformation for the X is correct but for the Y is not. I've tried different coordinates and always the same deviation. the code I use is the same from the post I've mentioned, is as it follows:

        double[] xy = { this.x, this.y };

        var cf = new CoordinateSystemFactory();
        var f = new CoordinateTransformationFactory();
        string wkt25831 = "PROJCS[\"ETRS89 / UTM zone 31N\", GEOGCS[\"ETRS89\", DATUM[\"D_ETRS_1989\", SPHEROID[\"GRS_1980\", 6378137, 298.257222101]], PRIMEM[\"Greenwich\", 0], UNIT[\"Degree\", 0.017453292519943295]], PROJECTION[\"Transverse_Mercator\"], PARAMETER[\"latitude_of_origin\", 0], PARAMETER[\"central_meridian\", 3], PARAMETER[\"scale_factor\", 0.9996], PARAMETER[\"false_easting\", 500000], PARAMETER[\"false_northing\", 0], UNIT[\"Meter\", 1]]";
        string wkt3857 = "PROJCS[\"WGS 84 / World Mercator\",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\"]],PROJECTION[\"Mercator_1SP\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",0],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],AUTHORITY[\"EPSG\",\"3395\"]]";

        var sys25831 = cf.CreateFromWkt(wkt25831);
        var sys3857 = cf.CreateFromWkt(wkt3857);

        var transformTo3857 = f.CreateFromCoordinateSystems(sys25831, sys3857);

        double[] ret = transformTo3857.MathTransform.Transform(xy);

        this.x = ret[0];
        this.y = ret[1];

Any idea why I'm getting this deviation? Maybe something with the WKT for the EPSG:3857 is wrong?

3 Answers 3

2

Finally I was able to make the transformation correctly. Thanks to @mkennedy for the answer because that code was useful for the WKT 3857 but I also needed to change the WKT 25831.

I post the strings I have finally used to make the transformation correctly in case someone wants to use it:

string wkt25831 = "PROJCS[\"ETRS89 / UTM zone 31N\",GEOGCS[\"ETRS89\",DATUM[\"European_Terrestrial_Reference_System_1989\",SPHEROID[\"GRS 1980\",6378137,298.257222101,AUTHORITY[\"EPSG\",\"7019\"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY[\"EPSG\",\"6258\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4258\"]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",3],PARAMETER[\"scale_factor\",0.9996],PARAMETER[\"false_easting\",500000],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],AUTHORITY[\"EPSG\",\"25831\"]]";
string wkt3857 = "PROJCS[\"WGS 84 / World Mercator\",GEOGCS[\"WGS 84 sphere\",DATUM[\"WGS_1984 sphere\",SPHEROID[\"WGS 84 sphere\",6378137,0.0]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]]],PROJECTION[\"Mercator_1SP\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",0],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH]]";

The rest of the code posted in the question works fine as it was.

1

Yes. Notice that at the end of the string you're using for wkt3857 it says that the Authority well-known ID is 3395, and not 3857. ProjNet is using the ellipsoidal version of transverse Mercator projection. You need to force it to use the spherical version. One way is to modify the wkt3857 string from:

    string wkt3857 = "PROJCS[\"WGS 84 / World Mercator\",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\"]],PROJECTION[\"Mercator_1SP\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",0],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],AUTHORITY[\"EPSG\",\"3395\"]]";

to this:

    string wkt3857 = "PROJCS[\"WGS 84 / World Mercator\",GEOGCS[\"WGS 84 sphere\",DATUM[\"WGS_1984 sphere\",SPHEROID[\"WGS 84 sphere\",6378137,0.0]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]]],PROJECTION[\"Mercator_1SP\"],PARAMETER[\"latitude_of_origin\",0],PARAMETER[\"central_meridian\",0],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH]]";
3
  • Still getting the same exact result. Maybe the problem is not with the WKT for EPSG:3857. I do not understand what's wrong.
    – mrvinent
    Sep 14, 2018 at 10:58
  • Give me a few hours and I'll check the numbers.in another software.
    – mkennedy
    Sep 14, 2018 at 12:38
  • Thanks for the answer, it's been useful for the 3857 SRS but I have also changed the 25831 SRS string. I'm going to post both strings in a separate answer.
    – mrvinent
    May 23, 2019 at 8:47
1

This works right out of the box for 4326 and 3857 at least (leaving aside textual WKT definitions):

// Coordinate systems
var cs4386 = ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84;
var cs3857 = ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator;

// Transformation
var ctfac = new CoordinateTransformationFactory();
var trans = ctfac.CreateFromCoordinateSystems(cs4326, cs3857);

This answer comes from a GitHub thread. Possibly ProjNet4GeoAPI has some other coordinate systems baked in as well which you can make use of and will work as expected and deliver correct transformation results.

2
  • I'm having medium accuracy problem with EPSG:2393. All WGS-84 transformations are off by several hundred meters. On NodeJS / Proj4 a transformation can be defined to improve accuracy. I dunno how such transformation could be defined with ProjNet. Jan 2 at 14:51
  • I changed my code from ProjNet into github.com/TomasJohansson/crsTransformations-dotnet and now my conversions are accurate. Jan 4 at 16:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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