Using Mapsui, how do I create a new transformation class for coordinate system read from shapefile prj file?

795 views Asked by At

How do I create a new transformation class compatible with MapSui.Projections.ITransformation interface using ProjNet4GeoAPI that reads the source coordindate system from a prj file.

From Mapsui source code, there is a MinimalTransformation that implements ITransformation interface to convert between SphericalMercator and WGS84.

From Mapsui documentation : The out of the box Mapsui support for projections is limited. The MinimalProjection class only projects between SphericalMercator (EPSG:3857) and WGS84 (EPSG:4326). It is however possible to create your own Transformation. You need to implement the ITransformation interface. Within this implementation you need to use some other projection library. A recommended one is ProjNet4GeoAPI.

I can create a working the transformation class with ProjNet4GeoAPI but it implements GeoAPI.CoordinateSystems.Transformations.ICoordinateTransformation not Mapsui.Projection.ITransformation

            // (FROM SOURCE) prj name: NAD_1983_StatePlane_Massachusetts_Mainland_FIPS_2001"
            ICoordinateSystemFactory csFac = new ProjNet.CoordinateSystems.CoordinateSystemFactory();
            string file = @"C:\DRC_Data\Arcview\USA\Townships\NYTOWNS_POLY.prj";
            string wkt= System.IO.File.ReadAllText(file);
            var csFrom = csFac.CreateFromWkt(wkt);

            //(TO) Prj name: "WGS 84 / Pseudo-Mercator"
            file = @"C:\DRC_Data\Arcview\3857.prj";
            wkt = System.IO.File.ReadAllText(file);
            ICoordinateSystem csTo = csFac.CreateFromWkt(wkt);

            //Step 2) Create transformation class.
            CoordinateTransformationFactory ctFac = new CoordinateTransformationFactory();

            //To 3857                
            //var is ICoordinateTransformation
            ICoordinateTransformation ct = ctFac.CreateFromCoordinateSystems(csFrom, ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator);

How do I use the ICoordinateTransformation class with Mapsui? Do I create a projection class like SphericalMercator in Mapsui.Projection (see code below)?

From Mapsui.Projection:

public class MinimalTransformation : ITransformation
    {
        private readonly IDictionary<string, Func<double, double, Point>> _toLonLat = new Dictionary<string, Func<double, double, Point>>();
        private readonly IDictionary<string, Func<double, double, Point>> _fromLonLat = new Dictionary<string, Func<double, double, Point>>();

        public MinimalTransformation()
        {
            _toLonLat["EPSG:4326"] = (x, y) => new Point(x, y);
            _fromLonLat["EPSG:4326"] = (x, y) => new Point(x, y);
            _toLonLat["EPSG:3857"] = SphericalMercato.ToLonLat;
            _fromLonLat["EPSG:3857"] = SphericalMercator.FromLonLat;
        }

Source code: https://github.com/garykindel/ShapefileProjectionDemo Used Mapsui 2.0.0-beta.22 nuget package and I manually built Mapsui.desktop.dll from master.

1

There are 1 answers

1
pauldendulk On BEST ANSWER

You already did the hard part which is to get the ProjNet4GeoAPI projection right.

For your own projection class you could copy the MinimalTransformation class. Then add dictionary entries for the from and to projections to your custom projection.

            _toLonLat["EPSG:4326"] = (x, y) => new Point(x, y);
            _fromLonLat["EPSG:4326"] = (x, y) => new Point(x, y);
            _toLonLat["EPSG:3857"] = SphericalMercato.ToLonLat;
            _fromLonLat["EPSG:3857"] = SphericalMercator.FromLonLat;
            _toLonLat["EPSG:CUSTOM"] = MethodToProjectFromMyCustomProjectionToLonLat;
            _fromLonLat["EPSG:CUSTOM"] = MethodToProjectToMyCustomProjectionFromLonLat;

Set "EPSG:CUSTOM" on the CRS of the datasource.