Capture Coordinates in Google Map on User Click - google-maps-api-3

I'm using this code to capture the co-ordinates when user clicks on the map by using below event listener:
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
However this function doesn't get called when user click on already marked location in Map.
Meaning this function is not called for points where mouse pointer changes to hand icon on Google Map.
Need help on capturing these kind of locations.

You should add the click listener on marker will give you the position of marker.
//Add listener
google.maps.event.addListener(marker, "click", function (event) {
var latitude = event.latLng.lat();
var longitude = event.latLng.lng();
console.log( latitude + ', ' + longitude );
}); //end addListener
Edit:
You need something like this
//Add listener
google.maps.event.addListener(marker, "click", function (event) {
var latitude = event.latLng.lat();
var longitude = event.latLng.lng();
console.log( latitude + ', ' + longitude );
radius = new google.maps.Circle({map: map,
radius: 100,
center: event.latLng,
fillColor: '#777',
fillOpacity: 0.1,
strokeColor: '#AA0000',
strokeOpacity: 0.8,
strokeWeight: 2,
draggable: true, // Dragable
editable: true // Resizable
});
// Center of map
map.panTo(new google.maps.LatLng(latitude,longitude));
}); //end addListener

Another solution is to place a polygon over the map, same size as the map rectangle, and collect this rectangles clicks.
function initialize() {
var mapDiv = document.getElementById('map-canvas');
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addListener(map, 'bounds_changed', function() {
var lat1 = 37.41463623043073;
var lat2 = 37.46915383933881;
var lng1 = -122.1848153442383;
var lng2 = -122.09898465576174;
var rectangle = new google.maps.Polygon({
paths : [
new google.maps.LatLng(lat1, lng1),
new google.maps.LatLng(lat2, lng1),
new google.maps.LatLng(lat2, lng2),
new google.maps.LatLng(lat1, lng2)
],
strokeOpacity: 0,
fillOpacity : 0,
map : map
});
google.maps.event.addListener(rectangle, 'click', function(args) {
console.log('latlng', args.latLng);
});
});
}
Now you get LatLng's for places of interest (and their likes) also.
demo -> http://jsfiddle.net/qmhku4dh/

You're talking about the Point of Interest icons that Google puts on the map.
Would it work for you to remove these icons entirely? You can do that with a Styled Map. To see what this would look like, open the Styled Map Wizard and navigate the map to the area you're interested in.
Click Point of interest under Feature type, and then click Labels under Element type. Finally, click Visibility under Stylers and click the Off radio button under that.
This should remove all of the point of interest icons without affecting the rest of the map styling. With those gone, clicks there will respond to your normal map click event listener.
The Map Style box on the right should show:
Feature type: poi
Element type: labels
Visibility: off
If the result looks like what you want, then click Show JSON at the bottom of the Map Style box. The resulting JSON should like this this:
[
{
"featureType": "poi",
"elementType": "labels",
"stylers": [
{ "visibility": "off" }
]
}
]
You can use that JSON (really a JavaScript object literal) using code similar to the examples in the Styled Maps developer's guide. Also see the MapTypeStyle reference for a complete list of map styles.

This example demonstrates the use of click event listeners on POIs (points of interest). It listens for the click event on a POI icon and then uses the placeId from the event data with a directionsService.route request to calculate and display a route to the clicked place. It also uses the placeId to get more details of the place.
Read the google documentation.
<!DOCTYPE html>
<html>
<head>
<title>POI Click Events</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.title {
font-weight: bold;
}
#infowindow-content {
display: none;
}
#map #infowindow-content {
display: inline;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="infowindow-content">
<img id="place-icon" src="" height="16" width="16">
<span id="place-name" class="title"></span><br>
Place ID <span id="place-id"></span><br>
<span id="place-address"></span>
</div>
<script>
function initMap() {
var origin = {lat: -33.871, lng: 151.197};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 18,
center: origin
});
var clickHandler = new ClickEventHandler(map, origin);
}
/**
* #constructor
*/
var ClickEventHandler = function(map, origin) {
this.origin = origin;
this.map = map;
this.directionsService = new google.maps.DirectionsService;
this.directionsDisplay = new google.maps.DirectionsRenderer;
this.directionsDisplay.setMap(map);
this.placesService = new google.maps.places.PlacesService(map);
this.infowindow = new google.maps.InfoWindow;
this.infowindowContent = document.getElementById('infowindow-content');
this.infowindow.setContent(this.infowindowContent);
// Listen for clicks on the map.
this.map.addListener('click', this.handleClick.bind(this));
};
ClickEventHandler.prototype.handleClick = function(event) {
console.log('You clicked on: ' + event.latLng);
// If the event has a placeId, use it.
if (event.placeId) {
console.log('You clicked on place:' + event.placeId);
// Calling e.stop() on the event prevents the default info window from
// showing.
// If you call stop here when there is no placeId you will prevent some
// other map click event handlers from receiving the event.
event.stop();
this.calculateAndDisplayRoute(event.placeId);
this.getPlaceInformation(event.placeId);
}
};
ClickEventHandler.prototype.calculateAndDisplayRoute = function(placeId) {
var me = this;
this.directionsService.route({
origin: this.origin,
destination: {placeId: placeId},
travelMode: 'WALKING'
}, function(response, status) {
if (status === 'OK') {
me.directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
};
ClickEventHandler.prototype.getPlaceInformation = function(placeId) {
var me = this;
this.placesService.getDetails({placeId: placeId}, function(place, status) {
if (status === 'OK') {
me.infowindow.close();
me.infowindow.setPosition(place.geometry.location);
me.infowindowContent.children['place-icon'].src = place.icon;
me.infowindowContent.children['place-name'].textContent = place.name;
me.infowindowContent.children['place-id'].textContent = place.place_id;
me.infowindowContent.children['place-address'].textContent =
place.formatted_address;
me.infowindow.open(me.map);
}
});
};
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap"
async defer></script>
</body>
</html>

If you are using npm load-google-maps-api with webpack this worked for me:
const loadGoogleMapApi = require("load-google-maps-api");
loadGoogleMapApi({ key: process.env.GOOGLE_MAP_API_KEY }).then(map => {
let mapCreated = new map.Map(mapElem, {
center: { lat: lat, lng: long },
zoom: 7
});
mapCreated.addListener('click', function(e) {
console.log(e.latLng.lat()); // this gives you access to the latitude value of the click
console.log(e.latLng.lng()); // gives you access to the latitude value of the click
var marker = new map.Marker({
position: e.latLng,
map: mapCreated
});
mapCreated.panTo(e.latLng); // finally this adds red marker to the map on click.
});
});
Next if you are integrating openweatherMap in your app you can use the value of e.latLng.lat() and e.latLng.lng() which I console logged above in your api request. This way:
http://api.openweathermap.org/data/2.5/weather?lat=${e.latLng.lat()}&lon=${e.latLng.lng()}&APPID=${YOUR_API_KEY}
I hope this helps someone as it helped me.
Cheers!

Related

Google maps API getting infowindow on click with geojson file

I am using the google maps API and I am displaying polygons on a map using a GeoJSON file. When the user presses inside the polygon, I would like an InfoWindow to appear and display data that is stored in the properties. Seems easy enough but when I am clicking on the polygons, nothing is popping up. Can anyone explain what I am doing wrong?
Below is what I am currently attempting:
map.data.loadGeoJson('plant_bounds_2011.json');
map.data.setStyle({
fillColor: 'red',
strokeWeight: 1
});
var infowindow = new google.maps.InfoWindow({
content: "hello"
});
map.data.addListener('click', function(event) {
let id = event.feature.getProperty('ID');
let name = event.feature.getProperty('HORZ_ORG');
let html = id + " " + name;
infowindow.setContent(html); // show the html variable in the infowindow
infowindow.setPosition(event.feature.getGeometry().get()); // anchor the infowindow at the marker
infowindow.setOptions({pixelOffset: new google.maps.Size(0,-30)}); // move the infowindow up slightly to the top of the marker icon
infowindow.open(map);
});
There is a javascript error with the posted code: Uncaught TypeError: event.feature.getGeometry(...).get is not a function on the line:
infowindow.setPosition(event.feature.getGeometry().get()); // anchor the infowindow at the marker`
A Data.Polygon geometry doesn't have a .get() method. It has a .getArray() method (which returns an array of LineStrings)
One location to place the InfoWindow at would be the point clicked (which is in the polygon):
infowindow.setPosition(event.latLng);
(if you want to either add an fixed point for the infowindow to the GeoJson or you want to compute a fixed point from the polygon you can do that as well)
proof of concept fiddle
code snippet:
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
zoom: 4,
center: {
lat: -28,
lng: 137
},
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.data.loadGeoJson('https://storage.googleapis.com/mapsdevsite/json/google.json');
map.data.setStyle({
fillColor: 'red',
strokeWeight: 1
});
var infowindow = new google.maps.InfoWindow({
content: "hello"
});
map.data.addListener('click', function(event) {
let id = event.feature.getProperty('ID');
let name = event.feature.getProperty('HORZ_ORG');
if (typeof id == "undefined") id = event.feature.getProperty('letter');
if (typeof name == "undefined") name = event.feature.getProperty('color');
let html = id + " " + name;
infowindow.setContent(html); // show the html variable in the infowindow
infowindow.setPosition(event.latLng);
infowindow.setOptions({
pixelOffset: new google.maps.Size(0, 0)
}); // move the infowindow up slightly to the top of the marker icon
infowindow.open(map);
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>

Google map resize not solving partial display issue within a modal dialogue

I known this question has been raised and answered many times but I can't seem to make the suggested solutions work for me...
I'm displaying a google map within a simplemodal dialogue.
Outside the modal dialogue the map displays correctly.
However, once inside a modal wrapper only part of the map is shown on the first iteration (see below).
The solution would appear to involve binding a 'resize' event to the map but it isn't working for me...
First iteration:
On opening the modal for the first iteration, my map displays with the partial section displaced over to the top RHS and overlaid on the full map.
On closing the first dialogue the screen returns to it's initial state.
Second and subsequent iterations:
On subsequent iterations the map displays correctly but on closing the background color of the map canvas is visible.
HTML:
<body>
<button class="modalMap">With Modal </button>
<button class="nonModalMap">Without Modal </button>
<div id="mapCanvas"></div>
</body>
CSS:
#simplemodal-overlay {background-color:#000;}
#simplemodal-container {color:#999; background-color:#fff;}
#simplemodal-container a{color:#ddd;}
.modalMap:hover,.nonModalMap:hover {
cursor:pointer;
}
#mapCanvas {
position:relative;
width:480px;height:300px;
}
JS:
$(document).ready(function(){
var myMap;
$('.modalMap').click(function(){
buildMap();
$('#mapCanvas').modal(
{onOpen:function(dialog){
dialog.overlay.fadeIn('fast',function(){
dialog.data.hide();dialog.container.fadeIn('fast',function(){
dialog.data.slideDown('fast');
});
});
}
,onClose:function(dialog){
dialog.data.fadeOut('fast',function(){
dialog.container.hide('fast',function(){
dialog.overlay.slideUp('fast',function(){
$.modal.close();
});
});
});
}
});
});
/* But without the modal the map displays correctly... */
$('.nonModalMap').click(function(){
buildMap();
});
});
function buildMap() {
var kpl = {
Place: function (data, map) {
var self = this;
this.data = data;
var coords = data.geo_coords.split(',');
this.position = new google.maps.LatLng(coords[0], coords[1]);
this.marker = new google.maps.Marker({
position: this.position,
map: map
});
google.maps.event.addListener(this.marker, 'click', function() {
if (self.data.url) {
window.location.href = self.data.url
}
});
},
MapManager: function (div, data) {
this.map = new google.maps.Map(div, {
zoom: 15,
center: new google.maps.LatLng(53.818298, -1.573263),
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false,
backgroundColor: '#cccccc',
streetViewControl: false,
navigationControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
});
saveCenter = this.map.center;
this.places = [];
for (var i in data) {
if (data.hasOwnProperty(i)) {
this.places.push(new kpl.Place(data[i], this.map));
}
}
}
};
myMap = new kpl.MapManager($('#mapCanvas').get(0), [{
url: "mailto:info#????.com",
geo_coords: "53.818298, -1.573263",
name: "Kensington Property LS6"
}]);
}
/* plus the simplemodal library... */
I've recreated the code in jsfiddle - http://jsfiddle.net/redApples/j23ue0n1/32/
Can anybody rescue my sanity...?

Count and output number of markers bound by circle radius

I have a map thats populated with markers of places from a fusion table. I'm taking the users location and displaying a circle of radius 10 miles from their location. Here is my code - http://connormccarra.com/sandbox/map/. How can I use the api to count the number of markers bound by the circle and output that number in the footer?
Cheers!
Relevant code:
var map;
function Initialize() {
var MapOptions = {
zoom: 7,
center: new google.maps.LatLng(53.4125694, -8.245014),
mapTypeId: google.maps.MapTypeId.ROADMAP,
sensor: true
};
map = new google.maps.Map(document.getElementById("map_canvas"), MapOptions);
var layer = new google.maps.FusionTablesLayer({
query: {
select: 'Address',
from: '1OPU6utSjRYwJSFK-EXdaGmt2KgLTq2loVIjS3AA'
}
});
layer.setMap(map);
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
var marker = new google.maps.Marker({
map: map,
position: pos,
content: 'You are here!'
});
// Add circle overlay and bind to marker
var circle = new google.maps.Circle({
map: map,
radius: 16093, // 10 miles in metres
fillColor: '#AA0000'
});
circle.bindTo('center', marker, 'position');
map.setCenter(pos);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
var count = mgr.getMarkerCount(circle);
document.getElementById("Address").innerHTML += count + "<BR>";
google.maps.event.addDomListener(window, 'load', initialize);
//Maps API loaded, now load customizations
var element = document.createElement('script');
element.src = 'template.js';
element.type = 'text/javascript';
var scripts = document.getElementsByTagName('script')[0];
scripts.parentNode.insertBefore(element, scripts);
}
The markers created by a FusionTableLayer are not real markers, there is no way to get them as a kind of list to filter them(you can't get any details for the markers, except you click them).
But you may request the FusionTableAPI with a spatial condition(via AJAX, jsonp is supported).
The syntax for the query:
SELECT COUNT() from tableId
WHERE ST_INTERSECTS('Address',CIRCLE(LATLNG(lat,lng),10000))
How to send a query : https://developers.google.com/fusiontables/docs/v1/sql-reference
Demo(using data of another FusionTable because your table is protected):
http://jsfiddle.net/doktormolle/bAtgf/
Simplest way: use the geometry library computeDistanceBetween method. If the distance from the user's location is less than 10 miles, the marker is in the circle.
I suggest you first fetch all the coordinates of your FusionTablesLayer.
Here is an example which was used in the sidebar
http://www.geocodezip.com/v3_FusionTables_AfricaMap_kml_sidebar.html
Then using a loop statement you can use the computeDistanceBetween function.
Detect If Marker is Within Circle Overlay

google maps API v3 - zoom after load How

I am trying to get google maps to load, then zoom into my marker, but I have something wrong with my javascript, as the scope of the map is not visible, despite it being defined globally.
Any ideas what I am doing wrong ?
Many thanks
Mark
<!DOCTYPE html>
<html>
<head>
<title>Geolocation</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<script src="js/jquery-1.10.1.min.js"></script>
<link href="css/default.css" rel="stylesheet">
<!--
Include the maps javascript with sensor=true because this code is using a
sensor (a GPS locator) to determine the user's location.
See: https://developers.google.com/apis/maps/documentation/javascript/basics#SpecifyingSensor
-->
<script src="https://maps.googleapis.com/maps/api/js?v=3.12&sensor=true"></script>
<script>
//START Global Variables
var geocoder;
var map;
var marker;
var initialZoomLevel = 7;
var endZoomLevel = 16;
var zoomTimeInterval_ms = 1000;
var mapIcon = {
url: "images/im_here.png",
// This marker is 130 pixels wide by 120 pixels tall
size: new google.maps.Size(130,120),
//scale image so it works with retina displays
scaledSize: new google.maps.Size(65,60),
// The origin for this image is 0,0.
origin: new google.maps.Point(0,0),
// The anchor point is be middle of the base
anchor: new google.maps.Point(32.5,60)
};
var mapIcon_shadow = {
url: "images/im_here_shadow.png",
// This shadow is 191 pixels wide by 120 pixels tall
size: new google.maps.Size(191,120),
//scale image so it works with retina displays
scaledSize: new google.maps.Size(95.5,60),
// The origin for this image is 0,0.
origin: new google.maps.Point(0,0),
// The anchor point is be middle of the base
anchor: new google.maps.Point(32.5,60)
};
//Enable the visual refresh
google.maps.visualRefresh = true;
//END Global Variables
/** Initialise function to render the map */
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
zoom: initialZoomLevel,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
panControl: false,
streetViewControl: false,
zoomControl: false
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
// set home location
home = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
// the marker where you are
marker = new google.maps.Marker({
map: map,
position: pos,
icon: mapIcon,
shadow: mapIcon_shadow,
draggable: true
});
codeLatLng(pos);
map.panTo(pos);
google.maps.event.addListener(marker, 'dragend', function(a) {
//alert('LatLng is '+a.latLng.lat()+ " "+ a.latLng.lng());
codeLatLng(a.latLng);
});
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
// Create the DIV to hold the control and
// call the HomeControl() constructor passing
// in this DIV.
//var homeControlDiv = document.createElement('div');
//var homeControl = new HomeControl(homeControlDiv, map);
//homeControlDiv.index = 1;
//map.controls[google.maps.ControlPosition.TOP_CENTER].push(homeControlDiv);
smoothZoom(map, endZoomLevel, map.getZoom()); // call smoothZoom, parameters map, final zoomLevel, and starting zoom level
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
var infowindow = new google.maps.InfoWindow(options);
map.setCenter(options.position);
}
function codeLatLng(markerLatLang) {
//var latlng = new google.maps.LatLng(latLng.lat(), latLng.lng());
geocoder.geocode({'latLng': markerLatLang}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
name = results[0].formatted_address;
latlongStr = "LAT = ["+markerLatLang.lat()+"] LNG = ["+markerLatLang.lng()+"]";
//alert("name = "+name);
$('#address').html(name);
$('#latlong').html(latlongStr);
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
}
/**
* The HomeControl adds a control to the map that simply
* returns the user to home. This constructor takes
* the control DIV as an argument.
* #constructor
*/
/** TODO need to rewite this as normal div, not on map **/
function HomeControl(controlDiv, map) {
// Set CSS styles for the DIV containing the control
// Setting padding to 5 px will offset the control
// from the edge of the map
controlDiv.style.padding = '5px';
// Set CSS for the control border
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = 'white';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '2px';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to set the map to Start Location';
controlDiv.appendChild(controlUI);
// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.fontFamily = 'Helvetica,sans-serif';
controlText.style.fontSize = '16px';
controlText.style.paddingLeft = '4px';
controlText.style.paddingRight = '4px';
controlText.style.zIndex = "100";
controlText.innerHTML = '<b>Reset Map</b>';
controlUI.appendChild(controlText);
// Setup the click event listeners: simply set the map back to home
google.maps.event.addDomListener(controlUI, 'click', function() {
marker.setPosition(home);
map.setCenter(home);
});
}
// the smooth zoom function
function smoothZoom (map, max, cnt) {
if (cnt >= max) {
return;
}
else {
z = google.maps.event.addListener(map, 'zoom_changed', function(event){
google.maps.event.removeListener(z);
self.smoothZoom(map, max, cnt + 1);
});
setTimeout(function(){map.setZoom(cnt)}, zoomTimeInterval_ms);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="panel">
<div id="latlong">No latlong Yet</div>
<div id="address">No Address Yet</div>
</div>
<div id="map-canvas"></div>
</body>
</html>
The fact that your map is defined globally isn't relevant if you don't wait until it is initialized before using it.
It is initialized by the initialize function which runs on the body onload event. You use it inline before that happens. This works for me:
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
zoom: initialZoomLevel,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
panControl: false,
streetViewControl: false,
zoomControl: false
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
google.maps.event.addListenerOnce(map,"zoom_changed", function() {
smoothZoom(map, endZoomLevel, map.getZoom()); // call smoothZoom, parameters map, final zoomLevel, and starting zoom level
});
working example
seems the zoom_changed event doesn't fire when the map initializes, using the "idle" event seems to work:
working example with zoom on idle

How to save map drawing state (Polygon, Polyline, Markers)

I want to enable drawing on Google Maps like (see this example)
When user finish with drawings he will click on save button to save his drawings in Database or KML file, anything :) .. I do not know how to the save part? Could anyone help me
Here, http://jsfiddle.net/X66L4/1/ try drawing some circles, click on SAVE, then edit the circles by switching to the hand cursor and SAVE again to see the changes.
I show an example to save circles' data, the main idea is to keep a global array for each drawing type (line, polygon, marker, circle), and use a listener on the drawing manager to detect each type being drawn (complete).
var circles = [];
google.maps.event.addDomListener(drawingManager, 'circlecomplete',
function(circle) {
circles.push(circle);
});
The reason to save the entire reference to the drawn object is to continue tracking changes. So you will need an array and listener for each type of drawing.
Then, when you want to save the data (you may wish to do so at every edit), iterate through the arrays and extract the minimum information to rebuild it (center, radius, path, latLng, and so on.)
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html, body, #map_canvas { margin: 0; padding: 0; height: 100% }
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=drawing"></script>
<script type="text/javascript">
var myOptions = {
center: new google.maps.LatLng(-25,177.5),
zoom: 3,
mapTypeId: google.maps.MapTypeId.SATELLITE
};
var map;
function initialize() {
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.CIRCLE,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [google.maps.drawing.OverlayType.CIRCLE]
},
circleOptions: {
editable: true
}
});
drawingManager.setMap(map);
var circles = [];
google.maps.event.addDomListener(drawingManager, 'circlecomplete', function(circle) {
circles.push(circle);
});
google.maps.event.addDomListener(savebutton, 'click', function() {
document.getElementById("savedata").value = "";
for (var i = 0; i < circles.length; i++) {
var circleCenter = circles[i].getCenter();
var circleRadius = circles[i].getRadius();
document.getElementById("savedata").value += "circle((";
document.getElementById("savedata").value +=
circleCenter.lat().toFixed(3) + "," + circleCenter.lng().toFixed(3);
document.getElementById("savedata").value += "), ";
document.getElementById("savedata").value += circleRadius.toFixed(3) + ")\n";
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<button id="savebutton">SAVE</button>
<textarea id="savedata" rows="8" cols="40"></textarea>
<div id="map_canvas"></div>
</body>
</html>
In my experience, it's easier to use map's dataLayer then the drawing manager.
Try out this fiddle.
FiddleLink
Showing the controls:
map.data.setControls(['Polygon']);
map.data.setStyle({
editable: true,
draggable: true
});
in this function you can see the Create, Read (localStorage) and Remove (not in that order):
function loadPolygons(map) {
var data = JSON.parse(localStorage.getItem('geoData'));
map.data.forEach(function (f) {
map.data.remove(f);
});
console.log(data);
map.data.addGeoJson(data)
}

Resources