formule di proiezione di Mercatore Comune di Google Maps non funziona correttamente
-
27-09-2019 - |
Domanda
Sto costruendo un server di sovrapposizione delle mattonelle a Google maps in C #, e hanno trovato un paio di esempi di codice differenti per calcolare Y da Latitude. Dopo di loro di arrivare a lavoro in generale, ho iniziato a notare alcuni casi in cui le sovrapposizioni non stavano allineando correttamente. Per verificare ciò, ho fatto un test harness per confrontare la conversione Mercator LatToY di Google Map contro le formule che ho trovato on-line. Come potete vedere qui sotto, non corrispondono in alcuni casi.
Caso # 1
ingrandito: Il problema è più evidente quando vengono ridotti. Da vicino, il problema è appena visibile.
Caso # 2
Point Vicinanza Top & Basso la visualizzazione di limiti: Il problema è peggio nel bel mezzo dei limiti di visualizzazione, e ottiene una migliore verso i bordi. Questo comportamento può negare il comportamento di Case # 1
Il test:
Ho creato una pagina di google maps per visualizzare le linee rosse che utilizzano la Google Map API costruito nella conversione Mercator, e sovrapporre questo con un'immagine utilizzando il codice di riferimento per fare Mercator conversione. Queste conversioni sono rappresentati come linee nere. Confrontare la differenza.
I risultati: Equatore http://www.kayak411.com/Mercator/MercatorComparison%20-%20Equator.png Nord ingrandito http://www.kayak411.com /Mercator/MercatorComparison%20-%20North%20Zoomed%20Out.png
Controlla i più in alto e in basso la maggior parte delle linee: Nord Top & Esempio Inferiore http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Out%20-%20TopAndBottom.png
Il problema diventa visivamente più grande, ma numericamente inferiore, come si esegue lo zoom in: alt text http://www.kayak411.com/ Mercator / MercatorComparison% 20-% 20North% 20Zoomed% 20Midway.png
E tutto ma scompare a livelli di zoom più stretti, indipendentemente dall'orientamento dello schermo. alt text http://www.kayak411.com/Mercator /MercatorComparison%20-%20North%20Zoomed%20In.png
Il codice:
Google Maps client codice lato:
var lat = 0;
for (lat = -80; lat <= 80; lat += 5) {
map.addOverlay(new GPolyline([new GLatLng(lat, -180), new GLatLng(lat, 0)], "#FF0033", 2));
map.addOverlay(new GPolyline([new GLatLng(lat, 0), new GLatLng(lat, 180)], "#FF0033", 2));
}
codice lato server:
Cutter Tile: http://mapki.com/wiki/Tile_Cutter
OpenStreetMap Wiki: http://wiki.openstreetmap.org/wiki/Mercator
protected override void ImageOverlay_ComposeImage(ref Bitmap ZipCodeBitMap)
{
Graphics LinesGraphic = Graphics.FromImage(ZipCodeBitMap);
Int32 MapWidth = Convert.ToInt32(Math.Pow(2, zoom) * 255);
Point Offset =
Cartographer.Mercator2.toZoomedPixelCoords(North, West, zoom);
TrimPoint(ref Offset, MapWidth);
for (Double lat = -80; lat <= 80; lat += 5)
{
Point StartPoint = Cartographer.Mercator2.toZoomedPixelCoords(lat, -179, zoom);
Point EndPoint = Cartographer.Mercator2.toZoomedPixelCoords(lat, -1, zoom);
TrimPoint(ref StartPoint, MapWidth);
TrimPoint(ref EndPoint, MapWidth);
StartPoint.X = StartPoint.X - Offset.X;
EndPoint.X = EndPoint.X - Offset.X;
StartPoint.Y = StartPoint.Y - Offset.Y;
EndPoint.Y = EndPoint.Y - Offset.Y;
LinesGraphic.DrawLine(new Pen(Color.Black, 2),
StartPoint.X,
StartPoint.Y,
EndPoint.X,
EndPoint.Y);
LinesGraphic.DrawString(
lat.ToString(),
new Font("Verdana", 10),
new SolidBrush(Color.Black),
new Point(
Convert.ToInt32((width / 3.0) * 2.0),
StartPoint.Y));
}
}
protected void TrimPoint(ref Point point, Int32 MapWidth)
{
point.X = Math.Max(point.X, 0);
point.X = Math.Min(point.X, MapWidth - 1);
point.Y = Math.Max(point.Y, 0);
point.Y = Math.Min(point.Y, MapWidth - 1);
}
Quindi, Chiunque abbia mai sperimentato questo? Oserei chiedo, risolto questo? O semplicemente avere una migliore C # implementazione di Mercator progetto di conversione di coordinate?
Grazie!
Soluzione
Grazie a tutti per i vostri suggerimenti e assistenza.
Quello che alla fine ho scoperto è che non è una formula o problema tecnico, credo che sia un problema di metodo.
Non è possibile definire l'area di visualizzazione in formato Lat / Lng, e si aspettano di popolarlo con le proiezioni Mercator appropriate. Ecco dove la distorsione avviene. Invece, è necessario definire la casella di visualizzazione corretto in Mercator, e proiettare Mercator.
farlo ero in grado di abbinare correttamente con le mappe di Google.
Altri suggerimenti
Potrebbe essere necessario creare diversi punti lungo la longtitude in modo che i punti da proiettare corretly lungo la latitudine. Nei tuoi esempi si sta veramente solo proiettando due punti all'inizio e alla fine della linea e che collega i due.
Il problema sarà più evidente all'equatore causa più significativa curvatura della terra. Sarà meno utilizzando lo zoom in per lo stesso motivo.
Date un'occhiata al http://code.google.com /apis/maps/documentation/overlays.html#Great_Circles
Prova a creare i tuoi polilinee di Google con il parametro geodsic per vedere se questo fa la differenza. Penso che questo aggiunge automaticamente punti lungo la linea e li progetti:
var lat = 0;
var polyOptions = {geodesic:true};
for (lat = -80; lat <= 80; lat += 5) {
map.addOverlay(new GPolyline([new GLatLng(lat, -180), new GLatLng(lat, 0)], "#FF0033", 2, polyOptions));
map.addOverlay(new GPolyline([new GLatLng(lat, 0), new GLatLng(lat, 180)], "#FF0033", 2, polyOptions));
}
Ho dovuto leggere in questo come tutti i miei le misure di distanza erano sbagliate in OpenLayers per ragioni simili: http://geographika.co.uk/watch-out-for-openlayer-distances (more links / spiegazioni)