Puoi aggiungere immagini sopra la mappa come livello riquadro. I livelli dei riquadri sono posizionati sulla parte superiore di un riquadro della mappa a un livello di zoom specifico. Se hai un numero sufficiente di riquadri, puoi integrare i dati della mappa di Google per l'intera mappa, a più livelli di zoom.
Introduzione
I livelli riquadro (a volte denominati anche overlay riquadro) consentono di sovrapporre immagini sui riquadri della mappa base di Google. Questo è un modo eccellente per aggiungere dati, come punti d'interesse o informazioni sul traffico, e immagini locali alla tua app. Se combinati con il tipo di mappa kGMSTypeNone
, i livelli dei riquadri ti consentono di sostituire efficacemente i dati delle mappe di base di Google con i tuoi.
I livelli riquadro sono utili quando vuoi aggiungere alla mappa immagini estese, in genere coperte aree geografiche estese. Al contrario, le sovrapposizioni del suolo sono utili quando vuoi correggere una singola immagine in un punto della mappa.
Coordinate riquadro
L'API di Google Maps suddivide le immagini a ogni livello di zoom in un insieme di riquadri di mappa quadrati, disposti in una griglia ordinata. Quando una mappa scorre su una nuova posizione o su un nuovo livello di zoom, l'API di Google Maps determina quali riquadri sono necessari e li converte in un insieme di riquadri da recuperare.
Per l'implementazione della proiezione di Mercatore da parte di Google, il riquadro con le coordinate (0,0) si trova sempre nell'angolo nord-ovest della mappa, con i valori x
che aumentano da ovest a est e i valori di y
da nord a sud.
I riquadri vengono indicizzati utilizzando le coordinate x,y
di quell'origine. Ad esempio, a livello di zoom 2, quando la Terra è divisa in 16 riquadri, ogni riquadro può essere fatto riferimento da una coppia x,y
univoca:
Ogni riquadro della mappa è un quadrato di 256 x 256 punti. A livello di zoom 0, il mondo intero viene visualizzato in un unico riquadro. Ogni livello di zoom aumenta l'ingrandimento di un fattore di due. Quindi, a livello di zoom 1, la mappa viene visualizzata come una griglia 2x2 di riquadri, una griglia 4x4 a livello di zoom 2, una griglia 8x8 a livello di zoom 3 e così via. Se crei immagini per un livello riquadro, devi creare una nuova immagine di 256 x 256 punti per ogni riquadro a ogni livello di zoom che vuoi supportare.
Aggiunta di un livello riquadro
- Crea l'istanza di un oggetto
GMSURLTileLayer
o di una sottoclasse personalizzata diGMSTileLayer
/GMSSyncTileLayer
. - (Facoltativo) Modifica la proprietà
zIndex
per regolarne la posizione rispetto ad altri livelli di riquadro. - Assegna l'oggetto
GMSTileLayer
alla mappa impostando la relativa proprietàmap
.
Maps SDK for iOS offre tre classi che possono essere utilizzate per
implementare un livello di riquadro. Per ogni classe, devi definire come recuperare
il riquadro della mappa corretto per un determinato insieme di coordinate di {x,y,zoom}
. Le opzioni disponibili sono:
- Sottoclasse
GMSSyncTileLayer
, che fornisce l'implementazione ditileForX:y:zoom
che restituisceUIImage
istanze. - La sottoclasse
GMSTileLayer
, che fornisce l'implementazione del metodo asincronorequestTileForX:y:zoom
che in seguito richiama con un'immagine riquadro. - Usa la classe esistente,
GMSURLTileLayer
, per recuperare automaticamente i riquadri dagli URL, fornendo il bloccoGMSTileURLConstructor
.GMSURLTileLayer
è una classe concreta che non può essere sottoclassificata.
Nel caso della sottoclasse GMSSyncTileLayer
o GMSTileLayer
, se fornisci un risultato per il riquadro nil
, indichi a Maps SDK per iOS che i dati non sono al momento disponibili, ma che potrebbero esserlo in futuro. In alternativa, restituisci kGMSTileLayerNoTile
per indicare che non esistono riquadri in questa posizione.
Per GMSURLTileLayer
, se restituisci nil
da GMSTileURLConstructor
indicherai che non ci sono riquadri in questa posizione.
Utilizzo di "GMSURLTilelayer" per recuperare riquadri dagli URL
GMSURLTileLayer
non richiede una sottoclasse, ma dovrai implementare il blocco GMSTileURLConstructor
. Il codice seguente mostra come
utilizzare GMSURLTileLayer
per mostrare la pianta del piano di un edificio a più piani.
Swift
let floor = 1 // Implement GMSTileURLConstructor // Returns a Tile based on the x,y,zoom coordinates, and the requested floor let urls: GMSTileURLConstructor = { (x, y, zoom) in let url = "https://www.example.com/floorplans/L\(floor)_\(zoom)_\(x)_\(y).png" return URL(string: url) } // Create the GMSTileLayer let layer = GMSURLTileLayer(urlConstructor: urls) // Display on the map at a specific zIndex layer.zIndex = 100 layer.map = mapView
Objective-C
NSInteger floor = 1; // Create the GMSTileLayer GMSURLTileLayer *layer = [GMSURLTileLayer tileLayerWithURLConstructor:^NSURL * _Nullable(NSUInteger x, NSUInteger y, NSUInteger zoom) { NSString *url = [NSString stringWithFormat:@"https://www.example.com/floorplans/L%ld_%lu_%lu_%lu.png", (long)floor, (unsigned long)zoom, (unsigned long)x, (unsigned long)y]; return [NSURL URLWithString:url]; }]; // Display on the map at a specific zIndex layer.zIndex = 100; layer.map = mapView;
La sottoclasse GMSSyncTileLayer
per pubblicare riquadri come UIImage
GMSSyncTileLayer
e GMSTileLayer
sono classi astratte progettate per essere
sottoclassate. Puoi utilizzare queste classi per pubblicare riquadri come quelli di UIImage
. L'esempio
di seguito mostra come eseguire il rendering di un'immagine personalizzata su alcuni riquadri sulla mappa
sottoclassificando GMSSyncTileLayer
.
Swift
class TestTileLayer: GMSSyncTileLayer { override func tileFor(x: UInt, y: UInt, zoom: UInt) -> UIImage? { // On every odd tile, render an image. if (x % 2 == 1) { return UIImage(named: "australia") } else { return kGMSTileLayerNoTile } } }
Objective-C
@interface TestTileLayer : GMSSyncTileLayer @end @implementation TestTileLayer - (UIImage *)tileForX:(NSUInteger)x y:(NSUInteger)y zoom:(NSUInteger)zoom { // On every odd tile, render an image. if (x % 2 == 1) { return [UIImage imageNamed:@"australia"]; } else { return kGMSTileLayerNoTile; } } @end
Per aggiungere il livello alla mappa, crea un'istanza dell'oggetto e imposta la relativa proprietà.
Swift
let layer = TestTileLayer() layer.map = mapView
Objective-C
GMSTileLayer *layer = [[TestTileLayer alloc] init]; layer.map = mapView;
Riquadri con DPI elevato per dispositivi Retina
Puoi utilizzare immagini con DPI elevato con GMSSyncTileLayer
o GMSURLTileLayer
impostando tileSize
su 512.
La proprietà tileSize
indica il numero di pixel che le immagini dei riquadri restituite preferiscono visualizzare. Il valore predefinito è 256, ovvero la dimensione di un riquadro di Google Maps su un dispositivo non Retina.
Se visualizzi riquadri DPI normali su un dispositivo ad alto DPI, puoi ridimensionare le immagini impostando tileSize
su 512. Tieni presente che l'aumento delle dimensioni delle immagini può ridurre
la qualità delle immagini, in particolare per le linee sottili o il testo. Per ottenere risultati ottimali, abbina l'tileSize
e il DPI dell'immagine al display. Le mappe mostrate su un dispositivo Retina avranno un aspetto migliore con immagini con DPI elevato e presentano un valore di tileSize
di 512; mentre le mappe mostrate su un dispositivo non Retina avranno un aspetto ottimale con immagini normali e il valore predefinito, ovvero tileSize
, è 256.
Cancellazione dei riquadri inattivi
Se i riquadri forniti dal livello diventano "inattivi", il metodo clearTileCache
deve essere richiamato nel livello per forzare un aggiornamento. In questo modo
tutti i riquadri di questo livello verranno ricaricati.
Swift
layer.clearTileCache()
Objective-C
[layer clearTileCache];