Search code examples
javascriptgoogle-mapsgoogle-maps-api-3polygonsgoogle-maps-drawing

Select a Google Maps Polygon outside map control and modify properties


I'm trying to modify a polygon when an event is triggered outside the map control and seem to be hitting a brick wall.

i have a series of divs to the right of my map and would like to change the strokeweight property on the polygon to a heavier line when the mouseenter event is fired and reset it to the default when the mouse leave is triggered.

i would also like to be able to select the polygon when they click on this div

$( ".zonal" ).mouseenter(function() {
  for (var i = 0; i < gPolygons.length; i++) {
   if(gPolygons[i].id == $(this).attr('id')) 
     {
       gPolygons[i].setOptions({strokeWeight: 6.0});       
     }
  }
});

$( ".zonal" ).mouseleave(function() {
  for (var i = 0; i < gPolygons.length; i++) {
   if(gPolygons[i].id == $(this).attr('id')) 
     {
       gPolygons[i].setOptions({strokeWeight: 2.0}); 
     }
  }
});

i have pushed the polygons out to an array and tried using the following but it doesn't work

gPolygons[i].setOptions({strokeWeight: 6.0}); 

Here is a visual of what im trying to do, so when they hover over zone 1 the border line of the polygon will get thicker and if the click on the div the relevant polygon will be selected.

Any help appreciated guys

enter image description here


Solution

  • I see the following javascript error in the console: Uncaught TypeError: gPolygons[i].setOptions is not a function.

    The poly object you are pushing on to both the gPolygons and the polygons arrays is not a google.maps.Polygon object, so it doesn't have a setOptions method.

    function formPolygon(shapePoly){
      var shapeid = shapePoly.get('id');
      var res = (shapePoly.getPath().getArray());
      var coordsArr = iterateCoords(res);
      // this is not a google.maps.Polygon:
      var poly = {id:shapeid,coords:coordsArr, polycolor:shapePoly.get('fillColor')}
      polygons = $.grep(polygons, function(e){ 
        return e.id != shapeid; 
      });
      polygons.push(poly);
      // push the reference to the google.maps.Polygon into the array
      gPolygons.push(shapePoly);
      console.log(polygons);
    }
    

    updated fiddle

    highlighted Polygon

    code snippet:

    var zVal = 999999999;
    var polygons = [];
    var gPolygons = [];
    var curID = "";
    var mapMain;
    $('#tt').click(function() {
      var res = (selectedShape.getPath().getArray());
      alert(res);
    });
    
    $('#tt2').click(function() {
      alert(polygons[0].coords[0].lat);
    });
    
    $(".zonal").mouseenter(function() {
      for (var i = 0; i < gPolygons.length; i++) {
        if (gPolygons[i].id == $(this).attr('id')) {
          gPolygons[i].setOptions({
            strokeWeight: 6.0
          });
        }
      }
    });
    
    $(".zonal").mouseleave(function() {
      for (var i = 0; i < gPolygons.length; i++) {
        if (gPolygons[i].id == $(this).attr('id')) {
          gPolygons[i].setOptions({
            strokeWeight: 2.0
          });
        }
      }
    });
    
    $('.zonal').click(function() {
      var testid = $(this).attr('id');
      $('#mapOverlay').hide();
      $('#hdActive').val(testid);
      curID = testid;
      clearSelection();
    });
    var drawingManager;
    var selectedShape;
    var colors = ['#1E90FF', '#32CD32', '#FF8C00', '#4B0082'];
    var selectedColor;
    var colorButtons = {};
    
    function clearSelection() {
      if (selectedShape) {
        selectedShape.setEditable(false);
        selectedShape = null;
      }
    
    }
    
    function checkIDSet(e, a) {
      e.preventDefault();
      if ($('#hdActive').val() == "") {
        alert('Please select a zone');
        return false;
      }
    }
    
    function setSelection(shape) {
      clearSelection();
      selectedShape = shape;
      shape.setEditable(true);
      selectColor(shape.get('fillColor') || shape.get('strokeColor'));
      $('#zInd').val(shape.get('id'));
      console.log(shape);
    }
    
    function deleteSelectedShape() {
      if (selectedShape) {
        $('#' + selectedShape.id).attr("disabled", false);
        deletePolygon(selectedShape);
        selectedShape.setMap(null);
      }
    }
    
    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;
      polygonOptions.strokeColor = color;
      drawingManager.set('polygonOptions', polygonOptions);
    }
    
    function formPolygon(shapePoly) {
      var shapeid = shapePoly.get('id');
      var res = (shapePoly.getPath().getArray());
      var coordsArr = iterateCoords(res);
      var poly = {
        id: shapeid,
        coords: coordsArr,
        polycolor: shapePoly.get('fillColor')
      }
      polygons = $.grep(polygons, function(e) {
        return e.id != shapeid;
      });
      polygons.push(poly);
      gPolygons.push(shapePoly);
      console.log(polygons);
    }
    
    function iterateCoords(arr) {
      var coords = [];
      var base = arr.toString();
      base = base.replace(/\(/g, "");
      var baseArr = base.split("),");
      $(baseArr).each(function(key, value) {
        var cObj = value.toString();
        var tcObj = cObj.split(',');
        var c = {
          lat: tcObj[0].toString(),
          lon: tcObj[1].toString()
        }
        coords.push(c);
      });
      console.log(coords);
      return coords;
    }
    
    function deletePolygon(shapePoly) {
      var shapeid = shapePoly.get('id');
      var res = (shapePoly.getPath().getArray());
      var poly = {
        id: shapeid,
        coords: res,
        polycolor: shapePoly.get('fillcolor')
      }
      polygons = $.grep(polygons, function(e) {
        return e.id != shapeid;
      });
      console.log(polygons);
    }
    
    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: 15,
        center: new google.maps.LatLng(55.034997, -7.193612),
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        disableDefaultUI: true,
        zoomControl: true
      });
      mapMain = map;
      var polyOptions = {
        strokeWeight: 2,
        fillOpacity: 0.25,
        id: $('#hdActive').val(),
        zIndex: zVal,
        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,
        markerOptions: {
          draggable: false,
          icon: 'http://www.myiconfinder.com/uploads/iconsets/256-256-a5485b563efc4511e0cd8bd04ad0fe9e.png'
        },
        polylineOptions: {
          editable: true
        },
        rectangleOptions: polyOptions,
        circleOptions: polyOptions,
        polygonOptions: polyOptions,
        drawingControlOptions: {
          position: google.maps.ControlPosition.TOP_CENTER,
          drawingModes: [
            google.maps.drawing.OverlayType.POLYGON
          ]
        },
        map: map
      });
      var iwfMarker = new google.maps.Marker({
        position: {
          lat: 55.034997,
          lng: -7.193612
        },
        icon: 'http://www.myiconfinder.com/uploads/iconsets/256-256-a5485b563efc4511e0cd8bd04ad0fe9e.png',
        map: map
      });
      iwfMarker.setMap(map);
      google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
        zVal = zVal - 1000000;
        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;
    
          //Check to see if the shape has an id if not alert user to pick a zone
          newShape.type = e.type;
          newShape.id = curID;
          //newShape.zIndex=zVal;
          newShape.set('zIndex', zVal);
          $('#' + curID).addClass("set", true);
          google.maps.event.addListener(newShape, 'click', function() {
            if (this.id == "" || this.id == null) {
              alert('no id');
            }
            setSelection(newShape);
          });
          setSelection(newShape);
          formPolygon(newShape);
          clearSelection();
        }
      });
    
      // 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);
    
      google.maps.event.addDomListener(document.getElementById('map'), 'click', checkIDSet);
    
      buildColorPalette();
    }
    google.maps.event.addDomListener(window, 'load', initialize);
    #zonalCont {
       position: relative;
     }
     .zonal {
       width: 30%;
       border: 2px solid blue;
       background-color: #cecece;
       height: 55px;
       border-bottom: 20px;
     }
     .zonal.set {
       width: 30%;
       border: 2px solid blue;
       background-color: red;
       height: 55px;
       border-bottom: 20px;
     }
     #map,
     html,
     body {
       padding: 0;
       margin: 0;
       height: 100%;
     }
     #panel {
       width: 200px;
       font-family: Arial, sans-serif;
       font-size: 13px;
       float: right;
       margin: 10px;
     }
     #color-palette {
       clear: both;
     }
     .color-button {
       width: 14px;
       height: 14px;
       font-size: 0;
       margin: 2px;
       float: left;
       cursor: pointer;
     }
     #delete-button {
       margin-top: 5px;
     }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://maps.google.com/maps/api/js?libraries=drawing&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <span id="tt">Test</span>
    <span id="tt2">Test Sel</span>
    <div id="panel">
      <div>
        <div class='zonalCont'>
          <div id="zone1" class="zonal">Zone 1</div>
        </div>
        <div class='zonalCont'>
          <div id="zone2" class="zonal">Zone 2</div>
        </div>
        <div class='zonalCont'>
          <div id="zone3" class="zonal">Zone 3</div>
        </div>
        <div class='zonalCont'>
          <div id="zone4" class="zonal">Zone 4</div>
        </div>
      </div>
      <div id="color-palette"></div>
      <div>
        <button id="delete-button">Delete Selected Shape</button>
      </div>
      <div>
        <input type="text" id="zInd" />
      </div>
    </div>
    
    <div id="map"></div>
    <div id="mapOverlay" style="position:absolute;left:0;top:0;width:75%;height:100%;background-color:#fff;opacity:0.5;text-align:center">
      <h2 style="line-height:15em">Select A Zone</h2>
    </div>
    <input type="hidden" class="hdAct" id="hdActive" value="" />