[GIS] How to get screen coordinate from geographic one

coordinate systemplacesspherical-geometryweb-mercator

I need to know, how can I convert some geographic coordinates to the screen one.

I want to remind you about desktop coordinates system, how it look like:

enter image description here

I've developed soft, which is loading map fragments into matrix ( 10×10 ) in the fullscreen mode. The map images are loading perfectly.

But I have a task to draw some real elements on map, which do have longitude, latitude values.

So… I first of all think to convert geographic data to the web mecator values by using such a formulas:

    internal Models.PointGeospatial ConvertFromMercatorToSpherical(double mercatorX, double mercatorY)
    {
        if (Math.Abs(mercatorX) < 180 && Math.Abs(mercatorY) < 90) return null;
        if ((Math.Abs(mercatorX) > 20037508.3427892) || (Math.Abs(mercatorY) > 20037508.3427892)) return null;

        double subitemFirst = mercatorX / 6378137.0;
        double subitemSecond = subitemFirst * 57.295779513082323;
        double subitemThird = Math.Floor((double)((subitemSecond + 180.0) / 360.0));
        double subitemFourth = subitemSecond - (subitemThird * 360.0);
        double subitemFifth = 1.5707963267948966 - (2.0 * Math.Atan(Math.Exp((-1.0 * mercatorY) / 6378137.0)));

        var model = new Models.PointGeospatial()
        {
            Longitude = subitemFourth,
            Latitude = subitemFifth * 57.295779513082323
        };

        return model;
    }

    internal Models.PointMercator ConvertFromSphericalToMercator(double longitude, double latitude)
    {
        if ((Math.Abs(longitude) > 180 || Math.Abs(latitude) > 90)) return null;

        double subitemFirst = longitude * 0.017453292519943295;
        double x = 6378137.0 * subitemFirst;
        double subitemSecond = latitude * 0.017453292519943295;

        var model = new Models.PointMercator()
        {
            X = 6378137.0 * subitemFirst,
            Y = 3189068.5 * Math.Log((1.0 + Math.Sin(subitemSecond)) / (1.0 - Math.Sin(subitemSecond)))
        };

        return model;
    }

Then I'm getting such values after conversion:


Building Id: 302

Geographic data: { Longitude: 37.5303305475 ; Latitude: 55.7481343179 }

Mercator data: { X: 4177857.2858509403; Y: 7508438.839224923 }

Really… I don't even imagine how could I place correctly the item on map just only knowing its longitude, latitude values and its mercator equivalent with having 640×480 opened window for e.g., on which I must place some pushpins…

The one detail I've foud, that first three digits from mercator values are not changing for the one city (and I understand they must not ), so the task to set a correct place for the item in the map with exact zoom level is rather diffcult for me and I don't understand how to solve this problem.

I'm listening for you suggestions, thanks!

Best Answer

To do this, you need to know the Bounds of your Viewport in Geospatial Terms.

In your scenario, your top left corner is (0,0) and your bottom right is (640,480) in screen coordinates.

So, you will need to transform/map the (0,0) and the (640,480) Screen Coordinates to a Lat/Lon or Mercator value, then it is just a simple matter of interpolating proportionally.

If you have fixed Tile Sets, with no panning or zooming then you can hard code the 4 corners, however, if you need to pan and zoom, I would recommend you consider looking at OpenLayers as this functionality is built in.

In what you are attempting to do, I would have started with Openlayers in the first place as it is designed to handle exactly what you want to do with the Minimal Amount of Coding.

Related Question