6

While writing some unit tests I thought it would be convenient/possible to use ProjNet to convert from EPSG:4326 into several other coordinate systems (3875,3395). I figured it would be as easy as grabbing the WKT values from spatialreference.org:

Add a reference to ProjNet and running the following code:

var cf = new ProjNet.CoordinateSystems.CoordinateSystemFactory ( );
var f = new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory ( );
var sys4326 = cf.CreateFromWkt ( wkt4326 );
var sys3857 = cf.CreateFromWkt ( wkt3857 );
var sys3395 = cf.CreateFromWkt ( wkt3395 );
var transformTo3875 = f.CreateFromCoordinateSystems ( sys4326, sys3857 );
var transformTo3395 = f.CreateFromCoordinateSystems ( sys4326, sys3395 );

But 3857 and 3395 could not be parsed. I googled around and found a workable 3857 though I haven't confirmed it produces a correct result. I continue to get an error parsing 3395 (Expecting ('PROJECTION') but got a 'UNIT' at line 1 column 296.).

Perhaps the "OGC WKT" can be modified in a predicable way to work with ProjNet? Or perhaps ProjNet is not the best .NET solution for re-projecting coordinates?

const string wkt4326 = "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\"]]";
const string wkt3857 = "PROJCS[\"Popular Visualisation CRS / Mercator\", GEOGCS[\"Popular Visualisation CRS\", DATUM[\"Popular Visualisation Datum\", SPHEROID[\"Popular Visualisation Sphere\", 6378137, 0, AUTHORITY[\"EPSG\",\"7059\"]], TOWGS84[0, 0, 0, 0, 0, 0, 0], 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[\"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\"]]";
const string wkt3395 = "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\"]],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],PROJECTION[\"Mercator_1SP\"],PARAMETER[\"central_meridian\",0],PARAMETER[\"scale_factor\",1],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],AUTHORITY[\"EPSG\",\"3395\"],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH]]";
2
  • projnet.codeplex.com/discussions/268940 discusses 3857 issue.
    – ca0v
    Apr 13 '12 at 18:25
  • 1
    Moving the AUTHORITY to be final element in the WKT resolves this issue. Make sure the WKT follows the syntax diagram shown here <coordinate system> = <projected cs> | <geographic cs> | <geocentric cs> <projected cs> = PROJCS["<name>", <geographic cs>, <projection>, {<parameter>,}* <linear unit>] <projection> = PROJECTION["<name>"] <parameter> = PARAMETER["<name>", <value>] <value> = <number>
    – ca0v
    Apr 13 '12 at 19:52
3

I found that manually conforming my WKT to the BNF described here eliminates the errors. Content repeated below:

<coordinate system> = <projected cs> | <geographic cs> | <geocentric cs>
<projected cs> = PROJCS["<name>", <geographic cs>, <projection>, {<parameter>,}* <linear unit>]
<projection> = PROJECTION["<name>"]
<parameter> = PARAMETER["<name>", <value>]
<value> = <number>

<geographic cs> = GEOGCS["<name>", <datum>, <prime meridian>, <angular unit>]
<datum> = DATUM["<name>", <spheroid>]
<spheroid> = SPHEROID["<name>", <semi-major axis>, <inverse flattening>]
<semi-major axis> = <number> NOTE: semi-major axis is measured in meters and must be > 0.
<inverse flattening> = <number>
<prime meridian> = PRIMEM["<name>", <longitude>]
<longitude> = <number>

<angular unit> = <unit>
<linear unit> = <unit>
<unit> = UNIT["<name>", <conversion factor>]
<conversion factor> = <number>

<geocentric cs> = GEOCCS["<name>", <datum>, <prime meridian>, <linear unit>]

So for my specific problem (EPSG:3395) the resulting WKT would be:

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], // required, missing from spatialreference.org
    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"]]
3

I had the same error (with a different SRID). Solution was to use the/an Esri WKT on spatialreference.org, which does not cause an issue with the ProjNet CoordinateSystemWktReader

1
  • 1
    Very good info and should probably be the answer! Thank you. Feb 18 '20 at 18:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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