我正在使用
@react-google-maps/api
在我的 React.js 应用程序中使用 google-maps,并且我正在使用它的不同组件。现在,我想使用预定义的多边形在 Google DrawingManager 中绘制多边形。我该怎么办?
import React, { useCallback, useRef, useState } from "react";
import { GoogleMap, useJsApiLoader } from "@react-google-maps/api";
import { DrawingManager } from "@react-google-maps/api";
export const libraries = ["geometry", "places", "drawing"];
function MyComponent({
setPolygons,
plottedPolygons,
operationType,
drawingEnabled,
setDrawingEnabled,
}) {
const { t } = useTranslation();
const mapRef = useRef(null);
const [zoom, setZoom] = useState(6);
const [shape, setShape] = useState(null);
const [center, setCenter] = useState({ lat: 23, lng: 54 });
const { isLoaded } = useJsApiLoader({
id: "script-loader",
googleMapsApiKey: "key",
language: "en",
region: "us",
libraries: libraries,
});
const onPolygonComplete = (polygon) => {
// Handle completed polygon
setDrawingEnabled(false);
const paths = polygon
.getPath()
.getArray()
.map((point) => ({
lat: point.lat(),
lng: point.lng(),
}));
// Make the polygon editable
polygon.setOptions({
draggable: false,
editable: true,
});
// Listen for polygon edits
window.google.maps.event.addListener(polygon.getPath(), "set_at", () => {
handlePolygonEdit(polygon.getPath().getArray());
});
window.google.maps.event.addListener(polygon.getPath(), "insert_at", () => {
handlePolygonEdit(polygon.getPath().getArray());
});
window.google.maps.event.addListener(polygon.getPath(), "remove_at", () => {
handlePolygonEdit(polygon.getPath().getArray());
});
setPolygons(paths);
//center map on polygon
const bounds = new window.google.maps.LatLngBounds();
polygon.getPath().forEach((element) => {
bounds.extend(element);
});
mapRef.current.fitBounds(bounds);
setZoom(mapRef.current.getZoom());
};
const handlePolygonEdit = (updatedPaths) => {
const paths = updatedPaths.map((point) => ({
lat: point.lat(),
lng: point.lng(),
}));
console.log("Updated Polygon Paths:", paths);
setPolygons(paths);
};
const onUnmount = useCallback(() => {
mapRef.current = null;
}, []);
// const handleOnLoad = (map) => (mapRef.current = map);
const handleOnLoad = (map) => {
mapRef.current = map;
// If in "edit" mode and there are plottedPolygons, fit bounds to show the polygon
if (operationType === "edit" && plottedPolygons.length > 0) {
const bounds = new window.google.maps.LatLngBounds();
plottedPolygons.forEach((polygon) => {
polygon.forEach((point) => {
bounds.extend(point);
});
});
mapRef.current.fitBounds(bounds);
}
};
const drawingManagerRef = useRef(null);
return (
<>
{isLoaded ? (
<GoogleMap
key="google-map"
ref={mapRef}
mapContainerClassName="App-map"
zoom={zoom}
version="weekly"
mapContainerStyle={{
width: "100%",
height: "500px",
}}
options={{
gestureHandling: "greedy",
disableDefaultUI: true,
keyboardShortcuts: false,
}}
center={center}
onLoad={handleOnLoad}
onUnmount={onUnmount}
>
<DrawingManager
ref={drawingManagerRef}
onPolygonComplete={onPolygonComplete}
onOverlayComplete={(e) => {
setShape(e.overlay);
}}
options={{
drawingMode:
drawingEnabled && operationType === "add"
? "polygon"
: null,
// drawingMode: drawingEnabled ? "polygon" : null,
drawingControl: drawingEnabled,
drawingControlOptions: {
position:
window.google.maps.ControlPosition.LEFT_CENTER,
drawingModes: ["polygon"],
},
markerOptions: {
draggable: false,
},
polylineOptions: {
editable: true,
draggable: false,
},
rectangleOptions: {
editable: true,
draggable: false,
},
circleOptions: {
editable: true,
draggable: false,
},
polygonOptions: {
editable: operationType === "edit", // Set to true only in edit mode
draggable: false,
fillOpacity: 0.5,
strokeWeight: 2,
strokeColor: "#0000FF",
zIndex: 999,
paths:
plottedPolygons.length > 0
? plottedPolygons[0]
: [],
},
}}
/>
</GoogleMap>
) : (
<div>loading</div>
)}
</>
);
}
export default MyComponent
<Polygon/>
组件代替 <DrawingManager/>
来预加载点官方API文档很清楚
DrawingManager
类的用途,就是,
”提供图形界面供用户绘图 地图上的多边形、矩形、折线、圆形和标记。"
DrawingManager
的目的是让用户“手动”在地图上绘制不同类型的对象。如果您想加载具有现有数据的多边形,而无需用户绘制它们,则 Google Maps API 已经具有 Polygon 对象。
如果您的目标是即使在渲染后也使其可编辑,那么您只需将
editable
的PolylineOptions
属性设置为true
即可。因为这将使用户能够通过拖动顶点和每个线段上显示的控制点来编辑形状。参考:https://developers.google.com/maps/documentation/javascript/reference/polygon#PolylineOptions.editable
在您的情况下,由于您使用的是
react-google-maps/api
库,因此您可以使用 <Polyline/>
组件。该库支持 editable
属性,因此您在实现此功能时不会遇到任何问题。
它应该看起来像这样:
import React from "react";
import { GoogleMap, useJsApiLoader, Polyline } from "@react-google-maps/api";
const containerStyle = {
width: "100%",
height: "100vh",
};
samplePolygon = [
{ lat: -3.746341, lng: -38.561108 },
{ lat: -3.742494, lng: -38.607967 },
{ lat: -3.81688, lng: -38.609995 },
{ lat: -3.815362, lng: -38.493357 },
{ lat: -3.746341, lng: -38.561108 },
];
const center = {
lat: -3.775,
lng: -38.55,
};
const zoom = 12;
function MyComponent() {
const { isLoaded } = useJsApiLoader({
id: "google-map-script",
googleMapsApiKey: "API_KEY_HERE",
});
const [map, setMap] = React.useState(null);
const onLoad = React.useCallback(function callback(map) {
setMap(map);
}, []);
const onUnmount = React.useCallback(function callback(map) {
setMap(null);
}, []);
return isLoaded ? (
<GoogleMap
mapContainerStyle={containerStyle}
center={center}
zoom={zoom}
onLoad={onLoad}
onUnmount={onUnmount}
>
<Polyline
onLoad={() => {
alert("Polyline Loaded");
}}
editable={true}
path={samplePolygon}
/>
<></>
</GoogleMap>
) : (
<></>
);
}
export default React.memo(MyComponent);
这是概念验证代码和框:可编辑多边形
注意:使用您自己的 API 密钥