I've made a website with the Google Maps API. If users click in a polygon a message appears. It works on click, so the user has to click in or outside the Polygon area, but I would like to make it on page load, based on the users current position.
Is it possible to trigger the function below on page load?
google.maps.event.addListener(map, 'click', function (event) {
if (boundaryPolygon!=null && boundaryPolygon.Contains(event.latLng)) {
document.getElementById('result').innerHTML = 'You live in this area.';
} else {
//alert(event.latLng + " Du bist ein Ossi!");
document.getElementById('result').innerHTML = 'You live outside this area.';
}
});
}
You can trigger a click event on the map like this (where the latLng property is the location of the click):
google.maps.event.trigger(map, 'click', {
latLng: new google.maps.LatLng(24.886, -70.268)
});
proof of concept fiddle
code snippet:
// polygon example from: https://developers.google.com/maps/documentation/javascript/examples/polygon-simple
// This example creates a simple polygon representing the Bermuda Triangle.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: {
lat: 24.886,
lng: -70.268
},
mapTypeId: google.maps.MapTypeId.TERRAIN
});
// Define the LatLng coordinates for the polygon's path.
var triangleCoords = [{
lat: 25.774,
lng: -80.190
}, {
lat: 18.466,
lng: -66.118
}, {
lat: 32.321,
lng: -64.757
}, {
lat: 25.774,
lng: -80.190
}];
// Construct the polygon.
var boundaryPolygon = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
clickable: false
});
boundaryPolygon.setMap(map);
google.maps.event.addListener(map, 'click', function(event) {
if (boundaryPolygon != null && google.maps.geometry.poly.containsLocation(event.latLng, boundaryPolygon)) {
document.getElementById('result').innerHTML = 'You live in this area.';
} else {
document.getElementById('result').innerHTML = 'You live outside this area.';
}
});
google.maps.event.trigger(map, 'click', {
latLng: new google.maps.LatLng(24.886, -70.268)
});
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
<div id="result"></div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?libraries=geometry&callback=initMap">
</script>
Related
I have a simple google maps map and when I click on it I want an alert to be triggered:
let map;
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
const triangleCoords = [
{ lat: -34.397, lng: 150.644 },
{ lat: -33.5, lng: 152 },
{ lat: -34.4, lng: 149 },
];
const triangle = new google.maps.Polygon({
paths: triangleCoords,
});
triangle.setMap(map);
google.maps.event.addListener(map, "click", (e) => {
alert('there was a click')
const result = google.maps.geometry.poly.containsLocation(
e.latLng,
triangle
);
if(result)alert('inside triangle')
else alert('outside triangle')
});
}
fiddle
However, when I click on the polygon, the event doesn't get triggered, the alert is not firing. Outside of the polygon it does work.
What am I doing wrong?
The google.maps.Polygon captures click when it is "clickable" (defaults to true). If you set clickable:false, the map click listener function will run. From the documentation:
clickable optional
Type: boolean optional
Indicates whether this Polygon handles mouse events. Defaults to true.
Related question: Cant GetPosition in Overlay Polygon Zone
(the other option would be to leave the Polygon as clickable:true, but add the same event listener to the Polygon)
proof of concept fiddle
code snippet:
let map;
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: {
lat: -34.397,
lng: 150.644
},
zoom: 8,
});
const triangleCoords = [{
lat: -34.397,
lng: 150.644
},
{
lat: -33.5,
lng: 152
},
{
lat: -34.4,
lng: 149
},
];
const triangle = new google.maps.Polygon({
paths: triangleCoords,
clickable: false
});
triangle.setMap(map);
google.maps.event.addListener(map, "click", (e) => {
alert('there was a click')
const result = google.maps.geometry.poly.containsLocation(
e.latLng,
triangle
);
if (result) alert('inside triangle')
else alert('outside triangle')
/* console.log(result) */
});
}
/* 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;
}
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=&v=weekly" defer></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="map"></div>
</body>
</html>
I tried to create a geofence in Google Maps JavaScript API, and now I want to get the geoJSON of the fence.
I tried the following:
polygon.getMap().data.toGeoJson((data)=>{
console.log(data);
});
polygon.map.data.toGeoJson((data)=>{
console.log(data);
});
... but it only returns empty features of a FeatureCollection.
This is my script:
"use strict";
let fence, map;
function initMap() {
const zerobstacle = {lat: 9.7934792, lng: 118.7300364};
map = new google.maps.Map(document.getElementById("map"), {
zoom: 11,
center: {
lat: zerobstacle.lat,
lng: zerobstacle.lng
},
mapTypeId: "terrain"
});
// Define the LatLng coordinates for the polygon's path.
const fence_coords = [
{
lat: (zerobstacle.lat+1*0.01),
lng: (zerobstacle.lng-10*0.01)
},
{
lat: (zerobstacle.lat-6*0.01),
lng: (zerobstacle.lng+4*0.01)
},
{
lat: (zerobstacle.lat+8*0.01),
lng: (zerobstacle.lng+6*0.01)
},
{
lat: (zerobstacle.lat+1*0.01),
lng: (zerobstacle.lng-10*0.01)
}
];
// Construct the polygon.
fence = new google.maps.Polygon({
paths: fence_coords,
strokeColor: "##FFF71D",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FFF71D",
fillOpacity: 0.35,
editable: true,
});
fence.setMap(map);
}
Thank you!
Data.toGeoJson returns geoJson from objects that have been added to the DataLayer. If you want your polygon in that result, you need to add it to the DataLayer, currently you are adding it to the map.
To add a polygon to the data layer, see the example in the documentation
For your polygon, that would be:
map.data.add({
geometry: new google.maps.Data.Polygon([fence_coords])
});
To export it, use .toGeoJson:
toGeoJson(callback)
Parameters:
callback: function(Object)
Return Value: None
Exports the features in the collection to a GeoJSON object.
Note that .toGeoJson doesn't have a return value, it takes a callback. To log the GeoJson output:
map.data.toGeoJson(function(geoJson){
console.log(geoJson);
});
proof of concept fiddle
logs:
{"type":"FeatureCollection",
"features":[
{"type":"Feature",
"geometry":{
"type":"Polygon",
"coordinates":[[
[118.63003640000001,9.8034792],
[118.77003640000001,9.7334792],
[118.7900364,9.8734792],
[118.63003640000001,9.8034792],
[118.63003640000001,9.8034792]
]]},
"properties":{}
}
]
}
code snippet:
"use strict";
let fence, map;
function initMap() {
const zerobstacle = {
lat: 9.7934792,
lng: 118.7300364
};
map = new google.maps.Map(document.getElementById("map"), {
zoom: 11,
center: {
lat: zerobstacle.lat,
lng: zerobstacle.lng
},
mapTypeId: "terrain"
});
// Define the LatLng coordinates for the polygon's path.
const fence_coords = [{
lat: (zerobstacle.lat + 1 * 0.01),
lng: (zerobstacle.lng - 10 * 0.01)
},
{
lat: (zerobstacle.lat - 6 * 0.01),
lng: (zerobstacle.lng + 4 * 0.01)
},
{
lat: (zerobstacle.lat + 8 * 0.01),
lng: (zerobstacle.lng + 6 * 0.01)
},
{
lat: (zerobstacle.lat + 1 * 0.01),
lng: (zerobstacle.lng - 10 * 0.01)
}
];
console.log(fence_coords);
map.data.add({
geometry: new google.maps.Data.Polygon([fence_coords])
});
map.data.toGeoJson(function(geoJson) {
console.log(JSON.stringify(geoJson));
document.getElementById('geojson').innerHTML = JSON.stringify(geoJson);
});
}
/* 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;
}
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=&v=weekly" defer></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="geojson"></div>
<div id="map"></div>
</body>
</html>
I have 2 markers on a map. I want to make those two markers visible on the map when some event happens. But when I add restriction option on map fitBounds does not show markers. When I remove restriction option it seems to work correctly.
Here is the sample code:
var map, markers;
var locations = [{
lat: 50.8503396,
lng: 4.351710300000036
},
{
lat: 49.9570366,
lng: 36.3431478
},
];
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 1,
center: {
lat: -28.024,
lng: 140.887
},
restriction: {
strictBounds: true,
latLngBounds: {
north: 85,
south: -85,
west: -180,
east: 180
},
},
});
markers = locations.map(function(location, i) {
return new google.maps.Marker({
position: location
});
});
markers.forEach(function(marker) {
marker.setMap(map);
});
}
setTimeout(function() {
var bounds = new google.maps.LatLngBounds();
markers.forEach(function(marker) {
bounds.extend(marker.position);
});
map.fitBounds(bounds);
}, 5000);
#map {
height: 400px;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
https://jsfiddle.net/fedman/6eoty0vm/
While this bug of google.maps.api still exists you can set map center to bounds center as a workaround.
map.fitBounds(bounds);
map.setCenter(bounds.getCenter());
This looks like a bug. It works fine with version 3.34 of the API as shown in the code below. Seems to work also fine depending on the map container height (tried with a height of 200px and it worked even with the latest versions).
I have opened a bug in the issue tracker.
var map, markers;
var locations = [{
lat: 50.8503396,
lng: 4.351710300000036
},
{
lat: 49.9570366,
lng: 36.3431478
},
];
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 1,
center: {
lat: -28.024,
lng: 140.887
},
restriction: {
strictBounds: true,
latLngBounds: {
north: 85,
south: -85,
west: -180,
east: 180
},
},
});
markers = locations.map(function(location, i) {
return new google.maps.Marker({
position: location
});
});
markers.forEach(function(marker) {
marker.setMap(map);
});
}
setTimeout(function() {
var bounds = new google.maps.LatLngBounds();
markers.forEach(function(marker) {
bounds.extend(marker.position);
});
map.fitBounds(bounds);
}, 5000);
#map {
height: 400px;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?v=3.34&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
When the user clicks on the marker the first time I want a polygon to appear. The second time they click the polygon should disappear. This code works fine for the appearing part but it does not remove the polygon from the map. Every odd click just makes the polygon darker.
body onload="initMap()">
<p id="instructions"></p>
<div id="map" style='overflow:hidden;height:500px;width:500px;'></div>
<script type="text/javascript">
function initMap() {
var myOptions = {zoom:11,center:new google.maps.LatLng(37.55020520861464,126.98140242753904),mapTypeId: google.maps.MapTypeId.ROADMAP};
map = new google.maps.Map(document.getElementById('map'), myOptions);
document.getElementById("myButton").addEventListener("click", function() {
initMarker();
myTimer();
});
}
function initMarker() {
var t1 = 1;
marker1 = new google.maps.Marker({map: map,position: new google.maps.LatLng(37.55020520861464,126.98140242753904)});
marker2 = new google.maps.Marker({map: map,position: new google.maps.LatLng(37.558816, 126.908212)});
marker3 = new google.maps.Marker({map: map,position: new google.maps.LatLng(37.580107, 127.056797)});
marker4 = new google.maps.Marker({map: map,position: new google.maps.LatLng(37.446290, 126.862625)});
marker5 = new google.maps.Marker({map: map,position: new google.maps.LatLng(37.435041, 126.999528)});
marker6 = new google.maps.Marker({map: map,position: new google.maps.LatLng(37.522926, 126.853862)});
marker1.addListener('click', function() {
var triangleCoords = [
{lat: 37.550, lng: 123.9814},
{lat: 18.466, lng: -66.118},
{lat: 32.321, lng: -64.757},
{lat: 25.774, lng: -80.190}
];
var triangle1 = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: 'FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
if (t1 == 1) {
triangle1.setMap(map);
t1 = 2;
}
else {
triangle1.setMap(null);
t1 = 1;
}
});
}
</script>
<div><button id="myButton">Start</button></div>
<div id="timer"></div>
<p id="explain"></p>
<script src='https://maps.googleapis.com/maps/api/js?v=3.exp'
async defer ></script>
</body>
Try moving the new polygon inside the if statement. I think, when ever you evoke that function it makes a new instance of triangle1, that's why when you try to remove polygon it deletes the new instance of "var triangle1" (which wasn't drawn to to map yet) rather than the one on the map. (sorry about the English)
marker1.addListener('click', function() {
var triangleCoords = [
{lat: 37.550, lng: 123.9814},
{lat: 18.466, lng: -66.118},
{lat: 32.321, lng: -64.757},
{lat: 25.774, lng: -80.190}
];
if (t1 == 1) {
var triangle1 = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: 'FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
triangle1.setMap(map);
t1 = 2;
}
else {
triangle1.setMap(null);
t1 = 1;
}
});
One option (from Removing Rectangle from Map, slightly modified...
define the triangle1 variable outside the scope of the click listener
check if the triangle1 object exists and has a .setMap method.
if it does, set it's map property to null (the polygon is currently displayed), hide it, and set it to null.
if it doesn't exist, or doesn't have a .setMap method, create the marker.
var map;
function initMap() {
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(37.55020520861464, 126.98140242753904),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), myOptions);
document.getElementById("myButton").addEventListener("click", function() {
initMarker();
});
}
function initMarker() {
marker1 = new google.maps.Marker({
map: map,
title: "marker 1",
position: new google.maps.LatLng(37.55020520861464, 126.98140242753904)
});
var triangle1;
marker1.addListener('click', function(evt) {
if (triangle1 && triangle1.setMap) {
triangle1.setMap(null);
triangle1 = null;
} else {
var triangleCoords = [{
lat: 37.550,
lng: 123.9814
}, {
lat: 18.466,
lng: -66.118
}, {
lat: 32.321,
lng: -64.757
}, {
lat: 25.774,
lng: -80.190
}];
triangle1 = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: 'FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map
});
}
});
}
google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div>
<button id="myButton">Start</button>
</div>
<div id="timer"></div>
<p id="explain"></p>
<div id="map"></div>
I have a simple Google Map with some markers added looping on a json object.
I'm trying to add a listener to all of these markers to do a simple action (change the rotation). Markers are added on map and listener is called, but when i click on one of the markers, the action is performed always on the latest added.
How I can get the fired marker? I think that the way is to use the evt parameter of the listener function, but I don't know how.
I watched inside the evt parameter with firebug but without results.
Here is the code:
for(var i in _points){
_markers[i] = new google.maps.Marker({
position: {
lat: parseFloat(_points[i]._google_lat),
lng: parseFloat(_points[i]._google_lon)
},
icon: {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
scale: 3,
rotation: parseInt(_points[i]._rotation)
},
map: _map,
title: _points[i]._obj_id
});
google.maps.event.addListener(_markers[i], 'click', function(evt){
//console.log(evt);
r = _markers[i].icon.rotation;
_markers[i].setIcon({
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
scale: 3,
rotation: r+15
});
});
}
The this inside the click listener function is a reference to the marker:
google.maps.event.addListener(_markers[i], 'click', function(evt){
//console.log(evt);
r = this.getIcon().rotation;
this.setIcon({
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
scale: 3,
rotation: r+15
});
});
proof of concept fiddle
code snippet:
function initMap() {
// Create a map and center it on Manhattan.
var _map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: {
lat: 40.771,
lng: -73.974
}
});
for (var i in _points) {
_markers[i] = new google.maps.Marker({
position: {
lat: parseFloat(_points[i]._google_lat),
lng: parseFloat(_points[i]._google_lon)
},
icon: {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
scale: 3,
rotation: parseInt(_points[i]._rotation)
},
map: _map,
title: _points[i]._obj_id
});
google.maps.event.addListener(_markers[i], 'click', function(evt) {
r = this.getIcon().rotation;
this.setIcon({
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
scale: 3,
rotation: r + 15
});
});
}
}
google.maps.event.addDomListener(window, "load", initMap);
var _markers = [];
var _points = [{
_google_lat: 40.7127837,
_google_lon: -74.0059413,
_obj_id: "A",
_rotation: 0
}, {
_google_lat: 40.735657,
_google_lon: -74.1723667,
_obj_id: "B",
_rotation: 90
}]
html,
body,
#map {
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>