androidxamarinxamarin.formsmapsui

How do I translate the output of map.Envelope.BottomLeft to a LatLon?


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.


Solution

  • 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 };
        }