Kamera i widok

Wybierz platformę: Android iOS JavaScript

Mapy w pakiecie Maps SDK na Androida można przechylać i obracać za pomocą prostych gestów, co pozwala użytkownikom dostosować mapę do odpowiedniej dla nich orientacji. Dzięki mniejszemu obszarowi kafelków mapy wektorowych możesz przesuwać mapę i zmieniać jej perspektywę na każdym poziomie powiększenia. To bardzo niewielkie opóźnienie.

Przykładowe fragmenty kodu

Repozytorium API Demos w GitHubie zawiera przykład, który prezentuje funkcje kamery:

Wstęp

Podobnie jak w przypadku Map Google w internecie, pakiet SDK Map Google na Androida reprezentuje powierzchnię świata (kulę) na ekranie urządzenia (płaską płaszczyznę) za pomocą rzutu miernika. We wschodnim i zachodnim kierunku mapa powtarza się w nieskończoność, ponieważ cały świat płynnie się nakłada. 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 określoną szerokość geograficzną wzdłuż i nieskończoną szerokość geograficzną. „Wycinamy” zdjęcia mapy podstawowej na podstawie odwzorowania Merkatora pod kątem około +/-85 stopni, aby powstały kwadrat ma kwadrat, co ułatwia wybór kafelków.

Pakiet SDK Map Google na Androida umożliwia zmianę widoku mapy przez użytkownika przez modyfikowanie aparatu mapy.

Zmiany w kamerze nie wpłyną na znaczniki, nakładki ani inne elementy graficzne dodane przez Ciebie, możesz jednak zmienić dodatki, aby lepiej pasowały do nowego widoku.

Wykrywasz gesty użytkowników na mapie, możesz więc zmieniać mapę w odpowiedzi na prośby użytkowników. Na przykład metoda wywołania zwrotnego OnMapClickListener.onMapClick() odpowiada na jedno kliknięcie na mapie. Ponieważ metoda odbiera szerokość i długość geograficzną miejsca dotknięcia, możesz reagować, przesuwając lub przybliżając do tego punktu. Dostępne są podobne metody reagowania na kliknięcia bąbelka znacznika lub reagowania na gesty przeciągania znacznika.

Możesz też nasłuchiwać ruchów kamery, dzięki czemu aplikacja otrzyma powiadomienie, gdy kamera zacznie się poruszać, zacznie się właśnie poruszać lub przestanie się poruszać. Szczegółowe informacje znajdziesz w przewodniku po zdarzeniach zmiany kamery.

Pozycja kamery

Widok mapy jest modelowany jako aparat patrzący na płaską płaszczyznę. Położenie kamery (a tym samym wyświetlanie mapy) jest określane przez te właściwości: cel (szerokość/długość geograficzna), nachylenie, przechylenie i powiększenie.

Diagram właściwości aparatu

Kierowanie (lokalizacja)

Cel kamery to położenie pośrodku mapy, określane za pomocą współrzędnych szerokości i długości geograficznej.

Szerokość geograficzna może wynosić od -85 do 85 stopni włącznie. Wartości powyżej lub poniżej tego zakresu będą ograniczane do najbliższej wartości z tego zakresu. Na przykład określenie szerokości geograficznej równą 100 spowoduje ustawienie wartości na 85. Długość geograficzna z zakresu od -180 do 180 stopni włącznie. Wartości powyżej lub poniżej tego zakresu będą zawijane, aby mieściły się w przedziale (-180, 180). Na przykład filmy 480, 840 i 1200 zostaną zawijane do 120 stopni.

Orientacja kierunkowa

Orientacja kamery określa kierunek kompasu mierzony w stopniach od północy rzeczywistej, odpowiadający górnej krawędzi mapy. Jeśli rysujesz pionową linię od środka mapy do górnej krawędzi mapy, kierunek geograficzny będzie odpowiadać kierunekowi (mierzonemu w stopniach) względem prawdziwej północy.

Wartość 0 oznacza, że górna część mapy wskazuje prawdziwą północ. Wartość odchylenia 90 oznacza górną część mapy w kierunku wschodnim (90 stopni na kompasie). Wartość 180 oznacza, że górna część mapy jest skierowana na południe.

Interfejs API Map Google umożliwia zmianę kierunku mapy. Na przykład gdy samochód często obraca mapę drogową, aby dopasować ją do kierunku jazdy, a turyści korzystający z mapy i kompasu zwykle ustalają kierunek mapy tak, aby pionowa linia była skierowana na północ.

Pochylenie (kąt patrzenia)

Nachylenie określa pozycję kamery na łuku bezpośrednio nad położeniem środkowym mapy, mierzonym w stopniach od nadiru (kierunku wskazującego bezpośrednio pod kamerą). Wartość 0 odpowiada ustawieniu kamery skierowanej prosto do dołu. Wartości większe niż 0 odpowiadają aparatowi wysuniętemu w kierunku horyzontu o określoną liczbę stopni. Po zmianie kąta patrzenia mapa jest wyświetlana jako perspektywa, przy czym odległe obiekty są mniejsze, a obiekty znajdujące się w pobliżu są większe. Poniższe ilustracje to ilustrują.

Kąt widzenia na poniższych obrazach wynosi 0 stopni. Pierwsze zdjęcie przedstawia schemat. Pozycja 1 to pozycja kamery, a pozycja 2 – bieżąca pozycja na mapie. Wynikowa mapa jest wyświetlana pod nią.

Zrzut ekranu mapy z kamerą ustawioną pod kątem 0 stopni i powiększeniem 18 stopni.
Mapa wyświetlana z domyślnym kątem patrzenia kamery.
Schemat pokazujący domyślne położenie kamery bezpośrednio nad położeniem na mapie pod kątem 0 stopni.
Domyślny kąt patrzenia kamery.

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

Zrzut ekranu mapy z kamerą ustawioną pod kątem 45 stopni i powiększeniem 18 stopni.
Mapa wyświetlana pod kątem 45 stopni.
Schemat przedstawiający kąt patrzenia kamery ustawiony na 45 stopni przy poziomie powiększenia 18.
Kąt patrzenia kamery: 45 stopni.

Mapa na tym zrzucie ekranu jest nadal wyśrodkowana w tym samym punkcie co oryginalna mapa, ale u góry mapy pojawiły się inne obiekty. Po zwiększeniu kąta o ponad 45 stopni obiekty znajdujące się między kamerą a widokiem na mapie będą proporcjonalnie większe, a obiekty poza zasięgiem mapy będą proporcjonalnie mniejsze, dając efekt trójwymiarowy.

Zoom

Poziom powiększenia kamery określa skalę mapy. Przy większym powiększeniu na ekranie widać więcej szczegółów, a przy mniejszych poziomach powiększenia więcej świata jest widoczne na ekranie. Przy powiększeniu 0 skala mapy jest tak, ż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 świata na ekranie. Dlatego przy powiększeniu N szerokość świata wynosi około 256 × 2N dp. Na przykład przy powiększeniu 2 cały świat ma około 1024 dp szerokości.

Poziom powiększenia nie musi być liczbą całkowitą. Zakres powiększenia dozwolony przez mapę zależy od wielu czynników, m.in. celu, typu mapy i rozmiaru ekranu. Każda liczba spoza zakresu zostanie przekonwertowana na następną prawidłową wartość, którą może być minimalny lub maksymalny poziom powiększenia. Poniższa lista pokazuje przybliżony poziom szczegółowości na każdym poziomie powiększenia:

  • 1: świat
  • 5: ląd/kontynent
  • 10: Miasto
  • 15: Ulice
  • 20. Budynki
Na tych obrazach pokazano wygląd różnych poziomów powiększenia:
Zrzut ekranu mapy ze powiększeniem 5
Mapa w powiększeniu 5.
Zrzut ekranu mapy ze zbliżeniem 15
Mapa w powiększeniu 15.
Zrzut ekranu mapy przy powiększeniu 20
Mapa w powiększeniu 20.

Poruszanie kamerą

Interfejs API Map Google pozwala Ci określić, które części świata mają być widoczne na mapie. Można to osiągnąć przez zmianę położenia kamery (a nie przesuwania mapy).

Przy zmianie kamery możesz animować jej ruch. Animacja interpoluje się między bieżącymi atrybutami kamery i nowymi atrybutami. Możesz też kontrolować czas trwania animacji.

Aby zmienić pozycję kamery, musisz określić, dokąd chcesz ją przesunąć, używając elementu CameraUpdate. Interfejs API Map Google umożliwia tworzenie wielu różnych typów obiektów CameraUpdate za pomocą CameraUpdateFactory. Dostępne są te ustawienia:

Zmiana poziomu powiększenia i ustawienie minimalnego/maksymalnego powiększenia

CameraUpdateFactory.zoomIn() i CameraUpdateFactory.zoomOut() dają CameraUpdate, który zmienia poziom powiększenia o 1,0 przy zachowaniu wszystkich innych właściwości.

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

CameraUpdateFactory.zoomBy(float) i CameraUpdateFactory.zoomBy(float, Point) dają wartość CameraUpdate, która zwiększa (lub zmniejsza, jeśli wartość jest ujemna) poziom powiększenia o daną wartość. To rozwiązanie koryguje wybrany punkt na ekranie w taki sposób, że pozostaje w tym samym miejscu (szerokość i długość geograficzną), więc może zmieniać lokalizację kamery, aby to osiągnąć.

Warto ustawić preferowany minimalny lub maksymalny poziom powiększenia. Jest to przydatne na przykład wtedy, gdy aplikacja wyświetla zdefiniowany obszar wokół wybranego miejsca lub używasz niestandardowej nakładki z kafelkami 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);

      

Istnieją jednak kwestie techniczne, które mogą uniemożliwić interfejsowi API zbyt małe lub zbyt duże powiększenie. Na przykład widok satelitarny lub terenu może mieć mniejsze maksymalne powiększenie niż fragmenty mapy podstawowej.

Zmiana pozycji aparatu

Istnieją dwie wygodne metody zmiany pozycji. CameraUpdateFactory.newLatLng(LatLng) zwraca parametr CameraUpdate, który zmienia szerokość i długość geograficzną kamery, zachowując jednocześnie wszystkie pozostałe właściwości. CameraUpdateFactory.newLatLngZoom(LatLng, float) wyświetla CameraUpdate, który zmienia szerokość i długość geograficzną kamery oraz powiększenie, zachowując jednocześnie wszystkie pozostałe właściwości.

Aby w pełni zmienić położenie kamery, użyj narzędzia CameraUpdateFactory.newCameraPosition(CameraPosition), które daje Ci element CameraUpdate, który porusza kamerę w określonym położeniu. CameraPosition można uzyskać bezpośrednio za pomocą new CameraPosition() lub CameraPosition.Builder za pomocą new CameraPosition.Builder().

Przesuwanie (przewijanie)

CameraUpdateFactory.scrollBy(float, float) udostępnia funkcję CameraUpdate, która zmienia szerokość i długość geograficzną kamery tak, aby mapa przesuwała się o określoną liczbę pikseli. Dodatnia wartość x powoduje, że kamera przesuwa się w prawo, przez co mapa wydaje się przesunąć w lewo. Dodatnia wartość y powoduje przesuwanie kamery w dół, dzięki czemu mapa wydaje się przesunąć w górę. I na odwrót: ujemne wartości x powodują przesuwanie kamery w lewo, tak by mapa przesunęła się w prawo, a ujemne wartości y – do góry. Przewijanie odbywa się względem bieżącej orientacji kamery. Na przykład, jeśli kąt nachylenia kamery wynosi 90 stopni, kierunek wschodni to „u góry”.

Wyznaczanie granic

Wyznaczanie granic mapy

Czasami warto przesunąć kamerę tak, aby cały interesujący obszar był widoczny przy największym możliwym poziomie powiększenia. Jeśli na przykład wyświetlasz wszystkie stacje benzynowe znajdujące się w promieniu pięciu kilometrów od aktualnej pozycji użytkownika, możesz przesunąć kamerę tak, aby wszystkie były widoczne na ekranie. Aby to zrobić, oblicz najpierw wartość LatLngBounds, która ma być widoczna na ekranie. Następnie możesz użyć CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int padding), aby uzyskać CameraUpdate, który zmienia położenie kamery, tak aby LatLngBounds mieścił się w całości na mapie, biorąc pod uwagę podane dopełnienie (w pikselach). Zwracany parametr CameraUpdate zapewnia, że przerwa (w pikselach) między podanymi granicami a krawędzią mapy będzie co najmniej równa określonemu dopełnieniu. Pamiętaj, że przechylenie i odchylenie mapy są równa 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środkowanie mapy na obszarze

W niektórych przypadkach warto wyśrodkować obraz w granicach, a nie na skrajnych granicach. Może to być na przykład wyśrodkowanie kamery na kraju z utrzymaniem stałego powiększenia. W tym przypadku możesz użyć podobnej metody, tworząc LatLngBounds i używając właściwości CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom) z LatLngBounds.getCenter(). Metoda getCenter() zwraca środek geograficzny obiektu 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 w pikselach prostokąta z myślą, że odpowiadają one wymiarom mapy. Prostokąt jest ustawiony tak, aby jego środek był taki sam jak w widoku mapy (jeśli określone wymiary są takie same jak w widoku mapy, prostokąt zbiega się z widokiem mapy). Zwrócony element CameraUpdate przesuwa kamerę tak, aby określony element LatLngBounds był wyśrodkowany na ekranie w danym prostokącie przy największym możliwym poziomie powiększenia, z uwzględnieniem wymaganego dopełnienia.

Uwaga: użyj prostszej metody newLatLngBounds(boundary, padding) do wygenerowania CameraUpdate tylko wtedy, gdy ma ona zostać użyta do przesuwania kamery po zmianie układu mapy. Podczas układu interfejs API oblicza granice wyświetlania mapy, które są potrzebne do poprawnego rzutu ramki ograniczającej. Dla porównania możesz użyć właściwości CameraUpdate zwróconej przez bardziej złożoną metodę newLatLngBounds(boundary, width, height, padding) w dowolnym momencie, nawet przed zmianą układu mapy, ponieważ interfejs API oblicza granice wyświetlania na podstawie podanych przez Ciebie argumentów.

Ograniczanie przesuwania użytkownika do danego obszaru

W powyższych scenariuszach wyznaczasz granice mapy, ale użytkownik może ją przewinąć lub przesunąć poza te granice. Możesz np. ograniczyć środkowe granice punktu centralnego mapy (celu kamery), aby użytkownicy mogli tylko przewijać i przesuwać widok w tych granicach. Na przykład aplikacja sprzedażowa centrum handlowego lub lotniska może ograniczać mapę do określonych granic, umożliwiając użytkownikom przewijanie i przesuwanie mapy w tych granicach.

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

      

Poniższy diagram przedstawia scenariusz, w którym cel kamery jest ograniczony do obszaru, który jest nieco większy od widocznego obszaru. Użytkownik może przewijać i przesuwać obraz, o ile cel kamery znajduje się w wyznaczonym obszarze. Krzyż symbolizuje cel kamery:

Diagram przedstawiający pasy geograficzne kamery, które są większe niż widoczny obszar.

Mapa zawsze wypełnia widoczny obszar, nawet jeśli powoduje to wyświetlenie obszarów poza zdefiniowanymi granicami. Jeśli na przykład umieścisz cel kamery w rogu ograniczonego obszaru, obszar znajdujący się poza rogiem będzie widoczny w widocznym obszarze, ale użytkownicy nie będą mogli przewijać go w górę. Scenariusz ten ilustruje ten schemat. Krzyż symbolizuje cel kamery:

Diagram przedstawiający cel kamery umieszczony w prawym dolnym rogu obiektywu LatLngBounds.

Na poniższym schemacie cel kamery ma bardzo ograniczone granice, więc użytkownik ma bardzo mało możliwości przewijania lub przesuwania mapy. Krzyż oznacza cel kamery:

Diagram przedstawiający współrzędne geograficzne kamery mniejszego niż widoczny obszar.

Aktualizuję pole widzenia kamery

Aby zastosować na mapie obiekt CameraUpdate, możesz od razu przesunąć kamerę lub płynnie ją animować. Aby natychmiast przesunąć kamerę za pomocą podanego elementu CameraUpdate, wywołaj połączenie GoogleMap.moveCamera(CameraUpdate).

Aby wrażenia użytkowników były przyjemniejsze, zwłaszcza w przypadku krótkich ruchów, możesz animować zmianę. Aby to zrobić, zamiast wywoływać metodę GoogleMap.moveCamera GoogleMap.animateCamera. Mapa przejdzie płynnie do nowych atrybutów. Najbardziej szczegółowa forma tej metody, GoogleMap.animateCamera(cameraUpdate, duration, callback), oferuje 3 argumenty:

cameraUpdate
CameraUpdate opisujący, gdzie należy przesunąć kamerę.
callback
Obiekt GoogleMap.CancellableCallback. Ten ogólny interfejs do obsługi zadań definiuje 2 metody: „onCancel()” i „onFinished()”. W przypadku animacji są one wywoływane w tych okolicznościach:
onFinish()
Wywoływana, jeśli animacja zostanie zakończona bez przerw.
onCancel()

Wywoływana, jeśli animacja została przerwana przez wywołanie funkcji stopAnimation() lub rozpoczęcie nowego ruchu kamery.

Może się to też zdarzyć, jeśli wywołasz metodę GoogleMap.stopAnimation().

duration
Oczekiwany czas trwania animacji w milisekundach, podany jako int.

Poniższe fragmenty kodu ilustrują typowe sposoby przesuwania kamery.

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