4

I am using sharpmap to render borders (geometry) from MSSQL as PNG image. It all works well, except countries are looking too "wide" on flat image format.

As I understand, I need to create transformation to EPSG:3857 projection, but I have no idea how to do it.

Here's my code

 var map = new Map(new Size(request.Width, request.Height));
 map.BackColor = Color.Transparent;
 var countryGeometry = GeometryFromWKT.Parse(dto.CountryWkt);

 IProvider countryProvider = new GeometryFeatureProvider(countryGeometry);
 var countryLayer = new VectorLayer("country", countryProvider);
 var borderColor = System.Drawing.ColorTranslator.FromHtml("#525252");

 countryLayer.Style.EnableOutline = true;
 countryLayer.Style.Outline = new Pen(borderColor);
 countryLayer.Style.Fill = Brushes.Transparent;
 //does not work with this
countryLayer.CoordinateTransformation = new
                ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory().CreateFromCoordinateSystems(
                    ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84,
                    ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator);

 map.Layers.Add(countryLayer);

 map.ZoomToBox(new Envelope(dto.Envelope.BottomLeft.Longitude,
            dto.Envelope.TopRight.Longitude,
            dto.Envelope.BottomLeft.Latitude,
            dto.Envelope.TopRight.Latitude
        ));

 var img = map.GetMap();

WKT Can be found here https://pastebin.com/PEbpAdxT

Any help is appreciated.

EDIT: This is the image i get now for france and it's region "Limousin". As you can see, it's too "wide". enter image description here

This is the image when i apply transformation, which can be found under code comment does not work with this enter image description here

EDIT 2

I've also tried following for transformation, but this renders blank png (without red cross over it)

 public  ICoordinateTransformation Wgs84toGoogleMercator
        {
            get
            {

                if (_wgs84ToGoogle == null)
                {
                    CoordinateSystemFactory csFac = new ProjNet.CoordinateSystems.CoordinateSystemFactory();
                    CoordinateTransformationFactory ctFac = new CoordinateTransformationFactory();

                    IGeographicCoordinateSystem wgs84 = csFac.CreateGeographicCoordinateSystem(
                      "WGS 84", AngularUnit.Degrees, HorizontalDatum.WGS84, PrimeMeridian.Greenwich,
                      new AxisInfo("north", AxisOrientationEnum.North), new AxisInfo("east", AxisOrientationEnum.East));

                  // var a =  csFac.CreateFromWkt("aa");


                    List<ProjectionParameter> parameters = new List<ProjectionParameter>();
                    parameters.Add(new ProjectionParameter("semi_major", 6378137.0));
                    parameters.Add(new ProjectionParameter("semi_minor", 6378137.0));
                    parameters.Add(new ProjectionParameter("latitude_of_origin", 0.0));
                    parameters.Add(new ProjectionParameter("central_meridian", 0.0));
                    parameters.Add(new ProjectionParameter("scale_factor", 1.0));
                    parameters.Add(new ProjectionParameter("false_easting", 0.0));
                    parameters.Add(new ProjectionParameter("false_northing", 0.0));
                    IProjection projection = csFac.CreateProjection("Google Mercator", "mercator_1sp", parameters);

                    IProjectedCoordinateSystem epsg900913 = csFac.CreateProjectedCoordinateSystem(
                      "Google Mercator", wgs84, projection, LinearUnit.Metre, new AxisInfo("East", AxisOrientationEnum.East),
                      new AxisInfo("North", AxisOrientationEnum.North));

                    ((CoordinateSystem)epsg900913).DefaultEnvelope = new [] { -20037508.342789, -20037508.342789, 20037508.342789, 20037508.342789 };

                    _wgs84ToGoogle = ctFac.CreateFromCoordinateSystems(wgs84, epsg900913);
                }

                return _wgs84ToGoogle;

            }
        }
Robert
  • 3,353
  • 4
  • 32
  • 50
  • Hi Robert. Temporary notes, such as bounties etc are not really useful in the long term in posts, so they're better in comments. Our experience is they usually get left in even after they are outdated or expired. I'd not have noticed except for the request for urgency, which is discouraged here. – halfer Jun 19 '17 at 15:43
  • The author is offering +100 for an answer to this post. – halfer Jun 19 '17 at 15:44
  • Please read [Under what circumstances may I add “urgent” or other similar phrases to my question, in order to obtain faster answers?](//meta.stackoverflow.com/q/326569) - the summary is that this is not an ideal way to address volunteers, and is probably counterproductive to obtaining answers. Please refrain from adding this to your questions. – halfer Jun 19 '17 at 15:44
  • 1
    @halfer thanks. I'll keep that in mind. – Robert Jun 19 '17 at 15:45
  • Are you sure your source data is in EPSG:4326? Not in the french national projection for instance? – pauldendulk Jun 20 '17 at 19:30
  • @pauldendulk Yes. I queried with `select distinct Borders.STSrid from dbo.Regions` and i got 4326 – Robert Jun 21 '17 at 08:57
  • Have you thought about using QGIS and reprojecting the layer manually? https://gis.stackexchange.com/questions/35590/reprojecting-vector-layer-in-qgis – ste-fu Jun 21 '17 at 13:03

1 Answers1

3

CoordinateTransformation that you used actually works.

You are getting blank image because your ZoomToBox coordinates are wrong, so it actually shows you the blank part of the image. If you use map.ZoomToExtents(); function instead, to view the whole image before you zoom, it looks something like this:

France - not zoomed

Now, if I zoom manually in browser to get close-up image of France with this transformation applied, you can see that it's not actually stretched anymore.

France - zoomed

As a conclusion, I'd say that you only need to fix your ZoomToBox coordinates and everything will work just fine. Hope it helps. :)

msmolcic
  • 6,407
  • 8
  • 32
  • 56
  • I tried that too, but mine was blank. I also tried to transform envelope to zoom. Did you used same WKT I posted? – Robert Jun 22 '17 at 07:00
  • @Robert Yea, that's the only one I had. – msmolcic Jun 22 '17 at 08:11
  • That's odd. Could you please put your code to GitHub, maybe some of my dependencies are messed up? – Robert Jun 22 '17 at 08:13
  • for some reason, I can't compile your project. Nuget won't pull anything related to sharpmap. – Robert Jun 22 '17 at 19:42
  • @Robert Do you get any errors or anything else? Try to remove the package and add it again, I installed latest version of it, 1.1.0 and Newtonsoft.Json 4.5.11 on which it depends. It builds without any issues on my PC. – msmolcic Jun 23 '17 at 08:16
  • does it work for you if you convert your project to .NET 4.6.1 ? I pulled sharpmap from git and built it manually to get latest version. Nuget package is kinda old. All works fine until i use transformation. I guess it's something with versions for one of my nuget packages. It's a bit trickier to add it in existing solution with new dependencies. – Robert Jun 23 '17 at 10:53
  • @Robert Works fine with .NET 4.6.1 as well. I had to install Newtonsoft.Json 4.5.11 (which is really old) manually because SharpMap depends on it. You could configure your web.config file to use both, old and new version of Newtonsoft.Json and try to do it like that. – msmolcic Jun 23 '17 at 15:32
  • 1
    Finally. It turns out my code is alright, but since i built sharpmap from their git, i messed up references when i wanted to add DLL manually. Solution was to move code to new project, install sharpmap dependencies manually and then reference that project in website. – Robert Jun 23 '17 at 17:49