如何通过传递预定义坐标在 Google DrawingManager 中预加载多边形

问题描述 投票:0回答:1

我正在使用

@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
reactjs google-maps react-google-maps-api
1个回答
0
投票

使用
<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 密钥

© www.soinside.com 2019 - 2024. All rights reserved.