Elementy mapy wektorowej

Wybierz platformę: Android iOS JavaScript

Wyświetl próbkę

Interfejs Maps JavaScript API oferuje 2 różne implementacje mapy: rastrową i wektorową. Mapa rastrowa wczytuje mapę jako siatkę kafelków obrazu rastrowego opartych na pikselach, które są generowane po stronie serwera Google Maps Platform, a następnie udostępniane aplikacji internetowej. Mapa wektorowa składa się z kafelków wektorowych, które są rysowane w czasie wczytywania po stronie klienta za pomocą WebGL, technologii internetowej, która umożliwia przeglądarce dostęp do GPU na urządzeniu użytkownika w celu renderowania grafiki 2D i 3D.

Mapa wektorowa to ta sama mapa Google, którą znają Twoi użytkownicy. Ma ona wiele zalet w porównaniu z domyślną mapą kafelkową, m.in. ostrość obrazów wektorowych i dodanie budynków 3D przy bliskich poziomach powiększenia. Mapa wektorowa obsługuje te funkcje:

Pierwsze kroki z mapami wektorowymi

Przechył i obrót

Możesz ustawić nachylenie i obrót (kierunek) na mapie wektorowej, uwzględniając właściwości heading i tilt podczas inicjowania mapy oraz wywołując metody setTilt i setHeading na mapie. W poniższym przykładzie dodano do mapy kilka przycisków, które pokazują automatyczne dostosowywanie nachylenia i kierunku w odstępach co 20 stopni.

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: {
        lat: 37.7893719,
        lng: -122.3942,
      },
      zoom: 16,
      heading: 320,
      tilt: 47.5,
      mapId: "90f87356969d889c",
    }
  );

  const buttons: [string, string, number, google.maps.ControlPosition][] = [
    ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER],
    ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER],
    ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER],
    ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER],
  ];

  buttons.forEach(([text, mode, amount, position]) => {
    const controlDiv = document.createElement("div");
    const controlUI = document.createElement("button");

    controlUI.classList.add("ui-button");
    controlUI.innerText = `${text}`;
    controlUI.addEventListener("click", () => {
      adjustMap(mode, amount);
    });
    controlDiv.appendChild(controlUI);
    map.controls[position].push(controlDiv);
  });

  const adjustMap = function (mode: string, amount: number) {
    switch (mode) {
      case "tilt":
        map.setTilt(map.getTilt()! + amount);
        break;
      case "rotate":
        map.setHeading(map.getHeading()! + amount);
        break;
      default:
        break;
    }
  };
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: {
      lat: 37.7893719,
      lng: -122.3942,
    },
    zoom: 16,
    heading: 320,
    tilt: 47.5,
    mapId: "90f87356969d889c",
  });
  const buttons = [
    ["Rotate Left", "rotate", 20, google.maps.ControlPosition.LEFT_CENTER],
    ["Rotate Right", "rotate", -20, google.maps.ControlPosition.RIGHT_CENTER],
    ["Tilt Down", "tilt", 20, google.maps.ControlPosition.TOP_CENTER],
    ["Tilt Up", "tilt", -20, google.maps.ControlPosition.BOTTOM_CENTER],
  ];

  buttons.forEach(([text, mode, amount, position]) => {
    const controlDiv = document.createElement("div");
    const controlUI = document.createElement("button");

    controlUI.classList.add("ui-button");
    controlUI.innerText = `${text}`;
    controlUI.addEventListener("click", () => {
      adjustMap(mode, amount);
    });
    controlDiv.appendChild(controlUI);
    map.controls[position].push(controlDiv);
  });

  const adjustMap = function (mode, amount) {
    switch (mode) {
      case "tilt":
        map.setTilt(map.getTilt() + amount);
        break;
      case "rotate":
        map.setHeading(map.getHeading() + amount);
        break;
      default:
        break;
    }
  };
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.ui-button {
  background-color: #fff;
  border: 0;
  border-radius: 2px;
  box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
  margin: 10px;
  padding: 0 0.5em;
  font: 400 18px Roboto, Arial, sans-serif;
  overflow: hidden;
  height: 40px;
  cursor: pointer;
}
.ui-button:hover {
  background: rgb(235, 235, 235);
}

HTML

<html>
  <head>
    <title>Tilt and Rotation</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>

Używanie gestów myszy i klawiatury

Jeśli interakcje użytkownika związane z nachyleniem i obrotem (kierunkiem) zostały włączone (programowo lub w konsoli Google Cloud), użytkownicy mogą dostosowywać nachylenie i obrót za pomocą myszy i klawiatury:

  • Za pomocą myszy: przytrzymaj klawisz Shift, a następnie przeciągnij myszą w górę i w dół, aby dostosować nachylenie, lub w prawo i w lewo, aby dostosować kierunek.
  • Na klawiaturze przytrzymaj klawisz Shift, a następnie użyj klawiszy strzałek w górę i w dół, aby dostosować nachylenie, oraz klawiszy strzałek w prawo i w lewo, aby dostosować kierunek.

Programowe dostosowywanie pochylenia i kierunku

Aby automatycznie dostosować nachylenie i kierunek na mapie wektorowej, użyj metod setTilt() i setHeading(). Kierunek to kierunek, w którym skierowana jest kamera, wyrażony w stopniach zgodnie z ruchem wskazówek zegara, zaczynając od północy, więc map.setHeading(90) obróci mapę tak, aby wschód był skierowany w górę. Kąt nachylenia jest mierzony od zenitu, więc map.setTilt(0) oznacza widok prosto w dół, a map.setTilt(45) – widok ukośny.

  • Przechylenie: wywołaj funkcję setTilt(), aby ustawić kąt nachylenia mapy. Użyj getTilt(), aby uzyskać bieżącą wartość nachylenia.
  • Kierunek: wywołaj funkcję setHeading(), aby ustawić kierunek mapy. Użyj getHeading(), aby uzyskać bieżącą wartość nagłówka.

Aby zmienić środek mapy, zachowując nachylenie i kierunek, użyj metody map.setCenter() lub map.panBy().

Dozwolony zakres kątów nachylenia zależy od bieżącego poziomu powiększenia mapy. Minimalny kąt nachylenia wynosi zawsze 0 stopni (patrzenie prosto w dół), a maksymalny kąt nachylenia zwiększa się wraz z poziomem powiększenia (interpolacja liniowa o 3,75 stopnia na poziom powiększenia od 10 do 14 i o 15 stopni na poziom powiększenia od 14 do 15,5). Wartości spoza dozwolonego zakresu dla bieżącego poziomu powiększenia są zmieniane na najbliższą dozwoloną wartość graniczną:

Poziom powiększenia Dozwolony zakres pochylenia Maksymalny kąt nachylenia
10 lub mniej Od 0° do 30° 30°
11 Od 0° do 33,75° 33,75°
12 Od 0 do 37,5° 37,5°
13 Od 0° do 41,25° 41,25°
14 0° do 45° 7 °C
14.5 Od 0° do 52,5° 52,5°
15 Od 0 do 60°C 15°
15.5 lub nowsza 0° do 67,5° 67,5°

Możesz też użyć metody moveCamera(), aby automatycznie zmieniać kierunek, nachylenie, środek i powiększenie. Więcej informacji

Wpływ na inne metody

Gdy mapa jest pochylona lub obrócona, wpływa to na działanie innych metod interfejsu Maps JavaScript API:

  • map.getBounds() zawsze zwraca najmniejszą ramkę ograniczającą, która obejmuje widoczny region. Gdy zastosowane jest nachylenie, zwrócone granice mogą reprezentować większy region niż widoczny region widocznego obszaru mapy.
  • map.fitBounds() zresetuje nachylenie i kierunek do zera przed dopasowaniem granic.
  • map.panToBounds() zresetuje nachylenie i kierunek do zera przed przesunięciem granic.
  • map.setTilt() akceptuje dowolną wartość, ale ogranicza maksymalne nachylenie na podstawie bieżącego poziomu powiększenia mapy.
  • map.setHeading() akceptuje dowolną wartość i modyfikuje ją, aby mieściła się w zakresie od 0 do 360 stopni.

Sterowanie kamerą

Użyj funkcji map.moveCamera(), aby zaktualizować dowolną kombinację właściwości kamery jednocześnie. Funkcja map.moveCamera() przyjmuje jeden parametr zawierający wszystkie właściwości kamery, które mają zostać zaktualizowane. Przykład poniżej pokazuje wywołanie map.moveCamera(), które ustawia jednocześnie center, zoom, heading i tilt:

map.moveCamera({
  center: new google.maps.LatLng(37.7893719, -122.3942),
  zoom: 16,
  heading: 320,
  tilt: 47.5
});

Możesz animować właściwości kamery, wywołując funkcję map.moveCamera() z pętlą animacji, jak pokazano tutaj:

const degreesPerSecond = 3;

function animateCamera(time) {
  // Update the heading, leave everything else as-is.
  map.moveCamera({
    heading: (time / 1000) * degreesPerSecond
  });

  requestAnimationFrame(animateCamera);
}

// Start the animation.
requestAnimationFrame(animateCamera);

Pozycja kamery

Widok mapy jest modelowany jako kamera skierowana w dół na płaską powierzchnię. Położenie kamery (a tym samym renderowanie mapy) określają te właściwości: cel (szerokość i długość geograficzna), orientacja, nachylenie i powiększenie.

Schemat właściwości kamery

Cel (lokalizacja)

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

Szerokość geograficzna może wynosić od –85 do 85 stopni. Wartości spoza tego zakresu są zmieniane na najbliższe wartości graniczne. 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 spoza 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ą przekształcone na 120 stopni.

Kierunek (orientacja)

Azymut kamery 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 kamery (mierzonemu w stopniach) względem północy geograficznej.

Wartość 0 oznacza, że góra mapy wskazuje północ geograficzną. Wartość 90 oznacza, że góra mapy wskazuje wschód (90 stopni na kompasie). Wartość 180 oznacza, że góra mapy jest skierowana na południe.

Interfejs API Map Google umożliwia zmianę orientacji mapy. Na przykład kierowca często obraca mapę drogową, aby dopasować ją do kierunku jazdy, podczas gdy turyści korzystający z mapy i kompasu zwykle ustawiają mapę tak, aby pionowa linia wskazywała północ.

Przechylenie (kąt widzenia)

Nachylenie określa pozycję kamery na łuku bezpośrednio nad środkiem mapy, mierzoną w stopniach od nadiru (kierunku bezpośrednio pod kamerą). Wartość 0 odpowiada kamerze skierowanej prosto w dół. Wartości większe niż 0 odpowiadają kamerze pochylonej w kierunku horyzontu o określoną liczbę stopni. Gdy zmienisz kąt widzenia, mapa będzie wyświetlana w perspektywie, z mniejszymi obiektami w oddali i większymi obiektami w pobliżu. Ilustracje poniżej pokazują, jak to działa.

Na obrazach poniżej kąt widzenia wynosi 0 stopni. Pierwszy obraz przedstawia schemat tego rozwiązania: pozycja 1 to pozycja kamery, a pozycja 2 to bieżąca pozycja na mapie. Poniżej znajduje się mapa, która powstała w wyniku tego zapytania.

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 widzenia kamery.
Schemat przedstawiający domyślną pozycję kamery bezpośrednio nad pozycją na mapie pod kątem 0 stopni.
Domyślny kąt widzenia kamery.

Na obrazach poniżej kąt widzenia wynosi 45 stopni. Zauważ, że kamera przesuwa się do pozycji 3, czyli do połowy łuku między pozycją bezpośrednio nad głową (0 stopni) a ziemią (90 stopni). Kamera nadal jest skierowana na punkt środkowy mapy, ale obszar reprezentowany przez linię w pozycji 4 jest teraz widoczny.

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

Mapa na tym zrzucie ekranu jest nadal wyśrodkowana na tym samym punkcie co oryginalna mapa, ale u góry mapy pojawiło się więcej funkcji. Gdy zwiększysz kąt powyżej 45 stopni, obiekty między kamerą a pozycją na mapie będą wydawać się proporcjonalnie większe, a obiekty poza pozycją na mapie – proporcjonalnie mniejsze, co daje efekt trójwymiarowości.

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ększy obszar świata.

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

  • 1: Świat
  • 5. Ląd/kontynent
  • 10: Miasto
  • 15: Ulice
  • 20: Budynki
Poniższe obrazy pokazują, jak wyglądają różne poziomy 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 przy poziomie powiększenia 20
Mapa na poziomie powiększenia 20.

Powiększenie ułamkowe

Mapy wektorowe obsługują powiększenie ułamkowe, które umożliwia powiększanie za pomocą wartości ułamkowych zamiast liczb całkowitych. Zarówno mapy rastrowe, jak i wektorowe obsługują ułamkowe powiększenie, ale jest ono domyślnie włączone w przypadku map wektorowych i wyłączone w przypadku map rastrowych. Aby włączyć lub wyłączyć powiększenie ułamkowe, użyj opcji mapy isFractionalZoomEnabled.

Ten przykład pokazuje, jak włączyć powiększenie ułamkowe podczas inicjowania mapy:

map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: -34.397, lng: 150.644},
  zoom: 8,
  isFractionalZoomEnabled: true
});

Możesz też włączać i wyłączać powiększenie ułamkowe, ustawiając opcję mapy isFractionalZoomEnabled, jak pokazano tutaj:

// Using map.set
map.set('isFractionalZoomEnabled', true);

// Using map.setOptions
map.setOptions({isFractionalZoomEnabled: true});

Możesz ustawić detektor, który będzie wykrywać, czy powiększenie ułamkowe jest włączone. Jest to najbardziej przydatne, jeśli nie ustawisz jawnie właściwości isFractionalZoomEnabled na true ani false. Poniższy przykładowy kod sprawdza, czy powiększenie ułamkowe jest włączone:

map.addListener('isfractionalzoomenabled_changed', () => {
  const isFractionalZoomEnabled = map.get('isFractionalZoomEnabled');
  if (isFractionalZoomEnabled === false) {
    console.log('not using fractional zoom');
  } else if (isFractionalZoomEnabled === true) {
    console.log('using fractional zoom');
  } else {
    console.log('map not done initializing yet');
  }
});