如何在React Google Map API中加载GeoJSON并检测用户点击区域
实现点击谷歌地图判断是否在GeoJSON区域内并展示详情
要实现点击位置是否在GeoJSON区域内的判断,核心是利用谷歌地图geometry库的containsLocation方法,结合加载的GeoJSON数据进行匹配,具体实现步骤如下:
1. 添加状态存储点击结果
在组件中新增状态,用于保存点击命中的区域详情:
const [clickedArea, setClickedArea] = useState(null);
2. 完善点击事件处理逻辑
修改onClick函数,遍历GeoJSON的所有区域,通过google.maps.geometry.poly.containsLocation判断点击坐标是否落在区域内,匹配成功后保存该区域的详情:
const onClick = (e) => { const clickLatLng = e.latLng; let matchedArea = null; // 遍历所有GeoJSON区域 Areas.features.forEach(feature => { // 处理Polygon类型区域 if (feature.geometry.type === 'Polygon') { const polygonPath = feature.geometry.coordinates[0].map(coord => new google.maps.LatLng(coord[1], coord[0]) ); const polygon = new google.maps.Polygon({ paths: polygonPath }); // 判断点击点是否在多边形内 if (google.maps.geometry.poly.containsLocation(clickLatLng, polygon)) { matchedArea = feature.properties; // 保存区域详情 } } // 处理MultiPolygon类型区域 else if (feature.geometry.type === 'MultiPolygon') { feature.geometry.coordinates.forEach(polygonCoords => { const polygonPath = polygonCoords[0].map(coord => new google.maps.LatLng(coord[1], coord[0]) ); const polygon = new google.maps.Polygon({ paths: polygonPath }); if (google.maps.geometry.poly.containsLocation(clickLatLng, polygon)) { matchedArea = feature.properties; } }); } }); setClickedArea(matchedArea); };
3. 渲染区域详情
在组件中添加展示区域详情的模块,根据clickedArea状态动态渲染内容:
// 放在GoogleMap组件下方 <div className="area-detail"> {clickedArea ? ( <div> <h3>区域详情</h3> {Object.entries(clickedArea).map(([key, value]) => ( <p key={key}><strong>{key}:</strong> {value}</p> ))} </div> ) : ( <p>点击地图上的区域查看详情</p> )} </div>
完整代码
import React, { useState, useCallback } from "react"; import { GoogleMap, LoadScript } from "@react-google-maps/api"; import Areas from "../GEOJSON.json"; const containerStyle = { width: "80%", height: "70vh", }; const GOOGLE_API_KEY = MY_KEY; function MyComponent() { const [map, setMap] = useState(null); const [clickedArea, setClickedArea] = useState(null); const onLoad = useCallback(function callback(map) { setMap(map); map.data.addGeoJson(Areas); }, []); const onUnmount = useCallback(function callback(map) { setMap(null); }, []); const center = { lat: 25.2858687, lng: 55.3281742, }; const onClick = (e) => { const clickLatLng = e.latLng; let matchedArea = null; Areas.features.forEach(feature => { if (feature.geometry.type === 'Polygon') { const polygonPath = feature.geometry.coordinates[0].map(coord => new google.maps.LatLng(coord[1], coord[0]) ); const polygon = new google.maps.Polygon({ paths: polygonPath }); if (google.maps.geometry.poly.containsLocation(clickLatLng, polygon)) { matchedArea = feature.properties; } } else if (feature.geometry.type === 'MultiPolygon') { feature.geometry.coordinates.forEach(polygonCoords => { const polygonPath = polygonCoords[0].map(coord => new google.maps.LatLng(coord[1], coord[0]) ); const polygon = new google.maps.Polygon({ paths: polygonPath }); if (google.maps.geometry.poly.containsLocation(clickLatLng, polygon)) { matchedArea = feature.properties; } }); } }); setClickedArea(matchedArea); }; return ( <React.Fragment> <LoadScript id="script-loader" googleMapsApiKey={GOOGLE_API_KEY} language="en" region="us" libraries={["drawing", "visualization", "geometry", "places"]} > <GoogleMap mapContainerClassName="App-map" zoom={12} version="weekly" mapContainerStyle={containerStyle} center={center} onLoad={onLoad} onUnmount={onUnmount} onClick={onClick} ></GoogleMap> </LoadScript> <div className="area-detail" style={{ marginTop: '20px', padding: '10px', border: '1px solid #ddd' }}> {clickedArea ? ( <div> <h3>区域详情</h3> {Object.entries(clickedArea).map(([key, value]) => ( <p key={key}><strong>{key}:</strong> {value}</p> ))} </div> ) : ( <p>点击地图上的区域查看详情</p> )} </div> </React.Fragment> ); } export default React.memo(MyComponent);
注意事项
- 确保GeoJSON数据的坐标格式为
[lng, lat],谷歌地图需要转换为LatLng(lat, lng),因此遍历坐标时要反转顺序。 - 如果GeoJSON包含其他地理类型(如LineString、Point),可根据需求添加对应的判断逻辑。
- 若区域数量较多,可优化遍历逻辑,比如先通过地图视野筛选区域,提升性能。
内容的提问来源于stack exchange,提问作者Andaman
相关产品推荐
相关产品推荐

