Reputation: 2017
I found a gist that enables drawing tools and gives the ability to choose from a few colors to draw on a google map: https://gist.github.com/Hagith/5765919
I'm trying to utilize this with socket.io so that multiple people can be viewing a map, and when one person draws something onto the map, all of the people can see what is drawn.
I've got the basic idea down with markers by doing
socket.emit("marker", e.overlay.position);
When a marker is placed, however, with rectangles, polygons, and circles, it seems a bit harder. When I log out the click event on the map with any of those shapes, the data that it gives back seems way more complicated than what it gave back with marker and I can't find the coordinates for the points that I need to be able to broadcast to the other users. Does anyone know where to find these in the context of the gist above?
Edit: I've been able to find the center with e.overlay.j.center
Upvotes: 1
Views: 17394
Reputation: 10432
getCoords(someShape){
const paths = someShape.getPath().getArray();
const coords = paths.map((a) => [a.lat(), a.lng()]);
}
Gives a list of [lat, lng]
Upvotes: 1
Reputation: 59328
It is not recommended to utilize those kind of properties (e.overlay.j
) since they are not intended for public access and there is no guarantee that they will not change in the next version of Google Maps JavaScript API.
For google.maps.drawing.OverlayType.RECTANGLE
and google.maps.drawing.OverlayType.CIRCLE
types you could utilize getBounds() function
to determine the lat/lng bounds of the current shape as demonstrated below:
//get lat/lng bounds of the current shape
var bounds = e.overlay.getBounds();
var start = bounds.getNorthEast();
var end = bounds.getSouthWest();
var center = bounds.getCenter();
For google.maps.drawing.OverlayType.POLYLINE
and google.maps.drawing.OverlayType.POLYGON
types you could utilize getPath() function
:
//get lat/lng array of the current shape
var locations = e.overlay.getPath().getArray()
Modified example
var drawingManager;
var selectedShape;
var colors = ['#1E90FF', '#FF1493', '#32CD32', '#FF8C00', '#4B0082'];
var selectedColor;
var colorButtons = {};
function clearSelection() {
if (selectedShape) {
selectedShape.setEditable(false);
selectedShape = null;
}
}
function setSelection(shape) {
clearSelection();
selectedShape = shape;
shape.setEditable(true);
selectColor(shape.get('fillColor') || shape.get('strokeColor'));
}
function deleteSelectedShape() {
if (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;
drawingManager.set('polygonOptions', polygonOptions);
}
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: 16,
center: new google.maps.LatLng(52.25097, 20.97114),
mapTypeId: google.maps.MapTypeId.SATELLITE,
disableDefaultUI: true,
zoomControl: true
});
var polyOptions = {
strokeWeight: 0,
fillOpacity: 0.45,
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({
drawingMode: google.maps.drawing.OverlayType.POLYGON,
markerOptions: {
draggable: true
},
polylineOptions: {
editable: true,
draggable: true
},
rectangleOptions: polyOptions,
circleOptions: polyOptions,
polygonOptions: polyOptions,
map: map
});
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);
// 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 (e) {
if (e.vertex !== undefined) {
if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
var path = newShape.getPaths().getAt(e.path);
path.removeAt(e.vertex);
if (path.length < 3) {
newShape.setMap(null);
}
}
if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
var path = newShape.getPath();
path.removeAt(e.vertex);
if (path.length < 2) {
newShape.setMap(null);
}
}
}
setSelection(newShape);
});
setSelection(newShape);
if (e.type == google.maps.drawing.OverlayType.POLYLINE || google.maps.drawing.OverlayType.POLYGON) {
var locations = e.overlay.getPath().getArray()
//console.log(bounds.toString());
document.getElementById('output').innerHTML = locations.toString();
}
else {
//get lat/lng bounds of the current shape
var bounds = e.overlay.getBounds();
var start = bounds.getNorthEast();
var end = bounds.getSouthWest();
var center = bounds.getCenter();
//console.log(bounds.toString());
document.getElementById('output').innerHTML = bounds.toString();
}
}
});
// 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);
buildColorPalette();
}
google.maps.event.addDomListener(window, 'load', initialize);
#map, html, body {
padding: 0;
margin: 0;
width: 960px;
height: 300px;
}
#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 type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false&libraries=drawing"></script>
<div id="panel">
<div id="color-palette"></div>
<div>
<button id="delete-button">Delete Selected Shape</button>
</div>
</div>
<div id="map"></div>
<div id="output"></div>
Upvotes: 9
Reputation: 1220
Edit: I've been able to find the center with e.overlay.j.center
You want to be VERY careful using the single-letter properties you can see in the browser debug tools. They are not documented, or static, and will change without warning.
To answer the actual question - the type of e.overlay
depends on what you've initialised the DrawingManager with, see the docs here. So if you're drawing polygons, e.overlay
will be of type Polygon
. You can then get the points that make up that Polygon using e.overlay.getPath(0).getArray()
, which gives you an array of LatLng
objects. (obviously loop over all the available paths, not just 0
).
There's a good example here which shows switching behaviour based on what type of geometry the overlay is returned as.
Upvotes: 3