Last active
November 20, 2021 11:53
-
-
Save loyalvares/c4ba7420b1eb055b309ab48bdcd34219 to your computer and use it in GitHub Desktop.
This is a custom library to add a Delete Button ( x mark) to a Google Maps v3 Circle or Polygon when drawn. This is the working JSFiddle link [ https://jsfiddle.net/foobarbazz/vn763fu7/ ] to see it in action.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* author: Loy Alvares | |
*/ | |
function initMap() { | |
setInitialMapOptions(); | |
map = getMapObject(mapOptions); | |
drawingManager = getDrawingManagerObject(); | |
google.maps.event.addListener(drawingManager, 'overlaycomplete', onOverlayComplete); | |
initializeDeleteOverlayButtonLibrary(); | |
} | |
// Get Map Geo Center Denver, USA Coordinates | |
var center = {lat: 39.810866, lng: -104.990347}; | |
var map, drawingManager, mapOptions = {}; | |
var listenerFiltersApplied = false; | |
var overlays = {}; | |
var circleOptions = { | |
fillColor: "#e20000", | |
fillOpacity: 0, | |
strokeColor: "#e20000", | |
strokeWeight: 4, | |
strokeOpacity: 1, | |
clickable: false, | |
editable: true, | |
suppressUndo: true, | |
zIndex: 999 | |
}; | |
var polygonOptions = { | |
editable: true, | |
fillColor: "#e20000", | |
fillOpacity: 0, | |
strokeColor: "#e20000", | |
strokeWeight: 4, | |
strokeOpacity: 1, | |
suppressUndo: true, | |
zIndex: 999 | |
}; | |
function setInitialMapOptions() { | |
mapOptions = { | |
zoom: 4, | |
center: center, | |
styles: [ | |
{"featureType":"road", elementType:"geometry", stylers: [{visibility:"off"}]}, //turns off roads geometry | |
{"featureType":"road", elementType:"labels", stylers: [{visibility:"off"}]}, //turns off roads labels | |
{"featureType":"poi", elementType:"labels", stylers: [{visibility:"off"}]}, //turns off points of interest lines | |
{"featureType":"poi", elementType:"geometry", stylers: [{visibility:"off"}]}, //turns off points of interest geometry | |
{"featureType":"transit", elementType:"labels", stylers: [{visibility:"off"}]}, //turns off transit lines labels | |
{"featureType":"transit", elementType:"geometry", stylers: [{visibility:"off"}]}, //turns off transit lines geometry | |
{"featureType":"administrative.land_parcel", elementType:"labels", stylers: [{visibility:"off"}]}, //turns off administrative land parcel labels | |
{"featureType":"administrative.land_parcel", elementType:"geometry", stylers: [{visibility:"off"}]}, //turns off administrative land parcel geometry | |
{"featureType":"water", elementType:"geometry", stylers: [{color: '#d1e1ff'}]}, //sets water color to a very light blue | |
{"featureType":"landscape", elementType:"geometry", stylers: [{color: '#fffffa'}]}, //sets landscape color to a light white color | |
], | |
mapTypeControl: false, | |
panControl: true, | |
panControlOptions: { | |
position: google.maps.ControlPosition.RIGHT_CENTER | |
}, | |
streetViewControl: false, | |
scaleControl: false, | |
zoomControl: true, | |
zoomControlOptions: { | |
style: google.maps.ZoomControlStyle.SMALL, | |
position: google.maps.ControlPosition.RIGHT_BOTTOM | |
}, | |
minZoom: 2 | |
}; | |
} | |
function getMapObject(mapOptions) { | |
var map = new google.maps.Map(document.getElementById('map'), mapOptions); | |
return map; | |
} | |
function getDrawingManagerObject(drawingManagerOptions) { | |
var drawingManager = new google.maps.drawing.DrawingManager({ | |
drawingMode: null, | |
drawingControl: true, | |
drawingControlOptions: { | |
position: google.maps.ControlPosition.TOP_CENTER, | |
drawingModes: [ | |
google.maps.drawing.OverlayType.CIRCLE, | |
google.maps.drawing.OverlayType.POLYGON | |
] | |
}, | |
circleOptions: circleOptions, | |
polygonOptions: polygonOptions | |
}); | |
drawingManager.setMap(map); | |
return drawingManager; | |
} | |
/* -- Overlay Functions Begin Here -- */ | |
function onOverlayComplete(shape) { | |
addDeleteButtonToOverlay(shape); | |
addOverlayListeners(shape); | |
if(listenerFiltersApplied) { | |
listenerFiltersApplied = false; | |
} | |
} | |
function addOverlayListeners(shape) { | |
// Filters already applied. | |
if(listenerFiltersApplied) { | |
return; | |
} | |
if (shape.type == google.maps.drawing.OverlayType.POLYGON) { | |
setBoundsChangedListener(shape); | |
} | |
if (shape.type == google.maps.drawing.OverlayType.CIRCLE) { | |
setCenterChangedListener(shape); | |
setRadiusChangedListener(shape); | |
} | |
} | |
function setBoundsChangedListener(shape) { | |
// Add listeners for each path of the polygon. | |
shape.overlay.getPaths().forEach(function(path, index){ | |
// New point | |
google.maps.event.addListener(path, 'insert_at', function(){ | |
listenerFiltersApplied = true; | |
onOverlayComplete(shape); | |
}); | |
// Point was removed | |
google.maps.event.addListener(path, 'remove_at', function(){ | |
listenerFiltersApplied = true; | |
onOverlayComplete(shape); | |
}); | |
// Point was moved | |
google.maps.event.addListener(path, 'set_at', function(){ | |
listenerFiltersApplied = true; | |
onOverlayComplete(shape); | |
}); | |
}); | |
} | |
function setCenterChangedListener(shape) { | |
google.maps.event.addListener(shape.overlay, 'center_changed', function() { | |
listenerFiltersApplied = true; | |
onOverlayComplete(shape); | |
}); | |
} | |
function setRadiusChangedListener(shape) { | |
google.maps.event.addListener(shape.overlay, 'radius_changed', function() { | |
listenerFiltersApplied = true; | |
onOverlayComplete(shape); | |
}); | |
} | |
function addDeleteButtonToOverlay(shape) { | |
var deleteOverlayButton = new DeleteOverlayButton(); | |
if(("deleteButton" in shape) && (shape.deleteButton != null)) { | |
shape.deleteButton.div.remove(); | |
shape.deleteButton = deleteOverlayButton; | |
} else { | |
shape.deleteButton = deleteOverlayButton; | |
} | |
if(shape.type == google.maps.drawing.OverlayType.CIRCLE) { | |
var radiusInKms = convertDistance(Math.round(shape.overlay.getRadius()), "metres", "kms"); | |
var circleCenter = new google.maps.LatLng(shape.overlay.getCenter().lat(), shape.overlay.getCenter().lng()); | |
var deleteOverlayButtonPosition = circleCenter.destinationPoint(30, radiusInKms); | |
deleteOverlayButton.open(map, deleteOverlayButtonPosition, shape); | |
} else if (shape.type == google.maps.drawing.OverlayType.POLYGON) { | |
deleteOverlayButton.open(map, shape.overlay.getPath().getArray()[0], shape); | |
} | |
if (!('uid' in shape)) { | |
shape.uid = Math.random().toString(36).substring(2) + (new Date()).getTime().toString(36); | |
} | |
overlays[shape.uid] = shape; | |
} | |
function clearAllOverlays() { | |
for(var shapeId in overlays) { | |
if(overlays.hasOwnProperty(shapeId)) { | |
var shape = overlays[shapeId]; | |
if(("deleteButton" in shape) && (shape.deleteButton != null)) { | |
shape.deleteButton.div.remove(); | |
} | |
shape.overlay.setMap(null); | |
} | |
} | |
overlays = {}; | |
} | |
/* | |
* Add any code that needs to be run or cleaned up in this method. | |
* This method is called in DeleteOverlayButton.removeShape(). | |
*/ | |
function callOnDelete(shape) { | |
if(shape['uid'] in overlays) { | |
delete overlays[shape['uid']]; | |
} | |
} | |
/* -- Overlay Functions End Here -- */ | |
function convertDistance(distanceValue, actualDistanceUnit, expectedDistanceUnit) { | |
var distanceInKms = 0; | |
switch(actualDistanceUnit) { | |
case "miles": | |
distanceInKms = distanceValue/0.62137; | |
break; | |
case "kms": | |
distanceInKms = distanceValue; | |
break; | |
case "metres": | |
distanceInKms = distanceValue/1000; | |
break; | |
default: | |
distanceInKms = undefined; | |
} | |
switch(expectedDistanceUnit) { | |
case "miles": | |
return distanceInKms * 0.62137; | |
case "kms": | |
return distanceInKms; | |
case "metres": | |
return distanceInKms * 1000; | |
default: | |
return undefined; | |
} | |
} |
Hi @loyalvares! Thank you for this script. You have helped me a lot. Just a couple questions though in using this script: how can I save the drawn shapes to MySQL and how to draw the saved shapes back to the map? I would appreciate it very much if you could give me some pointers. Thanks :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the working JSFiddle link to see it in action.