Skip to content

Instantly share code, notes, and snippets.

@dshorthouse
Last active August 29, 2019 10:32
Show Gist options
  • Save dshorthouse/0afc690b83ed056f6762a96702c041e7 to your computer and use it in GitHub Desktop.
Save dshorthouse/0afc690b83ed056f6762a96702c041e7 to your computer and use it in GitHub Desktop.
GMap WKT Drawing
<html>
<head>
<style type="text/css">
#map{width:600px;height:400px;}
#freehand {
margin-left:-5px;
margin-top:5px;
}
#freehand .button{
direction: ltr;
overflow: hidden;
text-align: left;
position: relative;
color: rgb(86, 86, 86);
font-family: Roboto,Arial,sans-serif;
-moz-user-select: none;
font-size: 11px;
background-color: rgb(255, 255, 255);
padding: 4px;
border-bottom-right-radius: 2px;
border-top-right-radius: 2px;
background-clip: padding-box;
box-shadow: 0px 1px 4px -1px rgba(0, 0, 0, 0.3);
border-left: 0px none;
cursor: default;
height:16px;
line-height:16px;
text-align:center;
}
#wkt{width:600px;height:100px;}
</style>
<title>WKT Drawing Tool</title>
</head>
<body>
<div id="map"></div>
<h2>Well-known text (WKT)</h2>
<form>
<textarea id="wkt"></textarea>
</form>
<script>
var WKT = (function() {
'use strict';
var _private = {
map_element: document.getElementById('map'),
wkt_element: document.getElementById('wkt'),
map_center: [30, 0],
map_zoom: 1,
map: {},
drawing: {type: null, overlay: {}, manager: {}},
drawing_manager: {},
init: function() {
this.map = new google.maps.Map(this.map_element, {
center: new google.maps.LatLng(this.map_center[0],this.map_center[1]),
defaults: {
editable: true,
strokeColor: '#0B0B09',
fillColor: '#E7E7E7',
fillOpacity: 0.2
},
zoom: this.map_zoom,
mapTypeId: google.maps.MapTypeId.TERRAIN,
mapTypeControl: true
});
this.removeDrawingOverlay();
this.addDrawingManager();
this.addDrawingListeners();
},
addDrawingManager: function() {
var self = this;
this.drawing_manager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['marker','polyline', 'rectangle', 'polygon']
},
circleOptions: this.map.defaults,
rectangleOptions: this.map.defaults,
polygonOptions: this.map.defaults
});
this.addFreehandMode();
this.drawing_manager.setMap(this.map);
},
addFreehandMode: function() {
var self = this,
customControlDiv = document.createElement('div'),
controlUI = document.createElement('div'),
controlText = document.createElement('div');
customControlDiv.setAttribute("id", "freehand");
controlUI.setAttribute("class", "button");
customControlDiv.appendChild(controlUI);
controlText.title = "Draw freehand";
controlText.innerHTML = "Freehand";
controlUI.appendChild(controlText);
customControlDiv.index = 1;
google.maps.event.addDomListener(controlUI, 'click', function() {
self.removeDrawingOverlay();
self.map.setOptions({
draggable: false,
zoomControl: false,
scrollwheel: false,
disableDoubleClickZoom: false
});
google.maps.event.addDomListener(self.map.getDiv(),'mousedown',function(e){
self.drawFreeHand();
});
});
this.map.controls[google.maps.ControlPosition.TOP_CENTER].push(customControlDiv);
},
drawFreeHand: function() {
var self = this;
var poly = new google.maps.Polyline({
map: this.map,
clickable:false,
editable: false
}),
move = google.maps.event.addListener(this.map,'mousemove',function(e){
poly.getPath().push(e.latLng);
});
google.maps.event.addListenerOnce(this.map,'mouseup',function(e) {
google.maps.event.removeListener(move);
self.drawing_manager.setOptions({ drawingMode: null });
var path = poly.getPath();
poly.setMap(null);
poly = new google.maps.Polygon({
map:self.map,
path:path,
strokeColor: '#0B0B09',
fillColor: '#E7E7E7',
fillOpacity: 0.2
});
self.drawing = {type: "polygon", overlay: poly};
self.writeWKT(self.polygonParameters());
google.maps.event.clearListeners(self.map.getDiv(), 'mousedown');
self.map.setOptions({
draggable: true,
zoomControl: true,
scrollwheel: true,
disableDoubleClickZoom: true
});
});
},
addDrawingListeners: function() {
var self = this;
google.maps.event.addListener(this.drawing_manager, 'drawingmode_changed', function() {
if(self.drawing_manager.drawingMode) {
self.removeDrawingOverlay();
}
});
google.maps.event.addListener(this.drawing_manager, "overlaycomplete", function(e) {
self.drawing_manager.setOptions({ drawingMode: null });
self.drawing = e;
self.getParameters();
self.addDrawingOverlayListeners();
});
},
getParameters: function() {
switch(this.drawing.type) {
case 'marker':
this.writeWKT(this.markerParameters());
break;
case 'polyline':
this.writeWKT(this.polylineParameters());
break;
case 'circle':
this.writeWKT(this.circleParameters());
break;
case 'rectangle':
this.writeWKT(this.rectangleParameters());
break;
case 'polygon':
this.writeWKT(this.polygonParameters());
break;
}
},
addDrawingOverlayListeners: function() {
var self = this;
switch(this.drawing.type) {
case 'circle':
["center", "bounds"].forEach(function(v) {
google.maps.event.addListener(self.drawing.overlay, v +"_changed", function() {
self.writeWKT(self.circleParameters());
});
});
break;
case 'rectangle':
google.maps.event.addListener(self.drawing.overlay, 'bounds_changed', function() {
self.writeWKT(self.rectangleParameters());
});
break;
case 'polygon':
["insert", "remove", "set"].forEach(function(v) {
google.maps.event.addListener(self.drawing.overlay.getPath(), v +"_at", function() {
self.writeWKT(self.polygonParameters());
});
});
break;
}
},
writeWKT: function(coords) {
var wkt = "";
switch(this.drawing.type) {
case 'marker':
wkt += "POINT(";
wkt += coords.join(" ");
wkt += ")";
break;
case 'polyline':
wkt += "LINESTRING(";
wkt += coords.join(",");
wkt += ")";
break;
case 'circle':
wkt += "NO WKT EXISTS FOR ELLIPSES";
break;
case 'polygon':
case 'rectangle':
wkt += "POLYGON((";
wkt += coords.join(",");
wkt += "))";
break;
}
this.wkt_element.value = wkt;
},
markerParameters: function() {
var o = this.drawing.overlay;
return [o.getPosition().lng(),o.getPosition().lat()];
},
polylineParameters: function() {
var o = this.drawing.overlay,
coords = o.getPath().getArray().map(function(n) { return [[n.lng(),n.lat()].join(" ")]; });
return coords;
},
circleParameters: function() {
var o = this.drawing.overlay;
return [o.getCenter().lat()+','+o.getCenter().lng(),o.getRadius()];
},
rectangleParameters: function() {
var o = this.drawing.overlay,
n = o.getBounds().toJSON().north,
e = o.getBounds().toJSON().east,
w = o.getBounds().toJSON().west,
s = o.getBounds().toJSON().south;
return [[e,n].join(" "), [e,s].join(" "), [w,s].join(" "), [w,n].join(" "), [e,n].join(" ")];
},
polygonParameters: function() {
var o = this.drawing.overlay,
coords = o.getPath().getArray().map(function(n) { return [n.lng() + ' ' + n.lat()]; });
coords.push(coords[0]);
return coords;
},
removeDrawingOverlay: function() {
if (this.drawing.overlay !== undefined && typeof this.drawing.overlay.setMap === 'function') {
this.drawing.overlay.setMap(null);
}
this.drawing = {};
this.wkt_element.value = "";
},
};
return {
init: function() {
_private.init();
}
};
}());
</script>
<script src="//maps.googleapis.com/maps/api/js?libraries=drawing&amp;callback=WKT.init"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment