Search code examples
javascriptruby-on-railsgoogle-mapsgoogle-maps-api-3

Edit and save updated polygon coordinates in google maps


In my rails application I have implemented a google maps using the polygon drawing tool. I have been able to add coordinates and save these to my database successfully.

The problem i'm having is when a user wants to edit and save any changes made to the polygon shape. How do i implement this function? My best guess is to use a conditional to see if the database has any saved coordinates, if so, load them in a listener?

HTML

<div style='width: 100%;'>
<%= hidden_field_tag(:map_coords, value = nil, html_options = {id: 'propertyCoordinates'}) %>

Javascript

function initMap() {
  var map = new google.maps.Map(document.getElementById("map"), {
  center: { lat: -40.6892, lng: 74.0445 },
  zoom: 8,
  mapTypeId: google.maps.MapTypeId.HYBRID,
});
        
var polyOptions = {
  strokeWeight: 0,
  fillOpacity: 0.45,
  strokeColor: "#FF0000",
  strokeOpacity: 0.8,
  strokeWeight: 2,
  fillColor: "#FF0000",
  fillOpacity: 0.35
};
// loads databased saved coordinates
var propertyCoords = [<%= @property.coordinates %>];
var points = [];
for (var i = 0; i < propertyCoords.length; i++) {
  points.push({
   lat: propertyCoords[i][0],
   lng: propertyCoords[i][1]
  });
}
                    
var drawingManager = new google.maps.drawing.DrawingManager({
 drawingMode: google.maps.drawing.OverlayType.POLYGON,
 drawingControlOptions: {
  position: google.maps.ControlPosition.TOP_CENTER,
  drawingModes: ["polygon"]
},
 polylineOptions: {
  editable: true,
  draggable: true
 },
 rectangleOptions: polyOptions,
 circleOptions: polyOptions,
 polygonOptions: polyOptions,
 map: map
});
            
if (typeof points !== 'undefined') {
 // My guess is to use a conditional statement to check if the map has any coordinates saved?
 } else {
 google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
  if (e.type !== google.maps.drawing.OverlayType.MARKER) {
  // Switch back to non-drawing mode after drawing a shape.
  drawingManager.setDrawingMode(null);
  // Add an event listener that selects the newly-drawn shape when the user
  // mouses down on it.
  var newShape = e.overlay;
  newShape.type = e.type;
  google.maps.event.addListener(newShape, 'click', function (e) {
   if (e.vertex !== undefined) {
    if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
     var path = newShape.getPaths().getAt(e.path);
      path.removeAt(e.vertex);
      if (path.length < 3) {
       newShape.setMap(null);
      }
     }
    }
  setSelection(newShape);
  });
 }
  var coords = e.overlay.getPath().getArray();
  document.getElementById("propertyCoordinates").value = coords;
  });
 }
} // END function initMap()

Solution

  • If I understand correctly, what you're looking for is the polygon editing functionality. My stackblitz example goes something like this:

    1. Draw a polygon if you already have user-saved coordinates. Then fit the map bounds to the poly's bounds. For this you'll probably need a getBounds polyfill.

    2. Make the polygon editable so you can listen to its points' changes. Check the function enableCoordinatesChangedEvent.

    3. Listen to the changes & extract the new polygon points. Look for function extractPolygonPoints.

    Then proceed with your business logic.

    FYI you'll need to put your own API key at the bottom of the stackblitz index.html. Look for YOUR_KEY.