เพิ่มแผนที่ Google ลงในแอป React

1. ก่อนเริ่มต้น

ในโค้ดแล็บนี้ คุณจะได้เรียนรู้ทุกอย่างที่จำเป็นในการเริ่มต้นใช้งานไลบรารี vis.gl/react-google-map สำหรับ Google Maps JavaScript API ซึ่งช่วยให้คุณเพิ่มแผนที่ Google ลงในแอป React ได้ คุณจะได้เรียนรู้วิธีการตั้งค่า โหลด Google Maps JavaScript API แสดงแผนที่แรก ทำงานกับเครื่องหมายและการจัดกลุ่มเครื่องหมาย วาดบนแผนที่ และจัดการการโต้ตอบของผู้ใช้

ข้อกำหนดเบื้องต้น

  • ความรู้พื้นฐานเกี่ยวกับ JavaScript, HTML และ CSS

สิ่งที่คุณจะได้เรียนรู้

  • วิธีเริ่มต้นใช้งานไลบรารี vis.gl/react-google-map สำหรับ Google Maps Platform
  • วิธีโหลด Maps JavaScript API แบบประกาศ
  • วิธีโหลดแผนที่ในแอป React
  • วิธีใช้เครื่องหมาย เครื่องหมายที่กำหนดเอง และการจัดกลุ่มเครื่องหมาย
  • วิธีใช้ระบบเหตุการณ์ของ Maps JavaScript API เพื่อให้ผู้ใช้โต้ตอบได้
  • วิธีควบคุมแผนที่แบบไดนามิก
  • วิธีวาดในแผนที่

สิ่งที่ต้องมี

  • บัญชี Google Cloud ที่เปิดใช้การเรียกเก็บเงิน
  • คีย์ API ของ Google Maps Platform ที่เปิดใช้ Maps JavaScript API
  • Node.js ติดตั้งอยู่ในคอมพิวเตอร์
  • โปรแกรมแก้ไขข้อความหรือ IDE ที่คุณเลือก
  • ไลบรารี vis.gl/react-google-map สำหรับ Google Maps JavaScript API
  • googlemaps/markerclusterer คลัง

ตั้งค่า Google Maps Platform

หากยังไม่มีบัญชี Google Cloud Platform และโปรเจ็กต์ที่เปิดใช้การเรียกเก็บเงิน โปรดดูคู่มือเริ่มต้นใช้งาน Google Maps Platform เพื่อสร้างบัญชีสำหรับการเรียกเก็บเงินและโปรเจ็กต์

  1. ใน Cloud Console ให้คลิกเมนูแบบเลื่อนลงของโปรเจ็กต์ แล้วเลือกโปรเจ็กต์ที่ต้องการใช้สำหรับ Codelab นี้

  1. เปิดใช้ Google Maps Platform APIs และ SDK ที่จำเป็นสำหรับ Codelab นี้ใน Google Cloud Marketplace โดยทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้
  2. สร้างคีย์ API ในหน้าข้อมูลเข้าสู่ระบบของ Cloud Console คุณสามารถทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้ คำขอทั้งหมดไปยัง Google Maps Platform ต้องใช้คีย์ API

2. ตั้งค่า

ดาวน์โหลดโปรเจ็กต์เริ่มต้น

หากต้องการดาวน์โหลดเทมเพลตโปรเจ็กต์เริ่มต้นและโค้ดโซลูชัน ให้ทำตามขั้นตอนต่อไปนี้

  1. ดาวน์โหลดหรือ Fork ที่เก็บ GitHub โปรเจ็กต์เริ่มต้นจะอยู่ในไดเรกทอรี /starter และมีโครงสร้างไฟล์พื้นฐานที่คุณต้องใช้เพื่อทำ Codelab ให้เสร็จสมบูรณ์ คุณทำงานทั้งหมดในไดเรกทอรี /starter/src
git clone https://github.com/googlemaps-samples/codelab-maps-platform-101-react-js.git

หรือคลิกปุ่มนี้เพื่อดาวน์โหลดซอร์สโค้ด

  1. ไปที่ไดเรกทอรี /starter แล้วติดตั้ง npm ซึ่งจะติดตั้งทรัพยากร Dependency ที่จำเป็นทั้งหมดที่ระบุไว้ในไฟล์ package.json
cd starter && npm install
  1. ขณะที่ยังอยู่ในไดเรกทอรี /starter ให้ทำดังนี้
npm start

เราได้ตั้งค่าโปรเจ็กต์เริ่มต้นเพื่อให้คุณใช้เซิร์ฟเวอร์การพัฒนา Vite ซึ่งจะคอมไพล์และเรียกใช้โค้ดที่คุณเขียนในเครื่อง นอกจากนี้ เซิร์ฟเวอร์การพัฒนา Vite ยังโหลดแอปของคุณในเบราว์เซอร์ซ้ำโดยอัตโนมัติทุกครั้งที่คุณทำการเปลี่ยนแปลงโค้ด หากคลิกลิงก์ที่ระบุไว้ในตอนท้ายของกระบวนการสร้าง คุณจะเห็นหน้าเว็บที่มีข้อความ "Hello, world!"

  1. หากต้องการเรียกใช้โค้ดโซลูชันแบบเต็ม ให้ไปที่ไดเรกทอรี /solution แล้วทำตามขั้นตอนการตั้งค่าเดียวกัน

3. โหลด Maps JavaScript API

รากฐานของการใช้ Google Maps Platform สำหรับเว็บคือ Maps JavaScript API API นี้มีอินเทอร์เฟซ JavaScript สำหรับใช้ฟีเจอร์ทั้งหมดของ Google Maps Platform ซึ่งรวมถึงแผนที่ เครื่องหมาย เครื่องมือวาด และบริการอื่นๆ ของ Google Maps Platform เช่น Places

หากต้องการโหลด Maps JavaScript API ด้วยเฟรมเวิร์ก React คุณต้องใช้คอมโพเนนต์ APIProvider ซึ่งเป็นส่วนหนึ่งของไลบรารี vis.gl/react-google-map คุณเพิ่มคอมโพเนนต์นี้ได้ที่ระดับใดก็ได้ของแอป โดยปกติจะอยู่บริเวณด้านบน และจะแสดงคอมโพเนนต์ย่อยทั้งหมดโดยไม่มีการแก้ไข นอกจากจะจัดการการโหลด Maps JavaScript API แล้ว ยังมีข้อมูลบริบทและฟังก์ชันสำหรับคอมโพเนนต์และ Hook อื่นๆ ของไลบรารีนี้ด้วย APIProvider รวมอยู่ในไลบรารี vis.gl/react-google-map จึงมีการติดตั้งเมื่อคุณเรียกใช้ npm install ก่อนหน้านี้

หากต้องการใช้คอมโพเนนต์ APIProvider ให้ทำตามขั้นตอนต่อไปนี้

  1. เปิดไฟล์ /src/app.tsx ไฟล์นี้เป็นที่ที่คุณจะทำงานทั้งหมดสำหรับโค้ดแล็บนี้
  2. ที่ด้านบนของไฟล์ ให้นำเข้าAPIProviderคลาสจากไลบรารี @vis.gl/react-google-maps ดังนี้
import {APIProvider} from '@vis.gl/react-google-maps';
  1. ในAppคำจำกัดความฟังก์ชัน ให้ตั้งค่าพารามิเตอร์ apiKey ของคอมโพเนนต์ APIProvider ด้วยคีย์ API ที่สร้างขึ้นในขั้นตอนก่อนหน้า และตั้งค่าพร็อพเพอร์ตี้ onLoad ด้วยข้อความบันทึกคอนโซล
<APIProvider apiKey={'Your API key here'} onLoad={() => console.log('Maps API has loaded.')}>

คอมโพเนนต์ APIProvider รับชุดพร็อพเพอร์ตี้ที่ระบุตัวเลือกต่างๆ สำหรับการโหลด Maps JavaScript API ซึ่งรวมถึงคีย์ API ของ Google Maps Platform, API เวอร์ชันที่คุณต้องการโหลด และไลบรารีเพิ่มเติมที่ Maps JavaScript API มีให้ซึ่งคุณต้องการโหลด

คีย์ API ของ Google Maps เป็นพร็อพเพอร์ตี้เดียวที่จำเป็นสำหรับให้ APIProvider ทำงานได้ และเราได้รวมพร็อพเพอร์ตี้ onLoad ไว้เพื่อวัตถุประสงค์ในการสาธิต ดูข้อมูลเพิ่มเติมได้ที่<APIProvider> คอมโพเนนต์

ไฟล์ app.tsx ควรมีลักษณะดังนี้

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;

หากทุกอย่างเรียบร้อยดี คุณควรเห็นข้อความ console.log ในคอนโซลของเบราว์เซอร์ เมื่อโหลด Maps JavaScript API แล้ว คุณจะแสดงแผนที่แบบไดนามิกในขั้นตอนถัดไปได้

4. แสดงแผนที่

ได้เวลาแสดงแผนที่แรกแล้ว

ส่วนที่ใช้กันมากที่สุดของ Maps JavaScript API คือ google.maps.Map ซึ่งเป็นคลาสที่ช่วยให้คุณสร้างและจัดการอินสแตนซ์ของแผนที่ได้ ไลบรารี vis.gl/react-google-map จะรวมคลาสนี้ไว้ในคอมโพเนนต์ Map ก่อนอื่น ให้นำเข้าชั้นเรียน Map และ MapCameraChangedEvent

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

Map คอมโพเนนต์รองรับการตั้งค่าที่แตกต่างกันมากมายสำหรับแผนที่ สำหรับโค้ดแล็บนี้ คุณจะใช้การตั้งค่าต่อไปนี้

  • defaultCenter ซึ่งกำหนดละติจูดและลองจิจูดสำหรับศูนย์กลางของแผนที่
  • defaultZoom ซึ่งกำหนดระดับการซูมเริ่มต้นของแผนที่
  • หากต้องการแสดงแผนที่ ให้วางโค้ดต่อไปนี้ภายในแท็ก APIProvider เพื่อจัดกึ่งกลางแผนที่ที่ซิดนีย์ ออสเตรเลีย และกำหนดระดับการซูมเป็น 13 ซึ่งเป็นระดับการซูมที่เหมาะสมในการแสดงใจกลางเมือง
 <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>

ตอนนี้คุณควรเห็นแผนที่ซิดนีย์ในเบราว์เซอร์

761c8c51c6631174.png

สรุปคือ ในส่วนนี้คุณได้แสดงแผนที่ด้วยคอมโพเนนต์ <Map> และตั้งค่าสถานะเริ่มต้นด้วยพร็อพเพอร์ตี้ นอกจากนี้ คุณยังใช้เหตุการณ์เพื่อบันทึกเมื่อกล้องมีการเปลี่ยนแปลงด้วย

ไฟล์ app.tsx ควรมีลักษณะดังนี้

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. เพิ่มการจัดรูปแบบแผนที่ในระบบคลาวด์

คุณต้องมีรหัสแผนที่จึงจะใช้เครื่องหมายขั้นสูงได้ ซึ่งคุณใช้เพื่อทำเครื่องหมายจุดที่น่าสนใจบนแผนที่ซิดนีย์ นอกจากนี้ยังใช้รหัสแผนที่สำหรับการจัดรูปแบบแผนที่ในระบบคลาวด์ด้วย

คุณปรับแต่งสไตล์ของแผนที่ได้โดยใช้การจัดรูปแบบแผนที่ในระบบคลาวด์

สร้างรหัสแผนที่

หากยังไม่ได้สร้างรหัสแมปที่มีรูปแบบแผนที่เชื่อมโยงอยู่ โปรดดูคำแนะนำเกี่ยวกับรหัสแมปเพื่อทำตามขั้นตอนต่อไปนี้

  1. สร้างรหัสแผนที่
  2. เชื่อมโยงรหัสแผนที่กับรูปแบบแผนที่

หากต้องการใช้รหัสแผนที่ที่สร้างขึ้น ให้ตั้งค่าพร็อพเพอร์ตี้ mapId ของคอมโพเนนต์ <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>

คุณควรเห็นสไตล์ที่เลือกบนแผนที่

6. เพิ่มเครื่องหมายลงในแผนที่

นักพัฒนาซอฟต์แวร์ทำสิ่งต่างๆ มากมายด้วย Maps JavaScript API แต่การวางเครื่องหมายบนแผนที่ได้รับความนิยมมากที่สุดอย่างแน่นอน เครื่องหมายช่วยให้คุณแสดงจุดที่เฉพาะเจาะจงบนแผนที่ และเป็นองค์ประกอบ UI ทั่วไปสำหรับการจัดการการโต้ตอบของผู้ใช้ หากเคยใช้ Google Maps มาก่อน คุณอาจคุ้นเคยกับเครื่องหมายเริ่มต้นซึ่งมีลักษณะดังนี้

d9a6513b82a2f1e1.png

หากต้องการใช้คอมโพเนนต์ AdvancedMarker เพื่อวางเครื่องหมายบนแผนที่ ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างรายการออบเจ็กต์เพื่อแสดงจุดที่น่าสนใจในพื้นที่ซิดนีย์ วางรายการไว้ใต้การนำเข้าของคุณทันที นอก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. ปรับแต่งพินด้วยองค์ประกอบ <Pin> ดังนี้
<Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
  1. สร้างคอมโพเนนต์ที่กำหนดเองเพื่อแสดงรายการด้วยเครื่องหมายขั้นสูง โดยวางไว้ใต้คำจำกัดความของ 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. เพิ่มคอมโพเนนต์ PoiMarkers เป็นองค์ประกอบย่อยของคอมโพเนนต์ Map ดังนี้
<Map
  ... map properties ...
>
  <PoiMarkers pois={locations} />
</Map>
  1. สุดท้าย ให้เพิ่ม Pin และ AdvancedMarker ลงในการนำเข้า
import {
  APIProvider,
  Map,
  AdvancedMarker,
  MapCameraChangedEvent,
  Pin
} from '@vis.gl/react-google-maps';

คุณควรเห็นเครื่องหมายขั้นสูงที่ปรับแต่งแล้วบนแผนที่

98d12a994e12a2c1.png

7. เปิดใช้การจัดกลุ่มเครื่องหมาย

เมื่อใช้เครื่องหมายจำนวนมากหรือเครื่องหมายที่อยู่ใกล้กัน คุณอาจพบปัญหาที่เครื่องหมายซ้อนทับกันหรือปรากฏอยู่ใกล้กันมากเกินไป ซึ่งทำให้ผู้ใช้ได้รับประสบการณ์ที่ไม่ดี ตัวอย่างเช่น หลังจากสร้างเครื่องหมายในขั้นตอนสุดท้าย คุณอาจเห็นสิ่งต่อไปนี้

98d12a994e12a2c1.png

การคลัสเตอร์เครื่องหมายจึงเข้ามามีบทบาทในจุดนี้ การจัดกลุ่มเครื่องหมายเป็นอีกฟีเจอร์ที่ใช้กันโดยทั่วไป ซึ่งจะจัดกลุ่มเครื่องหมายที่อยู่ใกล้เคียงกันเป็นไอคอนเดียวที่เปลี่ยนแปลงตามระดับการซูม ดังนี้

3da24a6b737fe499.png

อัลกอริทึมสำหรับการจัดกลุ่มเครื่องหมายจะแบ่งพื้นที่ที่มองเห็นได้ของแผนที่ออกเป็นตารางกริด จากนั้นจะจัดกลุ่มไอคอนที่อยู่ในเซลล์เดียวกัน โชคดีที่คุณไม่ต้องกังวลเรื่องดังกล่าวเนื่องจากทีมแพลตฟอร์ม Google Maps ได้สร้างคลังยูทิลิตีแบบโอเพนซอร์สที่มีประโยชน์ชื่อ MarkerClustererPlus ซึ่งจะจัดการทุกอย่างให้คุณโดยอัตโนมัติ คุณดูแหล่งที่มาของไลบรารี MarkerClustererPlus ได้ใน GitHub

หากต้องการเปิดใช้การจัดกลุ่มเครื่องหมาย ให้ทำตามขั้นตอนต่อไปนี้

  1. ที่ด้านบนของapp.tsx ไฟล์ เรามาอัปเดตและเพิ่มการนำเข้าไลบรารีและประเภทที่รองรับกัน
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';

สำหรับโปรเจ็กต์เทมเพลตของโค้ดแล็บนี้ ไลบรารียูทิลิตี MarkerClustererPlus จะรวมอยู่ในทรัพยากร Dependency ที่ประกาศไว้ในไฟล์ package.json อยู่แล้ว ดังนั้นคุณจึงได้ติดตั้งไลบรารีนี้ไปแล้วเมื่อเรียกใช้ npm install ในช่วงต้นของโค้ดแล็บนี้

  1. สร้างตัวแปรสำหรับ MarkerClusterer และองค์ประกอบที่รองรับในคอมโพเนนต์ PoiMarkers

คุณต้องมีอินสแตนซ์ของแผนที่เพื่อเริ่มต้น MarkerClusterer รับอินสแตนซ์จากฮุก useMap()

const map = useMap();
  1. สร้างรายการเครื่องหมายที่จัดเก็บไว้ในตัวแปรสถานะ
const [markers, setMarkers] = useState<{[key: string]: Marker}>({});
  1. จัดเก็บ Clusterer เป็นการอ้างอิง
const clusterer = useRef<MarkerClusterer | null>(null);
  1. นอกจากนี้ ในคอมโพเนนต์ PoiMarkers ให้สร้างอินสแตนซ์ของ MarkerClusterer และส่งอินสแตนซ์ของ Map ไปยังตำแหน่งที่ต้องการให้แสดงคลัสเตอร์เครื่องหมาย
 useEffect(() => {
    if (!map) return;
    if (!clusterer.current) {
      clusterer.current = new MarkerClusterer({map});
    }
  }, [map]);
  1. สร้างเอฟเฟกต์ที่จะอัปเดต Clusterer เมื่อรายการเครื่องหมายเปลี่ยนแปลง
useEffect(() => {
    clusterer.current?.clearMarkers();
    clusterer.current?.addMarkers(Object.values(markers));
  }, [markers]);
  1. สร้างฟังก์ชันเพื่อสร้างข้อมูลอ้างอิงสำหรับเครื่องหมายใหม่
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. ใช้วิธีนี้ในองค์ประกอบ AdvancedMarker เพื่อสร้างการอ้างอิงสำหรับเครื่องหมายแต่ละรายการ
<AdvancedMarker
  key={poi.key}
  position={poi.location}
  ref={marker => setMarkerRef(marker, poi.key)}
  >
    <Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
</AdvancedMarker>

ตอนนี้คุณควรเห็นคลัสเตอร์เครื่องหมายบนแผนที่แล้ว

3da24a6b737fe499.png

หากคุณซูมเข้าและออก MarkerClustererPlus จะเรียงหมายเลขและปรับขนาดคลัสเตอร์ให้คุณโดยอัตโนมัติ นอกจากนี้ คุณยังคลิกไอคอนคลัสเตอร์เครื่องหมายเพื่อซูมเข้าและดูเครื่องหมายทั้งหมดที่รวมอยู่ในคลัสเตอร์นั้นได้ด้วย

d5e75480e9abd3c7.png

สรุปคือ ในส่วนนี้ คุณได้นำเข้าไลบรารียูทิลิตี MarkerClustererPlus แบบโอเพนซอร์สและใช้เพื่อสร้างอินสแตนซ์ของ MarkerClusterer ซึ่งจะจัดกลุ่มเครื่องหมายที่คุณสร้างในขั้นตอนก่อนหน้าโดยอัตโนมัติด้วยความช่วยเหลือของสถานะและการอ้างอิงของ React

PoiMarkers ควรมีลักษณะดังนี้

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

จากนั้นคุณจะได้เรียนรู้วิธีจัดการการโต้ตอบของผู้ใช้

8. เพิ่มการโต้ตอบของผู้ใช้

ตอนนี้คุณมีแผนที่ที่ดูดีซึ่งแสดงสถานที่ท่องเที่ยวยอดนิยมบางแห่งของซิดนีย์แล้ว ในส่วนนี้ คุณจะเพิ่มการจัดการเพิ่มเติมบางอย่างเกี่ยวกับการโต้ตอบของผู้ใช้กับระบบเหตุการณ์ของ Maps JavaScript API เพื่อปรับปรุงประสบการณ์ของผู้ใช้ในแผนที่ให้ดียิ่งขึ้น

Maps JavaScript API มีระบบเหตุการณ์ที่ครอบคลุมซึ่งใช้ตัวแฮนเดิลเหตุการณ์ JavaScript เพื่อให้คุณจัดการการโต้ตอบของผู้ใช้ต่างๆ ในโค้ดได้ เช่น คุณสามารถสร้างเครื่องมือฟังเหตุการณ์เพื่อทริกเกอร์การเรียกใช้โค้ดสำหรับการโต้ตอบ เช่น ผู้ใช้คลิกแผนที่และเครื่องหมาย การเลื่อนมุมมองของแผนที่ การซูมเข้าและออก และอื่นๆ

หากต้องการเพิ่มclick Listener ลงในเครื่องหมาย แล้วตั้งโปรแกรมให้แผนที่เลื่อนเพื่อให้เครื่องหมายที่คลิกปรากฏตรงกลางแผนที่ ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างแฮนเดิลเลอร์ click Callback

ในPoiMarkersคอมโพเนนต์ ให้กำหนดclickแฮนเดิลเลอร์ด้วย useCallback() ของ React

click จะทริกเกอร์ทุกครั้งที่ผู้ใช้คลิกหรือแตะเครื่องหมาย และแสดงผลเหตุการณ์เป็นออบเจ็กต์ JSON พร้อมข้อมูลเกี่ยวกับองค์ประกอบ UI ที่คลิก หากต้องการปรับปรุงประสบการณ์ของผู้ใช้ในแผนที่ คุณสามารถจัดการเหตุการณ์ click และใช้ออบเจ็กต์ LatLng ของเหตุการณ์เพื่อรับละติจูดและลองจิจูดของเครื่องหมายที่คลิก

เมื่อได้ละติจูดและลองจิจูดแล้ว ให้ส่งค่าดังกล่าวไปยังฟังก์ชัน panTo() ในตัวของMapอินสแตนซ์เพื่อให้แผนที่เลื่อนอย่างราบรื่นเพื่อจัดกึ่งกลางใหม่บนเครื่องหมายที่คลิกโดยเพิ่มข้อมูลต่อไปนี้ในฟังก์ชันเรียกกลับของตัวแฮนเดิลเหตุการณ์

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. กำหนดตัวแฮนเดิล click ให้กับเครื่องหมาย

AdvancedMarker องค์ประกอบของไลบรารี vis.gl/react-google-map จะแสดงพร็อพเพอร์ตี้ 2 รายการที่เป็นประโยชน์ในการจัดการการคลิก

  • clickable: หากเป็นจริง AdvancedMarker จะคลิกได้และทริกเกอร์เหตุการณ์ gmp-click และจะโต้ตอบได้เพื่อวัตถุประสงค์ในการช่วยเหลือพิเศษ เช่น จะอนุญาตการไปยังส่วนต่างๆ ด้วยแป้นพิมพ์โดยใช้ปุ่มลูกศร
  • onClick: ฟังก์ชัน Callback ที่จะเรียกใช้เมื่อเกิดเหตุการณ์ click
  1. อัปเดตการแสดงผล PoiMarkers เพื่อกำหนดตัวแฮนเดิล click ให้กับเครื่องหมายแต่ละรายการ
return (
    <>
      {props.pois.map( (poi: Poi) => (
        <AdvancedMarker
          ... other properties ...
          clickable={true}
          onClick={handleClick}
          >
           ...
        </AdvancedMarker>
      ))}
    </>
  );
  1. ไปที่เบราว์เซอร์แล้วคลิกเครื่องหมาย คุณควรเห็นแผนที่เลื่อนเพื่อจัดกึ่งกลางใหม่โดยอัตโนมัติเมื่อคลิกเครื่องหมาย

สรุปคือ ในส่วนนี้ คุณใช้ระบบเหตุการณ์ของ React เพื่อกําหนดclickแฮนเดิลเลอร์ให้กับเครื่องหมายทั้งหมดในแผนที่ ดึงละติจูดและลองจิจูดของเครื่องหมายจากเหตุการณ์ click ที่ทริกเกอร์ และใช้ข้อมูลดังกล่าวเพื่อจัดกึ่งกลางแผนที่ใหม่ทุกครั้งที่มีการคลิกเครื่องหมาย

เหลืออีกเพียงขั้นตอนเดียวเท่านั้น จากนั้น คุณจะปรับปรุงประสบการณ์ของผู้ใช้ในแผนที่ให้ดียิ่งขึ้นได้ด้วยฟีเจอร์การวาดของ Maps JavaScript API

9. วาดในแผนที่

จนถึงตอนนี้ คุณได้สร้างแผนที่ของซิดนีย์ที่แสดงเครื่องหมายสำหรับจุดหมายปลายทางยอดนิยมของนักท่องเที่ยวและจัดการการโต้ตอบของผู้ใช้ สำหรับขั้นตอนสุดท้ายของ Codelab นี้ คุณจะใช้ฟีเจอร์การวาดของ Maps JavaScript API เพื่อเพิ่มฟีเจอร์ที่มีประโยชน์เพิ่มเติมลงในประสบการณ์การใช้งานแผนที่

สมมติว่าผู้ใช้ที่ต้องการสำรวจเมืองซิดนีย์จะใช้แผนที่นี้ ฟีเจอร์ที่มีประโยชน์คือการแสดงภาพรัศมีรอบเครื่องหมายเมื่อมีการคลิก ซึ่งจะช่วยให้ผู้ใช้ทราบว่ามีจุดหมายปลายทางอื่นๆ ใดบ้างที่อยู่ภายในระยะเดินจากเครื่องหมายที่คลิก

Maps JavaScript API มีชุดฟังก์ชันสำหรับวาดรูปร่างบนแผนที่ เช่น สี่เหลี่ยม รูปหลายเหลี่ยม เส้น และวงกลม ไลบรารี vis.gl/react-google-map ช่วยให้คุณใช้ความสามารถเหล่านี้ใน React ได้

จากนั้นแสดงวงกลมเพื่อแสดงรัศมี 800 เมตร (ประมาณครึ่งไมล์) รอบเครื่องหมายเมื่อมีการคลิก

ที่เก็บเริ่มต้นมีคอมโพเนนต์ที่กำหนดเองสำหรับองค์ประกอบ circle คุณดูได้ในไฟล์ src/components/circle.tsx

หากต้องการอนุญาตให้ผู้ใช้วาดบนแผนที่ ให้ทำตามขั้นตอนต่อไปนี้

  1. อัปเดตการนำเข้าให้รวมคอมโพเนนต์วงกลมที่ระบุ
import {Circle} from './components/circle'
  1. สร้างตัวแปรสถานะสำหรับจุดศูนย์กลางของวงกลม

บันทึกสถานะของจุดศูนย์กลางของวงกลมในPoiMarkersคอมโพเนนต์ คุณตั้งค่าสถานะเริ่มต้นเป็น null และพิจารณาว่าวงกลมจะไม่แสดงผลเว้นแต่จะมีตำแหน่งกึ่งกลาง (และรัศมี) ที่ถูกต้อง

const PoiMarkers = (props: { pois: Poi[] }) => {
...
  const [circleCenter, setCircleCenter] = useState(null)
...
};
  1. อัปเดตจุดศูนย์กลางของวงกลมเมื่อมีการจัดการclickเหตุการณ์

เรียกใช้ setCircleCenter โดยใช้ตำแหน่งที่พบในออบเจ็กต์เหตุการณ์

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

ฟังก์ชันการวาดใน Maps JavaScript API มีตัวเลือกมากมายเกี่ยวกับลักษณะของออบเจ็กต์ที่วาดบนแผนที่ หากต้องการแสดงรัศมีวงกลม ให้ตั้งค่าพร็อพเพอร์ตี้ขององค์ประกอบวงกลม เช่น สีและความหนาของเส้นขีด โดยที่วงกลมควรอยู่ตรงกลางและมีรัศมี

  1. เพิ่มวงกลมในการแสดงผลและเชื่อมโยงกึ่งกลางกับตัวแปรสถานะ การแสดงผลควรมีลักษณะดังนี้
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>
      ))}
    </>
  );
};

เสร็จเรียบร้อย ไปที่เบราว์เซอร์แล้วคลิกเครื่องหมายใดเครื่องหมายหนึ่ง คุณควรเห็นรัศมีวงกลมแสดงรอบๆ ดังนี้

d243587f4a9ec4a6.png

10. ขอแสดงความยินดี

คุณได้สร้างเว็บแอปแรกด้วยไลบรารี vis.gl/react-google-map สำหรับ Google Maps Platform ซึ่งรวมถึงการโหลด Maps JavaScript API, การโหลดแผนที่, การทำงานกับเครื่องหมาย, การควบคุมและการวาดบนแผนที่ และการเพิ่มการโต้ตอบของผู้ใช้

หากต้องการดูโค้ดที่เสร็จสมบูรณ์แล้ว ให้ไปที่ไดเรกทอรี /solutions

ดูข้อมูลเพิ่มเติม