1

I am currently working on a map-based service. There the user can select items on the map by drawing rectangles and polygons using the drawingManager. I push these shapes to an global array after they are created to keep control on them like this:

      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);
      var newShape = e.overlay;
      all_overlays.push(newShape);
      newShape.type = e.type;
      newShape.id = all_overlays.length-1;
      all_overlays[newShape.id].id = all_overlays.length-1;
}

The user has the option to delete a single shape. I implemented the deletion like this:

function deleteSelectedShape() {
if (selectedShape) {
    all_overlays.splice(selectedShape.id,1);
    while(jQuery.inArray(selectedShape.id, selected_shapes) != -1)
        {
        var shape_index = jQuery.inArray(selectedShape.id, selected_shapes);
        selected_shapes.splice(shape_index,1);
        selected_buoys.splice(shape_index,1);
        }
    selectedShape.setMap(null);
    selectedShape = '';
    buildList();
    highlightSelectedBuoys();   
}

Unfortunatly this is not working. If I e.g. got an array with 4 shapes (ids:0,1,2,3) and delete the array with id=0, the all_overlays array does not change it's size, which messes the whole thing up in the next step. Where is my mistake?

Axel
  • 1,415
  • 1
  • 16
  • 40
  • In your code you have mentioned `newShape.id = all_overlays.length-1;`. Is this correct? Otherwise the shape id will be in negative number. – bprasanna Nov 27 '14 at 10:57
  • This happens after `all_overlays.push(newShape)`, so `all_overlays.length-1` is 0 for the first shape. – Axel Nov 27 '14 at 13:14
  • I'm doing this in order to achieve zero-based indexing. – Axel Nov 27 '14 at 13:29
  • Where in `deleteSelectedShape` are you removing items from `all_overlays`? – duncan Nov 27 '14 at 15:08
  • I thought this is done by the `all_overlays.splice(selectedShape.id,1)`, but I'm not sure if I correctly understood the concept of splice. – Axel Nov 27 '14 at 16:01

2 Answers2

5

Forget newShape.id, the index of the shape will change after a splice.

Use indexOf instead:

 all_overlays.splice(all_overlays.indexOf(selectedShape),1);

The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present. indexOf compares searchElement to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator). Note that splice does nothing if you pass -1 as a parameter.

Complete example:

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);
         var newShape = e.overlay;
         all_overlays.push(newShape);
         newShape.type = e.type;
      }
}

function deleteSelectedShape() {
    if (selectedShape) {
        // here is the difference
        all_overlays.splice(all_overlays.indexOf(selectedShape),1);
        // here maybe you need the same fix.
        selected_shapes.splice(selected_shapes.indexOf(selectedShape),1);
        selected_buoys.splice(selected_buoys.indexOf(selectedShape),1);
        // remove from map.
        selectedShape.setMap(null);
        selectedShape = ''; // maybe should be undefined.
        // do stuffs
        buildList();
        highlightSelectedBuoys();   
    }
}

NOTE: This is not fully cross-browser due indexOf is not supported natively by all browsers. But you can implement it by yourself. Read This post to support old browsers.

Community
  • 1
  • 1
rnrneverdies
  • 15,243
  • 9
  • 65
  • 95
  • @Axel feedback please. – rnrneverdies Dec 01 '14 at 02:31
  • Sorry, wasn't home over the weekend. Changing `all_overlays.splice(selectedShape.id,1);` to `all_overlays.splice(all_overlays.indexOf(selectedShape),1);` solved the problem. Thanks for your help! – Axel Dec 01 '14 at 11:10
  • I wish I could vote this up further this was plaguing me for days trying to figure out how to remove shapes on deletion this was a massive headache solver, thanks! – Someone Oct 12 '15 at 11:41
0

I wrote a similiar project.

while(overlays.length>0)
{
    var tmpOverlay = overlays.shift();
    tmpOverlay.setMap(null); 
}

Other way:

for(var i = 0; i < markers.length; i++) { var t = markers[i]; t.setMap(null); t = null; }
for(var i = 0; i < overlays.length; i++) { var t = overlays[i]; t.setMap(null); t = null; }

while (markers.length) { markers.pop(); } 
while (overlays.length) { overlays.pop(); }

overlays = []; markers = []; 

overlays are polygons draw by the user and markers are generated after the overlaycomplete trigger.

This code will delete all overlays that were pushed to the Array. For deleting only one (the user clicks 'Delete' on the InfoWindow), I got that working with this:

shapeListTmp = []; 
var tmp = shapeList.slice(); //ShapeList is my GPoly Arrays
var index = 1;  
removeAllOverlays();  //Delete all shapes from Map

tmp.forEach(function (e) {
    if (e.id != polyId) //All GPoly have an 'id' just like yours 1,2,3, 4--- polyId is going to be deleted
    {
         e.id = index;
         shapeListTmp.push(e); //Push this Poly to the new Array
         drawPolygon(e); //Draw it again on map. (Mine function)
         index = index + 1;
    }
 });        
 shapeList = shapeListTmp.slice(); #Copy tmpArray to original. 

I have to delete them all from map and redraw again. Setting setMap(null) does nothing for me either.

Esselans
  • 1,540
  • 2
  • 24
  • 44