Elementy mapy wektorowej

Wybierz platformę: Android iOS JavaScript

Wyświetl przykład

Interfejs Maps JavaScript API oferuje 2 różne implementacje mapy: rastrową i wektorową. Mapa rastrowa wczytuje mapę jako siatkę kafelków obrazów rastrowych opartych na pikselach, które są generowane po stronie serwera przez Google Maps Platform, a następnie udostępniane Twojej 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 umożliwiającej przeglądarce dostęp do procesora graficznego na urządzeniu użytkownika w celu renderowania grafiki 2D i 3D.

Mapa wektorowa to ta sama mapa Google, z której korzystają Twoi użytkownicy. Ma ona wiele zalet w porównaniu z domyślną mapą rastrową, przede wszystkim ostrość obrazów wektorowych i dodanie budynków 3D przy dużym powiększeniu. Mapa wektorowa obsługuje te funkcje:

Pierwsze kroki z mapami wektorowymi

Przechył i obrót

Możesz ustawić pochylenie i obrót (kierunek) na mapie wektorowej dodając właściwości heading i tilt podczas inicjowania mapy oraz wywołując metody setTilt i setHeading na mapie. Poniższy przykład dodaje do mapy kilka przycisków, które pokazują programowe dostosowywanie pochylenia 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 dotyczące pochylenia i obrotu (kierunku) zostały włączone (programowo lub w konsoli Google Cloud), użytkownicy mogą dostosowywać pochylenie 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ć pochylenie, oraz w prawo i w lewo, aby dostosować kierunek.
  • Za pomocą klawiatury przytrzymaj klawisz Shift, a następnie użyj klawiszy strzałek w górę i w dół , aby dostosować pochylenie, oraz klawiszy strzałek w prawo i w lewo, aby dostosować kierunek.

Programowe dostosowywanie pochylenia i kierunku

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

  • Wywołaj setTilt(), aby ustawić kąt pochylenia mapy. Użyj getTilt(), aby uzyskać bieżącą wartość pochylenia.
  • Wywołaj setHeading(), aby ustawić kierunek mapy. Użyj getHeading(), aby uzyskać bieżącą wartość kierunku.

Aby zmienić środek mapy przy zachowaniu pochylenia i kierunku, użyj map.setCenter() lub map.panBy().

Pamiętaj, że zakres kątów, których można użyć, zależy od bieżącego poziomu powiększenia. Wartości spoza tego zakresu są zmieniane na wartości graniczne.

Możesz też użyć metody moveCamera, aby programowo zmienić kierunek, pochylenie, środek i powiększenie. Więcej informacji.

Wpływ na inne metody

Gdy do mapy zostanie zastosowane pochylenie lub obrót, zmieni się działanie innych metod interfejsu Maps JavaScript API:

  • map.getBounds() zawsze zwraca najmniejszy prostokąt ograniczający, który obejmuje widoczny obszar. Gdy zastosowane jest pochylenie, zwrócone granice mogą reprezentować większy obszar niż widoczny obszar okna mapy.
  • map.fitBounds() przed dopasowaniem granic zresetuje pochylenie i kierunek do zera.
  • map.panToBounds() przed przesunięciem granic zresetuje pochylenie i kierunek do zera.
  • map.setTilt() akceptuje dowolną wartość, ale ogranicza maksymalne pochylenie na podstawie bieżącego poziomu powiększenia mapy.
  • map.setHeading() akceptuje dowolną wartość i modyfikuje ją tak, aby mieściła się w zakresie [0, 360].

Sterowanie kamerą

Użyj funkcji map.moveCamera(), aby jednocześnie zaktualizować dowolną kombinację właściwości kamery. map.moveCamera() akceptuje jeden parametr zawierający wszystkie właściwości kamery do zaktualizowania. Poniższy przykład pokazuje wywołanie map.moveCamera() w celu jednoczesnego ustawienia center, zoom, heading i tilt:

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

Właściwości kamery możesz animować, wywołując 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) jest określone przez te właściwości: target (lokalizacja szerokości i długości geograficznej), bearing, tilt, i zoom.

Diagram właściwości aparatu

Target (lokalizacja)

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

Szerokość geograficzna może się mieścić w zakresie od –85 do 85 stopni włącznie. Wartości powyżej lub poniżej tego zakresu są zmieniane na najbliższą wartość w tym zakresie. Na przykład określenie szerokości geograficznej jako 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 są zawijane 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.

Bearing (orientacja)

Bearing 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, bearing odpowiada kierunkowi kamery (mierzonym w stopniach) względem północy geograficznej.

Bearing równy 0 oznacza, że górna część mapy wskazuje północ geograficzną. Wartość bearing równa 90 oznacza, że górna część mapy wskazuje wschód (90 stopni na kompasie). Wartość 180 oznacza, że górna część mapy wskazuje południe.

Interfejs API Map Google umożliwia zmianę bearingu 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 wskazywała północ.

Tilt (kąt widzenia)

Pochylenie określa położenie kamery na łuku bezpośrednio nad środkiem mapy, mierzone w stopniach od nadiru (kierunku skierowanego bezpośrednio pod kamerę). Wartość 0 odpowiada kamerze skierowanej prosto w dół. Wartości większe od 0 odpowiadają kamerze, która jest pochylona w kierunku horyzontu o określoną liczbę stopni. Gdy zmienisz kąt widzenia, mapa będzie wyświetlana w perspektywie, a odległe obiekty będą mniejsze, a pobliskie – większe. Ilustrują to poniższe rysunki.

Na obrazach poniżej kąt widzenia wynosi 0 stopni. Pierwszy obraz przedstawia schemat. Pozycja 1 to położenie kamery, 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 0 stopni i poziomem powiększenia 18.
Mapa wyświetlana z domyślnym kątem widzenia kamery.
Diagram przedstawiający domyślną pozycję kamery, która znajduje się 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. Zwróć uwagę, że kamera 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. Kamera nadal jest skierowana na punkt środkowy 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 widzenia 45 stopni.
Diagram przedstawiający kąt widzenia kamery ustawiony na 45 stopni, a poziom powiększenia nadal ustawiony na 18.
Kąt widzenia kamery wynoszący 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 obiektów. Gdy zwiększysz kąt powyżej 45 stopni, obiekty między kamerą a położeniem mapy będą proporcjonalnie większe, a obiekty poza położeniem mapy – proporcjonalnie mniejsze, co da 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ększą część świata.

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 targetu, 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 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 pokazują wygląd mapy przy różnych poziomach powiększenia:
Zrzut ekranu mapy na poziomie powiększenia 5
Mapa z poziomem powiększenia 5.
Zrzut ekranu mapy na poziomie powiększenia 15
Mapa z poziomem powiększenia 15.
Zrzut ekranu mapy na poziomie powiększenia 20
Mapa z poziomem 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ą powiększenie ułamkowe, ale w przypadku map wektorowych jest ono domyślnie włączone, a w przypadku map rastrowych – domyślnie wyłączone. Aby włączyć lub wyłączyć powiększenie ułamkowe, użyj opcji mapy isFractionalZoomEnabled.

Poniższy 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
});

Powiększenie ułamkowe możesz też włączać i wyłączać, 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 sprawdzać, czy powiększenie ułamkowe jest włączone. Jest to najbardziej przydatne, jeśli nie ustawisz wyraźnie isFractionalZoomEnabled na true lub 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');
  }
});