Преобразование долготы / широты в пиксели x / y при заданном уровне масштабирования

Я пытаюсь разработать страницу в ASP.NET, которая будет действовать как тайловый сервер для карты Google.

Он извлечет набор точек широты / долготы из базы данных, а затем отобразит их в виде маленьких красных точек на прозрачном фоне с заданным уровнем масштабирования (по умолчанию: 15).

Затем он вернет результат в виде изображения типа GIF.

Были ли разработаны какие-либо алгоритмы или библиотеки, которые позволят мне взять этот набор широт / долгот и преобразовать их в набор координат 2D пикселей при заданном уровне масштабирования?

(Все это делается на стороне сервера, поэтому я не могу использовать Google Maps API.)


Обновление: нашел образец кода в Perl, который делает что-то похожее:

http://blog.barros.ws/2009/03/06/convert-lat-lng-and-zoom-values-to-pixel-xy-on-a-map/

Проблема в том, что я не знаю Perl, и у меня действительно нет времени, чтобы открыть книгу и изучить ее.

Может ли кто-нибудь помочь мне расшифровать, что творится в этой функции?

sub Google_Coord_to_Pix
{
    my $value   = shift ;
    my $lat = shift ;
    my $lng = shift ;
    my @d       = ( ) ; 
    my $e       = 0 ;

    $d[1] = sprintf("%0.0f", $$value{'bmO'} + $lng * $$value{'pixLngDeg'} ) ;

    $e = sin($lat * $$value{'Wa'}) ;

    if( $e > 0.99999 )
    {
        $e = 0.99999 ;
    }

    if( $e < -0.99999 )
    {
        $e = -0.99999 ;
    }

    $d[0] = sprintf("%0.0f", $$value{'bmO'} + 0.5 * log((1 + $e) / (1 - $e)) * (-1) * $$value{'pixLngRad'} ) ;

    return (@d) ;
}

person Jonathan    schedule 20.10.2009    source источник


Ответы (2)


«Если это проекция Меркатора, вам не нужно беспокоиться о кривизне Земли, поскольку все линии широты и долготы находятся на одинаковом расстоянии»

Возможно, вы думаете о проекции Географическая (она же Плейт Карри)? В проекции Меркатора линии долготы расположены на одинаковом расстоянии, но нет линий широты на одинаковом расстоянии (lat = atan (sinh (y)), поэтому 90 ° находится на бесконечности).

Кстати, математика для проекции Меркатора на сферу находится здесь, но если Google Maps использует эллипсоид WGS84, и вам нужно уточнить его, он становится более сложным. В этом случае я бы посмотрел на this, но будьте осторожны: это не для слабонервных.

person lguy    schedule 21.10.2009

Вот код, который я сейчас использую. Это в 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);
}

На основе кода с этой страницы , написанный этим парнем.

Удачи!

Обновление: эта карта - отличный способ понять, как плитки работают в Google Картах.

Изменить: Вот эквивалентный набор функций в 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

И в 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);
}
person Chris B    schedule 21.10.2009
comment
+ ½ - хотя исходный вопрос касался решения .NET, это отличное и простое в реализации решение, и читателю должно быть тривиально преобразовать его в C # или VB.NET. - person Paul d'Aoust; 23.07.2012