Converting long/lat to pixel x/y, given a zoom-level

后端 未结 2 1116
不知归路
不知归路 2021-01-02 09:19

I\'m trying to develop a page in ASP.NET that will act as a tile-server for a Google Map

It will pull a collection of latitude/longitude points from the database, th

相关标签:
2条回答
  • 2021-01-02 09:42

    "If it is a Mercator projection, you shouldn't need to worry about the curvature of the earth since all of the lat/lon lines are at equal spacing"

    Perhaps you're thinking of the Geographic (aka Plate Carree) projection? The Mercator projection does have equally spaced lines of longitude, but does not have equally spaced lines of latitude (lat = atan(sinh(y)), so 90° is at infinity).

    BTW, the math for the Mercator projection on a sphere is here, but if Google Maps is using the WGS84 ellipsoid and you need to get it exact it gets more complicated. In that case, I'd look at this, but beware: it's not for the faint of heart.

    0 讨论(0)
  • 2021-01-02 10:01

    Here's some code I'm currently using. It's in PHP.

    // Returns longitude in pixels at a certain zoom level
    function lonToX($lon, $zoom) {
        $offset = 256 << ($zoom-1);
        return round($offset + ($offset * $lon / 180));
    }
    // Returns latitude in pixels at a certain zoom level
    function latToY($lat, $zoom) {
        $offset = 256 << ($zoom-1);
        return round($offset - $offset/pi() * log((1 + sin($lat * pi() / 180)) / (1 - sin($lat * pi() / 180))) / 2);
    }
    

    Based on code from this page, written by this guy.

    Good luck!

    Update: This map is a great way to help understand how tiles work in Google Maps

    Edit: Here's an equivalent set of functions in VB.NET:

    Public Function LonToX(Lon As Double, Zoom as UInteger) As UInteger
        Dim Offset = 256 << (Zoom - 1)
        Return Math.Round(Offset + (Offset * Lon / 180))
    End Function
    
    Public Function LatToY(Lat As Double, Zoom as UInteger) As UInteger
        Dim Offset = 256 << (Zoom - 1)
        Return Math.Round(Offset - Offset / Math.Pi * Math.Log((1 + Math.Sin(Lat * Math.Pi / 180)) / (1 - Math.Sin(Lat * Math.Pi / 180))) / 2)
    End Function
    

    And in C#:

    public uint lonToX(double lon, uint zoom) {
        uint offset = 256 << (zoom - 1);
        return Math.Round(offset + (offset * lon / 180));
    }
    
    public uint latToY(double lat, uint zoom) {
        uint offset = 256 << (zoom - 1);
        return Math.Round(offset - offset / Math.Pi * Math.Log((1 + Math.Sin(lat * Math.Pi / 180)) / (1 - Math.Sin(lat * Math.Pi / 180))) / 2);
    }
    
    0 讨论(0)
提交回复
热议问题