Kształty i linie

Wybierz platformę: Android iOS JavaScript

Do mapy możesz dodawać różne kształty. Kształt to obiekt na mapie powiązany ze współrzędnymi geograficznymi. Dostępne są te kształty: linie, wielokąty, koła i prostokąty. Możesz też skonfigurować kształty tak, aby użytkownicy mogli je edytować lub przeciągać, albo połączyć kształty z biblioteką geometrii (google.maps.GeometryLibrary), aby sprawdzać geofence i granice bezpiecznych stref.

Linie łamane

Aby narysować linię na mapie, użyj linii łamanej. Klasa Polyline definiuje liniową nakładkę połączonych segmentów linii na mapie. Obiekt Polyline składa się z tablicy lokalizacji LatLng i tworzy serię segmentów linii, które łączą te lokalizacje w uporządkowaną sekwencję.

Dodawanie linii łamanej

Konstruktor Polyline przyjmuje zbiór PolylineOptions określający współrzędne LatLng linii oraz zbiór stylów, które dostosowują wizualne zachowanie linii łamanej.

Obiekty Polyline są rysowane na mapie jako seria prostych segmentów. Podczas tworzenia linii możesz określić spersonalizowane kolory, grubość i przezroczystość jej obrysu w obiekcie PolylineOptions. Możesz też zmienić te właściwości po utworzeniu linii. Polilinia obsługuje te style obrysu:

  • strokeColor określa szesnastkowy kod koloru HTML w formacie "#FFFFFF". Klasa Polyline nie obsługuje nazwanych kolorów.
  • strokeOpacity określa wartość liczbową z zakresu od 0.0 do 1.0, która określa przezroczystość koloru linii. Wartość domyślna to 1.0.
  • strokeWeight określa szerokość linii w pikselach.

Właściwość editable linii łamanej określa, czy użytkownicy mogą edytować kształt. Zobacz kształty, które użytkownik może edytować poniżej. Podobnie możesz ustawić właściwość draggable, aby umożliwić użytkownikom przeciąganie linii.

W tym przykładzie tworzymy czerwoną linię łamaną o szerokości 2 pikseli, która pokazuje trasę pierwszego lotu transatlantyckiego między Oakland w Kalifornii a Brisbane w Australii.

TypeScript

// This example creates a 2-pixel-wide red polyline showing the path of
// the first trans-Pacific flight between Oakland, CA, and Brisbane,
// Australia which was made by Charles Kingsford Smith.
const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;

async function init() {
    const { Polyline } = await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;

    const flightPlanCoordinates = [
        { lat: 37.772, lng: -122.214 },
        { lat: 21.291, lng: -157.821 },
        { lat: -18.142, lng: 178.431 },
        { lat: -27.467, lng: 153.027 },
    ];
    const flightPath = new Polyline({
        path: flightPlanCoordinates,
        geodesic: true,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
    });

    flightPath.setMap(innerMap);
}

void init();

JavaScript

// This example creates a 2-pixel-wide red polyline showing the path of
// the first trans-Pacific flight between Oakland, CA, and Brisbane,
// Australia which was made by Charles Kingsford Smith.
const mapElement = document.querySelector('gmp-map');
let innerMap;

async function init() {
    const { Polyline } = await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;

    const flightPlanCoordinates = [
        { lat: 37.772, lng: -122.214 },
        { lat: 21.291, lng: -157.821 },
        { lat: -18.142, lng: 178.431 },
        { lat: -27.467, lng: 153.027 },
    ];
    const flightPath = new Polyline({
        path: flightPlanCoordinates,
        geodesic: true,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
    });

    flightPath.setMap(innerMap);
}

void init();
Zobacz przykład

Usuwanie linii łamanej

Aby usunąć linię łamaną z mapy, wywołaj metodę setMap(), przekazując null jako argument. W tym przykładzie flightPath to obiekt linii łamanej:

flightPath.setMap(null);

Pamiętaj, że powyższa metoda nie usuwa linii łamanej. Usuwa linię łamaną z mapy. Jeśli chcesz usunąć polilinię, usuń ją z mapy, a następnie ustaw polilinię na null.

Sprawdzanie linii łamanej

Linia łamana określa serię współrzędnych jako tablicę obiektów LatLng. Te współrzędne określają ścieżkę linii. Aby pobrać współrzędne, wywołaj funkcję getPath(), która zwróci tablicę typu MVCArray. Tablicą można manipulować i sprawdzać ją za pomocą tych operacji:

  • getAt() zwraca LatLng o podanej wartości indeksu (liczonego od zera).
  • insertAt() wstawia przekazany obiekt LatLng przy danej wartości indeksu rozpoczynającego się od 0. Pamiętaj, że wszystkie istniejące współrzędne o tej wartości indeksu zostaną przesunięte do przodu.
  • removeAt() usuwa LatLng o podanej wartości indeksu (liczonego od zera).

Poniższy przykład pokazuje, jak utworzyć linię łamaną na podstawie kliknięć (kliknij mapę, aby dodać wierzchołek).

TypeScript

/**
 * This example creates an interactive map which constructs a polyline based on
 * user clicks. Note that the polyline only appears once its path property
 * contains two LatLng coordinates.
 */

let poly: google.maps.Polyline;
const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;

async function init() {
    // Import the needed libraries.
    const [{ Polyline }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('marker'),
    ]);

    innerMap = mapElement.innerMap;

    poly = new Polyline({
        strokeColor: '#000000',
        strokeOpacity: 1.0,
        strokeWeight: 3,
    });
    poly.setMap(innerMap);

    // Handles click events on a map, and adds a new point to the Polyline.
    innerMap.addListener('click', (event: google.maps.MapMouseEvent) => {
        const latLng = event.latLng;
        if (!latLng) return;

        const path = poly.getPath();

        // Because path is an MVCArray, we can simply append a new coordinate
        // and it will automatically appear.
        path.push(latLng);

        // Add a new marker at the new plotted point on the polyline.
        new AdvancedMarkerElement({
            position: latLng,
            title: '#' + path.getLength(),
            map: innerMap,
        });
    });
}

void init();

JavaScript

/**
 * This example creates an interactive map which constructs a polyline based on
 * user clicks. Note that the polyline only appears once its path property
 * contains two LatLng coordinates.
 */

let poly;
const mapElement = document.querySelector('gmp-map');
let innerMap;

async function init() {
    // Import the needed libraries.
    const [{ Polyline }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('marker'),
    ]);

    innerMap = mapElement.innerMap;

    poly = new Polyline({
        strokeColor: '#000000',
        strokeOpacity: 1.0,
        strokeWeight: 3,
    });
    poly.setMap(innerMap);

    // Handles click events on a map, and adds a new point to the Polyline.
    innerMap.addListener('click', (event) => {
        const latLng = event.latLng;
        if (!latLng) return;

        const path = poly.getPath();

        // Because path is an MVCArray, we can simply append a new coordinate
        // and it will automatically appear.
        path.push(latLng);

        // Add a new marker at the new plotted point on the polyline.
        new AdvancedMarkerElement({
            position: latLng,
            title: '#' + path.getLength(),
            map: innerMap,
        });
    });
}

void init();
Zobacz przykład

Dostosowywanie linii łamanej

Do linii łamanej możesz dodawać obrazy wektorowe w postaci symboli. Dzięki połączeniu symboli i klasy PolylineOptions masz dużą kontrolę nad wyglądem i stylem linii łamanych na mapie. Więcej informacji o strzałkach, liniach przerywanych, symbolach niestandardowych i symbolach animowanych znajdziesz w sekcji Symbole.

Wielokąty

Wielokąt reprezentuje obszar zamknięty ścieżką zamkniętą (lub pętlą), która jest zdefiniowana przez serię współrzędnych. Obiekty Polygon są podobne do obiektów Polyline, ponieważ składają się z serii współrzędnych w uporządkowanej sekwencji. Wielokąty są rysowane z obrysem i wypełnieniem. Możesz zdefiniować spersonalizowane kolory, grubość i nieprzezroczystość krawędzi wielokąta (kreski) oraz spersonalizowane kolory i nieprzezroczystość objętego nim obszaru (wypełnienie). Kolory powinny być podane w szesnastkowym formacie HTML. Nazwy kolorów nie są obsługiwane.

Obiekty Polygon mogą opisywać złożone kształty, w tym:

  • Wiele nieprzylegających obszarów zdefiniowanych przez jeden wielokąt.
  • Obszary z dziurami.
  • Przecięcia co najmniej 1 obszaru.

Aby zdefiniować złożony kształt, użyj wielokąta z wieloma ścieżkami.

Uwaga: warstwa danych umożliwia proste rysowanie wielokątów. Zajmuje się nawijaniem wielokątów, co ułatwia rysowanie wielokątów z otworami. Zobacz dokumentację warstwy danych.

Dodaj wielokąt

Ponieważ obszar wielokąta może obejmować kilka oddzielnych ścieżek, właściwość paths obiektu Polygon określa tablicę tablic, z których każda jest typu MVCArray. Każda tablica definiuje osobną sekwencję uporządkowanych współrzędnych LatLng.

W przypadku prostych wielokątów składających się tylko z jednej ścieżki możesz utworzyć obiekt Polygon, używając pojedynczej tablicy współrzędnych LatLng. Interfejs Maps JavaScript API podczas tworzenia przekonwertuje prostą tablicę na tablicę tablic, gdy będzie ją przechowywać we właściwości paths. Interfejs API udostępnia prostą metodę getPath() dla wielokątów składających się z jednej ścieżki.

Właściwość editable wielokąta określa, czy użytkownicy mogą edytować kształt. Zobacz kształty edytowalne przez użytkownika poniżej. Podobnie możesz ustawić właściwość draggable, aby umożliwić użytkownikom przeciąganie kształtu.

TypeScript

// This example creates a simple polygon representing the Bermuda Triangle.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 5,
      center: { lat: 24.886, lng: -70.268 },
      mapTypeId: "terrain",
    }
  );

  // Define the LatLng coordinates for the polygon's path.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
    { lat: 25.774, lng: -80.19 },
  ];

  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

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

JavaScript

// This example creates a simple polygon representing the Bermuda Triangle.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
    mapTypeId: "terrain",
  });
  // Define the LatLng coordinates for the polygon's path.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
    { lat: 25.774, lng: -80.19 },
  ];
  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

window.initMap = initMap;
Zobacz przykład

Autouzupełnianie wielokątów

W powyższym przykładzie Polygon składa się z 4 zestawów współrzędnych LatLng, ale pierwszy i ostatni zestaw określają tę samą lokalizację, co zamyka pętlę. W praktyce jednak, ponieważ wielokąty definiują zamknięte obszary, nie musisz podawać ostatniego zestawu współrzędnych. Interfejs Maps JavaScript API automatycznie uzupełni wielokąt, rysując obrys łączący ostatnią lokalizację z pierwszą dla każdej ścieżki.

Poniższy przykład jest identyczny z poprzednim, z tą różnicą, że pominięto ostatni element LatLng: zobacz przykład.

Usuwanie wielokąta

Aby usunąć wielokąt z mapy, wywołaj metodę setMap(), przekazując null jako argument. W tym przykładzie bermudaTriangle jest obiektem wielokąta:

bermudaTriangle.setMap(null);

Pamiętaj, że powyższa metoda nie powoduje usunięcia wielokąta. Spowoduje to usunięcie wielokąta z mapy. Jeśli chcesz usunąć wielokąt, usuń go z mapy, a następnie ustaw sam wielokąt na null.

Sprawdzanie wielokąta

Wielokąt określa serię współrzędnych jako tablicę tablic, gdzie każda tablica jest typu MVCArray. Każda tablica „leaf” to tablica współrzędnych LatLng określających pojedynczą ścieżkę. Aby pobrać te współrzędne, wywołaj metodę getPaths() obiektu Polygon. Tablica jest typu MVCArray, więc musisz ją przekształcić i sprawdzić za pomocą tych operacji:

  • getAt() zwraca LatLng o podanej wartości indeksu (liczonego od zera).
  • insertAt() wstawia przekazany obiekt LatLng przy danej wartości indeksu rozpoczynającego się od 0. Pamiętaj, że wszystkie istniejące współrzędne o tej wartości indeksu zostaną przesunięte do przodu.
  • removeAt() usuwa element LatLng o podanej wartości indeksu (liczonego od zera).

TypeScript

// This example creates a simple polygon representing the Bermuda Triangle.
// When the user clicks on the polygon an info window opens, showing
// information about the polygon's coordinates.

let map: google.maps.Map;

let infoWindow: google.maps.InfoWindow;

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
    mapTypeId: "terrain",
  });

  // Define the LatLng coordinates for the polygon.
  const triangleCoords: google.maps.LatLngLiteral[] = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];

  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);

  // Add a listener for the click event.
  bermudaTriangle.addListener("click", showArrays);

  infoWindow = new google.maps.InfoWindow();
}

function showArrays(event: any) {
  // Since this polygon has only one path, we can call getPath() to return the
  // MVCArray of LatLngs.
  // @ts-ignore
  const polygon = this as google.maps.Polygon;
  const vertices = polygon.getPath();

  let contentString =
    "<b>Bermuda Triangle polygon</b><br>" +
    "Clicked location: <br>" +
    event.latLng.lat() +
    "," +
    event.latLng.lng() +
    "<br>";

  // Iterate over the vertices.
  for (let i = 0; i < vertices.getLength(); i++) {
    const xy = vertices.getAt(i);

    contentString +=
      "<br>" + "Coordinate " + i + ":<br>" + xy.lat() + "," + xy.lng();
  }

  // Replace the info window's content and position.
  infoWindow.setContent(contentString);
  infoWindow.setPosition(event.latLng);

  infoWindow.open(map);
}

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

JavaScript

// This example creates a simple polygon representing the Bermuda Triangle.
// When the user clicks on the polygon an info window opens, showing
// information about the polygon's coordinates.
let map;
let infoWindow;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
    mapTypeId: "terrain",
  });

  // Define the LatLng coordinates for the polygon.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];
  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
  // Add a listener for the click event.
  bermudaTriangle.addListener("click", showArrays);
  infoWindow = new google.maps.InfoWindow();
}

function showArrays(event) {
  // Since this polygon has only one path, we can call getPath() to return the
  // MVCArray of LatLngs.
  // @ts-ignore
  const polygon = this;
  const vertices = polygon.getPath();
  let contentString =
    "<b>Bermuda Triangle polygon</b><br>" +
    "Clicked location: <br>" +
    event.latLng.lat() +
    "," +
    event.latLng.lng() +
    "<br>";

  // Iterate over the vertices.
  for (let i = 0; i < vertices.getLength(); i++) {
    const xy = vertices.getAt(i);

    contentString +=
      "<br>" + "Coordinate " + i + ":<br>" + xy.lat() + "," + xy.lng();
  }

  // Replace the info window's content and position.
  infoWindow.setContent(contentString);
  infoWindow.setPosition(event.latLng);
  infoWindow.open(map);
}

window.initMap = initMap;
Zobacz przykład

Wycinanie otworu w wielokącie

Aby utworzyć pusty obszar wewnątrz wielokąta, musisz utworzyć 2 ścieżki, jedną wewnątrz drugiej. Aby utworzyć otwór, współrzędne definiujące ścieżkę wewnętrzną muszą być w kolejności odwrotnej do współrzędnych definiujących ścieżkę zewnętrzną. Jeśli na przykład współrzędne ścieżki zewnętrznej są podane w kolejności zgodnej z ruchem wskazówek zegara, ścieżka wewnętrzna musi być podana w kolejności w lewo.

Uwaga: warstwa danych obsługuje kolejność ścieżek wewnętrznych i zewnętrznych, co ułatwia rysowanie wielokątów z otworami. Zapoznaj się z dokumentacją warstwy danych.

W poniższym przykładzie rysowany jest wielokąt z 2 ścieżkami, przy czym ścieżka wewnętrzna jest skierowana w przeciwnym kierunku niż ścieżka zewnętrzna.

TypeScript

// This example creates a triangular polygon with a hole in it.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 5,
      center: { lat: 24.886, lng: -70.268 },
    }
  );

  // Define the LatLng coordinates for the polygon's  outer path.
  const outerCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];

  // Define the LatLng coordinates for the polygon's inner path.
  // Note that the points forming the inner path are wound in the
  // opposite direction to those in the outer path, to form the hole.
  const innerCoords = [
    { lat: 28.745, lng: -70.579 },
    { lat: 29.57, lng: -67.514 },
    { lat: 27.339, lng: -66.668 },
  ];

  // Construct the polygon, including both paths.
  const bermudaTriangle = new google.maps.Polygon({
    paths: [outerCoords, innerCoords],
    strokeColor: "#FFC107",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FFC107",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

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

JavaScript

// This example creates a triangular polygon with a hole in it.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
  });
  // Define the LatLng coordinates for the polygon's  outer path.
  const outerCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];
  // Define the LatLng coordinates for the polygon's inner path.
  // Note that the points forming the inner path are wound in the
  // opposite direction to those in the outer path, to form the hole.
  const innerCoords = [
    { lat: 28.745, lng: -70.579 },
    { lat: 29.57, lng: -67.514 },
    { lat: 27.339, lng: -66.668 },
  ];
  // Construct the polygon, including both paths.
  const bermudaTriangle = new google.maps.Polygon({
    paths: [outerCoords, innerCoords],
    strokeColor: "#FFC107",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FFC107",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

window.initMap = initMap;
Zobacz przykład

Prostokąty

Oprócz ogólnej klasy Polygon interfejs Google Maps JavaScript API zawiera też specjalną klasę obiektów Rectangle, która upraszcza ich tworzenie.

Dodawanie prostokąta

Rectangle jest podobny do Polygon, ponieważ możesz zdefiniować spersonalizowane kolory, grubość i nieprzezroczystość krawędzi prostokąta (kreski) oraz spersonalizowane kolory i nieprzezroczystość obszaru wewnątrz prostokąta (wypełnienie). Kolory powinny być podane w szesnastkowym formacie liczbowym HTML.

W odróżnieniu od Polygon nie definiujesz paths dla Rectangle. Zamiast tego prostokąt ma właściwość bounds, która definiuje jego kształt przez określenie google.maps.LatLngBounds.

Właściwość editable prostokąta określa, czy użytkownicy mogą edytować kształt. Zobacz kształty edytowalne przez użytkownika poniżej. Podobnie możesz ustawić właściwość draggable, aby umożliwić użytkownikom przeciąganie prostokąta.

TypeScript

// This example adds a red rectangle to a map.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 11,
      center: { lat: 33.678, lng: -116.243 },
      mapTypeId: "terrain",
    }
  );

  const rectangle = new google.maps.Rectangle({
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
    map,
    bounds: {
      north: 33.685,
      south: 33.671,
      east: -116.234,
      west: -116.251,
    },
  });
}

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

JavaScript

// This example adds a red rectangle to a map.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 11,
    center: { lat: 33.678, lng: -116.243 },
    mapTypeId: "terrain",
  });
  const rectangle = new google.maps.Rectangle({
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
    map,
    bounds: {
      north: 33.685,
      south: 33.671,
      east: -116.234,
      west: -116.251,
    },
  });
}

window.initMap = initMap;
Zobacz przykład

Poniższy kod tworzy prostokąt za każdym razem, gdy użytkownik zmienia powiększenie na mapie. Rozmiar prostokąta jest określany przez widoczny obszar.

TypeScript

// This example creates a rectangle based on the viewport
// on any 'zoom-changed' event.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 11,
      center: { lat: 40.74852, lng: -73.981687 },
      mapTypeId: "terrain",
    }
  );

  const rectangle = new google.maps.Rectangle();

  map.addListener("zoom_changed", () => {
    // Get the current bounds, which reflect the bounds before the zoom.
    rectangle.setOptions({
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map,
      bounds: map.getBounds() as google.maps.LatLngBounds,
    });
  });
}

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

JavaScript

// This example creates a rectangle based on the viewport
// on any 'zoom-changed' event.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 11,
    center: { lat: 40.74852, lng: -73.981687 },
    mapTypeId: "terrain",
  });
  const rectangle = new google.maps.Rectangle();

  map.addListener("zoom_changed", () => {
    // Get the current bounds, which reflect the bounds before the zoom.
    rectangle.setOptions({
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map,
      bounds: map.getBounds(),
    });
  });
}

window.initMap = initMap;
Zobacz przykład

Usuwanie prostokąta

Aby usunąć prostokąt z mapy, wywołaj metodę setMap(), przekazując argument null.

rectangle.setMap(null);

Pamiętaj, że powyższa metoda nie powoduje usunięcia prostokąta. Spowoduje to usunięcie prostokąta z mapy. Jeśli chcesz usunąć prostokąt, usuń go z mapy, a następnie ustaw sam prostokąt na null.

Kręgi

Oprócz ogólnej klasy Polygon interfejs Google Maps JavaScript API zawiera też specjalną klasę dla obiektów Circle, która upraszcza ich tworzenie.

Dodawanie kręgu

Circle jest podobny do Polygon, ponieważ możesz zdefiniować spersonalizowane kolory, grubość i nieprzezroczystość krawędzi okręgu (kreski) oraz spersonalizowane kolory i nieprzezroczystość obszaru wewnątrz okręgu (wypełnienie). Kolory powinny być podane w szesnastkowym formacie liczbowym w stylu HTML.

W odróżnieniu od Polygon nie definiujesz paths dla Circle. Zamiast tego okrąg ma 2 dodatkowe właściwości, które określają jego kształt:

  • center określa google.maps.LatLng środka okręgu.
  • radius określa promień okręgu w metrach.

Właściwość editable okręgu określa, czy użytkownicy mogą edytować kształt. Zobacz kształty edytowalne przez użytkownika poniżej. Podobnie możesz ustawić właściwość draggable, aby umożliwić użytkownikom przeciąganie okręgu.

W tym przykładzie użyto okręgów, aby pokazać przybliżony czas przejścia między lokalizacjami w Kioto w Japonii. Wybierz w menu odpowiednią odległość, kliknij mapę, aby wyśrodkować okrąg, i przeciągnij go, aby zmienić jego położenie.

TypeScript

const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;

async function init() {
    // Request needed libraries.
    const [{ Circle }, { AdvancedMarkerElement }, { event }] =
        await Promise.all([
            google.maps.importLibrary('maps'),
            google.maps.importLibrary('marker'),
            google.maps.importLibrary('core'),
        ]);

    // Set the initial map center point.
    const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan

    // Get the inner map.
    innerMap = mapElement.innerMap;

    // Get the buttons.
    const buttons = document.querySelectorAll('input[name="radius"]');

    // Create the circle.
    const walkingCircle = new Circle({
        strokeColor: '#ffdd00ff',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#ffdd00ff',
        fillOpacity: 0.35,
        map: innerMap,
        center: initialCenter,
        radius: 400,
        draggable: true,
        editable: false,
    });

    // Define a "Crosshair" vector icon
    const parser = new DOMParser();
    const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-6 -6 12 12"><path d="M -6,0 L 6,0 M 0,-6 L 0,6" stroke="black" stroke-width="1"/></svg>`;

    const pinSvg = parser.parseFromString(
        svgString,
        'image/svg+xml'
    ).documentElement;

    const centerMarker = new AdvancedMarkerElement({
        position: initialCenter,
        title: 'A marker using a custom SVG image.',
        anchorLeft: '-50%',
        anchorTop: '-50%',
    });
    centerMarker.append(pinSvg);
    mapElement.append(centerMarker);

    // Wait for the map to finish drawing its tiles.
    event.addListenerOnce(innerMap, 'tilesloaded', () => {
        // Get the controls div
        const controls = document.getElementById('control-panel');

        // Display controls once map is loaded.
        if (controls) {
            controls.style.display = 'block';
        }
    });

    // Add event listener to update the radius based on user selection.
    buttons.forEach((button) => {
        button.addEventListener('change', (changeEvent) => {
            const target = changeEvent.target as HTMLInputElement;
            walkingCircle.setRadius(Number(target.value));
        });
    });

    // Handle user click, reset the map center and position the circle.
    innerMap.addListener(
        'click',
        (
            mapsMouseEvent:
                google.maps.MapMouseEvent | google.maps.IconMouseEvent
        ) => {
            const newCenter = mapsMouseEvent.latLng;
            if (!newCenter) return;
            walkingCircle.setCenter(newCenter);
            centerMarker.position = newCenter;
            innerMap.panTo(newCenter);
        }
    );

    // Handle user dragging the circle, update the center marker position.
    walkingCircle.addListener('center_changed', () => {
        centerMarker.position = walkingCircle.getCenter();
    });
}

void init();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;

async function init() {
    // Request needed libraries.
    const [{ Circle }, { AdvancedMarkerElement }, { event }] =
        await Promise.all([
            google.maps.importLibrary('maps'),
            google.maps.importLibrary('marker'),
            google.maps.importLibrary('core'),
        ]);

    // Set the initial map center point.
    const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan

    // Get the inner map.
    innerMap = mapElement.innerMap;

    // Get the buttons.
    const buttons = document.querySelectorAll('input[name="radius"]');

    // Create the circle.
    const walkingCircle = new Circle({
        strokeColor: '#ffdd00ff',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#ffdd00ff',
        fillOpacity: 0.35,
        map: innerMap,
        center: initialCenter,
        radius: 400,
        draggable: true,
        editable: false,
    });

    // Define a "Crosshair" vector icon
    const parser = new DOMParser();
    const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-6 -6 12 12"><path d="M -6,0 L 6,0 M 0,-6 L 0,6" stroke="black" stroke-width="1"/></svg>`;

    const pinSvg = parser.parseFromString(
        svgString,
        'image/svg+xml'
    ).documentElement;

    const centerMarker = new AdvancedMarkerElement({
        position: initialCenter,
        title: 'A marker using a custom SVG image.',
        anchorLeft: '-50%',
        anchorTop: '-50%',
    });
    centerMarker.append(pinSvg);
    mapElement.append(centerMarker);

    // Wait for the map to finish drawing its tiles.
    event.addListenerOnce(innerMap, 'tilesloaded', () => {
        // Get the controls div
        const controls = document.getElementById('control-panel');

        // Display controls once map is loaded.
        if (controls) {
            controls.style.display = 'block';
        }
    });

    // Add event listener to update the radius based on user selection.
    buttons.forEach((button) => {
        button.addEventListener('change', (changeEvent) => {
            const target = changeEvent.target;
            walkingCircle.setRadius(Number(target.value));
        });
    });

    // Handle user click, reset the map center and position the circle.
    innerMap.addListener('click', (mapsMouseEvent) => {
        const newCenter = mapsMouseEvent.latLng;
        if (!newCenter) return;
        walkingCircle.setCenter(newCenter);
        centerMarker.position = newCenter;
        innerMap.panTo(newCenter);
    });

    // Handle user dragging the circle, update the center marker position.
    walkingCircle.addListener('center_changed', () => {
        centerMarker.position = walkingCircle.getCenter();
    });
}

void init();

CSS

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

#control-panel {
    display: none; /* Set to 'display: block' after the map loads. */
    background-color: #fff;
    border: 2px solid #fff;
    border-radius: 3px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    font-family: 'Roboto', sans-serif;
    font-size: medium;
    margin: 10px;
    padding: 10px;
}

HTML

<html>
    <head>
        <title>Circles</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <gmp-map
            center="34.98956821576194, 135.74239981260283"
            zoom="15"
            map-id="DEMO_MAP_ID">
            <div id="control-panel" slot="control-inline-start-block-start">
                <input
                    id="short-walk"
                    type="radio"
                    name="radius"
                    value="400"
                    checked />
                <label for="short-walk">Short Walk (~5 minutes)</label><br />
                <input
                    id="medium-walk"
                    type="radio"
                    name="radius"
                    value="800" />
                <label for="medium-walk">Medium Walk (~15 minutes)</label><br />
                <input id="long-walk" type="radio" name="radius" value="1600" />
                <label for="long-walk">Long Walk (~30 minutes) </label>
            </div>
        </gmp-map>
    </body>
</html>
Zobacz przykład

Usuwanie kręgu

Aby usunąć okrąg z mapy, wywołaj metodę setMap(), przekazując argument null.

circle.setMap(null);

Pamiętaj, że powyższa metoda nie powoduje usunięcia kręgu. Spowoduje to usunięcie okręgu z mapy. Jeśli chcesz usunąć okrąg, usuń go z mapy, a następnie ustaw sam okrąg na null.

Kształty, które użytkownik może edytować i przeciągać

Ustawienie kształtu jako edytowalnego powoduje dodanie do niego uchwytów, których użytkownicy mogą używać do zmiany położenia, kształtu i rozmiaru bezpośrednio na mapie. Możesz też ustawić kształt jako możliwy do przeciągania, aby użytkownicy mogli go przenieść w inne miejsce na mapie.

Zmiany wprowadzone przez użytkownika w obiekcie nie są zachowywane między sesjami. Jeśli chcesz zapisać zmiany wprowadzone przez użytkownika, musisz samodzielnie przechwycić i zapisać te informacje.

Włączanie możliwości edytowania kształtu

Dowolny kształt (linie łamane, wielokąty, okręgi i prostokąty) można ustawić jako edytowalny przez użytkownika, ustawiając editable na true w opcjach kształtu.

var bounds = {
  north: 44.599,
  south: 44.490,
  east: -78.443,
  west: -78.649
};

// Define a rectangle and set its editable property to true.
var rectangle = new google.maps.Rectangle({
  bounds: bounds,
  editable: true
});

Zobacz przykład

Umożliwianie przeciągania kształtu

Domyślnie kształt narysowany na mapie będzie miał stałą pozycję. Aby umożliwić użytkownikom przeciąganie kształtu w inne miejsce na mapie, w opcjach kształtu ustaw właściwość draggable na true.

var redCoords = [
  {lat: 25.774, lng: -80.190},
  {lat: 18.466, lng: -66.118},
  {lat: 32.321, lng: -64.757}
];

// Construct a draggable red triangle with geodesic set to true.
new google.maps.Polygon({
  map: map,
  paths: redCoords,
  strokeColor: '#FF0000',
  strokeOpacity: 0.8,
  strokeWeight: 2,
  fillColor: '#FF0000',
  fillOpacity: 0.35,
  draggable: true,
  geodesic: true
});

Włączając przeciąganie wielokąta lub linii łamanej, warto też rozważyć ustawienie właściwości geodesic na true, aby wielokąt lub linia łamana były geodezyjne.

Wielokąt geodezyjny zachowuje swój prawdziwy kształt geograficzny podczas przesuwania, co powoduje, że wydaje się zniekształcony, gdy jest przesuwany na północ lub południe w odwzorowaniu Mercatora. Wielokąty niegeodezyjne zawsze zachowują swój początkowy wygląd na ekranie.

W przypadku polilinii geodezyjnej jej segmenty są rysowane jako najkrótsza ścieżka między 2 punktami na powierzchni Ziemi, przy założeniu, że Ziemia jest kulą, a nie płaską powierzchnią w odwzorowaniu Merkatora.

Więcej informacji o systemach współrzędnych znajdziesz w przewodniku po współrzędnych mapy i kafelka.

Na mapie poniżej widać 2 trójkąty o podobnym rozmiarze i wymiarach. Właściwość geodesic czerwonego trójkąta jest ustawiona na true. Zwróć uwagę, jak zmienia się jego kształt, gdy przemieszcza się na północ.

Zobacz przykład

Nasłuchiwanie zdarzeń edycji

Gdy kształt zostanie zmodyfikowany, po zakończeniu edycji zostanie wywołane zdarzenie. Te zdarzenia są wymienione poniżej.

Kształt Wydarzenia
Okrąg radius_changed
center_changed
Wielokąt insert_at
remove_at
set_at

Detektor musi być ustawiony na ścieżce wielokąta. Jeśli wielokąt ma wiele ścieżek, detektor musi być ustawiony na każdej z nich.

Linia łamana insert_at
remove_at
set_at

Detektor musi być ustawiony na ścieżce linii łamanej.

Prostokąt bounds_changed

Przydatne fragmenty kodu:

google.maps.event.addListener(circle, 'radius_changed', function() {
  console.log(circle.getRadius());
});

google.maps.event.addListener(outerPath, 'set_at', function() {
  console.log('Vertex moved on outer path.');
});

google.maps.event.addListener(innerPath, 'insert_at', function() {
  console.log('Vertex removed from inner path.');
});

google.maps.event.addListener(rectangle, 'bounds_changed', function() {
  console.log('Bounds changed.');
});

Zobacz przykład obsługi zdarzenia edycji prostokąta: wyświetl przykład.

Nasłuchiwanie zdarzeń przeciągania

Podczas przeciągania kształtu zdarzenia są wywoływane na początku i na końcu przeciągania, a także w trakcie przeciągania. W przypadku linii łamanych, wielokątów, okręgów i prostokątów wywoływane są te zdarzenia.

Zdarzenie Opis
dragstart Uruchamiane, gdy użytkownik zaczyna przeciągać kształt.
drag Uruchamiane wielokrotnie, gdy użytkownik przeciąga kształt.
dragend Uruchamiane, gdy użytkownik przestanie przeciągać kształt.

Więcej informacji o obsłudze zdarzeń znajdziesz w dokumentacji dotyczącej zdarzeń.

geofence i granice bezpiecznych stref;

Google Maps Platform nie udostępnia samodzielnego interfejsu Geofencing API. Aby wyświetlić promień geofence lub bezpieczną strefę na mapie internetowej i sprawdzić, czy współrzędne na żywo znajdują się w tych granicach, połącz kształty z biblioteką Geometry (google.maps.GeometryLibrary) wczytaną przez google.maps.importLibrary("geometry"):

W tym przykładzie rysowany jest okrągły bezpieczny obszar i wielokątny geofence, a następnie sprawdzane jest, czy współrzędne na żywo znajdują się wewnątrz każdej granicy:

const {Circle, Polygon} = await google.maps.importLibrary("maps");
const {poly} = await google.maps.importLibrary("geometry");

const livePosition = {lat: 37.424, lng: -122.085};

// 1. Circular geofence (500-meter radius)
const circularGeofence = new Circle({
  map,
  center: {lat: 37.422, lng: -122.084},
  radius: 500,
});
const isInsideCircle = poly.containsLocation(livePosition, circularGeofence);

// 2. Polygonal geofence
const polygonGeofence = new Polygon({
  map,
  paths: [
    {lat: 37.420, lng: -122.088},
    {lat: 37.420, lng: -122.080},
    {lat: 37.426, lng: -122.080},
    {lat: 37.426, lng: -122.088},
  ],
});
const isInsidePolygon = poly.containsLocation(livePosition, polygonGeofence);