0

I'm creating an app with MapsUI and Xamarin.Forms.

"BottomLeft" is of type "Point" and has values: X: -20037508.342789 Y: -20037508.342789

I'm not really sure what these values even are. I've read they might be pixels, but that doesn't make a whole lot of sense to me. TopRight is the same values negated. I can't seem to get anything useful out of this information.

MyMapControl.Viewport.ScreenToWorld(map.Envelope.BottomLeft) just gives me a point with the Y coordinate negated (so it's positive now).

Any help would be greatly appreciated.

Robert McCraw
  • 663
  • 3
  • 8
  • 22
  • 3
    http://mapsui.com/documentation/projections.html#the-most-common-scenario – Jason Aug 07 '19 at 17:17
  • @Jason Thanks, this helped. Seeing the juxtaposition of the two coordinate formats/projections helped me understand what I was looking at. – Robert McCraw Aug 09 '19 at 21:18

2 Answers2

0

It depends on what projection your map is using. Mapsui's samples often use the openstreetmap background map. This map is in a projection called SphericalMercator. In this case you can use the Mapsui class SphericalMercator with the ToLonLat and FromLonLat methods.

Here is some sample code.

Here some more documentation on projections in Mapsui.

pauldendulk
  • 1,378
  • 12
  • 23
0

Ok, I figured it out. I was trying to grab the "Envelope" of MapsUI's MapView.Map

What I really needed was MapView.Viewport.Extent.

I had a second problem where I was trying to grab this information before the map was loaded. That's why I always got X: -20037508.342789 Y: -20037508.342789 for bottom left.
This notation is in EPSG:3857 format and these coordinates equate to the south pole. I wanted traditional "lat/lng" which is EPSG:4326.

So first I waited til the map was loaded to grab the coordinates, then I found this formula for conversion from EPSG:3857 to EPSG:4326 and implemented it in C#:

    private double[] Convert3857To4326(double X, double Y)
    {
        double lng = X * 180 / 20037508.34;

        double lat = Y / (20037508.34 / 180);
        lat = ((Math.Atan(Math.Pow(Math.E, ((Math.PI / 180) * lat))))/(Math.PI / 360)) - 90;

        return new double[] { lng, lat };
    }

If you need to go the other way, here's the inverse:

    private double[] Convert4326To3857(double lat, double lng)
    {
        double x = lng * 20037508.34 / 180;

        double y = Math.Log(Math.Tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
        y = y * 20037508.34 / 180;

        return new double[] { x, y };
    }
Robert McCraw
  • 663
  • 3
  • 8
  • 22