map.fitBounds works weird when map has 'restriction' option set - javascript

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>

Related

click on map doesn't get triggered when the click is on a polygon

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>

Google Maps API in a for loop, how to incorporate a info window?

So I have 4 maps all together on one page. I have them all working through the for loop. Now I need to add markers/ Infowindows any idea the best way to add that into the loop, thanks!
// array of lat and lng locations
let locations = [
{
lat:-33.91722,
lng:151.23064
},
{
lat:22.3193,
lng:114.1694
},
{
lat:22.3255,
lng:114.3532
},
{
lat:23.3532,
lng:115.1234
}
];
let elements = ['maps', 'map-rec-one', 'map-rec-two', 'map-rec-three']; // array of html element ids
window.addEventListener('load',
function() {
for (i = 0; i < elements.length; i++) {
initMap(locations[i], elements[i]);
console.log(elements[i]);
console.log(locations[i])}
}, false);
function initMap(location, element) {
console.log(location)
console.log(element)
map = new google.maps.Map(document.getElementById(element), {zoom:4, center: location});
}
One option would be to add the information for the markers to your array.
(if you want the same markers on each map, you can simplify the array or have a separate array for the markers)
let locations = [{
lat: -33.91722,
lng: 151.23064,
markers: [{
lat: -33.91722,
lng: 151.23064,
info: "this is a marker at -33.91722,151.23064"
}, {
lat: -33.8722,
lng: 151.03064,
info: "this is a marker at -33.8722,151.03064"
},
{
lat: -33.5722,
lng: 151.03064,
info: "this is a marker at -33.5722,151.03064"
}
]
},
{
lat: 22.3193,
lng: 114.1694,
markers: [{
lat: 22.3193,
lng: 114.1694,
info: "this is a marker at 22.3193,114.1694"
}]
},
{
lat: 22.3255,
lng: 114.3532
},
{
lat: 23.3532,
lng: 115.1234
}
];
Then in your initMap function, add those markers to the map:
function initMap(location, element, infowindow) {
console.log(location)
console.log(element)
map = new google.maps.Map(document.getElementById(element), {
zoom: 4,
center: location
});
if (location.markers) {
for (var i = 0; i < location.markers.length; i++) {
createMarker(location.markers[i], map, infowindow);
}
}
}
createMarker function:
function createMarker(location, map, infowindow) {
let marker = new google.maps.Marker({
position: location,
map: map
});
google.maps.event.addListener(marker, 'click', function(evt) {
infowindow.setContent(location.info);
infowindow.open(map, marker);
})
}
proof of concept fiddle
code snippet:
// The following example creates complex markers to indicate beaches near
// Sydney, NSW, Australia. Note that the anchor is set to (0,32) to correspond
// to the base of the flagpole.
function initialize() {
// array of lat and lng locations
let locations = [{
lat: -33.91722,
lng: 151.23064,
markers: [{
lat: -33.91722,
lng: 151.23064,
info: "this is a marker at -33.91722,151.23064"
}, {
lat: -33.8722,
lng: 151.03064,
info: "this is a marker at -33.8722,151.03064"
},
{
lat: -33.5722,
lng: 151.03064,
info: "this is a marker at -33.5722,151.03064"
}
]
},
{
lat: 22.3193,
lng: 114.1694,
markers: [{
lat: 22.3193,
lng: 114.1694,
info: "this is a marker at 22.3193,114.1694"
}]
},
{
lat: 22.3255,
lng: 114.3532
},
{
lat: 23.3532,
lng: 115.1234
}
];
let elements = ['maps', 'map-rec-one', 'map-rec-two', 'map-rec-three']; // array of html element ids
window.addEventListener('load',
function() {
for (i = 0; i < elements.length; i++) {
initMap(locations[i], elements[i], new google.maps.InfoWindow());
console.log(elements[i]);
console.log(locations[i])
}
}, false);
function initMap(location, element, infowindow) {
console.log(location)
console.log(element)
map = new google.maps.Map(document.getElementById(element), {
zoom: 4,
center: location
});
if (location.markers) {
for (var i = 0; i < location.markers.length; i++) {
createMarker(location.markers[i], map, infowindow);
}
}
}
function createMarker(location, map, infowindow) {
let marker = new google.maps.Marker({
position: location,
map: map
});
google.maps.event.addListener(marker, 'click', function(evt) {
infowindow.setContent(location.info);
infowindow.open(map, marker);
})
}
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#maps,
#map-rec-one,
#map-rec-two,
#map-rec-three {
height: 100%;
width: 25%;
float: right;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Complex Marker Icons</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=initialize&libraries=&v=weekly" defer></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="maps"></div>
<div id="map-rec-one"></div>
<div id="map-rec-two"></div>
<div id="map-rec-three"></div>
</body>
</html>

How to get the GeoJSON of my geofence in Google Maps API?

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>

Javascript - Trigger Click on Page Load

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>

Google Maps API V3: Exclude single marker from clustering

I am using the google maps api and using grid clustering for the markers. I wanted to know if there is a way to exclude a single marker from clustering. I want a "You are here" marker that is always visible. I tried using a different array for just that marker and not including it the cluster function but that didn't work.
Does anyone have a solution for this?
Here is how i am doing the clustering
$(document).on('click', '#mapbut', function() {
var items, distances, you_are_here = [], markers_data = [], markers_data2 = [], fred, clust1, markss;
you_are_here.push({
lat : Geo.lat,
lng : Geo .lng,
animation: google.maps.Animation.DROP,
title : 'Your are here',
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 10
},
infoWindow: {
content: '<p>You are Here</p>'
}
});
function loadResults (data) {
if (data.map.length > 0) {
items = data.map;
for (var i = 0; i < items.length; i++)
{
var item = items[i];
var distances = [];
var dist2;
if (item.Lat != undefined && item.Lng != undefined)
{
markers_data.push({
lat : item.Lat,
lng : item.Lng,
title : item.Site,
infoWindow: {
content: '<p>' + item.Site + '</p><p>' + Math.round(item.distance) + ' miles away</p>'
}
});
}
}
}
map.addMarkers(markers_data);
map = new GMaps({
el: '#map',
lat: Geo.lat,
lng: Geo.lng,
zoom: 10,
mapTypeControl: false,
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_CENTER
},
markerClusterer: function(map) {
options = {
gridSize: 50
}
clust1 = new MarkerClusterer(map,[], options);
return clust1;
},
scaleControl: true,
streetViewControl: false
});
map.addMarkers(you_are_here);
The GMaps clusters all the markers you add to it with the addMarker method (if you provide a MarkerClusterer).
One option: add your "special" marker (the one that you don't want clustered) to the map manually, so it isn't added to the MarkerClusterer:
The GMaps.map property is a reference to the Google Maps Javascript API v3 map object. So this will add a marker to the map without letting the GMaps library know about it:
you_are_here = new google.maps.Marker({
position: {lat: Geo.lat,lng: Geo.lng},
animation: google.maps.Animation.DROP,
title: 'Your are here',
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 10
},
map: map.map
});
proof of concept fiddle
code snippet:
var Geo = {
lat: 40.7281575,
lng: -74.07764
};
$(document).on('click', '#mapbut', function() {
var items, distances, you_are_here = [],
markers_data = [],
markers_data2 = [],
fred, clust1, markss;
function loadResults(data) {
if (data.map.length > 0) {
items = data.map;
for (var i = 0; i < items.length; i++) {
var item = items[i];
var distances = [];
var dist2;
if (item.Lat != undefined && item.Lng != undefined) {
markers_data.push({
lat: item.Lat,
lng: item.Lng,
title: item.Site,
infoWindow: {
content: '<p>' + item.Site + '</p><p>' + Math.round(item.distance) + ' miles away</p>'
}
});
}
}
}
map = new GMaps({
el: '#map',
lat: Geo.lat,
lng: Geo.lng,
zoom: 8,
mapTypeControl: false,
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_CENTER
},
markerClusterer: function(map) {
options = {
gridSize: 50,
imagePath: "https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m"
}
clust1 = new MarkerClusterer(map, [], options);
return clust1;
},
scaleControl: true,
streetViewControl: false
});
map.addMarkers(markers_data);
you_are_here = new google.maps.Marker({
position: {
lat: Geo.lat,
lng: Geo.lng
},
animation: google.maps.Animation.DROP,
title: 'Your are here',
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 10
},
infoWindow: {
content: '<p>You are Here</p>'
},
map: map.map
});
// map.addMarkers(you_are_here);
}
loadResults(data);
});
var data = {
map: [{
Lat: 40.7127837,
Lng: -74.005941,
Site: "New York, NY",
distance: 1
}, {
Site: "Newark, NJ",
Lat: 40.735657,
Lng: -74.1723667,
distance: 2
}]
};
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://rawgit.com/HPNeo/gmaps/master/gmaps.js"></script>
<script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerclustererplus/src/markerclusterer.js"></script>
<input id="mapbut" type="button" value="map" />
<div id="map"></div>
To get around this is relatively simple, just after I send the markers array to MarkerClusterer I then add my location.
// Setup cluster markers
var markerCluster = new MarkerClusterer( gmap.map, options )
// add my location
gmap.addMarker({
lat: data.latitude,
lng: data.longitude
...
})
Thanks

Categories

Resources