Dodawanie mapy Google do aplikacji React

1. Zanim zaczniesz

Z tego samouczka dowiesz się wszystkiego, co jest potrzebne, aby zacząć korzystać z biblioteki vis.gl/react-google-map interfejsu Maps JavaScript API, która umożliwia dodawanie map Google do aplikacji React. Dowiesz się, jak skonfigurować bibliotekę, wczytać interfejs Maps JavaScript API, wyświetlić pierwszą mapę, pracować ze znacznikami i grupowaniem znaczników, rysować na mapie oraz obsługiwać interakcje użytkownika.

Wymagania wstępne

  • Podstawowa znajomość języków JavaScript, HTML i CSS

Czego się dowiesz

  • Jak zacząć korzystać z biblioteki vis.gl/react-google-map w Google Maps Platform.
  • Jak deklaratywnie wczytać interfejs Maps JavaScript API.
  • Jak wczytać mapę w aplikacji React.
  • Jak używać znaczników, znaczników niestandardowych i grupowania znaczników.
  • Jak korzystać z systemu zdarzeń interfejsu Maps JavaScript API, aby umożliwić interakcję z użytkownikiem.
  • Jak dynamicznie sterować mapą.
  • Jak rysować na mapie.

Wymagania

  • Konto Google Cloud z włączonym rozliczeniem.
  • Klucz interfejsu API Google Maps Platform z włączonym interfejsem Maps JavaScript API.
  • Node.js zainstalowany na komputerze.
  • dowolny edytor tekstu lub IDE;
  • Biblioteka vis.gl/react-google-map interfejsu Maps JavaScript API od Google.
  • Biblioteka googlemaps/markerclusterer

Konfigurowanie Google Maps Platform

Jeśli nie masz jeszcze konta Google Cloud Platform i projektu z włączonymi płatnościami, zapoznaj się z przewodnikiem Pierwsze kroki z Google Maps Platform, aby utworzyć konto rozliczeniowe i projekt.

  1. W konsoli Google Cloud kliknij menu projektu i wybierz projekt, którego chcesz użyć w tym samouczku.

  1. Włącz interfejsy API i pakiety SDK Google Maps Platform wymagane w tym samouczku w Google Cloud Marketplace. Aby to zrobić, wykonaj czynności opisane w tym filmie lub tej dokumentacji.
  2. Wygeneruj klucz interfejsu API na stronie Dane logowania w konsoli Cloud. Możesz wykonać czynności opisane w tym filmie lub tej dokumentacji. Wszystkie żądania wysyłane do Google Maps Platform wymagają klucza interfejsu API.

2. Konfiguracja

Pobierz projekt początkowy

Aby pobrać szablon projektu początkowego i kod rozwiązania, wykonaj te czynności:

  1. Pobierz lub utwórz rozwidlenie repozytorium GitHub. Projekt początkowy znajduje się w katalogu /starter i zawiera podstawową strukturę plików, która jest potrzebna do ukończenia ćwiczenia. Wszystkie zadania wykonujesz w katalogu /starter/src.
git clone https://github.com/googlemaps-samples/codelab-maps-platform-101-react-js.git

Możesz też kliknąć ten przycisk, aby pobrać kod źródłowy.

  1. Przejdź do katalogu /starter i zainstaluj npm. Spowoduje to zainstalowanie wszystkich potrzebnych zależności wymienionych w pliku package.json.
cd starter && npm install
  1. W katalogu /starter:
npm start

Projekt początkowy został skonfigurowany tak, aby można było używać serwera programistycznego Vite, który kompiluje i uruchamia pisany lokalnie kod. Serwer deweloperski Vite automatycznie przeładowuje też aplikację w przeglądarce za każdym razem, gdy wprowadzisz zmiany w kodzie. Jeśli klikniesz link podany na końcu procesu kompilacji, powinna pojawić się strona internetowa z tekstem „Hello, world!”.

  1. Jeśli chcesz uruchomić pełny kod rozwiązania, przejdź do katalogu /solution i wykonaj te same czynności konfiguracyjne.

3. Wczytywanie interfejsu Maps JavaScript API

Podstawą korzystania z Google Maps Platform w internecie jest interfejs Maps JavaScript API. Ten interfejs API udostępnia interfejs JavaScript do korzystania ze wszystkich funkcji Google Maps Platform, w tym mapy, znaczników, narzędzi do rysowania i innych usług Google Maps Platform, takich jak Miejsca.

Aby wczytać interfejs Maps JavaScript API za pomocą platformy React, musisz użyć komponentu APIProvider, który jest częścią biblioteki vis.gl/react-google-map. Ten komponent można dodać na dowolnym poziomie aplikacji, zwykle w górnej części. Renderuje on wszystkie komponenty podrzędne bez zmian. Oprócz obsługi wczytywania interfejsu Maps JavaScript API udostępnia on też informacje kontekstowe i funkcje dla innych komponentów i hooków tej biblioteki. Pakiet APIProvider jest częścią biblioteki vis.gl/react-google-map, więc został zainstalowany, gdy wcześniej uruchomiono polecenie npm install.

Aby użyć komponentu APIProvider, wykonaj te czynności:

  1. Otwórz plik /src/app.tsx. W tym pliku wykonasz wszystkie zadania w tym laboratorium.
  2. U góry pliku zaimportuj klasę APIProvider z biblioteki @vis.gl/react-google-maps:
import {APIProvider} from '@vis.gl/react-google-maps';
  1. W definicji funkcji App ustaw parametr apiKey komponentu APIProvider za pomocą klucza interfejsu API utworzonego w poprzednim kroku, a właściwość onLoad za pomocą komunikatu dziennika konsoli:
<APIProvider apiKey={'Your API key here'} onLoad={() => console.log('Maps API has loaded.')}>

Komponent APIProvider przyjmuje szereg właściwości, które określają różne opcje wczytywania interfejsu Maps JavaScript API, w tym klucz interfejsu API Google Maps Platform, wersję interfejsu API, którą chcesz wczytać, oraz wszelkie dodatkowe biblioteki udostępniane przez interfejs Maps JavaScript API, które chcesz wczytać.

Klucz interfejsu Google Maps API jest jedyną wymaganą właściwością, aby funkcja APIProvider działała. Właściwość onLoad została dodana w celach demonstracyjnych. Więcej informacji znajdziesz w sekcji <APIProvider> Komponent.

Plik app.tsx powinien wyglądać tak:

import React from 'react';
import {createRoot} from "react-dom/client";
import {APIProvider} from '@vis.gl/react-google-maps';

const App = () => (
 <APIProvider apiKey={'Your API key here'} onLoad={() => console.log('Maps API has loaded.')}>
   <h1>Hello, world!</h1>
 </APIProvider>
);

const root = createRoot(document.getElementById('app'));
root.render(<App />);

export default App;

Jeśli wszystko przebiegnie pomyślnie, w konsoli przeglądarki zobaczysz instrukcję console.log. Po wczytaniu interfejsu Maps JavaScript API możesz w następnym kroku wyrenderować dynamiczną mapę.

4. Wyświetlanie mapy

Czas wyświetlić pierwszą mapę.

Najczęściej używaną częścią interfejsu Maps JavaScript API jest google.maps.Map, czyli klasa, która umożliwia tworzenie instancji mapy i manipulowanie nimi. Biblioteka vis.gl/react-google-map otacza tę klasę komponentem Map. Najpierw zaimportuj zajęcia Map i MapCameraChangedEvent.

import {APIProvider, Map, MapCameraChangedEvent} from '@vis.gl/react-google-maps';

Komponent Map obsługuje różne ustawienia mapy. W tym laboratorium użyjesz tych ustawień:

  • defaultCenter, która ustawia szerokość i długość geograficzną środka mapy.
  • defaultZoom, który określa początkowy poziom powiększenia mapy.
  • Aby wyświetlić mapę, umieść poniższy kod w tagach APIProvider, aby wyśrodkować mapę na Sydney w Australii i ustawić poziom powiększenia na 13, który jest odpowiedni do wyświetlania centrum miasta:
 <Map
      defaultZoom={13}
      defaultCenter={ { lat: -33.860664, lng: 151.208138 } }
      onCameraChanged={ (ev: MapCameraChangedEvent) =>
        console.log('camera changed:', ev.detail.center, 'zoom:', ev.detail.zoom)
      }>
</Map>

W przeglądarce powinna pojawić się mapa Sydney:

761c8c51c6631174.png

Podsumowując, w tej sekcji wyświetlono mapę za pomocą komponentu <Map> i ustawiono jej stan początkowy za pomocą właściwości. Używasz też zdarzeń do rejestrowania zmian kamery.

Plik app.tsx powinien wyglądać mniej więcej tak:

import React from 'react';
import {createRoot} from "react-dom/client";
import {APIProvider, Map, MapCameraChangedEvent} from '@vis.gl/react-google-maps';

const App = () => (
 <APIProvider apiKey={'Your API key here'} onLoad={() => console.log('Maps API has loaded.')}>
   <Map
      defaultZoom={13}
      defaultCenter={ { lat: -33.860664, lng: 151.208138 } }
      onCameraChanged={ (ev: MapCameraChangedEvent) =>
        console.log('camera changed:', ev.detail.center, 'zoom:', ev.detail.zoom)
      }>
   </Map>
 </APIProvider>
);

const root = createRoot(document.getElementById('app'));
root.render(<App />);

export default App;

5. Dodawanie definiowania stylów map w Google Cloud

Identyfikator mapy jest wymagany do korzystania z zaawansowanych znaczników, których używasz do oznaczania ciekawych miejsc na mapie Sydney. Identyfikator mapy jest też używany w przypadku definiowania stylów map w Google Cloud.

Styl mapy możesz dostosować za pomocą definiowania stylów map w Google Cloud.

Tworzenie identyfikatora mapy

Jeśli nie masz jeszcze identyfikatora mapy powiązanego ze stylem mapy, zapoznaj się z przewodnikiem Identyfikatory mapy i wykonaj te czynności:

  1. Utwórz identyfikator mapy.
  2. powiązać identyfikator mapy ze stylem mapy.

Aby użyć utworzonego identyfikatora mapy, ustaw właściwość mapId komponentu <Map>:

<Map
    defaultZoom={13}
    defaultCenter={ { lat: -33.860664, lng: 151.208138 } }
    mapId='DEMO_MAP_ID'
    onCameraChanged={ (ev: MapCameraChangedEvent) =>
        console.log('camera changed:', ev.detail.center, 'zoom:', ev.detail.zoom)
    }>
</Map>

Na mapie powinien być widoczny wybrany styl.

6. Dodawanie znaczników do mapy

Deweloperzy wykorzystują interfejs Maps JavaScript API na wiele sposobów, ale umieszczanie znaczników na mapie jest zdecydowanie najpopularniejsze. Znaczniki umożliwiają wyświetlanie konkretnych punktów na mapie i są powszechnym elementem interfejsu do obsługi interakcji użytkownika. Jeśli korzystasz z Map Google, prawdopodobnie znasz domyślny znacznik, który wygląda tak:

d9a6513b82a2f1e1.png

Aby użyć komponentu AdvancedMarker do umieszczania znaczników na mapie, wykonaj te czynności:

  1. Utwórz listę obiektów reprezentujących ciekawe miejsca w Sydney i umieść ją bezpośrednio pod importami, poza definicją App:
type Poi ={ key: string, location: google.maps.LatLngLiteral }
const locations: Poi[] = [
  {key: 'operaHouse', location: { lat: -33.8567844, lng: 151.213108  }},
  {key: 'tarongaZoo', location: { lat: -33.8472767, lng: 151.2188164 }},
  {key: 'manlyBeach', location: { lat: -33.8209738, lng: 151.2563253 }},
  {key: 'hyderPark', location: { lat: -33.8690081, lng: 151.2052393 }},
  {key: 'theRocks', location: { lat: -33.8587568, lng: 151.2058246 }},
  {key: 'circularQuay', location: { lat: -33.858761, lng: 151.2055688 }},
  {key: 'harbourBridge', location: { lat: -33.852228, lng: 151.2038374 }},
  {key: 'kingsCross', location: { lat: -33.8737375, lng: 151.222569 }},
  {key: 'botanicGardens', location: { lat: -33.864167, lng: 151.216387 }},
  {key: 'museumOfSydney', location: { lat: -33.8636005, lng: 151.2092542 }},
  {key: 'maritimeMuseum', location: { lat: -33.869395, lng: 151.198648 }},
  {key: 'kingStreetWharf', location: { lat: -33.8665445, lng: 151.1989808 }},
  {key: 'aquarium', location: { lat: -33.869627, lng: 151.202146 }},
  {key: 'darlingHarbour', location: { lat: -33.87488, lng: 151.1987113 }},
  {key: 'barangaroo', location: { lat: - 33.8605523, lng: 151.1972205 }},
];

const App = () => (
  ...
);
  1. Dostosuj pinezki za pomocą elementu <Pin>:
<Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
  1. Utwórz komponent niestandardowy, aby renderować listę za pomocą zaawansowanych znaczników. Umieść go poniżej definicji App:
const App = () => (
  ...
);

const PoiMarkers = (props: {pois: Poi[]}) => {
  return (
    <>
      {props.pois.map( (poi: Poi) => (
        <AdvancedMarker
          key={poi.key}
          position={poi.location}>
        <Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
        </AdvancedMarker>
      ))}
    </>
  );
};
  1. Dodaj komponent PoiMarkers jako element podrzędny komponentu Map:
<Map
  ... map properties ...
>
  <PoiMarkers pois={locations} />
</Map>
  1. Na koniec dodaj do instrukcji importu PinAdvancedMarker.
import {
  APIProvider,
  Map,
  AdvancedMarker,
  MapCameraChangedEvent,
  Pin
} from '@vis.gl/react-google-maps';

Na mapie powinny być widoczne dostosowane zaawansowane znaczniki:

98d12a994e12a2c1.png

7. Włączanie klastrowania znaczników

Jeśli używasz wielu znaczników lub znaczników, które znajdują się blisko siebie, mogą one na siebie nachodzić lub być zbyt blisko siebie, co pogarsza komfort użytkownika. Na przykład po utworzeniu markerów w ostatnim kroku możesz zauważyć, że:

98d12a994e12a2c1.png

W takiej sytuacji przydaje się grupowanie znaczników. Kolejną często wdrażaną funkcją jest grupowanie znaczników, które polega na łączeniu pobliskich znaczników w jedną ikonę zmieniającą się w zależności od poziomu powiększenia, np. tak:

3da24a6b737fe499.png

Algorytm klastrowania znaczników dzieli widoczny obszar mapy na siatkę, a następnie grupuje ikony znajdujące się w tej samej komórce. Na szczęście nie musisz się tym martwić, ponieważ zespół Google Maps Platform stworzył przydatną bibliotekę narzędziową o otwartym kodzie źródłowym o nazwie MarkerClustererPlus, która wykonuje wszystko automatycznie. Źródło biblioteki MarkerClustererPlus możesz wyświetlić na GitHubie.

Aby włączyć grupowanie znaczników, wykonaj te czynności:

  1. U góry pliku app.tsx zaktualizujmy i dodajmy importy bibliotek oraz obsługiwane typy.
import React, {useEffect, useState, useRef, useCallback} from 'react';
import {createRoot} from "react-dom/client";
import {
    APIProvider,
    Map,
    AdvancedMarker,
    MapCameraChangedEvent,
    useMap,
    Pin
  } from '@vis.gl/react-google-maps';
  import {MarkerClusterer} from '@googlemaps/markerclusterer';
  import type {Marker} from '@googlemaps/markerclusterer';

W projekcie szablonu na potrzeby tego laboratorium MarkerClustererPlus jest już uwzględniona w zależnościach zadeklarowanych w pliku package.json, więc została zainstalowana podczas uruchamiania polecenia npm install na początku tego laboratorium.

  1. Utwórz zmienne dla elementu MarkerClusterer i elementów pomocniczych w komponencie PoiMarkers.

Aby zainicjować MarkerClusterer, potrzebujesz instancji mapy. Pobierz instancję z haka useMap():

const map = useMap();
  1. Utwórz listę znaczników przechowywanych w zmiennej stanu:
const [markers, setMarkers] = useState<{[key: string]: Marker}>({});
  1. Zapisz klasteryzator jako odwołanie:
const clusterer = useRef<MarkerClusterer | null>(null);
  1. W komponencie PoiMarkers utwórz też instancję MarkerClusterer i przekaż do niej instancję Map, w której chcesz wyświetlać klastry znaczników:
 useEffect(() => {
    if (!map) return;
    if (!clusterer.current) {
      clusterer.current = new MarkerClusterer({map});
    }
  }, [map]);
  1. Utwórz efekt, który aktualizuje klaster, gdy zmienia się lista znaczników:
useEffect(() => {
    clusterer.current?.clearMarkers();
    clusterer.current?.addMarkers(Object.values(markers));
  }, [markers]);
  1. Utwórz funkcję do tworzenia odwołań do nowych znaczników:
const setMarkerRef = (marker: Marker | null, key: string) => {
    if (marker && markers[key]) return;
    if (!marker && !markers[key]) return;

    setMarkers(prev => {
      if (marker) {
        return {...prev, [key]: marker};
      } else {
        const newMarkers = {...prev};
        delete newMarkers[key];
        return newMarkers;
      }
    });
  };
  1. Użyj tej metody w elemencie AdvancedMarker, aby utworzyć odniesienie do każdego znacznika.
<AdvancedMarker
  key={poi.key}
  position={poi.location}
  ref={marker => setMarkerRef(marker, poi.key)}
  >
    <Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
</AdvancedMarker>

Na mapie powinny pojawić się teraz klastry znaczników:

3da24a6b737fe499.png

Jeśli powiększysz lub pomniejszysz widok, MarkerClustererPlus automatycznie zmieni numerację i rozmiar klastrów. Możesz też kliknąć dowolną ikonę klastra znaczników, aby powiększyć widok i zobaczyć wszystkie znaczniki w tym klastrze.

d5e75480e9abd3c7.png

Podsumowując, w tej sekcji zaimportowaliśmy bibliotekę narzędziową open source MarkerClustererPlus i użyliśmy jej do utworzenia instancji MarkerClusterer, która za pomocą stanu i odwołań Reacta automatycznie zgrupowała znaczniki utworzone w poprzednim kroku.

Komponent PoiMarkers powinien wyglądać tak:

const PoiMarkers = (props: { pois: Poi[] }) => {
  const map = useMap();
  const [markers, setMarkers] = useState<{[key: string]: Marker}>({});
  const clusterer = useRef<MarkerClusterer | null>(null);

  // Initialize MarkerClusterer, if the map has changed
  useEffect(() => {
    if (!map) return;
    if (!clusterer.current) {
      clusterer.current = new MarkerClusterer({map});
    }
  }, [map]);

  // Update markers, if the markers array has changed
  useEffect(() => {
    clusterer.current?.clearMarkers();
    clusterer.current?.addMarkers(Object.values(markers));
  }, [markers]);

  const setMarkerRef = (marker: Marker | null, key: string) => {
    if (marker && markers[key]) return;
    if (!marker && !markers[key]) return;

    setMarkers(prev => {
      if (marker) {
        return {...prev, [key]: marker};
      } else {
        const newMarkers = {...prev};
        delete newMarkers[key];
        return newMarkers;
      }
    });
  };

  return (
    <>
      {props.pois.map( (poi: Poi) => (
        <AdvancedMarker
          key={poi.key}
          position={poi.location}
          ref={marker => setMarkerRef(marker, poi.key)}
          >
            <Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
        </AdvancedMarker>
      ))}
    </>
  );
};

Następnie dowiesz się, jak obsługiwać interakcje użytkownika.

8. Dodawanie interakcji użytkownika

Masz teraz świetnie wyglądającą mapę, która wyświetla niektóre z najpopularniejszych atrakcji turystycznych Sydney. W tej sekcji dodasz dodatkową obsługę interakcji użytkownika z systemem zdarzeń interfejsu Maps JavaScript API, aby jeszcze bardziej poprawić komfort korzystania z mapy.

Interfejs Maps JavaScript API udostępnia kompleksowy system zdarzeń, który wykorzystuje procedury obsługi zdarzeń JavaScript, aby umożliwić obsługę różnych interakcji użytkownika w kodzie. Możesz na przykład utworzyć detektory zdarzeń, które będą wywoływać wykonanie kodu w przypadku interakcji takich jak kliknięcie mapy i znaczników, przesuwanie widoku mapy, powiększanie i pomniejszanie oraz inne.

Aby dodać click do znaczników detektor zdarzeń, a następnie programowo przesunąć mapę tak, aby kliknięty znacznik pojawił się na środku mapy, wykonaj te czynności:

  1. Utwórz wywołanie zwrotne modułu obsługi click.

W komponencie PoiMarkers zdefiniuj procedurę obsługi click za pomocą funkcji useCallback() Reacta.

Zdarzenie click jest wywoływane za każdym razem, gdy użytkownik kliknie lub naciśnie znacznik. Zwraca ono zdarzenie w postaci obiektu JSON z informacjami o klikniętym elemencie interfejsu. Aby poprawić komfort użytkowników, możesz obsługiwać zdarzenie click i używać jego obiektu LatLng do uzyskiwania szerokości i długości geograficznej klikniętego markera.

Gdy uzyskasz szerokość i długość geograficzną, przekaż je do wbudowanej funkcji panTo() instancji Map, aby mapa płynnie przesunęła się i wyśrodkowała kliknięty znacznik. Aby to zrobić, dodaj w funkcji wywołania zwrotnego obsługi zdarzeń ten kod:

const PoiMarkers = (props: { pois: Poi[] }) => {
...
const handleClick = useCallback((ev: google.maps.MapMouseEvent) => {
    if(!map) return;
    if(!ev.latLng) return;
    console.log('marker clicked:', ev.latLng.toString());
    map.panTo(ev.latLng);
  });
...
};
  1. Przypisz do znaczników funkcje obsługi click.

Elementy AdvancedMarker biblioteki vis.gl/react-google-map udostępniają 2 właściwości, które są przydatne do obsługi kliknięć:

  • clickable: jeśli wartość to „true”, element AdvancedMarker będzie klikalny i wywoła zdarzenie gmp-click, a także będzie interaktywny na potrzeby ułatwień dostępu. Na przykład umożliwi nawigację za pomocą klawiszy strzałek.
  • onClick: wywołanie zwrotne, które ma być uruchomione, gdy wystąpi zdarzenie click.
  1. Zaktualizuj renderowanie PoiMarkers, aby przypisać do każdego znacznika moduł obsługi click:
return (
    <>
      {props.pois.map( (poi: Poi) => (
        <AdvancedMarker
          ... other properties ...
          clickable={true}
          onClick={handleClick}
          >
           ...
        </AdvancedMarker>
      ))}
    </>
  );
  1. Otwórz przeglądarkę i kliknij znaczniki. Po kliknięciu znacznika mapa powinna się automatycznie przesunąć, aby ponownie wyśrodkować widok.

Podsumowując, w tej sekcji wykorzystaliśmy system zdarzeń Reacta, aby przypisać do wszystkich znaczników na mapie funkcję obsługi zdarzeń click, pobrać szerokość i długość geograficzną znacznika z wywołanego zdarzenia click i użyć tych danych do ponownego wyśrodkowania mapy po kliknięciu znacznika.

Został już tylko jeden krok. Następnie możesz jeszcze bardziej ulepszyć wygodę użytkowników mapy za pomocą funkcji rysowania interfejsu Maps JavaScript API.

9. Rysuj na mapie

Do tej pory utworzyliśmy mapę Sydney, która wyświetla markery popularnych miejsc turystycznych i obsługuje interakcje użytkownika. W ostatnim kroku tego ćwiczenia (w Codelabs) użyjesz funkcji rysowania interfejsu Maps JavaScript API, aby dodać do mapy przydatną funkcję.

Wyobraź sobie, że z tej mapy będą korzystać użytkownicy, którzy chcą zwiedzić Sydney. Przydatną funkcją byłoby wizualizowanie promienia wokół znacznika po jego kliknięciu. Dzięki temu użytkownik będzie wiedzieć, jakie inne miejsca docelowe znajdują się w odległości, którą można pokonać pieszo od klikniętego znacznika.

Interfejs Maps JavaScript API zawiera zestaw funkcji do rysowania na mapie kształtów, takich jak kwadraty, wielokąty, linie i okręgi. Biblioteka vis.gl/react-google-map udostępnia te funkcje w React.

Następnie wyrenderuj okrąg, aby po kliknięciu markera wyświetlić promień 800 metrów (około pół mili).

Repozytorium początkowe zawiera komponent niestandardowy dla elementu circle. Znajdziesz go w pliku src/components/circle.tsx.

Aby umożliwić użytkownikom rysowanie na mapie:

  1. Zaktualizuj importy, aby uwzględnić podany komponent Circle.
import {Circle} from './components/circle'
  1. Utwórz zmienną stanu dla środka okręgu.

Zapisz stan środka okręgu w komponencie PoiMarkers. Ustawiasz stan początkowy na null i wykorzystujesz fakt, że okrąg nie będzie renderowany, dopóki nie będzie miał prawidłowego położenia środka (i promienia).

const PoiMarkers = (props: { pois: Poi[] }) => {
...
  const [circleCenter, setCircleCenter] = useState(null)
...
};
  1. Aktualizuj środek okręgu po obsłużeniu zdarzenia click.

Wywołaj funkcję setCircleCenter z lokalizacją znalezioną w obiekcie zdarzenia:

const handleClick = useCallback((ev: google.maps.MapMouseEvent) => {
    ...
    setCircleCenter(ev.latLng);
  });

Funkcje rysowania w interfejsie Maps JavaScript API zapewniają wiele opcji wyglądu rysowanego obiektu na mapie. Aby wyrenderować okrąg o określonym promieniu, ustaw właściwości elementu okręgu, takie jak kolor i grubość linii, miejsce, w którym ma być wyśrodkowany, oraz jego promień.

  1. Dodaj okrąg do renderowania i powiąż jego środek ze zmienną stanu. Renderowanie powinno wyglądać tak:
return (
    <>
      <Circle
          radius={800}
          center={circleCenter}
          strokeColor={'#0c4cb3'}
          strokeOpacity={1}
          strokeWeight={3}
          fillColor={'#3b82f6'}
          fillOpacity={0.3}
        />
      {props.pois.map( (poi: Poi) => (
        <AdvancedMarker
          key={poi.key}
          position={poi.location}
          ref={marker => setMarkerRef(marker, poi.key)}
          clickable={true}
          onClick={handleClick}
          >
            <Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
        </AdvancedMarker>
      ))}
    </>
  );
};

Wszystko gotowe Otwórz przeglądarkę i kliknij jeden ze znaczników. Powinien się wokół niego wyświetlić okrąg o określonym promieniu:

d243587f4a9ec4a6.png

10. Gratulacje

Pierwszą aplikację internetową z biblioteką vis.gl/react-google-map do Google Maps Platform, w tym wczytywanie interfejsu Maps JavaScript API, wczytywanie mapy, praca ze znacznikami, sterowanie mapą i rysowanie na niej oraz dodawanie interakcji z użytkownikiem.

Aby wyświetlić gotowy kod, otwórz katalog /solutions.

Więcej informacji