Risposte:
Se stai progettando una mappa che prevedi di sovrapporre su google maps o terra virtuale e creando uno schema di piastrellatura, penso che ciò che stai cercando siano le scale per ogni livello di zoom, usa questi:
20 : 1128.497220
19 : 2256.994440
18 : 4513.988880
17 : 9027.977761
16 : 18055.955520
15 : 36111.911040
14 : 72223.822090
13 : 144447.644200
12 : 288895.288400
11 : 577790.576700
10 : 1155581.153000
9 : 2311162.307000
8 : 4622324.614000
7 : 9244649.227000
6 : 18489298.450000
5 : 36978596.910000
4 : 73957193.820000
3 : 147914387.600000
2 : 295828775.300000
1 : 591657550.500000
Fonte: http://webhelp.esri.com/arcgisserver/9.3/java/index.htm#designing_overlay_gm_mve.htm
Ho trovato questa risposta, scritta da un dipendente di Google, che probabilmente sarebbe la più accurata:
Questo non sarà accurato, perché la risoluzione di una mappa con la proiezione di un mercatore (come Google Maps) dipende dalla latitudine.
È possibile calcolare usando questa formula:
metersPerPx = 156543.03392 * Math.cos(latLng.lat() * Math.PI / 180) / Math.pow(2, zoom)
Questo si basa sul presupposto che il raggio terrestre sia di 6378137 m. Qual è il valore che usiamo :)
tratto da: https://groups.google.com/forum/#!topic/google-maps-js-api-v3/hDRO4oHVSeM
A proposito, suppongo che:
'latLng.lat()' = map.getCenter.lat()
'zoom' = map.getZoom()
Per aiutarti a capire la matematica (non un calcolo preciso, è solo a scopo illustrativo):
supponiamo che il monitor del tuo computer abbia 100 pixel per pollice (PPI). Ciò significa che 256 pixel sono lunghi circa 6,5 cm. E questo è 0,065 m .
al livello di zoom 0 , tutti i 360 gradi di longitudine sono visibili in una singola tessera . Non puoi osservarlo in Google Maps poiché si sposta automaticamente sul livello di zoom 1, ma puoi vederlo sulla mappa di OpenStreetMap (utilizza lo stesso schema di piastrellatura).
360 gradi sull'equatore sono pari alla circonferenza terrestre, 40.075,16 km, che è 40075160 m
dividi 40075160 m con 0,065 me otterrai 616313361 , che è una scala del livello di zoom 0 sull'Equatore per un monitor di computer con 100 DPI
Controlla anche: http://wiki.openstreetmap.org/wiki/FAQ#What_is_the_map_scale_for_a_particular_zoom_level_of_the_map.3F
591657550.500000
è di livello 0 secondo questa risposta. Ma secondo @CaptDragon è il livello 1. Dovrei considerare di partire dal livello 1 per calcolare con Google Maps?
Non così facile. Data la proiezione, la dimensione dei pixel del riquadro dipende dalla latitudine dell'area che ti interessa. Quindi, in termini di trasformazione della dimensione del pixel del riquadro in dimensione del pixel dello schermo, dipende dallo schermo e dalla risoluzione dei dati visualizzati, il dpi utilizzato dallo schermo.
Risposta corretta autorevole semplice:
591657550.500000 / 2^(level-1)
ti dà la tabella sopra, inserendo il livello di zoom.
Provalo dal vivo su jsfiddle.net
Poiché la domanda riguarda solo Google MAPS, non la TERRA, l'OP non si preoccupa della geometria 3D. Le mappe di Google sono GIÀ appiattite, quindi 1 pixel è sempre alla stessa distanza (in GRADI, che è ciò che riguarda una mappa di Google), qui e nell'ecuatore come nei poli.
A proposito, ti sei reso conto che da qualche parte all'interno della prima fila di pixel di una mappa del mondo, la scala è 1: 1?
C'è una tabella del genere nella documentazione del sistema di tessere Virtal Earth di Microsoft . Ma come detto da GuillaumeC i valori dipendono dalla latitudine e dalla risoluzione dello schermo. La tabella fornisce i valori misurati all'equatore e con una risoluzione dello schermo di 96 dpi.
PS: Non ne sono sicuro, ma i livelli di zoom di Microsoft potrebbero essere spostati di 1 rispetto ai livelli di zoom di Google. Ma usano definitivamente la stessa proiezione in modo che i valori rimangano corretti per Google.
Raggio @ Equatore 6.378.137 metri esatti (WGS-84)
Circonferenza all'equatore = 40.075.017 metri (2πr)
Il livello di zoom 24 utilizza da 2 a 32 potenze (4.294.967.296) pixel alla circonferenza.
Circonferenza equatoriale / 2 32 = .009330692 metri per pixel
Unità a latitudine = (coseno di latitudine) X (unità all'equatore)
Il livello di zoom raddoppia ogni incremento.
1 piede (internazionale) = 0,3048 metri
modificare
Beh, non è davvero una domanda legittima per cominciare. I rapporti di scala sono relativi ai documenti stampati e non agli schermi dei computer. Ciò di cui hai bisogno per utilizzare queste immagini con precisione è conoscere la dimensione di ciascun pixel, quindi ridimensionare l'immagine in base a ciò che si sovrappone.
Quindi 15-20 anni fa qualcuno prese WGS-84 come dati di base. (nota in un post precedente qualcuno ha usato un valore di 40.075.160 l'ho visto in Wikipedia in alcuni punti ed è errato. Il valore corretto è 40.075.017
Lo hanno quindi preso e diviso per un intero a 32 bit. Questa è una scelta logica in quanto fornisce una precisione globale a circa un centimetro, il che è abbastanza per le immagini aeree. Gli interi a 32 bit sono anche efficienti per l'archiviazione e l'elaborazione.
Perché è stato scelto questo livello 24, non lo so, tuttavia, dato che qualcun altro ha risolto 0 ti porta a una tessera da 256 pixel per la terra.
Ora per un esempio di come utilizzare i dati di cui sopra. Diciamo che ho un'immagine a livello di zoom 20 (ingrandita come attualmente ti consente di ottenere) Prendi 0,009330692 (Zoom 24 all'equatore) raddoppia per zoom 23, di nuovo per zoom 22, di nuovo per zoom 21 e un'ultima volta per zoom 20 Ora dovresti avere 0.149231071.
Ora supponiamo che la nostra immagine sia a latitudine 45. Prendi il Coseno di quello (0,707106781) e moltiplicalo per il nostro 0,149231071 e ti darà 0,105564729 metri. Questa è la lunghezza e l'altezza di un pixel da un'immagine alla latitudine 45 al livello di zoom 20. Se si cattura un'immagine di 1000 x 1000 pixel di quell'area, la dimensione è di 105,56 metri quadrati. Se vuoi i piedi dividi quello 0,3048
Per quanto riguarda le fonti, circa 5 anni fa ho invertito l'ingegnere tecnico in base a varie informazioni e documentazione che ho trovato sul web, inclusi i siti di supporto per la mappatura di Google e MS.
Ho usato questo centinaio di volte e lo ho sovrapposto con i dati del rilevamento sul campo ed è sempre stato corretto. Controllalo con uno qualsiasi dei tavoli pubblicati qui e i numeri corrisponderanno.
Ho appena fatto alcuni calcoli e ottenuto i seguenti risultati:
Google Maps mostra un righello di 1 km (in basso a sinistra della mappa) di 90 pixel di lunghezza, al livello di zoom 13. Il che significa quanto segue:
Supponendo che la risoluzione dello schermo sia 96 dpi o 36 dpcm, al livello di zoom 13 abbiamo 0,4 km (da 36/90) in 1 cm, che produce una scala della mappa di 1: 40.000 per uno schermo da 96 dpi.
Per varie operazioni sullo schermo, la cosa migliore è prendere 90 px come base, poiché tutti i numeri saranno arrotondati a tutti i livelli di zoom, cioè
e così via.
Si noti che questa è un'approssimazione che dovrebbe funzionare più o meno bene su scale più piccole anziché su quelle grandi.
(E a Google piacciono i numeri rotondi alla fine ...)
Sulla base di tutte le informazioni fornite, ho creato una funzione che fornisce la migliore z applicata a una mappa quando si desidera avere una linea orizzontale che rappresenta N% della mappa visualizzata.
La mappa visualizzata è caratterizzata da una propria larghezza di pixel.
function calculateZoom(WidthPixel,Ratio,Lat,Length){
// from a segment Length (km),
// with size ratio of the segment expected on a map (70%),
// with a map WidthPixel width in pixels (100px),
// and a latitude (45°) we can get the best Zoom
// assume earth is a perfect ball with radius : 6,378,137m and
// circumference at the equator = 40,075,016.7 m
// The full world on google map is available in tiles of 256 px;
// it has a ratio of 156543.03392 (px/m).
// For Z = 0;
// pixel scale at the Lat_level is ( 156543,03392 * cos ( PI * (Lat/180) ))
// The map scale increases at the rate of square root of Z.
//
Length = Length *1000; //Length is in Km
var k = WidthPixel * 156543.03392 * Math.cos(Lat * Math.PI / 180); //k = circumference of the world at the Lat_level, for Z=0
var myZoom = Math.round( Math.log( (Ratio * k)/(Length*100) )/Math.LN2 );
myZoom = myZoom -1; // Z starts from 0 instead of 1
//console.log("calculateZoom: width "+WidthPixel+" Ratio "+Ratio+" Lat "+Lat+" length "+Length+" (m) calculated zoom "+ myZoom);
// not used but it could be useful for some: Part of the world size at the Lat
MapDim = k /Math.pow(2,myZoom);
//console.log("calculateZoom: size of the map at the Lat: "+MapDim + " meters.");
//console.log("calculateZoom: world circumference at the Lat: " +k+ " meters.");
return(myZoom);
}
Non posso ancora aggiungere un commento, ma questa è una possibile fonte della risposta di Pete sopra: https://developers.google.com/maps/documentation/javascript/maptypes#MapCoordinates
[...] notare che ogni livello di zoom in aumento è due volte più grande in entrambe le direzioni xey. Pertanto, ogni livello di zoom più alto contiene una risoluzione quattro volte maggiore rispetto al livello precedente. Ad esempio, al livello di zoom 1, la mappa è composta da 4 riquadri da 256x256 pixel, con uno spazio pixel di 512x512. Al livello di zoom 19, è possibile fare riferimento a ciascun pixel xey sulla mappa utilizzando un valore compreso tra 0 e 256 * 2 19
Ho calcolato le scale per quattro livelli di zoom:
Livello di zoom | Scala 20 1: 500 19 1: 1000 18 1: 2000 17 1: 4000
Sembra che la scala sia raddoppiata all'aumentare del livello di zoom di un passo. Quindi, spero che la scala per il livello di zoom 16 sia 1: 8000 e così via.
Ciao, penso di aver calcolato che 1 pixel = 11.627 km in linea retta; non tenendo conto del raggio della terra. Ecco il link del video che spiega come: https://www.youtube.com/watch?v=Y3cvTeiMJqE&feature=youtu.be . Spero che ti schiarisca le idee.
Zoom level set meters: ${meters}
); var zoomfactor = 1; if (metri <1128) {zoomfactor = 15; } else if ((metri> 1128) && (metri <2256)) {zoomfactor = 14; } else if ((metri> 2256) && (metri <4513)) {zoomfactor = 13; } else if ((metri> 4513) && (metri <9027)) {zoomfactor = 12; } else if ((metri> 9027) && (metri <18055)) {zoomfactor = 11; } else if ((metri> 18055) && (metri <36111)) {zoomfactor = 10; } altro se ((metri> 36111) && (metri <72