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ę rastrowych obrazów opartych na pikselach, które są generowane po stronie serwera w Google Maps Platform, a następnie przesyłane do aplikacji internetowej. Mapa wektorowa składa się z kafelków wektorowych, które są rysowane w momencie 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ą, a najważniejsze z nich to 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

Przechylanie i obracanie

Pochylenie i obrót (kierunek) na mapie wektorowej możesz ustawić, uwzględniając właściwości headingtilt podczas inicjowania mapy oraz wywołując na niej metody setTiltsetHeading. W przykładzie poniżej dodano do mapy przyciski, które umożliwiają programowe dostosowywanie pochylenia i kierunku o 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>

Wypróbuj przykład

Używanie gestów myszy i klawiatury

Jeśli interakcje użytkownika związane z pochyleniem i obrotem (kierunkiem) zostały włączone (programowo lub w Google Cloud Console), 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ć nachylenie, oraz 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 lewo i w prawo, aby dostosować kierunek.

Programowe dostosowywanie pochylenia i kierunku

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

  • Wywołaj setTilt(), aby ustawić kąt nachylenia mapy. Użyj getTilt(), aby uzyskać bieżącą wartość nachylenia.
  • 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 przyciskówmap.setCenter() lubmap.panBy().

Pamiętaj, że zakres kątów, których można używać, 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ć nagłówek, pochylenie, środek i powiększenie. Więcej informacji

Wpływ na inne metody

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

  • map.getBounds() zawsze zwraca najmniejsze pole ograniczające, które obejmuje widoczny region. Gdy zastosowane jest pochylenie, zwrócone granice mogą reprezentować większy region niż widoczny region obszaru widoku mapy.
  • map.fitBounds() przed dopasowaniem do 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 nachylenie na podstawie bieżącego poziomu powiększenia mapy.
  • map.setHeading() akceptuje dowolną wartość i dostosowuje ją do zakresu [0, 360].

Sterowanie kamerą

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

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 funkcję map.moveCamera() z pętlą animacji, jak pokazano poniżej:

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 określona przez szerokość i długość geograficzną), bearing, tiltzoom.

Diagram właściwości kamery

Miejsce docelowe (lokalizacja)

Punkt docelowy kamery to lokalizacja środka mapy określona za pomocą współrzędnych geograficznych.

Szerokość geograficzna może się mieścić w zakresie od -85 do 85 stopni. Wartości powyżej lub poniżej tego zakresu zostaną zmienione na najbliższą wartość 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ą przekształcone tak, aby mieściły się w zakresie (-180, 180). Na przykład wartości 480, 840 i 1200 zostaną zaokrąglone do 120 stopni.

Kierunek (orientacja)

Kierunek kamery określa kierunek kompasu mierzony w stopniach od północy geograficznej, który odpowiada górnej krawędzi mapy. Jeśli narysujesz pionową linię od środka mapy do jej górnej krawędzi, uzyskasz kierunek, w którym jest skierowany aparat (mierzony w stopniach) względem północy geograficznej.

Wartość 0 oznacza, że górna część mapy wskazuje północ geograficzną. Wartość 90 oznacza, że góra 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 samochodu 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.

Przechylenie (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 skierowanej w stronę horyzontu o określoną liczbę stopni. Gdy zmienisz kąt widzenia, mapa będzie wyświetlana w perspektywie, w której odległe obiekty są mniejsze, a pobliskie – większe. Ilustrują to poniższe przykłady.

Na obrazach poniżej kąt widzenia wynosi 0 stopni. Pierwszy obraz przedstawia schemat tej sytuacji. Pozycja 1 to pozycja kamery, a pozycja 2 to bieżąca pozycja na mapie. Wynikowa mapa jest widoczna poniżej.

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.
Diagram 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. Zwróć uwagę, że kamera przesuwa się w połowie łuku między pozycją bezpośrednio nad głową (0 stopni) a ziemią (90 stopni), aby zająć pozycję 3. Kamera nadal jest skierowana 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 powiększeniem 18.
Mapa wyświetlana pod kątem 45 stopni.
Diagram pokazują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 pojawiło się więcej elementów. Gdy zwiększysz kąt powyżej 45 stopni, obiekty między kamerą a pozycją na mapie będą proporcjonalnie większe, a obiekty za pozycją na mapie będą proporcjonalnie mniejsze, co da 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 mniejszym – 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 miejsca docelowego, typu mapy i rozmiaru ekranu. Każda liczba spoza 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
Obrazy poniżej pokazują, jak wyglądają różne poziomy powiększenia:
Zrzut ekranu mapy na poziomie powiększenia 5
Mapa na poziomie powiększenia 5.
Zrzut ekranu mapy na poziomie powiększenia 15
Mapa na poziomie powiększenia 15.
Zrzut ekranu mapy na 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 w przypadku map wektorowych jest ono domyślnie włączone, a w przypadku map rastrowych – wyłączone. Aby włączyć lub wyłączyć ułamkowe powiększenie, użyj opcji mapy isFractionalZoomEnabled.

Poniższy przykład pokazuje, jak włączyć ułamkowe powiększenie 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 isFractionalZoomEnabledopcję mapy w ten sposób:

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

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

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

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