Dot-Net
給定縮放級別,將 long/lat 轉換為像素 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) ; }
“如果是墨卡托投影,則不必擔心地球的曲率,因為所有緯度/經度線的間距都相等”
也許您正在考慮地理(又名 Plate Carree)投影?墨卡托投影確實有等間距的經線,但沒有等間距的緯線 (lat = atan(sinh(y)),因此 90° 處於無窮遠)。
順便說一句,球體上的墨卡托投影的數學是在這裡,但如果Google地圖使用 WGS84 橢球並且你需要得到它會變得更加複雜。在那種情況下,我會看看這個,但要注意:它不適合膽小的人。
這是我目前正在使用的一些程式碼。它在 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); }