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, dzięki czemu użytkownicy mogą dostosować mapę do orientacji, która im odpowiada. Na każdym poziomie powiększenia możesz przesuwać mapę lub zmieniać jej perspektywę z bardzo małym opóźnieniem dzięki mniejszemu rozmiarowi kafelków mapy wektorowej.

Przykładowe fragmenty kodu

Repozytorium ApiDemos w GitHubie zawiera przykład, który pokazuje funkcje aparatu:

Wprowadzenie

Podobnie jak Mapy Google w internecie, pakiet Maps SDK na Androida przedstawia powierzchnię Ziemi (sferę) na ekranie urządzenia (płaszczyźnie) za pomocą odwzorowania Merkatora. W kierunku wschód-zachód mapa powtarza się w nieskończoność, ponieważ świat płynnie się zawija. W kierunku północ-południe mapa jest ograniczona do około 85 stopni na północ i 85 stopni na południe.

Uwaga: odwzorowanie Merkatora ma skończoną szerokość w kierunku południkowym, ale nieskończoną wysokość w kierunku równoleżnikowym. Obrazy mapy podstawowej „odcinamy” za pomocą odwzorowania Merkatora w przybliżeniu na poziomie +/- 85 stopni, aby uzyskać kwadratowy kształt mapy, co ułatwia logikę wyboru fragmentów mapy.

Pakiet Maps SDK na Androida umożliwia zmianę punktu widzenia użytkownika na mapę przez modyfikację aparatu mapy.

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

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

Możesz też nasłuchiwać ruchów aparatu, aby aplikacja otrzymywała powiadomienia, gdy aparat zaczyna się poruszać, porusza się lub przestaje się poruszać. Więcej informacji znajdziesz w przewodniku po zdarzeniach zmiany aparatu.

Pozycja aparatu

Widok mapy jest modelowany jako aparat skierowany w dół na płaską powierzchnię. Położenie aparatu (a tym samym renderowanie mapy) jest określone przez te właściwości: cel (szerokość i długość geograficzna), kierunek, nachylenie, i powiększenie.

Schemat właściwości aparatu

Cel (lokalizacja)

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

Szerokość geograficzna może się zawierać w przedziale 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 podanie szerokości geograficznej 100 spowoduje ustawienie wartości 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ą zawinięte tak, aby mieściły się w zakresie (-180, 180). Na przykład wartości 480, 840 i 1200 zostaną zawinięte do 120 stopni.

Kierunek (orientacja)

Kierunek aparatu określa kierunek kompasu, mierzony w stopniach od północy geograficznej, odpowiadający górnej krawędzi mapy. Jeśli narysujesz pionową linię od środka mapy do jej górnej krawędzi, kierunek będzie odpowiadać kierunkowi aparatu (mierzony w stopniach) względem północy geograficznej.

Kierunek 0 oznacza, że górna część mapy jest skierowana na północ geograficzną. Wartość kierunku 90 oznacza, że górna część mapy jest skierowana na wschód (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 kierowca często obraca mapę drogową, aby dopasować ją do kierunku jazdy, a turyści korzystający z mapy i kompasu zwykle orientują mapę tak, aby pionowa linia była skierowana na północ.

Nachylenie (kąt patrzenia)

Nachylenie określa położenie aparatu na łuku bezpośrednio nad środkiem mapy, mierzone w stopniach od zenitu (kierunku skierowanego bezpośrednio pod aparat). Wartość 0 odpowiada aparatowi skierowanemu prosto w dół. Wartości większe niż 0 odpowiadają aparatowi, który jest nachylony w kierunku horyzontu o określoną liczbę stopni. Gdy zmienisz kąt patrzenia, mapa będzie wyświetlana w perspektywie, a odległe elementy będą mniejsze, a pobliskie – większe. Ilustrują to poniższe rysunki.

Na obrazach poniżej kąt patrzenia wynosi 0 stopni. Pierwszy obraz przedstawia schemat: pozycja 1 to położenie aparatu, a pozycja 2 to bieżące położenie mapy. Poniżej znajduje się wynikowa mapa.

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

Na obrazach poniżej kąt patrzenia wynosi 45 stopni. Zwróć uwagę, że aparat przesuwa się w połowie łuku między położeniem bezpośrednio nad głową (0 stopni) a ziemią (90 stopni) do pozycji 3. Aparat nadal jest skierowany na środek mapy, ale widoczny jest teraz obszar reprezentowany przez linię w pozycji 4.

Zrzut ekranu mapy z kamerą ustawioną pod kątem 45 stopni i poziomem powiększenia 18.
Mapa wyświetlana z kątem patrzenia 45 stopni.
Diagram przedstawiający kąt widzenia kamery ustawiony na 45 stopni i poziom powiększenia ustawiony na 18.
Kąt patrzenia aparatu 45 stopni.

Mapa na tym zrzucie ekranu jest nadal wyśrodkowana w tym samym punkcie co na oryginalnej mapie, ale u góry mapy pojawiło się więcej elementów. Gdy zwiększysz kąt powyżej 45 stopni, elementy między aparatem a położeniem mapy będą proporcjonalnie większe, a elementy poza położeniem mapy będą proporcjonalnie mniejsze, co da efekt trójwymiarowy.

Zoom

Poziom powiększenia aparatu określa skalę mapy. Przy większych poziomach powiększenia na ekranie widać więcej szczegółów, a przy mniejszych – większą część świata. Przy poziomie powiększenia 0 skala mapy jest taka, że cały świat ma szerokość 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. Dlatego przy poziomie powiększenia N szerokość świata wynosi około 256 * 2N dp. Na przykład przy poziomie powiększenia 2 cały świat ma szerokość około 1024 dp.

Poziom powiększenia nie musi być liczbą całkowitą. Zakres poziomów powiększenia dozwolonych na mapie zależy od wielu czynników, w tym od celu, typu mapy i rozmiaru ekranu. Każda liczba spoza tego zakresu zostanie przekonwertowana na najbliższą prawidłową wartość, która może być minimalnym lub maksymalnym poziomem powiększenia. Poniższa lista przedstawia przybliżony poziom szczegółowości, który można zobaczyć na każdym poziomie powiększenia:

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

Przesuwanie aparatu

Interfejs API Map Google umożliwia zmianę części świata widocznej na mapie. Osiąga się to przez zmianę położenia aparatu (a nie przez przesuwanie mapy).

Gdy zmienisz aparat, możesz animować wynikowy ruch aparatu. Animacja interpoluje między bieżącymi a nowymi atrybutami aparatu. Możesz też kontrolować czas trwania animacji.

Aby zmienić położenie aparatu, musisz określić, gdzie chcesz go przesunąć, używając CameraUpdate. Interfejs API Map Google 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 wszystkie inne właściwości bez zmian.

CameraUpdateFactory.zoomTo(float) daje CameraUpdate, który zmienia poziom powiększenia na podaną wartość, zachowując wszystkie inne właściwości bez zmian.

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ść. Ten ostatni ustala dany punkt na ekranie tak, aby pozostał w tej samej lokalizacji (szerokość i długość geograficzna), dlatego może zmienić położenie aparatu, aby to osiągnąć.

Może się okazać, że warto ustawić preferowany minimalny lub maksymalny poziom powiększenia. Jest to przydatne np. do kontrolowania wrażeń użytkownika, jeśli aplikacja pokazuje określony obszar wokół interesującego miejsca lub jeśli używasz niestandardowej nakładki kafelków z ograniczonym zestawem poziomów powiększenia.

Kotlin

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

      

Java

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

      

Pamiętaj, że istnieją względy techniczne, które mogą uniemożliwić interfejsowi API zbyt duże lub zbyt małe powiększenie. Na przykład mapa satelitarna lub terenowa może mieć mniejszy maksymalny poziom powiększenia niż kafelki mapy podstawowej.

Zmiana pozycji aparatu

Istnieją 2 wygodne metody do typowych zmian pozycji. CameraUpdateFactory.newLatLng(LatLng) daje CameraUpdate, który zmienia szerokość i długość geograficzną aparatu, zachowując wszystkie inne właściwości. CameraUpdateFactory.newLatLngZoom(LatLng, float) daje CameraUpdate, który zmienia szerokość, długość geograficzną i powiększenie aparatu, zachowując wszystkie inne właściwości.

Aby w pełni elastycznie zmieniać położenie aparatu, użyj CameraUpdateFactory.newCameraPosition(CameraPosition) który daje CameraUpdate który przesuwa aparat do podanej pozycji. A CameraPosition można uzyskać bezpośrednio za pomocą new CameraPosition() lub za pomocą CameraPosition.Builder za pomocą new CameraPosition.Builder().

Przesuwanie (przewijanie)

CameraUpdateFactory.scrollBy(float, float) daje CameraUpdate który zmienia szerokość i długość geograficzną aparatu tak, aby mapa przesuwała się o określoną liczbę pikseli. Dodatnia wartość x powoduje przesunięcie aparatu w prawo, tak aby mapa wydawała się przesunięta w lewo. Dodatnia wartość y powoduje przesunięcie aparatu w dół, tak aby mapa wydawała się przesunięta w górę. Odwrotnie, ujemne wartości x powodują przesunięcie aparatu w lewo, tak aby mapa wydawała się przesunięta w prawo, a ujemne wartości y powodują przesunięcie aparatu w górę. Przewijanie jest względne w stosunku do bieżącej orientacji aparatu. Jeśli np. kierunek aparatu wynosi 90 stopni, wschód jest „w górę”.

Ustawianie granic

Ustawianie granic mapy

Czasami warto przesunąć aparat tak, aby cały interesujący obszar był widoczny przy największym możliwym poziomie powiększenia. Jeśli np. wyświetlasz wszystkie stacje benzynowe w promieniu 8 km od bieżącego położenia użytkownika, możesz przesunąć aparat tak, aby wszystkie 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 położenie aparatu tak, aby dany LatLngBounds mieścił się w całości na mapie, z uwzględnieniem określonego dopełnienia (w pikselach). Zwrócony CameraUpdate zapewnia, że odstęp (w pikselach) między danymi granicami a krawędzią mapy będzie co najmniej równy określonemu dopełnieniu. Pamiętaj, że nachylenie i kierunek mapy będą 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 możesz chcieć wyśrodkować aparat w granicach zamiast uwzględniać skrajne granice. Na przykład aby wyśrodkować aparat na 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) z LatLngBounds.Metoda getCenter(). Metoda getCenter() zwróci środek geograficzny 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, z założeniem, że odpowiadają one wymiarom mapy. Prostokąt jest umieszczony tak, aby jego środek był taki sam jak środek widoku mapy (czyli jeśli określone wymiary są takie same jak wymiary widoku mapy, prostokąt pokrywa się z widokiem mapy). Zwrócony CameraUpdate przesunie aparat tak, aby określony 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: prostszą metodę newLatLngBounds(boundary, padding) używaj tylko do generowania CameraUpdate, jeśli ma ona służyć do przesuwania aparatu po ułożeniu mapy. Podczas układu interfejs API oblicza granice wyświetlania mapy, które są potrzebne do prawidłowego rzutowania ramki ograniczającej. W porównaniu z tym możesz używać CameraUpdate zwróconego przez bardziej złożoną metodę newLatLngBounds(boundary, width, height, padding) w dowolnym momencie, nawet przed ułożeniem mapy, ponieważ interfejs API oblicza granice wyświetlania na podstawie przekazanych argumentów.

Ograniczanie przesuwania użytkownika do danego obszaru

W opisanych powyżej scenariuszach ustawiasz granice mapy, ale użytkownik może przewijać lub przesuwać widok poza te granice. Zamiast tego możesz ograniczyć granice środka szerokości i długości geograficznej punktu centralnego mapy (celu aparatu) tak, aby użytkownicy mogli przewijać i przesuwać widok tylko w tych granicach. Na przykład aplikacja handlowa dla centrum handlowego lub lotniska może chcieć ograniczyć mapę do określonych granic, umożliwiając użytkownikom przewijanie i przesuwanie widoku 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 ilustruje scenariusz, w którym cel aparatu jest ograniczony do obszaru nieco większego niż widoczny obszar. Użytkownik może przewijać i przesuwać widok, o ile cel aparatu pozostaje w ograniczonym obszarze. Krzyżyk reprezentuje cel aparatu:

Diagram przedstawiający obiekt LatLngBounds kamery, który jest większy niż widoczny obszar.

Mapa zawsze wypełnia widoczny obszar, nawet jeśli powoduje to wyświetlanie obszarów znajdujących się poza zdefiniowanymi granicami. Jeśli np. umieścisz cel aparatu w rogu ograniczonego obszaru, obszar poza rogiem będzie widoczny w widocznym obszarze, ale użytkownicy nie będą mogli przewijać dalej w tym obszarze. Poniższy diagram ilustruje ten scenariusz. Krzyżyk reprezentuje cel aparatu:

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

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

Diagram przedstawiający obiekt LatLngBounds kamery, który jest mniejszy niż widoczny obszar.

Aktualizowanie widoku z aparatu

Aby zastosować CameraUpdate do mapy, możesz natychmiast przesunąć aparat lub animować go płynnie. Aby natychmiast przesunąć aparat za pomocą danego CameraUpdate, możesz wywołać GoogleMap.moveCamera(CameraUpdate).

Możesz poprawić wrażenia użytkownika, zwłaszcza w przypadku krótkich ruchów, animując zmianę. Aby to zrobić, zamiast wywoływać GoogleMap.moveCamera , wywołaj GoogleMap.animateCamera. Mapa będzie się płynnie przesuwać do nowych atrybutów. Najbardziej szczegółowa forma tej metody, GoogleMap.animateCamera(cameraUpdate, duration, callback), ma 3 argumenty:

cameraUpdate
The CameraUpdate opisujący, gdzie przesunąć aparat.
callback
Obiekt, który implementuje GoogleMap.CancellableCallback. Ten uogólniony interfejs do obsługi zadań definiuje 2 metody: `onCancel()` i `onFinished()`. W przypadku animacji metody są wywoływane w tych okolicznościach:
onFinish()
Wywoływana, jeśli animacja zostanie ukończona bez przerwy.
onCancel()

Wywoływana, jeśli animacja zostanie przerwana przez wywołanie stopAnimation() lub rozpoczęcie nowego ruchu aparatu.

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

duration
Pożądany czas trwania animacji w milisekundach jako int.

Poniższe fragmenty kodu ilustrują niektóre typowe sposoby przesuwania aparatu.

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