I have this google script that can create shape and delete shape but nothing much about saving the shapes.
I looked up the internet and know that I can access the paths coordinates via getpaths() within the overlaycomplete And I can also push the coordinates into an array which collects all the shapes. However, what if user delete a shape? or update it?
My problem is I have no idea how to identify the deleted shape so that I can update the shape collection array accordingly
The second problem is I have no idea how to identify if user updated the shape and which shape got updated. Therefore can't update the shape collection array.
I will need a solution that, when click save button. I can get all the coordinates of the shapes that exist on the map. So I would not have to care about what got updated or deleted. My current code is as below:
<!DOCTYPE html>
<html>
<head>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=drawing,geometry,places"></script>
<style>
#map,html,body{
height:100%;
margin:0;
padding:0;
}
#delete-button, #save-button {
margin-top: 5px;
position:absolute;
z-index:999;
right:6%;
top:3%;
}
#save-button{
right:1%;
}
</style>
</head>
<body>
<div id="map"></div>
<button id="delete-button" class="btn">Delete seleted shape</button>
<button id="save-button" class="btn" onclick="save();">Save all</button>
<script>
var drawingManager;
var selectedShape;
var shapeCollection = [];
function save(){
console.log(shapeCollection);
}
function clearSelection() {
if (selectedShape) {
selectedShape.setEditable(false);
selectedShape = null;
}
}
function setSelection(shape) {
clearSelection();
selectedShape = shape;
shape.setEditable(true);
}
function deleteSelectedShape() {
if (selectedShape) {
selectedShape.setMap(null);
}
}
function initialize() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom:10,
center: new google.maps.LatLng(22.344, 114.048),
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
var polyOptions = {
strokeWeight: 3,
fillOpacity: 0.2,
editable: true,
draggable: 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({
drawingControl: true,
drawingControlOptions: {
drawingModes: [google.maps.drawing.OverlayType.POLYGON]
},
drawingMode: google.maps.drawing.OverlayType.POLYGON,
polygonOptions: polyOptions,
map: map
});
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
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() {
setSelection(newShape);
});
setSelection(newShape);
});
//polygonPoints will be the array and index of the array will be the order
// 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(window, 'load', initialize);
</script>
</body>
</html>
Create a unique property(ID) for the shapes and store the shapes in an object(use the ID as key).
When you want to delete a shape you may use delete
to remove the shape from the collection(based on the ID of the shape).
You don't have to care about updates by the user, when you store the shapes(references) in the collection they will be updated automatically.
Demo:
function initialize() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom:10,
center: new google.maps.LatLng(22.344, 114.048),
mapTypeId: google.maps.MapTypeId.ROADMAP,
noClear:true
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM]
.push(document.getElementById('save-button'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM]
.push(document.getElementById('delete-button'));
var polyOptions = {
strokeWeight: 3,
fillOpacity: 0.2
};
var shapes={
collection:{},
selectedShape:null,
add:function(e){
var shape=e.overlay,
that=this;
shape.type=e.type;
shape.id=new Date().getTime()+'_'+Math.floor(Math.random()*1000);
this.collection[shape.id]=shape;
this.setSelection(shape);
google.maps.event.addListener(shape,'click',function(){
that.setSelection(this);
});
},
setSelection:function(shape){
if(this.selectedShape!==shape){
this.clearSelection();
this.selectedShape = shape;
shape.set('draggable',true);
shape.set('editable',true);
}
},
deleteSelected:function(){
if(this.selectedShape){
var shape= this.selectedShape;
this.clearSelection();
shape.setMap(null);
delete this.collection[shape.id];
}
},
clearSelection:function(){
if(this.selectedShape){
this.selectedShape.set('draggable',false);
this.selectedShape.set('editable',false);
this.selectedShape=null;
}
},
save:function(){
var collection=[];
for(var k in this.collection){
var shape=this.collection[k],
types=google.maps.drawing.OverlayType;
switch(shape.type){
case types.POLYGON:
collection.push({ type:shape.type,
path:google.maps.geometry.encoding
.encodePath(shape.getPath())});
break;
default:
alert('implement a storage-method for '+shape.type)
}
}
//collection is the result
console.log(collection);
}
};
var drawingManager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
drawingModes: [google.maps.drawing.OverlayType.POLYGON]
},
drawingMode: google.maps.drawing.OverlayType.POLYGON,
polygonOptions: polyOptions,
map: map
});
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
drawingManager.setDrawingMode(null);
shapes.add(e);
});
google.maps.event.addListener(drawingManager,
'drawingmode_changed',
function(){shapes.clearSelection();});
google.maps.event.addListener(map,
'click',
function(){shapes.clearSelection();});
google.maps.event.addDomListener(document.getElementById('delete-button'),
'click',
function(){shapes.deleteSelected();});
google.maps.event.addDomListener(document.getElementById('save-button'),
'click',
function(){shapes.save();});
}
#map,html,body{
height:100%;
margin:0;
padding:0;
}
<div id="map">
<button id="delete-button" class="btn">Delete selected shape</button>
<button id="save-button" class="btn">Save all</button>
</div>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=drawing,geometry,places&v=3&callback=initialize"></script>
Demo including a load
-method for automatically loading of shapes:
function initialize() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom:9,
center: new google.maps.LatLng(22.344, 114.048),
mapTypeId: google.maps.MapTypeId.ROADMAP,
noClear:true
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM]
.push(document.getElementById('save-button'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM]
.push(document.getElementById('delete-button'));
var polyOptions = {
strokeWeight: 3,
fillOpacity: 0.2
};
var shapes={
collection:{},
selectedShape:null,
add:function(e,s){
var shape=e.overlay,
that=this;
shape.type=e.type;
shape.id=new Date().getTime()+'_'+Math.floor(Math.random()*1000);
this.collection[shape.id]=shape;
if(!s)this.setSelection(shape);
google.maps.event.addListener(shape,'click',function(){
that.setSelection(this);
});
},
setSelection:function(shape){
if(this.selectedShape!==shape){
this.clearSelection();
this.selectedShape = shape;
shape.set('draggable',true);
shape.set('editable',true);
}
},
deleteSelected:function(){
if(this.selectedShape){
var shape= this.selectedShape;
this.clearSelection();
shape.setMap(null);
delete this.collection[shape.id];
}
},
clearSelection:function(){
if(this.selectedShape){
this.selectedShape.set('draggable',false);
this.selectedShape.set('editable',false);
this.selectedShape=null;
}
},
save:function(){
var collection=[];
for(var k in this.collection){
var shape=this.collection[k],
types=google.maps.drawing.OverlayType;
switch(shape.type){
case types.POLYGON:
collection.push({ type:shape.type,
path:google.maps.geometry.encoding
.encodePath(shape.getPath())});
break;
default:
alert('implement a storage-method for '+shape.type)
}
}
//collection is the result
console.log(JSON.stringify(collection));
return collection;
},
load:function(arr){
var types=google.maps.drawing.OverlayType;
for(var i=0;i<arr.length;++i){
switch(arr[i].type){
case types.POLYGON:
var shape=new google.maps.Polygon(polyOptions);
shape.setOptions({map:map,
path:google.maps.geometry.encoding
.decodePath(arr[i].path)});
shapes.add({type:types.POLYGON,overlay:shape},true)
break;
default:
alert('implement a loading-method for '+arr[i].type)
}
}
}
};
//initially load some shapes
shapes.load([{"type":"polygon","path":"_}sgCamyuT~ee@eP|FkdEskn@nr@rdH`wM"},
{"type":"polygon","path":"mnngCchxvT?y{DylG{{D~tFihCng_@v{O?wiVymDdPzNblLah\\i}LksLngJ"}]);
var drawingManager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
drawingModes: [google.maps.drawing.OverlayType.POLYGON]
},
drawingMode: google.maps.drawing.OverlayType.POLYGON,
polygonOptions: polyOptions,
map: map
});
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
drawingManager.setDrawingMode(null);
shapes.add(e);
});
google.maps.event.addListener(drawingManager,
'drawingmode_changed',
function(){shapes.clearSelection();});
google.maps.event.addListener(map,
'click',
function(){shapes.clearSelection();});
google.maps.event.addDomListener(document.getElementById('delete-button'),
'click',
function(){shapes.deleteSelected();});
google.maps.event.addDomListener(document.getElementById('save-button'),
'click',
function(){shapes.save();});
}
#map,html,body{
height:100%;
margin:0;
padding:0;
}
<div id="map">
<button id="delete-button" class="btn">Delete selected shape</button>
<button id="save-button" class="btn">Save all</button>
</div>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=drawing,geometry,places&v=3&callback=initialize"></script>