0

In that, I add polygon using drawing manager after that I want to edit that polygon. When I use the below code, getting the function not found error and getPath function is not working when I use that getting errors. I want to add a city with location but in that code it not working. When I use the getPath function and editable function it getting errors.

import { compose, withProps } from "recompose";
import {
  withGoogleMap,
  GoogleMap,
  withScriptjs,
  Polygon,
} from "react-google-maps";
const {
  DrawingManager,
} = require("react-google-maps/lib/components/drawing/DrawingManager");

var polygon = [];
const onAdd = (data) => {
  const path = data.getPath();
  var coordinates = [];
  for (var i = 0; i < path.length; i++) {
    var pathArray = [path.getAt(i).lat(), path.getAt(i).lng()];
    coordinates.push(pathArray);
  }
  polygon = JSON.stringify(coordinates, null, 6);
};

const onEdit = (data) => {
  var pathArray = [data.latLng.lat(), data.latLng.lng()];
  console.log("edit path", pathArray);
  console.log("poly", polygonPath);
  polygonPath.push(pathArray);
};
const onDragEnd = (data) => {
  const path = data.getPath();
  var coordinates = [];
  for (var i = 0; i < path.length; i++) {
    var pathArray = [path.getAt(i).lat(), path.getAt(i).lng()];
    coordinates.push(pathArray);
  }
  console.log("polygon", JSON.stringify(coordinates, null, 6));
};
let polygonPath = [];
const MyMapComponent = compose(
  withProps({
    googleMapURL:
      "https://maps.googleapis.com/maps/api/js?key=" +
      global.config.googleApiKey +
      "&v=3.exp&libraries=geometry,drawing,places",
    loadingElement: <div style={{ height: `100%` }} />,
    containerElement: <div style={{ height: `500px` }} />,
    mapElement: <div style={{ height: `100%` }} />,
  }),
  withScriptjs,
  withGoogleMap
)((props) => {
  let addPolygonPath = [];
  if (props.isEdit) {
    polygonPath = props.isEdit.geometry.coordinates[0];

    addPolygonPath = props.isEdit.geometry.coordinates[0].map(
      (coordinateItem) => {
        return { lat: coordinateItem[0], lng: coordinateItem[1] };
      }
    );
  }

  return (
    <GoogleMap defaultZoom={12} center={props.mapCenter}>
      {props.isEdit ? (
        <Polygon
          editable={true}
          draggable={true}
          paths={addPolygonPath}
          options={{
            strokeWeight: 2,
            fillColor: "#000",
            fillOpacity: 0.4,
            zIndex: 1,
          }}
          onMouseUp={onEdit}
          onDragEnd={onDragEnd}
        />
      ) : (
        <DrawingManager
          defaultOptions={{
            drawingControl: true,
            drawingControlOptions: {
              drawingModes: ["polygon"],
            },

            polygonOptions: {
              strokeWeight: 2,
              fillColor: "#000",
              fillOpacity: 0.4,
              clickable: true,
              editable: true,
              zIndex: 1,
            },
          }}
          onPolygonComplete={onAdd}
        />
      )}
    </GoogleMap>
  );
});

1 Answer 1

3

You can use the onLoad prop on your Polygon component to get a reference to the polygon object. Then save that reference in your state.

You can now use it to update your Polygon after each edit.

Like this:

export default function Map () {
  const [polygon, setPolygon] = React.useState(null);
  const [polygonRef, setPolygonRef] = React.useState(null);

  // Util to create a polygon with options
  function createPolygon (path) {
    const polygon = new window.google.maps.Polygon({
      path: path,
      fillColor: "#D43AAC",
      strokeColor: "#EB807E",
      fillOpacity: 0.2,
      strokeWeight: 5,
      editable: true,
      clickable: true,
    });

    return polygon;
  };

  // When first drawing is complete and edit has been made, this function is run
  const onPolygonComplete = (polygon, destroy=false) => {
    setPolygon(createPolygon(polygon.getPath()));

    // Destroys the polygon that has been drawn by the manager.
    if(destroy) {
      polygon.setMap(null);
    }
  };

  // Set the ref
  const onPolygonLoad = (polygon) => setPolygonRef(polygon);

  // Update the polygon
  const onPolygonMouseUp = () => onPolygonComplete(polygonRef);

  const polygonProps = polygon
    ? {
        path: polygon.latLngs.i[0].i,
        editable: polygon.editable,
        clickable: polygon.clickable,
        options: {
          fillOpacity: polygon.fillOpacity,
          strokeWeight: polygon.strokeWeight,
        },
      }
    : null;

  return (
    <GoogleMap>
      {/* Map components */}
      {polygon ? (
        <Polygon
          {...polygonProps}
          onLoad={onPolygonLoad}
          onMouseUp={onPolygonMouseUp}
        />
      ) : (
        <DrawingManager
          drawingMode={"polygon"}
          onPolygonComplete={(polygon) => onPolygonComplete(polygon, true)}
        />
      )}
    </GoogleMap>
  );
};

Hope this helps. :)

Sign up to request clarification or add additional context in comments.

1 Comment

I found your answer useful as I'm having a similar issue. Though i'm getting "TypeError: polygon.latLngs.i is undefined" from your posted solution. Any ideas on why my returned object is different than what you are getting? I'm not seeing i but fb in the nested object latLngs. thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.