Le mappe in Maps SDK for Android possono essere inclinate e ruotate con semplici gesti, consentendo agli utenti di regolare la mappa con un orientamento adatto alle loro esigenze. A qualsiasi livello di zoom, puoi eseguire la panoramica della mappa o modificarne la prospettiva con pochissima latenza grazie al minore ingombro dei riquadri della mappa basati su vettori.
Esempi di codice
Il repository ApiDemos su GitHub include un esempio che dimostra le funzionalità della fotocamera:
- CameraDemoActivity - Kotlin: modifica della posizione della fotocamera
- CameraDemoActivity - Java: modifica della posizione della fotocamera
Introduzione
Come Google Maps sul web, l'SDK Maps per Android rappresenta la superficie terrestre (una sfera) sullo schermo del dispositivo (un piano piatto) utilizzando la proiezione di Mercatore. In direzione est e ovest, la mappa si ripete all'infinito man mano che il mondo si avvolge su se stesso. In direzione nord e sud, la mappa è limitata a circa 85 gradi a nord e 85 gradi a sud.
Nota: una proiezione di Mercatore ha una larghezza finita in longitudine, ma un'altezza infinita in latitudine. "Tagliamo" le immagini della mappa di base utilizzando la proiezione di Mercatore a circa +/- 85 gradi per fare in modo che la forma della mappa risultante sia quadrata, il che consente una logica più semplice per la selezione dei riquadri.
Maps SDK for Android ti consente di modificare il punto di vista dell'utente sulla mappa modificando la camera della mappa.
Le modifiche alla videocamera non influiscono su indicatori, overlay o altri elementi grafici che hai aggiunto, anche se ti consigliamo di modificare le aggiunte in modo che si adattino meglio alla nuova visualizzazione.
Poiché puoi ascoltare i gesti dell'utente sulla mappa, puoi modificarla in risposta alle richieste dell'utente. Ad esempio, il metodo di callback
OnMapClickListener.onMapClick()
risponde a un singolo tocco sulla mappa. Poiché il metodo riceve la latitudine e la longitudine della posizione del tocco, puoi rispondere eseguendo la panoramica o lo zoom su quel punto.
Sono disponibili metodi simili per rispondere ai tocchi sulla bolla di un indicatore o per rispondere a un gesto di trascinamento su un indicatore.
Puoi anche rilevare i movimenti della videocamera, in modo che la tua app riceva una notifica quando la videocamera inizia a muoversi, è in movimento o smette di muoversi. Per maggiori dettagli, consulta la guida agli eventi di modifica della videocamera.
La posizione della videocamera
La visualizzazione mappa è modellata come una fotocamera che guarda verso il basso su un piano piatto. La posizione della fotocamera (e quindi il rendering della mappa) è specificata dalle seguenti proprietà: target (posizione latitudine/longitudine), bearing, tilt e zoom.
Target (località)
Il target della fotocamera è la posizione del centro della mappa, specificata come coordinate di latitudine e longitudine.
La latitudine può essere compresa tra -85 e 85 gradi, inclusi. I valori superiori o inferiori a questo intervallo verranno bloccati al valore più vicino all'interno dell'intervallo. Ad esempio, se specifichi una latitudine di 100, il valore verrà impostato su 85. La longitudine pu' assumere valori compresi tra -180 e 180 gradi, inclusi. I valori superiori o inferiori a questo intervallo verranno arrotondati in modo da rientrare nell'intervallo (-180, 180). Ad esempio, 480, 840 e 1200 verranno tutti arrotondati a 120 gradi.Inclinazione (orientamento)
L'azimut della fotocamera specifica la direzione della bussola, misurata in gradi dal nord vero, corrispondente al bordo superiore della mappa. Se disegni una linea verticale dal centro della mappa al suo bordo superiore, l'azimut corrisponde alla direzione della videocamera (misurata in gradi) rispetto al nord vero.
Un rilevamento pari a 0 indica che la parte superiore della mappa punta a nord vero. Un valore di rilevamento pari a 90 indica che la parte superiore della mappa punta a est (90 gradi su una bussola). Un valore di 180 indica che la parte superiore della mappa punta a sud.
L'API Maps ti consente di modificare l'azimut di una mappa. Ad esempio, chi guida un'auto spesso gira una mappa stradale per allinearla alla direzione di marcia, mentre gli escursionisti che utilizzano una mappa e una bussola di solito la orientano in modo che una linea verticale indichi nord.
Inclinazione (angolo di visualizzazione)
L'inclinazione definisce la posizione della videocamera su un arco direttamente sopra la posizione centrata della mappa, misurata in gradi dal nadir (la direzione che punta direttamente sotto la videocamera). Un valore pari a 0 corrisponde a una fotocamera rivolta direttamente verso il basso. I valori maggiori di 0 corrispondono a una fotocamera inclinata verso l'orizzonte per il numero di gradi specificato. Quando modifichi l'angolo di visualizzazione, la mappa viene visualizzata in prospettiva, con gli elementi lontani che appaiono più piccoli e quelli vicini più grandi. Le seguenti illustrazioni lo dimostrano.
Nelle immagini seguenti, l'angolo di visualizzazione è di 0 gradi. La prima immagine mostra un esquematico di questo; la posizione 1 è la posizione della fotocamera e la posizione 2 è la posizione attuale della mappa. La mappa risultante viene visualizzata sotto.
Nelle immagini seguenti, l'angolo di visualizzazione è di 45 gradi. Tieni presente che la fotocamera si muove a metà di un arco tra la posizione in alto (0 gradi) e il suolo (90 gradi) fino alla posizione 3. La fotocamera è ancora puntata sul punto centrale della mappa, ma ora è visibile l'area rappresentata dalla linea in posizione 4.
La mappa in questo screenshot è ancora centrata sullo stesso punto della mappa originale, ma nella parte superiore sono presenti più elementi. Man mano che aumenti l'angolo oltre i 45 gradi, gli elementi tra la fotocamera e la posizione sulla mappa appaiono proporzionalmente più grandi, mentre gli elementi oltre la posizione sulla mappa appaiono proporzionalmente più piccoli, creando un effetto tridimensionale.
Zoom
Il livello di zoom della fotocamera determina la scala della mappa. Con livelli di zoom più elevati, sullo schermo sono visibili più dettagli, mentre con livelli di zoom più ridotti, sullo schermo è visibile una porzione più ampia del mondo. A livello di zoom 0, la scala della mappa è tale che l'intero mondo ha una larghezza di circa 256 dp (pixel indipendenti dalla densità).
Se aumenti il livello di zoom di 1, la larghezza del mondo sullo schermo raddoppia. Di conseguenza, a livello di zoom N, la larghezza del mondo è di circa 256 * 2N dp. Ad esempio, a livello di zoom 2, l'intero mondo misura circa 1024 dp di larghezza.
Il livello di zoom non deve essere un numero intero. L'intervallo di livelli di zoom consentito dalla mappa dipende da una serie di fattori, tra cui target, tipo di mappa e dimensioni dello schermo. Qualsiasi numero fuori dall'intervallo verrà convertito nel valore valido più vicino successivo, che può essere il livello di zoom minimo o il livello di zoom massimo. L'elenco seguente mostra il livello approssimativo di dettaglio che puoi aspettarti di vedere a ogni livello di zoom:
- 1: Mondo
- 5: massa continentale/continente
- 10: Città
- 15: Strade
- 20: Edifici
Movimento della fotocamera
L'API Maps ti consente di modificare la parte del mondo visibile sulla mappa. Ciò si ottiene modificando la posizione della videocamera (anziché muovendo la mappa).
Quando cambi videocamera, hai la possibilità di animare il movimento risultante della videocamera. L'animazione esegue l'interpolazione tra gli attributi della fotocamera corrente e quelli della nuova fotocamera. Puoi anche controllare la durata dell'animazione.
Per modificare la posizione della fotocamera, devi specificare dove vuoi muoverla utilizzando un CameraUpdate
. L'API Maps consente di creare molti tipi diversi di CameraUpdate
utilizzando
CameraUpdateFactory
. Sono disponibili le seguenti opzioni:
Modificare il livello di zoom e impostare lo zoom minimo/massimo
CameraUpdateFactory.zoomIn()
e
CameraUpdateFactory.zoomOut()
generano un CameraUpdate
che modifica il livello di zoom di 1,0, mantenendo invariate tutte le altre proprietà.
CameraUpdateFactory.zoomTo(float)
genera un CameraUpdate
che modifica il livello di zoom in base al valore specificato,
mantenendo invariate tutte le altre proprietà.
CameraUpdateFactory.zoomBy(float)
e
CameraUpdateFactory.zoomBy(float, Point)
forniscono un CameraUpdate
che aumenta (o diminuisce, se il valore è
negativo) il livello di zoom in base al valore specificato. Quest'ultimo fissa il punto specificato sullo schermo in modo che rimanga nella stessa posizione (latitudine/longitudine) e potrebbe modificare la posizione della videocamera per raggiungere questo obiettivo.
Potresti trovare utile impostare un livello di zoom minimo e/o massimo preferito. Ad esempio, è utile per controllare l'esperienza dell'utente se la tua app mostra un'area definita attorno a un punto d'interesse o se utilizzi un overlay di riquadri personalizzato con un insieme limitato di livelli di zoom.
Kotlin
private lateinit var map: GoogleMap map.setMinZoomPreference(6.0f) map.setMaxZoomPreference(14.0f)
Java
private GoogleMap map; map.setMinZoomPreference(6.0f); map.setMaxZoomPreference(14.0f);
Tieni presente che esistono considerazioni tecniche che potrebbero impedire all'API di consentire agli utenti di aumentare o diminuire lo zoom troppo. Ad esempio, le mappe satellitari o del rilievo potrebbero avere uno zoom massimo inferiore rispetto ai riquadri della mappa di base.
Modificare la posizione della videocamera
Esistono due metodi di utilità per le modifiche comuni della posizione.
CameraUpdateFactory.newLatLng(LatLng)
genera un CameraUpdate
che modifica la latitudine e la longitudine della fotocamera,
mantenendo invariate tutte le altre proprietà.
CameraUpdateFactory.newLatLngZoom(LatLng, float)
genera un CameraUpdate
che modifica la latitudine, la longitudine e lo zoom della fotocamera, mantenendo invariate tutte le altre proprietà.
Per una completa flessibilità nella modifica della posizione della fotocamera, utilizza
CameraUpdateFactory.newCameraPosition(CameraPosition)
che ti fornisce un CameraUpdate
che sposta la fotocamera
nella posizione specificata. Un CameraPosition
può essere ottenuto direttamente utilizzando
new CameraPosition()
o con un CameraPosition.Builder
utilizzando
new CameraPosition.Builder()
.
Panoramica (scorrimento)
CameraUpdateFactory.scrollBy(float, float)
restituisce un CameraUpdate
che
modifica la latitudine e la longitudine della fotocamera in modo che la mappa si muova in base al
numero di pixel specificato. Un valore x positivo fa spostare la fotocamera verso destra, in modo che la mappa sembri spostarsi verso sinistra. Un valore positivo per y fa sì che la fotocamera si sposti verso il basso, in modo che la mappa sembri essere stata spostata verso l'alto. Al contrario, i valori x negativi fanno spostare la fotocamera verso sinistra, quindi la mappa sembra essersi spostata verso destra, mentre i valori y negativi fanno spostare la fotocamera verso l'alto. Lo scorrimento è relativo all'orientamento corrente della videocamera. Ad esempio, se la videocamera ha un'inclinazione di 90 gradi, est è "su".
Definire dei confini
Impostazione dei limiti della mappa
A volte è utile spostare la
videocamera in modo che un'intera area di interesse sia visibile con il livello di zoom più elevato possibile. Ad esempio, se mostri tutte le stazioni di servizio nel raggio di 8 chilometri dalla posizione attuale dell'utente, ti consigliamo di spostare la fotocamera in modo che siano tutte visibili sullo schermo. Per farlo, calcola innanzitutto il
LatLngBounds
che vuoi che sia visibile sullo schermo. Puoi quindi utilizzare CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int
padding)
per ottenere un CameraUpdate
che modifica la posizione della fotocamera in modo che il LatLngBounds
specificato rientri completamente nella mappa, tenendo conto del padding (in pixel) specificato. Il valore CameraUpdate
restituito garantisce che lo spazio (in pixel) tra i limiti specificati e il bordo della mappa sia almeno uguale al padding specificato. Tieni presente che l'inclinazione e la direzione della mappa saranno entrambe pari a 0.
Kotlin
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0))
Java
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0));
Centrare la mappa all'interno di un'area
In alcuni casi, ti consigliamo di centrare la videocamera all'interno di un confine anziché includere i bordi estremi. Ad esempio, per centrare la fotocamera su un paese mantenendo costante lo zoom. In questo caso, puoi utilizzare un metodo simile,
creando un LatLngBounds
e utilizzando
CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom)
con il
LatLngBounds
.getCenter()
. Il metodo getCenter() restituisce il centro geografico del LatLngBounds
.
Kotlin
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.center, 10f))
Java
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.getCenter(), 10));
Un sovraccarico del metodo newLatLngBounds(boundary, width, height,
padding)
consente di specificare una larghezza e un'altezza in pixel per un rettangolo, in modo che corrispondano alle dimensioni della mappa. Il rettangolo è posizionato in modo che il suo centro corrisponda a quello della visualizzazione della mappa (in modo che, se le dimensioni specificate corrispondono a quelle della visualizzazione della mappa, il rettangolo coincida con la visualizzazione della mappa). Il valore CameraUpdate
restituito sposterà la videocamera in modo che i valori LatLngBounds
specificati siano centrati sullo schermo all'interno del rettangolo specificato al livello di zoom massimo possibile, tenendo conto del padding richiesto.
Nota: utilizza il metodo più semplice
newLatLngBounds(boundary, padding)
per generare un CameraUpdate
solo se verrà utilizzato per spostare
la videocamera dopo che la mappa è stata sottoposta a layout. Durante il layout, l'API calcola i confini di visualizzazione della mappa necessari per proiettare correttamente il riquadro di delimitazione. In confronto, puoi utilizzare il valore CameraUpdate
restituito dal metodo più complesso newLatLngBounds(boundary, width, height, padding)
in qualsiasi momento, anche prima che la mappa abbia subito il layout, perché l'API calcola i limiti di visualizzazione dagli argomenti che passi.
Limitare la panoramica dell'utente a una determinata area
Negli scenari precedenti, imposti i limiti della mappa, ma l'utente può scorrere o eseguire la panoramica al di fuori di questi limiti. Ti consigliamo invece di limitare i limiti di latitudine/longitudine del centro del punto focale della mappa (il target della fotocamera) in modo che gli utenti possano scorrere e eseguire la panoramica solo all'interno di questi limiti. Ad esempio, un'app di vendita al dettaglio per un centro commerciale o un aeroporto potrebbe voler limitare la mappa a determinati confini, consentendo agli utenti di scorrere e eseguire la panoramica all'interno di questi confini.
Kotlin
// Create a LatLngBounds that includes the city of Adelaide in Australia. val adelaideBounds = LatLngBounds( LatLng(-35.0, 138.58), // SW bounds LatLng(-34.9, 138.61) // NE bounds ) // Constrain the camera target to the Adelaide bounds. map.setLatLngBoundsForCameraTarget(adelaideBounds)
Java
// Create a LatLngBounds that includes the city of Adelaide in Australia. LatLngBounds adelaideBounds = new LatLngBounds( new LatLng(-35.0, 138.58), // SW bounds new LatLng(-34.9, 138.61) // NE bounds ); // Constrain the camera target to the Adelaide bounds. map.setLatLngBoundsForCameraTarget(adelaideBounds);
Il seguente diagramma illustra uno scenario in cui il target della videocamera è vincolato a un'area leggermente più grande dell'area visibile. L'utente può scorrere e eseguire la panoramica, a condizione che il target della fotocamera rimanga all'interno dell'area delimitata. La croce rappresenta l'obiettivo della videocamera:
La mappa riempie sempre l'area visibile, anche se ciò comporta la visualizzazione di aree esterne ai limiti definiti. Ad esempio, se posizioni il target della fotocamera in un angolo dell'area delimitata, l'area oltre l'angolo è visibile nell'area visibile, ma gli utenti non possono continuare a scorrere in quella zona. Il seguente diagramma illustra questo scenario. La croce rappresenta il bersaglio della fotocamera:
Nel seguente diagramma, il target della fotocamera ha limiti molto ridotti, offrendo all'utente pochissime opportunità di scorrere o eseguire la panoramica della mappa. La croce rappresenta il target della videocamera:
Aggiornamento della visuale della videocamera
Per applicare un CameraUpdate
alla mappa, puoi muovere la fotocamera immediatamente o animarla in modo fluido. Per spostare la videocamera
immediatamente con il CameraUpdate
specificato, puoi chiamare
GoogleMap.moveCamera(CameraUpdate)
.
Puoi rendere l'esperienza utente più piacevole, in particolare per i movimenti brevi, animando la modifica. Per farlo, anziché chiamare
GoogleMap.moveCamera
chiama
GoogleMap.animateCamera
.
La mappa passerà senza problemi ai nuovi attributi. La forma più dettagliata di questo metodo,
GoogleMap.animateCamera(cameraUpdate, duration, callback)
,
offre tre argomenti:
cameraUpdate
- Il
CameraUpdate
che descrive dove spostare la fotocamera. callback
- Un oggetto che implementa
GoogleMap.CancellableCallback
. Questa interfaccia generalizzata per la gestione delle attività definisce due metodi: "onCancel()" e "onFinished()". Per l'animazione, i metodi vengono chiamati nelle seguenti circostanze:onFinish()
- Richiamato se l'animazione viene completata senza interruzioni.
onCancel()
-
Viene invocato se l'animazione viene interrotta chiamando
stopAnimation()
o avviando un nuovo movimento della fotocamera.In alternativa, questo può verificarsi anche se chiami
GoogleMap.stopAnimation()
.
duration
- Durata desiderata dell'animazione, in millisecondi, come
int
.
I seguenti snippet di codice illustrano alcuni dei modi comuni per spostare la fotocamera.
Kotlin
val sydney = LatLng(-33.88, 151.21) val mountainView = LatLng(37.4, -122.1) // Move the camera instantly to Sydney with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15f)) // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomIn()) // Zoom out to zoom level 10, animating with a duration of 2 seconds. map.animateCamera(CameraUpdateFactory.zoomTo(10f), 2000, null) // Construct a CameraPosition focusing on Mountain View and animate the camera to that position. val cameraPosition = CameraPosition.Builder() .target(mountainView) // Sets the center of the map to Mountain View .zoom(17f) // Sets the zoom .bearing(90f) // Sets the orientation of the camera to east .tilt(30f) // Sets the tilt of the camera to 30 degrees .build() // Creates a CameraPosition from the builder map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
Java
LatLng sydney = new LatLng(-33.88,151.21); LatLng mountainView = new LatLng(37.4, -122.1); // Move the camera instantly to Sydney with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomIn()); // Zoom out to zoom level 10, animating with a duration of 2 seconds. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); // Construct a CameraPosition focusing on Mountain View and animate the camera to that position. CameraPosition cameraPosition = new CameraPosition.Builder() .target(mountainView ) // Sets the center of the map to Mountain View .zoom(17) // Sets the zoom .bearing(90) // Sets the orientation of the camera to east .tilt(30) // Sets the tilt of the camera to 30 degrees .build(); // Creates a CameraPosition from the builder map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));