Kamera i widok

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.
Wybierz platformę: Android iOS JavaScript

Mapy dostępne w pakiecie Maps SDK na Androida możesz przechylać i obracać, wykonując proste gesty, dzięki czemu użytkownicy mogą dostosować mapę do własnych potrzeb. Na każdym poziomie powiększenia możesz przesuwać mapę lub zmieniać jej spojrzenie z niewielkim opóźnieniem ze względu na mniejszy zasięg kafelków opartych na wektorach.

Przykładowe fragmenty kodu

Repozytorium ApiDemos w GitHubie zawiera przykład, który demonstruje funkcje kamery:

Wprowadzenie

Podobnie jak Mapy Google w internecie pakiet SDK Map na Androida reprezentuje powierzchnię świata (kulę sferyczną) na ekranie urządzenia (płaską płaszczyznę) przy użyciu projekcji miksera. W kierunku wschodnim i zachodnim mapa jest powtarzana w nieskończoność, gdy świat płynnie przechodzi między nimi. W kierunku północnym i południowym mapa jest ograniczona do około 85 stopni na północ i 85 stopni na południe.

Uwaga: odwzorowanie Merkatora ma skończoną szerokość, ale nieskończoną wysokość. Obrazy map podstawowych są obcinane z użyciem odwzorowania Merkatora na poziomie +/-85 stopni, aby uzyskać kwadratowy kształt mapy, co ułatwia wybór kafelków.

Maps SDK na Androida umożliwia zmianę punktu widzenia mapy, modyfikując aparat mapy.

Zmiany w aparacie nie spowodują żadnych zmian w znacznikach, nakładkach ani innych dodanych grafikach, ale możesz je zmienić, tak aby lepiej pasowały do nowego widoku.

Ponieważ możesz nasłuchiwać gestów na mapie, możesz zmieniać mapę w odpowiedzi na prośby użytkowników. Na przykład metoda wywołania zwrotnego OnMapClickListener.onMapClick() reaguje na jedno kliknięcie na mapie. Ponieważ metoda otrzymuje szerokość i długość geograficzną miejsca kliknięcia, możesz na nie odpowiedzieć, przesuwając lub powiększając ją do tego punktu. Podobne metody są dostępne w przypadku reagowania na dotknięcia dymka znacznika lub na gest przeciągania.

Możesz też nasłuchiwać ruchów kamery, aby aplikacja otrzymywała powiadomienia, gdy kamera zaczyna się poruszać, obecnie porusza się lub zatrzymuje. Szczegółowe informacje znajdziesz w przewodniku o zdarzeniach związanych ze zmianą aparatu.

położenie kamery,

Widok mapy jest modelowany jako aparat patrzący w dół na płaskiej płaszczyźnie. Położenie kamery (a tym samym jej renderowanie) określają te właściwości: miejsce docelowe (lokalizacja geograficzna i szerokość geograficzna), wykorzystanie, przechylenie i powiększenie.

Diagram właściwości aparatu

Cel (lokalizacja)

Cel kamery to lokalizacja środka mapy, określona jako współrzędne długości i szerokości geograficznej.

Szerokość geograficzna może wynosić od -85 do 85 stopni (włącznie). Wartości powyżej lub poniżej tego zakresu zostaną ograniczone do najbliższej wartości w tym zakresie. Na przykład określenie szerokości geograficznej wynoszącej 100 spowoduje ustawienie wartości na 85. Długość geograficzna mieści się w zakresie od -180 do 180 stopni (włącznie). Wartości powyżej lub poniżej tego zakresu zostaną spakowane, aby mieściły się w zakresie (–180, 180). Na przykład rozmiary 480, 840 i 1200 zostaną spadzone do 120 stopni.

Orientacja (orientacja)

Łożysko kamery określa kierunek kompasu w stopniach wyrażony w stopniach od prawdziwej północy, co odpowiada górnej krawędzi mapy. Jeśli narysowasz pionową linię od środka mapy do górnej krawędzi mapy, kąt wierzchołka odpowiada ustawieniu kamery (mierzonej w stopniach) względem prawdziwej północy.

Znak 0 oznacza, że początek mapy wskazuje prawdziwą północ. Wartość 90 oznacza, że punkt u góry mapy wskazuje na wschód (90 stopni na kompasie). Wartość 180 oznacza początek mapy na południe.

Interfejs API Map Google umożliwia zmianę kierunku mapy. Na przykład ktoś, kto prowadzi samochód, często zmienia mapę drogową, by dostosować ją do kierunku podróżowania, natomiast turyści korzystający z mapy i kompasu zwykle ustawiają mapę tak, aby linia pionowa kierowała się na północ.

Pochylenie (kąt patrzenia)

Pochylenie definiuje położenie kamery na łuku bezpośrednio nad środkowym położeniem mapy mierzoną w stopniach od nadir (kierunku bezpośrednio pod aparatem). Wartość 0 oznacza aparat skierowany prosto do dołu. Wartości większe niż 0 to aparat, który jest ustawiany do horyzontu o określoną liczbę stopni. Gdy zmienisz kąt wyświetlania, mapa będzie wyświetlana z perspektywy. Różne obiekty mogą być mniejsze, a obiekty w pobliżu będą większe. Ilustracje poniżej pokazują to.

Na poniższych obrazach kąt patrzenia wynosi 0 stopni. Pierwszy obraz przedstawia schemat. Pozycja 1 oznacza położenie kamery, a 2 to aktualna pozycja na mapie. Otrzymana mapa jest widoczna pod spodem.

Zrzut ekranu mapy z kamerą ustawioną pod kątem 0 stopni, przy powiększeniu 18
Mapa wyświetlana z domyślnym kątem widzenia kamery.
Schemat przedstawiający domyślną pozycję kamery bezpośrednio nad pozycją mapy, pod kątem 0 stopni.
Domyślny kąt widzenia kamery.

Na poniższych obrazach kąt patrzenia wynosi 45 stopni. Zwróć uwagę, że kamera porusza się w połowie między łukami (0 stopni) a podłożem (90 stopni) do pozycji 3. Kamera nadal wskazuje punkt centralny mapy, ale obszar reprezentowany przez linię w pozycji 4 jest teraz widoczny.

Zrzut ekranu mapy z aparatem o 45 stopniach przy powiększeniu 18.
Mapa wyświetlana pod kątem 45 stopni.
Diagram przedstawiający kąt widzenia kamery ustawiony na 45 stopni z powiększeniem na poziomie 18 stopni.
Kąt oglądania pod kątem 45 stopni.

Mapa na tym zrzucie ekranu jest nadal wyśrodkowana na tym samym punkcie, co pierwotna mapa, ale na górze mapy pojawiło się więcej funkcji. W miarę zwiększania kąta przekraczającego 45 stopni funkcje kamery i pozycji na mapie wydają się proporcjonalnie większe, a elementy poza pozycją mapy wyglądają na proporcjonalnie mniejsze, co daje efekt trójwymiarowy.

Szersza

Poziom powiększenia kamery określa skalę mapy. Na większych poziomach powiększenia na ekranie widać więcej szczegółów, ale na mniejszych poziomach powiększenia widać większą część świata. Na poziomie powiększenia 0 skala mapy wygląda tak – szerokość całego świata wynosi około 256 dp (pikseli niezależnych od gęstości).

Zwiększenie poziomu powiększenia o 1 powoduje podwojenie szerokości świata na ekranie. W związku z tym przy powiększeniu N szerokość świata wynosi około 256 * 2N dp. Na przykład przy powiększeniu na poziomie 2 cały świat ma około 1024 dp szerokości.

Poziom powiększenia nie musi być liczbą całkowitą. Zakres poziomu powiększenia dozwolony przez mapę zależy od wielu czynników, w tym od typu celu, typu mapy i rozmiaru ekranu. Każda wartość 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 na poszczególnych poziomach powiększenia:

  • 1: Świat
  • 5: ląd/kontynent
  • 10: Miasto
  • 15: ulice
  • 20: Budynki
Poniższe obrazy przedstawiają wygląd w różnym stopniu powiększenia:
Zrzut ekranu mapy z poziomem powiększenia 5
Mapa z poziomem powiększenia 5.
Zrzut ekranu mapy z powiększeniem 15
Mapa z powiększeniem na poziomie 15.
Zrzut ekranu mapy na poziomie powiększenia 20
Mapa przy poziomie powiększenia 20.

Przenoszenie kamery

Interfejs API Map Google pozwala zmienić, która część świata jest widoczna na mapie. Jest to możliwe po zmianie położenia kamery (a nie po przesunięciu mapy).

Po zmianie kamery możesz animować efekt ruchu kamery. Animacja interpoluje między bieżącymi atrybutami kamery i nowymi atrybutami kamery. Możesz też kontrolować czas trwania animacji.

Aby zmienić położenie kamery, musisz określić, gdzie chcesz ją przenieść, za pomocą CameraUpdate. Interfejs API Map Google umożliwia tworzenie wielu różnych typów obiektów CameraUpdate za pomocą funkcji CameraUpdateFactory. Dostępne są te opcje:

Zmienianie poziomu powiększenia i ustawianie minimalnej i maksymalnej powiększenia

CameraUpdateFactory.zoomIn() i CameraUpdateFactory.zoomOut() dają CameraUpdate, który pozwala zmieniać poziom powiększenia o 1,0, zachowując wszystkie pozostałe właściwości.

CameraUpdateFactory.zoomTo(float) zwraca element CameraUpdate, który zmienia poziom powiększenia na określoną wartość, zachowując pozostałe właściwości.

CameraUpdateFactory.zoomBy(float) i CameraUpdateFactory.zoomBy(float, Point) dają CameraUpdate, który zwiększa (lub zmniejsza, jeśli wartość jest ujemna) poziom powiększenia o podaną wartość. Ta ostatnia opcja koryguje określony punkt na ekranie, pozostawając w tej samej lokalizacji (szerokości i długości geograficznej), więc może zmieniać położenie kamery, aby to osiągnąć.

Przydatne może być ustawienie preferowanego minimalnego i/lub maksymalnego poziomu powiększenia. Jest to przydatne na przykład w celu kontrolowania wrażeń użytkownika, jeśli aplikacja wyświetla określony obszar w ciekawym miejscu lub gdy używasz niestandardowego kafelka z ograniczonym poziomem powiększenia.

Java


private GoogleMap map;
    map.setMinZoomPreference(6.0f);
    map.setMaxZoomPreference(14.0f);

      

Kotlin


private lateinit var map: GoogleMap

    map.setMinZoomPreference(6.0f)
    map.setMaxZoomPreference(14.0f)

      

Pamiętaj o problemach technicznych, które mogą uniemożliwiać interfejsom API powiększanie lub oddalanie użytkowników. Na przykład satelita lub teren mogą mieć niższe maksymalne powiększenie niż fragmenty mapy podstawowej.

Zmiana pozycji kamery

Istnieją 2 metody związane z wygodnymi zmianami pozycji. CameraUpdateFactory.newLatLng(LatLng) zawiera wartość CameraUpdate, która zmienia szerokość i długość geograficzną aparatu, zachowując jednocześnie wszystkie pozostałe właściwości. CameraUpdateFactory.newLatLngZoom(LatLng, float) udostępnia element CameraUpdate, który zmienia szerokość i długość geograficzną kamery oraz zachowuje wszystkie pozostałe właściwości.

Aby uzyskać pełną elastyczność w zmienianiu pozycji kamery, użyj ikony CameraUpdateFactory.newCameraPosition(CameraPosition), która umożliwia CameraUpdate przesuwa kamerę w określone miejsce. CameraPosition można pobrać bezpośrednio, za pomocą new CameraPosition() lub CameraPosition.Builder, używając new CameraPosition.Builder().

Przesuwanie (przewijanie)

CameraUpdateFactory.scrollBy(float, float) podaje CameraUpdate, który powoduje zmianę szerokości i długości geograficznej kamery tak, aby mapa przesunęła się o określoną liczbę pikseli. Dodatnia wartość x powoduje, że aparat porusza się w prawo, więc mapa wydaje się przesuwać w lewo. Dodatnia wartość y powoduje przesunięcie kamery w dół, tak aby mapa mogła się przesunąć w górę. I na odwrót – wartości x powodują przesunięcie kamery w lewo, dzięki czemu mapa wydaje się przesuwać w prawo, a ujemne wartości Y powodują przesunięcie kamery w górę. Przewijanie odpowiada bieżącej orientacji kamery. Jeśli na przykład kamera jest ustawiona na 90 stopni, to wschód to „góra”.

Wyznaczanie granic

Ustawianie granic mapy

Czasami warto przesunąć kamerę tak, aby cały obszar zainteresowań był widoczny na jak najwyższym poziomie. Jeśli na przykład wszystkie stacje paliw mają się wyświetlać w promieniu 5 km od bieżącego położenia użytkownika, możesz przesunąć kamerę tak, aby były one widoczne na ekranie. Aby to zrobić, najpierw oblicz pole LatLngBounds, które ma być widoczne na ekranie. Następnie możesz użyć CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int padding), by uzyskać CameraUpdate, który zmieni położenie kamery, tak by podany LatLngBounds był całkowicie dopasowany do mapy, z uwzględnieniem dopełnienia (w pikselach). Zwracana wartość CameraUpdate zapewnia, że przerwa (w pikselach) między podanymi granicami a krawędzią mapy będzie co najmniej taka sama jak określone dopełnienie. Pamiętaj, że przechylenie i zniekształcenie mapy wynosi 0.

Java


LatLngBounds australiaBounds = new LatLngBounds(
    new LatLng(-44, 113), // SW bounds
    new LatLng(-10, 154)  // NE bounds
);
map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 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))

      

Wyśrodkowanie mapy na obszarze

W niektórych przypadkach możesz wyśrodkować kamerę w granicach, zamiast uwzględniać skrajne granice. Może to być np. wyśrodkowanie kamery na danym kraju przy zachowaniu stałego powiększenia. W takim przypadku możesz użyć podobnej metody, tworząc LatLngBounds i używając CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom) w LatLngBounds.Metoda getCenter(). Metoda getCenter() zwróci centrum geograficzne elementu LatLngBounds.

Java


LatLngBounds australiaBounds = new LatLngBounds(
    new LatLng(-44, 113), // SW bounds
    new LatLng(-10, 154)  // NE bounds
);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.getCenter(), 10));

      

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))

      

Przeciążenie metody newLatLngBounds(boundary, width, height, padding) umożliwia określenie szerokości i wysokości w pikselach w przypadku prostokątnego prostokątu z zamiarem, by pasowały do wymiarów mapy. Prostokąt jest ustawiony tak, że jego środek jest taki sam jak widok mapy (jeśli podane wymiary są takie same jak w przypadku widoku mapy, prostokąt zbiega się z widokiem mapy). Zwrócona wartość CameraUpdate będzie przesuwać aparat tak, aby określony LatLngBounds został wyśrodkowany na ekranie w ramach prostokąta o największym możliwym poziomie powiększenia, biorąc pod uwagę wymagane dopełnienie.

Uwaga: prostszą metodę newLatLngBounds(boundary, padding) należy generować tylko wtedy, gdy obiekt CameraUpdate ma być używany do przesuwania kamery po wprowadzeniu zmian na mapie. Podczas konfigurowania interfejsu API oblicza wyświetlane granice, które są potrzebne do poprawnego pokazania ramki ograniczającej. W każdej chwili możesz też użyć funkcji CameraUpdate zwróconej przez bardziej skomplikowaną metodę newLatLngBounds(boundary, width, height, padding), nawet jeśli mapa jeszcze nie przeszła układu, ponieważ interfejs API oblicza granice wyświetlania na podstawie podanych argumentów.

Ograniczenie obrotu użytkownika do określonego obszaru

W powyższych scenariuszach możesz ustawić granice mapy, ale użytkownik będzie mógł je przewijać lub przesuwać. Zamiast tego możesz ograniczyć obszar środkowy i środkowy punktu centralnego mapy, tak by użytkownicy mogli przewijać tylko te granice. Na przykład aplikacja sklepu detalicznego lub centrum handlowego może ograniczyć mapę do określonych granic, tak aby użytkownicy mogli ją przewijać i przesuwać.

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);

      

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)

      

Poniższy diagram przedstawia scenariusz, w którym cel kamery jest ograniczony do obszaru, który jest nieco większy niż widoczny obszar. Użytkownik może przewijać i przesuwać, pod warunkiem, że cel kamery znajduje się w zawężonym obszarze. Krzyż reprezentuje cel kamery:

Schemat, który pokazuje wymiary kamery latLngBound, które są większe niż widoczny obszar.

Mapa zawsze wypełnia widoczny obszar, nawet jeśli widoczne obszary znajdują się poza zdefiniowanymi granicami. Jeśli np. ustawisz kamerę w rogu ograniczonego obszaru, obszar poza tym obszarem będzie widoczny, ale użytkownicy nie będą mogli przewijać obszaru w inne miejsce. Ten scenariusz obrazuje poniższy diagram. Krzyż reprezentuje cel kamery:

Schemat przedstawiający cel kamery umieszczony w prawym dolnym rogu kamery.

Na tym diagramie cel kamery ma bardzo ograniczone granice, co daje użytkownikowi bardzo małe możliwości przewijania lub przesuwania mapy. Krzyżyk reprezentuje cel kamery:

Schemat, który pokazuje wymiary kamery latLngBound, które są mniejsze niż widoczny obszar.

Aktualizuję widok z kamery

Aby zastosować na mapie obiekt CameraUpdate, możesz poruszać się od razu lub płynnie poruszać się po nim. Aby od razu zmienić ustawienie kamery z CameraUpdate, możesz wywołać GoogleMap.moveCamera(CameraUpdate).

Możesz uatrakcyjnić aplikację, zwłaszcza w przypadku krótkich ruchów. Aby to zrobić, zamiast dzwonić pod numer GoogleMap.moveCamera, wywołaj GoogleMap.animateCamera. Mapa płynnie przesunie się do nowych atrybutów. Najbardziej szczegółowa metoda tej metody, GoogleMap.animateCamera(cameraUpdate, duration, callback), udostępnia 3 argumenty:

cameraUpdate
CameraUpdate opisujący, gdzie przenieść kamerę.
callback
Obiekt, który implementuje GoogleMap.CancellableCallback. Ten ujednolicony interfejs do obsługi zadań definiuje 2 metody „onCancel()” i „onFinished()”. W przypadku animacji metody są wywoływane w tych sytuacjach:
onFinish()
Wywoływane, jeśli animacja została przerwana bez zakłóceń.
onCancel()

Wywoływana, jeśli animacja została przerwana, wywołując stopAnimation() lub uruchamiając nowy ruch kamery.

Błąd ten może też wystąpić, gdy wywołujesz metodę GoogleMap.stopAnimation().

duration
Oczekiwany czas trwania animacji w milisekundach, jako int.

Poniższe fragmenty kodu pokazują kilka typowych sposobów poruszania kamerą.

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));

      

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))