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 เพื่อสร้างบัญชีสำหรับการเรียกเก็บเงินและโปรเจ็กต์
- ใน Cloud Console ให้คลิกเมนูแบบเลื่อนลงของโปรเจ็กต์ แล้วเลือกโปรเจ็กต์ที่ต้องการใช้สำหรับ Codelab นี้
- เปิดใช้ Google Maps Platform APIs และ SDK ที่จำเป็นสำหรับ Codelab นี้ใน Google Cloud Marketplace โดยทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้
- สร้างคีย์ API ในหน้าข้อมูลเข้าสู่ระบบของ Cloud Console คุณสามารถทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้ คำขอทั้งหมดไปยัง Google Maps Platform ต้องใช้คีย์ API
2. ตั้งค่า
ดาวน์โหลดโปรเจ็กต์เริ่มต้น
หากต้องการดาวน์โหลดเทมเพลตโปรเจ็กต์เริ่มต้นและโค้ดโซลูชัน ให้ทำตามขั้นตอนต่อไปนี้
- ดาวน์โหลดหรือ Fork ที่เก็บ GitHub โปรเจ็กต์เริ่มต้นจะอยู่ในไดเรกทอรี
/starter
และมีโครงสร้างไฟล์พื้นฐานที่คุณต้องใช้เพื่อทำ Codelab ให้เสร็จสมบูรณ์ คุณทำงานทั้งหมดในไดเรกทอรี/starter/src
git clone https://github.com/googlemaps-samples/codelab-maps-platform-101-react-js.git
หรือคลิกปุ่มนี้เพื่อดาวน์โหลดซอร์สโค้ด
- ไปที่ไดเรกทอรี
/starter
แล้วติดตั้ง npm ซึ่งจะติดตั้งทรัพยากร Dependency ที่จำเป็นทั้งหมดที่ระบุไว้ในไฟล์package.json
cd starter && npm install
- ขณะที่ยังอยู่ในไดเรกทอรี
/starter
ให้ทำดังนี้
npm start
เราได้ตั้งค่าโปรเจ็กต์เริ่มต้นเพื่อให้คุณใช้เซิร์ฟเวอร์การพัฒนา Vite ซึ่งจะคอมไพล์และเรียกใช้โค้ดที่คุณเขียนในเครื่อง นอกจากนี้ เซิร์ฟเวอร์การพัฒนา Vite ยังโหลดแอปของคุณในเบราว์เซอร์ซ้ำโดยอัตโนมัติทุกครั้งที่คุณทำการเปลี่ยนแปลงโค้ด หากคลิกลิงก์ที่ระบุไว้ในตอนท้ายของกระบวนการสร้าง คุณจะเห็นหน้าเว็บที่มีข้อความ "Hello, world!"
- หากต้องการเรียกใช้โค้ดโซลูชันแบบเต็ม ให้ไปที่ไดเรกทอรี
/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
ให้ทำตามขั้นตอนต่อไปนี้
- เปิดไฟล์
/src/app.tsx
ไฟล์นี้เป็นที่ที่คุณจะทำงานทั้งหมดสำหรับโค้ดแล็บนี้ - ที่ด้านบนของไฟล์ ให้นำเข้า
APIProvider
คลาสจากไลบรารี@
vis.gl/react-google-maps
ดังนี้
import {APIProvider} from '@vis.gl/react-google-maps';
- ใน
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>
ตอนนี้คุณควรเห็นแผนที่ซิดนีย์ในเบราว์เซอร์
สรุปคือ ในส่วนนี้คุณได้แสดงแผนที่ด้วยคอมโพเนนต์ <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. เพิ่มการจัดรูปแบบแผนที่ในระบบคลาวด์
คุณต้องมีรหัสแผนที่จึงจะใช้เครื่องหมายขั้นสูงได้ ซึ่งคุณใช้เพื่อทำเครื่องหมายจุดที่น่าสนใจบนแผนที่ซิดนีย์ นอกจากนี้ยังใช้รหัสแผนที่สำหรับการจัดรูปแบบแผนที่ในระบบคลาวด์ด้วย
คุณปรับแต่งสไตล์ของแผนที่ได้โดยใช้การจัดรูปแบบแผนที่ในระบบคลาวด์
สร้างรหัสแผนที่
หากยังไม่ได้สร้างรหัสแมปที่มีรูปแบบแผนที่เชื่อมโยงอยู่ โปรดดูคำแนะนำเกี่ยวกับรหัสแมปเพื่อทำตามขั้นตอนต่อไปนี้
- สร้างรหัสแผนที่
- เชื่อมโยงรหัสแผนที่กับรูปแบบแผนที่
หากต้องการใช้รหัสแผนที่ที่สร้างขึ้น ให้ตั้งค่าพร็อพเพอร์ตี้ 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 มาก่อน คุณอาจคุ้นเคยกับเครื่องหมายเริ่มต้นซึ่งมีลักษณะดังนี้
หากต้องการใช้คอมโพเนนต์ AdvancedMarker
เพื่อวางเครื่องหมายบนแผนที่ ให้ทำตามขั้นตอนต่อไปนี้
- สร้างรายการออบเจ็กต์เพื่อแสดงจุดที่น่าสนใจในพื้นที่ซิดนีย์ วางรายการไว้ใต้การนำเข้าของคุณทันที นอก
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 = () => (
...
);
- ปรับแต่งพินด้วยองค์ประกอบ
<Pin>
ดังนี้
<Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
- สร้างคอมโพเนนต์ที่กำหนดเองเพื่อแสดงรายการด้วยเครื่องหมายขั้นสูง โดยวางไว้ใต้คำจำกัดความของ
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>
))}
</>
);
};
- เพิ่มคอมโพเนนต์
PoiMarkers
เป็นองค์ประกอบย่อยของคอมโพเนนต์Map
ดังนี้
<Map
... map properties ...
>
<PoiMarkers pois={locations} />
</Map>
- สุดท้าย ให้เพิ่ม
Pin
และAdvancedMarker
ลงในการนำเข้า
import {
APIProvider,
Map,
AdvancedMarker,
MapCameraChangedEvent,
Pin
} from '@vis.gl/react-google-maps';
คุณควรเห็นเครื่องหมายขั้นสูงที่ปรับแต่งแล้วบนแผนที่
7. เปิดใช้การจัดกลุ่มเครื่องหมาย
เมื่อใช้เครื่องหมายจำนวนมากหรือเครื่องหมายที่อยู่ใกล้กัน คุณอาจพบปัญหาที่เครื่องหมายซ้อนทับกันหรือปรากฏอยู่ใกล้กันมากเกินไป ซึ่งทำให้ผู้ใช้ได้รับประสบการณ์ที่ไม่ดี ตัวอย่างเช่น หลังจากสร้างเครื่องหมายในขั้นตอนสุดท้าย คุณอาจเห็นสิ่งต่อไปนี้
การคลัสเตอร์เครื่องหมายจึงเข้ามามีบทบาทในจุดนี้ การจัดกลุ่มเครื่องหมายเป็นอีกฟีเจอร์ที่ใช้กันโดยทั่วไป ซึ่งจะจัดกลุ่มเครื่องหมายที่อยู่ใกล้เคียงกันเป็นไอคอนเดียวที่เปลี่ยนแปลงตามระดับการซูม ดังนี้
อัลกอริทึมสำหรับการจัดกลุ่มเครื่องหมายจะแบ่งพื้นที่ที่มองเห็นได้ของแผนที่ออกเป็นตารางกริด จากนั้นจะจัดกลุ่มไอคอนที่อยู่ในเซลล์เดียวกัน โชคดีที่คุณไม่ต้องกังวลเรื่องดังกล่าวเนื่องจากทีมแพลตฟอร์ม Google Maps ได้สร้างคลังยูทิลิตีแบบโอเพนซอร์สที่มีประโยชน์ชื่อ MarkerClustererPlus
ซึ่งจะจัดการทุกอย่างให้คุณโดยอัตโนมัติ คุณดูแหล่งที่มาของไลบรารี MarkerClustererPlus
ได้ใน GitHub
หากต้องการเปิดใช้การจัดกลุ่มเครื่องหมาย ให้ทำตามขั้นตอนต่อไปนี้
- ที่ด้านบนของ
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
ในช่วงต้นของโค้ดแล็บนี้
- สร้างตัวแปรสำหรับ
MarkerClusterer
และองค์ประกอบที่รองรับในคอมโพเนนต์PoiMarkers
คุณต้องมีอินสแตนซ์ของแผนที่เพื่อเริ่มต้น MarkerClusterer
รับอินสแตนซ์จากฮุก useMap()
const map = useMap();
- สร้างรายการเครื่องหมายที่จัดเก็บไว้ในตัวแปรสถานะ
const [markers, setMarkers] = useState<{[key: string]: Marker}>({});
- จัดเก็บ Clusterer เป็นการอ้างอิง
const clusterer = useRef<MarkerClusterer | null>(null);
- นอกจากนี้ ในคอมโพเนนต์
PoiMarkers
ให้สร้างอินสแตนซ์ของMarkerClusterer
และส่งอินสแตนซ์ของMap
ไปยังตำแหน่งที่ต้องการให้แสดงคลัสเตอร์เครื่องหมาย
useEffect(() => {
if (!map) return;
if (!clusterer.current) {
clusterer.current = new MarkerClusterer({map});
}
}, [map]);
- สร้างเอฟเฟกต์ที่จะอัปเดต Clusterer เมื่อรายการเครื่องหมายเปลี่ยนแปลง
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;
}
});
};
- ใช้วิธีนี้ในองค์ประกอบ
AdvancedMarker
เพื่อสร้างการอ้างอิงสำหรับเครื่องหมายแต่ละรายการ
<AdvancedMarker
key={poi.key}
position={poi.location}
ref={marker => setMarkerRef(marker, poi.key)}
>
<Pin background={'#FBBC04'} glyphColor={'#000'} borderColor={'#000'} />
</AdvancedMarker>
ตอนนี้คุณควรเห็นคลัสเตอร์เครื่องหมายบนแผนที่แล้ว
หากคุณซูมเข้าและออก MarkerClustererPlus
จะเรียงหมายเลขและปรับขนาดคลัสเตอร์ให้คุณโดยอัตโนมัติ นอกจากนี้ คุณยังคลิกไอคอนคลัสเตอร์เครื่องหมายเพื่อซูมเข้าและดูเครื่องหมายทั้งหมดที่รวมอยู่ในคลัสเตอร์นั้นได้ด้วย
สรุปคือ ในส่วนนี้ คุณได้นำเข้าไลบรารียูทิลิตี 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 ลงในเครื่องหมาย แล้วตั้งโปรแกรมให้แผนที่เลื่อนเพื่อให้เครื่องหมายที่คลิกปรากฏตรงกลางแผนที่ ให้ทำตามขั้นตอนต่อไปนี้
- สร้างแฮนเดิลเลอร์
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);
});
...
};
- กำหนดตัวแฮนเดิล
click
ให้กับเครื่องหมาย
AdvancedMarker
องค์ประกอบของไลบรารี vis.gl/react-google-map
จะแสดงพร็อพเพอร์ตี้ 2 รายการที่เป็นประโยชน์ในการจัดการการคลิก
clickable
: หากเป็นจริงAdvancedMarker
จะคลิกได้และทริกเกอร์เหตุการณ์gmp-click
และจะโต้ตอบได้เพื่อวัตถุประสงค์ในการช่วยเหลือพิเศษ เช่น จะอนุญาตการไปยังส่วนต่างๆ ด้วยแป้นพิมพ์โดยใช้ปุ่มลูกศรonClick
: ฟังก์ชัน Callback ที่จะเรียกใช้เมื่อเกิดเหตุการณ์click
- อัปเดตการแสดงผล
PoiMarkers
เพื่อกำหนดตัวแฮนเดิลclick
ให้กับเครื่องหมายแต่ละรายการ
return (
<>
{props.pois.map( (poi: Poi) => (
<AdvancedMarker
... other properties ...
clickable={true}
onClick={handleClick}
>
...
</AdvancedMarker>
))}
</>
);
- ไปที่เบราว์เซอร์แล้วคลิกเครื่องหมาย คุณควรเห็นแผนที่เลื่อนเพื่อจัดกึ่งกลางใหม่โดยอัตโนมัติเมื่อคลิกเครื่องหมาย
สรุปคือ ในส่วนนี้ คุณใช้ระบบเหตุการณ์ของ 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
หากต้องการอนุญาตให้ผู้ใช้วาดบนแผนที่ ให้ทำตามขั้นตอนต่อไปนี้
- อัปเดตการนำเข้าให้รวมคอมโพเนนต์วงกลมที่ระบุ
import {Circle} from './components/circle'
- สร้างตัวแปรสถานะสำหรับจุดศูนย์กลางของวงกลม
บันทึกสถานะของจุดศูนย์กลางของวงกลมในPoiMarkers
คอมโพเนนต์ คุณตั้งค่าสถานะเริ่มต้นเป็น null และพิจารณาว่าวงกลมจะไม่แสดงผลเว้นแต่จะมีตำแหน่งกึ่งกลาง (และรัศมี) ที่ถูกต้อง
const PoiMarkers = (props: { pois: Poi[] }) => {
...
const [circleCenter, setCircleCenter] = useState(null)
...
};
- อัปเดตจุดศูนย์กลางของวงกลมเมื่อมีการจัดการ
click
เหตุการณ์
เรียกใช้ setCircleCenter
โดยใช้ตำแหน่งที่พบในออบเจ็กต์เหตุการณ์
const handleClick = useCallback((ev: google.maps.MapMouseEvent) => {
...
setCircleCenter(ev.latLng);
});
ฟังก์ชันการวาดใน Maps JavaScript API มีตัวเลือกมากมายเกี่ยวกับลักษณะของออบเจ็กต์ที่วาดบนแผนที่ หากต้องการแสดงรัศมีวงกลม ให้ตั้งค่าพร็อพเพอร์ตี้ขององค์ประกอบวงกลม เช่น สีและความหนาของเส้นขีด โดยที่วงกลมควรอยู่ตรงกลางและมีรัศมี
- เพิ่มวงกลมในการแสดงผลและเชื่อมโยงกึ่งกลางกับตัวแปรสถานะ การแสดงผลควรมีลักษณะดังนี้
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>
))}
</>
);
};
เสร็จเรียบร้อย ไปที่เบราว์เซอร์แล้วคลิกเครื่องหมายใดเครื่องหมายหนึ่ง คุณควรเห็นรัศมีวงกลมแสดงรอบๆ ดังนี้
10. ขอแสดงความยินดี
คุณได้สร้างเว็บแอปแรกด้วยไลบรารี vis.gl/react-google-map
สำหรับ Google Maps Platform ซึ่งรวมถึงการโหลด Maps JavaScript API, การโหลดแผนที่, การทำงานกับเครื่องหมาย, การควบคุมและการวาดบนแผนที่ และการเพิ่มการโต้ตอบของผู้ใช้
หากต้องการดูโค้ดที่เสร็จสมบูรณ์แล้ว ให้ไปที่ไดเรกทอรี /solutions