Mapy w pakiecie Maps SDK na Androida można przechylać i obracać za pomocą prostych gestów, co umożliwia użytkownikom dostosowanie mapy do ich potrzeb. Na dowolnym poziomie powiększenia możesz przesuwać mapę lub zmieniać jej perspektywę z bardzo małym opóźnieniem dzięki mniejszemu rozmiarowi pikselów płytek mapy opartej na wektorach.
Przykładowe fragmenty kodu
Repozytorium API Apigee na GitHubie zawiera przykład, przedstawia funkcje aparatu:
- CameraDemoActivity – Kotlin: zmiana pozycji kamery
- CameraDemoActivity (Java): zmiana pozycji kamery
Wprowadzenie
Podobnie jak Mapy Google w internecie, pakiet Maps SDK na Androida reprezentuje powierzchnię świata (sferę) na ekranie urządzenia (płaską płaszczyznę) za pomocą Odwzorowanie metryczne. W kierunku wschodnim i zachodnim mapa jest powtarzana w nieskończoność, ponieważ świat płynnie łączy się z sobą. W kierunek północny i południowy jest ograniczony do około 85 stopni na północ i 85 stopni na południe.
Uwaga: odwzorowanie Merkatora ma skończoną szerokość. na nieskończoność długości, ale na nieskończoną wysokość. „Odcinamy” obrazy mapy podstawowej, korzystając z projekcji Mercatora z przybliżeniem +/- 85°, aby uzyskać kwadratowy kształt mapy, co ułatwia logikę wyboru płytek.
Maps SDK na Androida pozwala zmienić punkt widzenia użytkownika mapy, modyfikując jej aparat.
Zmiany w aparacie nie wpłyną na dodane przez Ciebie znaczniki, nakładki ani inne elementy graficzne, ale warto je dostosować do nowego widoku.
Ponieważ możesz odbierać gesty użytkownika na mapie, możesz zmieniać mapę w odpowiedzi na prośby użytkownika. Na przykład metoda wywołania zwrotnego OnMapClickListener.onMapClick()
reaguje na pojedyncze kliknięcie na mapie. Ponieważ metoda otrzymuje szerokość i długość geograficzną
miejsca kliknięcia, możesz zareagować, przesuwając lub powiększając widok do tego punktu.
Podobne metody są dostępne w reakcji na kliknięcia okienka znacznika lub na gest przeciągania znacznika.
Możesz też słuchać dźwięków związanych z ruchu kamery, aby Twoja aplikacja otrzymywała powiadomienia, gdy kamera zaczyna się poruszać, porusza się lub przestaje się poruszać. Szczegółowe informacje znajdziesz w przewodniku po zdarzeniach zmiany kamery.
Położenie kamery
Widok mapy jest modelowany jako kamera skierowana w dół na płaską powierzchnię. Pozycja kamery (a zatem renderowanie mapy) jest określana przez te właściwości: cel (szerokość geograficzna/długość geograficzna), kierunek, pochylenie i powiększenie.
Cel (lokalizacja)
Cel kamery to lokalizacja środka mapy określona przez współrzędne geograficzne.
Szerokość geograficzna może się mieścić w przedziale od –85 do 85 stopni. Wartości powyżej lub poniżej tego zakresu zostanie ograniczona do najbliższej wartości z tego zakresu. Na przykład podanie szerokości geograficznej 100 spowoduje ustawienie wartości 85. Długość geograficzna może przyjmować wartości od -180 do 180 stopni włącznie. Wartości powyżej lub poniżej tej wartości zakres zostanie zawijany w taki sposób, aby mieścił się w zakresie (-180, 180). Na przykład wartości 480, 840 i 1200 zostaną zaokrąglone do 120 stopni.Orientacja
Orientacja kamery określa kierunek kompasu, mierzony w stopniach od rzeczywistej północy, odpowiadając do górnej krawędzi mapy. Jeśli narysujesz pionową linię od środka mapy do górnej krawędzi położenie na mapie, położenie odpowiada kierunkowi kamery (mierzonemu w stopniach) do północy geograficznej.
Orientacja 0 oznacza, że góra mapy wskazuje rzeczywistą północ. Wartość kierunku 90 oznacza, że góra mapy jest skierowana we wschód (90 stopni na kompasie). Wartość A 180 oznacza górną część mapy wskazujący kierunek południowy.
Interfejs Maps API umożliwia zmianę kierunku mapy. Na przykład osoba jadąca samochodem często obraca mapę drogową, aby dopasować ją do kierunku jazdy, a piechurzy korzystający z mapy i kompasu zwykle orientują mapę tak, aby linia pionowa wskazywała kierunek północny.
Pochylenie (kąt patrzenia)
Pochylenie określa położenie kamery na łuku bezpośrednio nad mapą położenie środkowe, mierzone w stopniach od Nadir (kierunek skierowany bezpośrednio pod aparatem). Wartość 0 oznacza, że aparat jest skierowany. prosto w dół. Wartości większe niż 0 odpowiadają kamerze skierowanej w kierunku horyzontu o określoną liczbę stopni. Gdy zmienisz kąt widzenia, mapa będzie wyglądać w perspektywie, a elementy znajdujące się daleko będą wydawać się mniejsze, a te znajdujące się blisko – większe. Poniżej znajdziesz ilustracje obrazujące ten proces.
Na poniższych obrazach kąt patrzenia wynosi 0 stopni. Pierwsze zdjęcie przedstawia schematyczną wersję tego procesu: pozycja 1 to pozycja kamery, a pozycja 2 to bieżąca pozycja na mapie. Powstała mapa jest widoczna pod nią.
Na poniższych obrazach kąt patrzenia wynosi 45 stopni. Zwróć uwagę, że kamera przesuwa się o połowę łuku między pozycją na wprost nad głową (0 stopni) a pozycją na wysokości ziemi (90 stopni) do pozycji 3. Kamera nadal wskazuje środek mapy, ale obszar reprezentowany przez linię w pozycji 4 jest teraz widoczny.
Na tym zrzucie ekranu mapa jest nadal wyśrodkowana w tym samym miejscu co na oryginalnej mapie, ale u góry pojawiło się więcej funkcji. Gdy zwiększ kąt powyżej 45 stopni, elementy między aparatem a mapą położenie jest proporcjonalnie większe, a obiekty poza położeniem na mapie wydawać się proporcjonalnie mniejsze, co daje efekt trójwymiarowy.
Zoom
Poziom powiększenia kamery określa skalę mapy. Przy większych poziomach powiększenia na ekranie widać więcej szczegółów, a przy mniejszych – więcej świata. Przy poziomie powiększenia 0 skala Mapa jest taka, że cały świat ma szerokość około 256 dp. (piksele niezależne od gęstości).
Zwiększenie poziomu powiększenia o 1 powoduje podwojenie szerokości ekranu. Dlatego przy poziomie powiększenia N szerokość świata wynosi około 256 × 2N dp. Na przykład przy powiększeniu 2 cały świat jest ustawiony na około Szerokość 1024 dp.
Poziom powiększenia nie musi być liczbą całkowitą. Zakres powiększenia poziomy dozwolone przez mapę zależą od wielu czynników, w tym od wartości docelowej, typu mapy i rozmiaru ekranu. Każda liczba spoza zakresu zostanie przekonwertowana na najbliższą prawidłową wartość, która może być minimalnym lub maksymalnym powiększeniem. Poniższa lista pokazuje przybliżony poziom szczegółowości które możesz zobaczyć przy każdym powiększeniu:
- 1: Świat
- 5: Ląd/kontynent
- 10: Miasto
- 15: ulice
- 20. Budynki
Przesuwanie kamery
W interfejsie API Map Google możesz wybrać, która część świata jest widoczna na mapy. Osiąga się to przez zmianę pozycji kamery (a nie przez przesuwanie mapy).
Gdy zmieniasz kamerę, możesz animować ruch kamery. Animacja interpoluje między bieżącymi atrybutami kamery a nowymi atrybutami kamery. Możesz też określić czas trwania animacji.
Aby zmienić pozycję kamery, musisz określić, dokąd ją przesunąć, za pomocą elementu CameraUpdate
. Interfejs Maps API umożliwia tworzenie wielu różnych typów CameraUpdate
za pomocą CameraUpdateFactory
. Dostępne są te ustawienia:
Zmiana poziomu powiększenia i ustawianie minimalnego/maksymalnego powiększenia
CameraUpdateFactory.zoomIn()
i CameraUpdateFactory.zoomOut()
dają CameraUpdate
, który zmienia poziom powiększenia o 1,0, zachowując przy tym wszystkie inne właściwości.
CameraUpdateFactory.zoomTo(float)
daje wartość CameraUpdate
, która zmienia poziom powiększenia na podaną wartość,
bez zmian we wszystkich pozostałych właściwościach.
CameraUpdateFactory.zoomBy(float)
oraz
CameraUpdateFactory.zoomBy(float, Point)
otrzymasz CameraUpdate
, który rośnie (lub maleje, jeśli wartość jest
ujemnego poziomu powiększenia o podaną wartość. Druga opcja polega na utrwaleniu danego punktu na ekranie, tak aby pozostał w tej samej lokalizacji (szerokość/długość geograficzna). Aby to osiągnąć, może zmienić położenie kamery.
Możesz ustawić preferowany minimalny lub maksymalny poziom powiększenia. Może to być przydatne np. do kontrolowania wrażeń użytkownika, jeśli aplikacja wyświetla zdefiniowany obszar wokół punktu zainteresowania lub jeśli używasz niestandardowej nakładki z ograniczonym zestawem poziomów powiększenia.
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);
Pamiętaj, że ze względów technicznych mogą one uniemożliwiać które umożliwiają użytkownikom zbyt małe lub zbyt duże powiększenie. Na przykład widok satelitarny lub widok terenu może mieć mniejsze maksymalne powiększenie niż płytki mapy bazowej.
Zmiana pozycji kamery
Istnieją 2 wygodne metody wprowadzania typowych zmian pozycji.
CameraUpdateFactory.newLatLng(LatLng)
daje CameraUpdate
, który zmienia szerokość i długość geograficzną kamery,
przy zachowaniu pozostałych właściwości.
CameraUpdateFactory.newLatLngZoom(LatLng, float)
daje CameraUpdate
, który zmienia
szerokości i długości geograficznej oraz powiększenia przy zachowaniu wszystkich pozostałych właściwości.
Aby mieć pełną swobodę zmiany pozycji kamery, użyj CameraUpdateFactory.newCameraPosition(CameraPosition)
, która umożliwia użycie CameraUpdate
, aby przesunąć kamerę do danej pozycji. CameraPosition
można uzyskać bezpośrednio przy użyciu
new CameraPosition()
lub w połączeniu z usługą CameraPosition.Builder
w przypadku:
new CameraPosition.Builder()
Przesuwanie (przewijanie)
CameraUpdateFactory.scrollBy(float, float)
zwraca CameraUpdate
, który zmienia współrzędne geograficzne kamery w taki sposób, że mapa przesuwa się o określoną liczbę pikseli. Dodatnia wartość x powoduje przesunięcie kamery w prawo, dzięki czemu mapa wydaje się przesunięta w lewo. A dodatnie y
powoduje przesuwanie kamery w dół, sprawiając, że mapa się przesunęła
w górę. Z kolei ujemne wartości x powodują przesunięcie kamery w lewo, przez co mapa wydaje się przesunięta w prawo, a ujemne wartości y powodują przesunięcie kamery w górę. Przewijanie jest względne do bieżącej orientacji kamery. Jeśli na przykład kamera ma kierunek 90 stopni, wschodnia strona świata jest „na górze”.
Wyznaczanie granic
Wyznaczanie granic mapy
Czasami warto przenieść
dzięki czemu cały interesujący Cię obszar jest widoczny
poziom powiększenia. Jeśli na przykład wyświetlasz wszystkie stacje benzynowe w okolicy:
na odległość 8 km od bieżącej pozycji użytkownika, możesz przesunąć kamerę tak,
aby były widoczne na ekranie. Aby to zrobić, najpierw oblicz
LatLngBounds
, które mają być widoczne na ekranie. Następnie możesz użyć CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int
padding)
, aby uzyskać CameraUpdate
, który zmienia pozycję kamery tak, aby dany LatLngBounds
mieścił się całkowicie na mapie, biorąc pod uwagę określony margines (w pikselach). Zwrócona wartość CameraUpdate
zapewnia przerwę (w pikselach) między podanymi granicami a krawędzią
mapa będzie równa co najmniej określonemu dopełnieniu. Pamiętaj, że funkcja przechylenia
przesunięcie mapy będzie wynosić 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));
Wyśrodkowywanie mapy w obszarze
W niektórych przypadkach warto wyśrodkować kamerę w określonym obszarze, a nie
łącznie z granicami skrajnymi. Aby na przykład wyśrodkować kamerę na kraju
utrzymując stałe powiększenie. W takim przypadku możesz użyć podobnej metody, tworząc element LatLngBounds
i używając elementu CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom)
z elementem LatLngBounds
.getCenter()
metody. Metoda getCenter() zwraca geograficzny środek 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));
Przeciążenie metody newLatLngBounds(boundary, width, height,
padding)
umożliwia określenie szerokości i wysokości prostokąta w pikselach, tak aby odpowiadały one wymiarom mapy. Prostokąt jest tak umieszczony, aby jego środek pokrywał się ze środkiem widoku mapy (tak więc jeśli określone wymiary są takie same jak wymiary widoku mapy, prostokąt pokrywa się z widokiem mapy). Zwrócona wartość CameraUpdate
spowoduje przesunięcie kamery tak, aby określone elementy LatLngBounds
znalazły się na środku ekranu w danym prostokącie przy największym możliwym poziomie powiększenia, biorąc pod uwagę wymagane wypełnienie.
Uwaga: prostszą metodę newLatLngBounds(boundary, padding)
do generowania pliku CameraUpdate
stosuj tylko wtedy, gdy ma on służyć do przemieszczania kamery po ułożeniu mapy. Podczas tworzenia układu interfejs API oblicza wyświetlane granice mapy, które są potrzebne do prawidłowego wyświetlania ramki ograniczającej. Dla porównania możesz użyć atrybutu
Funkcja CameraUpdate
zwrócona przez bardziej złożoną metodę
newLatLngBounds(boundary, width, height, padding)
w dowolnym momencie, jeszcze przed zmianą układu mapy, ponieważ interfejs API
oblicza granice wyświetlania na podstawie przekazywanych argumentów.
Ograniczanie przesuwania w danym obszarze przez użytkownika
W wymienionych powyżej scenariuszach określasz granice mapy, ale użytkownik może przewijać lub przesuwać widok poza te granice. Zamiast tego lepiej będzie: ograniczyć granicę środka szerokości i długości geograficznej punktu fokalnego mapy (kamera cel), dzięki czemu użytkownicy mogą tylko przewijać i przesuwać tylko w obrębie tych granic. Przykład: w przypadku aplikacji dla sklepów w centrum handlowym lub na lotnisku może być konieczne ograniczenie mapy określonych granic, co umożliwia użytkownikom przewijanie i przesuwanie w obrębie tych granic.
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);
Ten diagram przedstawia sytuację, w której cel kamery jest ograniczony do obszaru nieco większego niż widoczny obszar. Użytkownik może przewijanie i przesuwanie, pod warunkiem że cel kamery pozostaje w ograniczonym obszarze. Krzyżyk oznacza cel kamery:
Mapa zawsze wypełnia widoczny obszar, nawet jeśli spowoduje to obszary znajdujące się poza zdefiniowanymi granicami. Jeśli na przykład umieścisz punkt docelowy kamery w rogu ograniczonego obszaru, obszar za rogiem będzie widoczny w widocznym obszarze, ale użytkownicy nie będą mogli przewinąć dalej w tym kierunku. Ten diagram przedstawia ten scenariusz. Krzyż oznacza cel kamery:
Na poniższym schemacie cel kamery ma bardzo ograniczone granice. oferowanie użytkownikowi jak najmniejszej możliwości przewijania lub przesuwania mapy. Krzyż reprezentuje cel kamery:
Aktualizuję widok z kamery
Aby zastosować CameraUpdate
na mapie, możesz przesunąć kamerę natychmiast lub płynnie. Aby przesunąć kamerę
przy użyciu CameraUpdate
, możesz zadzwonić
GoogleMap.moveCamera(CameraUpdate)
Możesz zwiększyć wygodę użytkowników, zwłaszcza w przypadku krótkich przeskoków, przez animację zmian. Aby to zrobić, zamiast dzwonić
GoogleMap.moveCamera
zadzwoń
GoogleMap.animateCamera
Nowe atrybuty mapy zostaną płynnie przeniesione. Najbardziej szczegółowa forma tej metody
GoogleMap.animateCamera(cameraUpdate, duration, callback)
,
Podaje 3 argumenty:
cameraUpdate
CameraUpdate
który opisuje, gdzie przesunąć kamerę.callback
- Obiekt, który implementuje
GoogleMap.CancellableCallback
Ten ogólny interfejs do obsługi zadań definiuje 2 metody: onCancel() i onFinished(). W przypadku animacji metody są wywoływane w tych okolicznościach:onFinish()
- Wywoływany, gdy animacja zostanie dokończona bez przerwy.
onCancel()
-
Wywoływany, jeśli animacja zostanie przerwana przez wywołanie
stopAnimation()
lub rozpoczęcie nowego ruchu kamery.Może się to również zdarzyć, gdy zadzwonisz
GoogleMap.stopAnimation()
duration
- Pożądany czas trwania animacji (w milisekundach) jako
int
.
Poniższe fragmenty kodu ilustrują niektóre typowe sposoby przenoszenia aparat fotograficzny.
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));