TomasJohansson / crsTransformations-dotnet

Coordinate Reference System Transformations. This is a .NET library implemented with F#, but also usable from C#. Most of the test code is actually written with C#. The third-part libraries used from the F# code may also have been implemented with C#.
MIT License
6 stars 5 forks source link

Incorrect work of ProjNet 2.0 while crsTransformations works fine #2

Closed fjod closed 2 years ago

fjod commented 2 years ago

Hello! I found wierd issue with ProjNet and hope you can shed some light on it. I checked sources of crsTransformations, there is .csv file with WKT strings assigned to EPSG codes. In code you get WKT string by code (SridReader.fs) and use ProjNet classes to create CoordinateSystems and calculate result (CrsTransformationAdapterProjNet.fs). In my project I have many coordinate systems without EPSG codes, so I use ProjNet with WKTs and calculate result. It gives correct result when I transform GEOCS to PROJCS, but if I try to calculate between GEOCS to GEOCS, I receive results with mistake ~100 meters.

Consider code (dead simple):

string ProjSk42 = " GEOGCS[\"Pulkovo 1942\",DATUM[\"Pulkovo_1942\",SPHEROID[\"Krassowsky 1940\",6378245,298.3,AUTHORITY[\"EPSG\",\"7024\"]],TOWGS84[23.92,-141.27,-80.9,0,0.35,0.82,-0.12],AUTHORITY[\"EPSG\",\"6284\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4284\"]]";
string ProjWgs84 = "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.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]]";
CoordinateSystemFactory qq = new CoordinateSystemFactory();

var wgs= qq.CreateFromWkt(ProjWgs84);
var sk42 = qq.CreateFromWkt(ProjSk42);
CoordinateTransformationFactory ctfac = new ();

ICoordinateTransformation trans = ctfac.CreateFromCoordinateSystems( wgs,sk42);   
 double[] fromPoint = { 66, 76 };
 double[] toPoint = trans.MathTransform.Transform(fromPoint); 

I tried many WKT strings, get them from your CSV, from epsg.io etc. Your lib uses same ProjNet classes:

let crs = _coordinateSystemFactory.CreateFromWkt(wellKnownText)
let trans: ICoordinateTransformation  = ctFact.CreateFromCoordinateSystems(sourceCrs, targetCrs)
let result: double[] = trans.MathTransform.Transform(xy)

So I dont understand why ProjNet gives me bad result while crsTransformations works great. Maybe you have some ideas about it? I even checked binary content of ProjNet.dll, it's same for both cases :/ I answered this question here and got answers that ProjNet is outdated.

Also a suggestion, can you provide a feature to construct coordinateSystem from WKT ?

fjod commented 2 years ago

I found the error, args must be passed in correct order:

double[] fromPoint = { 76, 66 };
 double[] toPoint = trans.MathTransform.Transform(fromPoint); 

My suggestion about creating WKTs from code is still up though

TomasJohansson commented 2 years ago

Okay, I think I will add that feature, probably within a week or so. But it will just be a forwarding of a provided WKT-CRS string to an implementation, and the implementation libraries may not always support exactly the same format of the string. ESRI vs OGC: https://en.wikipedia.org/wiki/Well-known_text_representation_of_coordinate_reference_systems#ESRI_vs_OGC "DotSpatial.Projections" seem to use the Esri version, considering their method name "ProjectionInfo.FromEsriString"

TomasJohansson commented 2 years ago

WKT-CRS is now supported in version 3.0.0