2009-10-20 6 views
7

Sto cercando di sviluppare una pagina in ASP.NET che fungerà da una tegola-server per un Google MapConversione lungo/lat al pixel x/y, dato un livello di zoom

Sarà tirare un raccolta di punti di latitudine/longitudine dal database, quindi renderli come piccoli punti rossi su uno sfondo trasparente, dato un livello di zoom (predefinito: 15).

Quindi restituirà il risultato come un'immagine di tipo GIF.

Sono stati sviluppati algoritmi o librerie che mi consentono di prendere questo set di latitudini/longitudini e convertirli in un insieme di coordinate pixel 2D, dato un livello di zoom?

(Tutto questo è stato fatto sul lato server, quindi non posso utilizzare l'API di Google Maps.)


Update: Hai trovato un codice di esempio in Perl che fa qualcosa di simile:

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

Il problema è che non conosco Perl e non ho davvero il tempo di aprire un libro e impararlo.

Qualcuno può aiutarmi a decifrare cosa sta succedendo in questa funzione?

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

risposta

2

"Se si tratta di una proiezione di Mercatore, non dovrebbe essere necessario preoccuparsi della curvatura della terra in quanto tutte le lat/lon linee sono a spaziatura uguale"

Forse stai pensando della proiezione geografica (aka Plate Carree)? La proiezione di Mercator ha linee di longitudine equidistanti, ma lo non ha linee di latitudine equidistanti (lat = atan (sinh (y)), quindi 90 ° è all'infinito).

BTW, la matematica per la proiezione di Mercator su una sfera è here, ma se Google Maps utilizza l'ellissoide WGS84 ed è necessario ottenerlo con precisione, diventa più complicato. In tal caso, guarderei a this, ma attenzione: non è per i deboli di cuore.

+0

Ah sì, hai ragione. Rimuoverò la mia risposta –

9

Ecco un codice che sto attualmente utilizzando. È 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); 
} 

basato sul codice da this page, scritto da this guy.

Buona fortuna!

Aggiornamento:This map è un ottimo modo per aiutare a capire come funzionano le piastrelle in Google Maps

Edit: Ecco un insieme equivalente di funzioni 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 

E 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

+ ½ - sebbene la domanda iniziale fosse per a.Soluzione NET, questa è una soluzione eccellente e di facile implementazione, e dovrebbe essere banale per il lettore convertirla in C# o VB.NET. –