Le mappe in Maps SDK per Android possono essere inclinate e ruotate con semplici gesti, per offrire agli utenti la possibilità di modificare 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 alla riduzione dell'ingombro dei riquadri delle mappe basate su vettori.
Esempi di codice
Il repository ApiDemos su GitHub include un esempio che mostra le funzionalità della fotocamera:
- CameraDemoActivity - Kotlin: modifica della posizione della fotocamera
- CameraDemoActivity - Java: modifica della posizione della fotocamera
Introduzione
Come Google Maps sul web, Maps SDK per Android rappresenta la superficie del mondo (una sfera) sullo schermo del dispositivo (un piano piatto) utilizzando la proiezione di Mercator. In direzione est e ovest, la mappa si ripete all'infinito mentre il mondo si avvolge senza soluzione di continuità. Nelle direzioni nord e sud, la mappa è limitata a circa 34 gradi nord e 33° sud.
Nota: una proiezione di Mercatore ha una larghezza finita longitudinalmente, ma un'altezza infinita in latitudine. Abbiamo "tagliato" le immagini della mappa base utilizzando la proiezione di Mercatore a circa +/- 85 gradi per rendere quadrata la forma della mappa risultante, 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 della mappa modificando la fotocamera della mappa.
Le modifiche alla fotocamera non apportano modifiche agli indicatori, agli overlay o agli altri elementi grafici che hai aggiunto, anche se potresti voler cambiare le aggiunte per adattarle meglio alla nuova visualizzazione.
Poiché puoi ascoltare i gesti degli utenti sulla mappa, puoi modificare la mappa in
risposta alle richieste degli utenti. 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.
Metodi simili sono disponibili per rispondere ai tocchi sul fumetto di un indicatore o
per rispondere a un gesto di trascinamento su un indicatore.
Puoi anche ascoltare i movimenti della videocamera, in modo che l'app riceva una notifica quando la videocamera inizia a muoversi, è in movimento o si ferma. Per maggiori dettagli, consulta la guida agli eventi di cambio della videocamera.
La posizione della fotocamera
La visualizzazione mappa è modellata come una fotocamera che guarda verso il basso su un aereo piatto. La posizione della videocamera (e quindi il rendering della mappa) viene specificata dalle seguenti proprietà: target (posizione di latitudine/longitudine), supporto, inclinazione e zoom.
Target (località)
L'obiettivo 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 di questo intervallo. Ad esempio, se specifichi una latitudine pari a 100, il valore verrà impostato su 85. La longitudine è compresa tra -180 e 180 gradi inclusi. I valori al di sopra o al di sotto di questo intervallo verranno aggregati in modo da rientrare nell'intervallo (-180, 180). Ad esempio, 480, 840 e 1200 saranno tutti avvolti a 120 gradi.Orientamento (orientamento)
L'orientamento della fotocamera specifica la direzione della bussola, misurata in gradi dal vero nord, corrispondente al bordo superiore della mappa. Se tracci una linea verticale dal centro della mappa al bordo superiore della mappa, l'orientamento corrisponde all'orientamento della fotocamera (misurato in gradi) rispetto al nord reale.
L'orientamento 0 indica che la parte superiore della mappa punta al vero nord. Un valore di rilevamento 90 indica la parte superiore dei punti della mappa verso est (90 gradi su una bussola). Il valore 180 indica la parte superiore dei punti della mappa verso sud.
L'API di Google Maps consente di modificare l'orientamento di una mappa. Ad esempio, chi guida un'auto spesso trasforma una mappa stradale per allinearla alla direzione di marcia, mentre gli escursionisti che utilizzano una mappa e una bussola di solito orientano la mappa in modo che una linea verticale punti verso nord.
Inclinazione (angolo di visualizzazione)
L'inclinazione definisce la posizione della fotocamera su un arco direttamente sopra la posizione centrale della mappa, misurata in gradi dal nadir (la direzione che punta direttamente sotto la fotocamera). Il valore 0 corrisponde a una fotocamera puntata in basso. I valori maggiori di 0 corrispondono a una fotocamera inclinata verso l'orizzonte del numero di gradi specificato. Quando modifichi l'angolo di visualizzazione, la mappa appare in prospettiva, con gli elementi lontani che appaiono più piccoli e gli elementi vicini che appaiono più grandi. Le seguenti illustrazioni lo dimostrano.
Nelle immagini seguenti, l'angolo di visualizzazione è di 0 gradi. La prima immagine mostra uno schematico di questa operazione: la posizione 1 è la posizione della fotocamera, mentre la posizione 2 è la posizione corrente della mappa. La mappa risultante viene visualizzata sotto di essa.
Nelle immagini seguenti, l'angolo di visione è di 45 gradi. Nota che la fotocamera si sposta a metà di un arco tra la superficie dritta (0°) e il suolo (90°) nella posizione 3. La fotocamera continua a puntare nel punto centrale della mappa, ma l'area rappresentata dalla linea in posizione 4 è ora visibile.
La mappa in questo screenshot è ancora centrata sullo stesso punto della mappa originale, ma nella parte superiore della mappa sono stati visualizzati altri elementi. Man mano che aumenti l'angolazione 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 appariranno proporzionalmente più piccoli, producendo un effetto tridimensionale.
Zoom
Il livello di zoom della fotocamera determina la scala della mappa. A livelli di zoom maggiori si possono vedere più dettagli sullo schermo, mentre a livelli di zoom più piccoli si può vedere più parti del mondo sullo schermo. A livello di zoom 0, la scala della mappa è tale che l'intero mondo abbia 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, il mondo intero ha una larghezza di circa 1024 dp.
Il livello di zoom non deve essere un numero intero. L'intervallo di livelli di zoom consentiti dalla mappa dipende da una serie di fattori, tra cui il target, il tipo di mappa e le dimensioni dello schermo. Qualsiasi numero al di fuori dell'intervallo verrà convertito al valore valido successivo più vicino, che può essere il livello di zoom minimo o il livello di zoom massimo. Nell'elenco che segue viene mostrato il livello approssimativo di dettaglio previsto per ogni livello di zoom:
- 1: Mondo
- 5: massa continentale/continente
- 10: Città
- 15: Strade
- 20: Edifici
Spostamento della videocamera
L'API di Google Maps ti consente di modificare la parte del mondo visibile sulla mappa. Per farlo, è necessario cambiare la posizione della fotocamera (anziché spostare la mappa).
Quando cambi la videocamera, hai la possibilità di animare il movimento risultante della videocamera. L'animazione interpola tra gli attributi attuali della fotocamera e i nuovi attributi della videocamera. Puoi anche controllare la durata dell'animazione.
Per cambiare la posizione della videocamera, devi specificare dove vuoi
spostarla utilizzando un CameraUpdate
. L'API di Google Maps
ti consente di creare molti tipi diversi di CameraUpdate
utilizzando
CameraUpdateFactory
. Sono disponibili le seguenti opzioni:
Modifica del livello di zoom e impostazione dello zoom minimo/massimo
CameraUpdateFactory.zoomIn()
e
CameraUpdateFactory.zoomOut()
offrono un CameraUpdate
che modifica il livello di zoom di 1,0, mantenendo
invariate tutte le altre proprietà.
CameraUpdateFactory.zoomTo(float)
offre 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)
offrono un CameraUpdate
che aumenta (o diminuisce, se il valore è
negativo) il livello di zoom del valore specificato. Quest'ultimo sistema il punto specificato sullo schermo in modo che rimanga nella stessa posizione (latitudine/longitudine) e potrebbe quindi cambiare la posizione della videocamera per ottenere questo risultato.
Può essere utile impostare il livello di zoom minimo e/o massimo preferito. Ad esempio, questo è utile per controllare l'esperienza dell'utente se la tua app mostra un'area definita intorno a un punto d'interesse o se utilizzi un overlay di riquadri personalizzati 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 eseguire lo zoom troppo basso o troppo alto. Ad esempio, satellite o rilievo potrebbero avere uno zoom massimo inferiore rispetto ai riquadri della mappa base.
Modifica della posizione della fotocamera
Esistono due metodi pratici per le modifiche di posizione comune.
CameraUpdateFactory.newLatLng(LatLng)
offre un valore CameraUpdate
che modifica la latitudine e la longitudine della videocamera,
trattenendo tutte le altre proprietà.
CameraUpdateFactory.newLatLngZoom(LatLng, float)
offre un CameraUpdate
che modifica la latitudine, la longitudine e lo zoom della videocamera, preservando tutte le altre proprietà.
Per la massima flessibilità nella modifica della posizione della videocamera, utilizza CameraUpdateFactory.newCameraPosition(CameraPosition)
, che offre un CameraUpdate
che sposta la videocamera nella posizione specifica. Puoi ottenere un CameraPosition
direttamente utilizzando new CameraPosition()
o con CameraPosition.Builder
tramite new CameraPosition.Builder()
.
Panoramica (scorrimento)
CameraUpdateFactory.scrollBy(float, float)
fornisce un valore CameraUpdate
che
modifica la latitudine e la longitudine della videocamera in modo che la mappa si sposti in base al
numero specificato di pixel. Se il valore x è positivo, la fotocamera si sposta
a destra e la mappa sembra essere spostata a sinistra. Un valore y positivo fa sì che la fotocamera si sposti verso il basso, in modo che la mappa si sia spostata verso l'alto. Al contrario, i valori x negativi causano lo spostamento della fotocamera verso sinistra,
quindi la mappa sembra essere spostata a destra, mentre i valori y negativi fanno sì che la
videocamera si sposti verso l'alto. Lo scorrimento è relativo
all'orientamento corrente della videocamera. Ad esempio, se la videocamera ha un rilevamento di 90 gradi, est
è "su".
Stabilire dei limiti
Impostare i confini della mappa
A volte è utile spostare la videocamera in modo che un'intera area di interesse sia visibile al massimo livello di zoom possibile. Ad esempio, se stai mostrando tutte le stazioni di servizio nel raggio di cinque miglia dalla posizione corrente dell'utente, puoi spostare la videocamera in modo che siano tutte visibili sullo schermo. Per farlo, devi prima calcolare il valore di 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 LatLngBounds
specificato si adatti interamente alla mappa, tenendo conto della spaziatura interna (in pixel) specificata. Il valore CameraUpdate
restituito
garantisce che lo spazio (in pixel) tra i limiti specificati e il bordo della mappa sia almeno pari alla spaziatura interna specificata. Tieni presente che l'inclinazione e
l'orientamento della mappa sono entrambi 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, potresti voler centrare la videocamera entro un limite invece di includere i bordi estremi. Ad esempio, per centrare la fotocamera su un
paese mantenendo uno zoom costante. In questo caso, puoi utilizzare un metodo simile creando un elemento LatLngBounds
e utilizzando CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom)
con LatLngBounds
.getCenter()
. Il metodo getCenter() restituisce
il centro geografico dell'elemento 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)
, ti consente di specificare la larghezza e l'altezza in pixel per un rettangolo, con l'intenzione che queste corrispondano alle dimensioni della mappa. Il rettangolo è posizionato in modo che il suo centro sia lo stesso della visualizzazione della mappa (in modo che se le dimensioni specificate sono uguali a quelle della visualizzazione della mappa, il rettangolo coincide con la visualizzazione della mappa). L'elemento CameraUpdate
restituito sposterà la videocamera in modo che i LatLngBounds
specificati siano centrati sullo schermo all'interno del rettangolo specificato al livello di zoom più alto possibile, tenendo conto della spaziatura interna richiesta.
Nota: utilizza il metodo più semplice
newLatLngBounds(boundary, padding)
per generare un CameraUpdate
se verrà utilizzato per spostare
la fotocamera dopo il layout della mappa. Durante il layout, l'API
calcola i confini di visualizzazione della mappa necessari per proiettare correttamente
il riquadro di delimitazione. In confronto, puoi utilizzare
CameraUpdate
restituito dal metodo più complesso
newLatLngBounds(boundary, width, height, padding)
in qualsiasi momento, anche prima che la mappa sia stata sottoposta al layout, perché l'API
calcola i confini di visualizzazione in base agli argomenti che passi.
Limitazione della panoramica dell'utente a una determinata area
Negli scenari precedenti, puoi impostare i limiti della mappa, ma l'utente può quindi scorrere o eseguire la panoramica al di fuori di questi limiti. Puoi invece limitare i limiti centrali latitudine/longitudine del punto focale della mappa (il target della fotocamera) in modo che gli utenti possano solo scorrere e fare una panoramica all'interno di questi limiti. Ad esempio, un'app di retail per un centro commerciale o un aeroporto potrebbe voler limitare la mappa a un determinato limite, consentendo agli utenti di scorrere ed 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 videocamera rimanga all'interno dell'area delimitata. La croce rappresenta il target della videocamera:
La mappa riempie sempre l'area visibile, anche se in questo modo l'area visibile mostra aree che si trovano al di fuori dei limiti definiti. Ad esempio, se posizioni il target della videocamera in un angolo dell'area delimitata, l'area oltre l'angolo è visibile nell'area visibile, ma gli utenti non possono scorrere oltre l'area. Il seguente diagramma illustra questo scenario. La croce rappresenta il target della fotocamera:
Nel diagramma seguente, il target della videocamera presenta limiti molto limitati, offrendo all'utente scarse opportunità di scorrere o eseguire la panoramica della mappa. La croce rappresenta l'obiettivo della fotocamera:
Aggiornamento della visualizzazione della videocamera in corso...
Per applicare una CameraUpdate
alla mappa, puoi spostare
la videocamera all'istante o animarla uniformemente. Per spostare istantaneamente la videocamera
con l'oggetto CameraUpdate
specificato, puoi chiamare
GoogleMap.moveCamera(CameraUpdate)
.
Puoi rendere più piacevole l'esperienza utente, in particolare per i movimenti brevi,
animando la modifica. Per farlo, anziché chiamare
GoogleMap.moveCamera
chiama
GoogleMap.animateCamera
.
La mappa si sposterà facilmente nei nuovi attributi. La forma più dettagliata di questo metodo, GoogleMap.animateCamera(cameraUpdate, duration, callback)
, offre tre argomenti:
cameraUpdate
- La
CameraUpdate
che descrive dove spostare la videocamera. 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 richiamati nelle seguenti circostanze:onFinish()
- Richiamato se l'animazione termina senza interruzioni.
onCancel()
-
Richiamato se l'animazione viene interrotta chiamando il numero
stopAnimation()
o avviando un nuovo movimento della videocamera.In alternativa, ciò 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 più comuni per spostare la videocamera.
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));