Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pre-loading an editable drawingmanager polygon in Google Maps

I'm writing an application that will allow users to draw geographical polygon "zones" using the Google Maps API and save them in a database. There can only be one zone per user so I'm limiting this by switching to the hand and hiding drawing tools on overlaycomplete. After overlaycomplete, I am able to hit save and it saves in my database just fine - so this bit works. Further, I am able to retrieve the polygon from the database and display it as an editable polygon on the map. The issues I am having though are:

  1. When trying to drag the points of the inserted polygon, they get "stuck" to the mouse and never release. My guess is some sort of mouseup issue?

  2. Despite a polygon already existing, I'm still able to draw another one. Should I just hide the drawing tools in the beginning if a polygon is being loaded from the db?

  3. How do I attach an event to the polygon being pulled from the database so I can capture its vertices coordinates?

You can see my current code here: http://jsfiddle.net/FUUxz/ or below:

JS:

            var map; // Global declaration of the map
            var iw = new google.maps.InfoWindow(); // Global declaration of the infowindow
            var lat_longs = new Array();
            var markers = new Array();
            var drawingManager;
            function initialize() {

                 var myLatlng = new google.maps.LatLng(40.9403762, -74.1318096);
                var myOptions = {
                    zoom: 13,
                    center: myLatlng,
                    mapTypeId: google.maps.MapTypeId.ROADMAP}
                map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
                drawingManager = new google.maps.drawing.DrawingManager({
                drawingMode: google.maps.drawing.OverlayType.POLYGON,
                drawingControl: true,
                drawingControlOptions: {
                    position: google.maps.ControlPosition.TOP_CENTER,
                    drawingModes: [google.maps.drawing.OverlayType.POLYGON]
                },
                        polygonOptions: {editable:true,fillColor:'#ff0000',strokeColor:'#ff0000',strokeWeight:2}
            });
            drawingManager.setMap(map);

            google.maps.event.addListener(drawingManager, "overlaycomplete", function(event) {
                var newShape = event.overlay;
                newShape.type = event.type;
                if (event.type==google.maps.drawing.OverlayType.POLYGON) {
                        overlayClickListener(event.overlay);$('#polygon').val(event.overlay.getPath().getArray());drawingManager.setOptions({drawingMode:null,drawingControl:false});
                    }

            });
                var polygon_plan_0 = [
                    new google.maps.LatLng(40.9534555976547, -74.0871620178223)
                    ,
                    new google.maps.LatLng(40.9410084152192, -74.0948867797852)
                    ,
                    new google.maps.LatLng(40.9411380854622, -74.1165161132812)
                    ,
                    new google.maps.LatLng(40.9490474888751, -74.1221809387207)
                    ,
                    new google.maps.LatLng(40.955140973234, -74.124584197998)
                    ,
                    new google.maps.LatLng(40.9604561066844, -74.1153144836426)
                    ,
                    new google.maps.LatLng(40.9534555976547, -74.0871620178223)
                    ];
                    lat_longs.push(new google.maps.LatLng(40.9534555976547, -74.0871620178223));

                    lat_longs.push(new google.maps.LatLng(40.9410084152192, -74.0948867797852));

                    lat_longs.push(new google.maps.LatLng(40.9411380854622, -74.1165161132812));

                    lat_longs.push(new google.maps.LatLng(40.9490474888751, -74.1221809387207));

                    lat_longs.push(new google.maps.LatLng(40.955140973234, -74.124584197998));

                    lat_longs.push(new google.maps.LatLng(40.9604561066844, -74.1153144836426));

                    lat_longs.push(new google.maps.LatLng(40.9534555976547, -74.0871620178223));

            var polygon_0 = new google.maps.Polygon({
                path: polygon_plan_0,

                strokeColor: "#ff0000",
                strokeOpacity: 0.8,
                strokeWeight: 2,
                fillColor: "#ff0000",
                fillOpacity: 0.3,
                editable: true
            });

            polygon_0.setMap(map);


            google.maps.event.addListener(polygon_0, "mouseup", function(event) {
                overlayClickListener(event.overlay);$('#polygon').val(event.overlay.getPath().getArray());drawingManager.setOptions({drawingMode:null,drawingControl:false});
            });


            }


        function createMarker(markerOptions) {
            var marker = new google.maps.Marker(markerOptions);
            markers.push(marker);
            lat_longs.push(marker.getPosition());
            return marker;
        }

initialize();

function overlayClickListener(overlay) {
    google.maps.event.addListener(overlay, "mouseup", function(event){
        $('#polygon').val(overlay.getPath().getArray());
    });
}

HTML:

<div id="map_canvas" style="width:100%; height:450px;"></div>
<form action="http://garbagedayreminder.com/test/save" method="post" accept-charset="utf-8" id="map_form">
<input type="text" name="polygon" value="" id="polygon"  />
<input type="submit" name="save" value="Save!" id="save"  />
</form>
like image 749
Yev Avatar asked Mar 19 '13 16:03

Yev


People also ask

How do you delete a polygon in Google Maps?

To remove a polygon from the map, call the setMap() method passing null as the argument. In the following example, bermudaTriangle is a polygon object: bermudaTriangle. setMap(null);


1 Answers

I know this is a little older but I have been working on a similar scenario. Loading polygons from a database, allowing them to be editable, and allowing other polygons to be added to the map. There's probably better ways to do this but this is functional and hopefully gets someone else on the right track.

      var areas = ( <?php echo json_encode($areas);?> );
  var coords = ( <?php echo json_encode($coords);?> );

  var drawingManager;
  var selectedShape;
  var colors = ['#1E90FF', '#FF1493', '#32CD32', '#FF8C00', '#4B0082'];
  var selectedColor;
  var colorButtons = {};

  // Saving vars
  var selectedShape;
  var contentString;
  var polygons = [];
  var newPolys = [];

  function clearSelection() {
    if (selectedShape) {
      selectedShape.setEditable(false);
      selectedShape = null;
    }
  }

  function setSelection(shape) {
    clearSelection();
    selectedShape = shape;
    shape.setEditable(true);
    selectColor(shape.get('fillColor') || shape.get('strokeColor'));
  }

  function deleteSelectedShape(e) {
    if (selectedShape) {
      selectedShape.setMap(null);
      for (i=0; i < polygons.length; i++) {   // Clear out the polygons entry
        if (selectedShape.getPath == polygons[i].getPath) {
            polygons.splice(i, 1);
        }
      }
    }
  }

  function selectColor(color) {
    selectedColor = color;
    for (var i = 0; i < colors.length; ++i) {
      var currColor = colors[i];
      colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
    }

    // Retrieves the current options from the drawing manager and replaces the
    // stroke or fill color as appropriate.
    var polylineOptions = drawingManager.get('polylineOptions');
    polylineOptions.strokeColor = color;
    drawingManager.set('polylineOptions', polylineOptions);

    var rectangleOptions = drawingManager.get('rectangleOptions');
    rectangleOptions.fillColor = color;
    drawingManager.set('rectangleOptions', rectangleOptions);

    var circleOptions = drawingManager.get('circleOptions');
    circleOptions.fillColor = color;
    drawingManager.set('circleOptions', circleOptions);

    var polygonOptions = drawingManager.get('polygonOptions');
    polygonOptions.fillColor = color;
    drawingManager.set('polygonOptions', polygonOptions);
  }

  function setSelectedShapeColor(color) {
    if (selectedShape) {
      if (selectedShape.type == google.maps.drawing.OverlayType.POLYLINE) {
        selectedShape.set('strokeColor', color);
      } else {
        selectedShape.set('fillColor', color);
      }
    }
  }

  function makeColorButton(color) {
    var button = document.createElement('span');
    button.className = 'color-button';
    button.style.backgroundColor = color;
    google.maps.event.addDomListener(button, 'click', function() {
      selectColor(color);
      setSelectedShapeColor(color);
    });

    return button;
  }

   function buildColorPalette() {
     var colorPalette = document.getElementById('color-palette');
     for (var i = 0; i < colors.length; ++i) {
       var currColor = colors[i];
       var colorButton = makeColorButton(currColor);
       colorPalette.appendChild(colorButton);
       colorButtons[currColor] = colorButton;
     }
     selectColor(colors[0]);
   }

  function initialize() {
      var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 7,
      center: new google.maps.LatLng(40.2444, -111.6608),           // Utah default coords
      mapTypeId: google.maps.MapTypeId.Terrain,
      disableDefaultUI: true,
      zoomControl: true
    });

    var polyOptions = {
      strokeWeight: 0,
      fillOpacity: 0.45,
      editable: true
    };


    // Creates a drawing manager attached to the map that allows the user to draw
    // markers, lines, and shapes.
    drawingManager = new google.maps.drawing.DrawingManager({
      drawingMode: google.maps.drawing.OverlayType.POLYGON,
      drawingControlOptions: {
        drawingModes: [google.maps.drawing.OverlayType.POLYGON]},
      markerOptions: {
        draggable: true
      },
      polylineOptions: {
        editable: true
      },
      rectangleOptions: polyOptions,
      circleOptions: polyOptions,
      polygonOptions: polyOptions,
      map: map
    });

    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;
        polygons.push(newShape);

        setSelection(newShape);


        google.maps.event.addListener(newShape, 'click', function() {
          setSelection(newShape);
        });

        google.maps.event.addListener(newShape, 'mouseup', function() {
          for (i=0; i < polygons.length; i++) {   // Clear out the old polygons entry
            if (newShape.getPath == polygons[i].getPath) {
                polygons.splice(i, 1);
            }
          }
          polygons.push(newShape);
        });
      }
    });


    // Clear the current selection when the drawing mode is changed, or when the
    // map is clicked.
    google.maps.event.addListener(drawingManager, 'drawingmode_changed', clearSelection);
    google.maps.event.addListener(map, 'click', clearSelection);
    google.maps.event.addDomListener(document.getElementById('delete-button'), 'click', deleteSelectedShape);

    buildColorPalette();


   /* Load Shapes that were previously saved */
    for (var inc = 0, ii = areas.length; inc < ii; inc++) {
      var newCoords = [];
      for (var c = 0, cc = coords.length; c < cc; c++) {
          if (coords[c].polygon == areas[inc].polygon) {
            var point = coords[c];
            newCoords.push(new google.maps.LatLng(point.lat, point.lng));
          }
      }

      newPolys[inc] = new google.maps.Polygon({
        path: newCoords,
        strokeWeight: 0,
        fillColor: areas[inc].fillColor,
        fillOpacity: areas[inc].fillOpacity
      });
      newPolys[inc].setMap(map);
      polygons.push(newPolys[inc]);
      addNewPolys(newPolys[inc]);
    }


    function addNewPolys(newPoly) {
        google.maps.event.addListener(newPoly, 'click', function() {
            setSelection(newPoly);
        });
    }

  }

  google.maps.event.addDomListener(window, 'load', initialize);
like image 113
lee Avatar answered Sep 27 '22 15:09

lee