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

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>

Related

Google Maps - Looping through array for polyline

I want to loop through an array of coordinates that I want to use for markers and drawing a line in google maps.
Is there a solution to create the path property with a loop of const locations?
Please check my example below:
const lineSymbol = {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
strokeColor: "red",
scale: 4
};
const locations = [
["Tampere", 61.50741562413278, 23.75886761967578, 1, "Termin: xx.xx"],
["Helsinki", 60.219957, 25.196776, 2, "test2"],
["Travemünde", 55.778989, 18.271974, 2, "test3"],
["Stuttgart", 48.7733567672875, 9.174572759931003, 3, "test4"],
["Ludwigsburg", 48.8893286910321, 9.197454231637288, 4, "test5"],
]
const line = new google.maps.Polyline({
path: [
{ lat: locations[0][1], lng: locations[0][2] },
{ lat: 60.219957, lng: 25.196776 },
{ lat: locations[2][1], lng: locations[2][2] },
{ lat: 53.941362, lng: 10.860464 },
{ lat: 48.7733567672875, lng: 9.174572759931003 },
],
strokeColor: "red",
scale: 7,
icons: [
{
icon: lineSymbol,
offset: "100%",
},
],
map: map,
});
By using above code it creates in Google Maps this:
The result
To process your input array and create a polyline in a loop:
var path = [];
for (var i=0; i<locations.length; i++) {
// add to polyline
path.push({lat: locations[i][2], lng: locations[i][1]});
// create marker
new google.maps.Marker({
position: path[path.length-1],
map: map
})
}
const line = new google.maps.Polyline({
path: path,
strokeColor: "red",
scale: 7,
icons: [
{
icon: lineSymbol,
offset: "100%",
},
],
map: map,
});
proof of concept fiddle
(note that the data in your question doesn't match your picture)
code snippet:
// This example creates a 2-pixel-wide red polyline showing the path of
// the first trans-Pacific flight between Oakland, CA, and Brisbane,
// Australia which was made by Charles Kingsford Smith.
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 3,
center: {
lat: 0,
lng: -180
},
mapTypeId: "terrain",
});
const lineSymbol = {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
strokeColor: "red",
scale: 4
};
const locations = [
["Tampere", 61.50741562413278, 23.75886761967578, 1, "Termin: xx.xx"],
["Helsinki", 60.219957, 25.196776, 2, "test2"],
["Travemünde", 55.778989, 18.271974, 2, "test3"],
["Stuttgart", 48.7733567672875, 9.174572759931003, 3, "test4"],
["Ludwigsburg", 48.8893286910321, 9.197454231637288, 4, "test5"],
]
var path = [];
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < locations.length; i++) {
path.push({
lat: locations[i][2],
lng: locations[i][1]
});
bounds.extend(path[path.length - 1]);
new google.maps.Marker({
position: path[path.length - 1],
map: map
})
}
const line = new google.maps.Polyline({
path: path,
strokeColor: "red",
scale: 7,
icons: [{
icon: lineSymbol,
offset: "100%",
}, ],
map: map,
});
map.fitBounds(bounds);
}
/* 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 Polylines</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="map"></div>
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly&channel=2" async></script>
</body>
</html>

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>

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

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>

Google maps don't display circles with certain coordinates

I have a set of data about earthquakes, which I need to display it on the google map using circles. At first I used marker to make sure maps work properly. Markers was displayed fine. Then I tried to draw circles with certain radius and coordinates the same as markers, unfortunately they wasn't drown. I found google's tutorial for circles with US cities, which works correct.
After some tests I understood that my problem somehow is related with point coordinates. I can't say what exactly wrong with coordinates, because they are object { lat: val, lng: val } and there isn't any errors, circles just aren't displayed.
I made this gist (please don't steal my api key:)) in order to you can see it for yourself. Hope someone has enough experiences in google maps to know that is wrong (looks like there is no other way to understand the problem). I use google maps for the first time.
As advised by geocodezip, if the calculated 'radius' values are too small may be the reason for not drawing the circle.
As per below calculation, radio is calculated as 2 to the power of 3.3 or 2 raised to 3.3 ( magnitude ), which is 9.849 divided by 2 = 4.924 which is the small to plot for a circle I guess.
Calculation:
radius: Math.pow(2, testEvents[event].magnitude) / 2.0
So I have increased the magnitude values to 17.3, 17.4, 15.4, 15.3 for all of the testEvents objects
and now I am able to see the circles for those markers; see the screen shot attached. Fiddle link attached too.
[![<!DOCTYPE html>
<html>
<head>
</head>
<style>
.map {
height: 500px;
}
</style>
<body>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div>
<div class="row">
<div class="col-md-6 map" id="map1"></div>
<div class="col-md-6 map" id="map2"></div>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=your_api_key&callback=initMap">
</script>
<script>
var map1;
var map2;
var citymap = {
chicago: {
center: { lat: 41.878, lng: -87.629 },
population: 2714856
},
newyork: {
center: { lat: 40.714, lng: -74.005 },
population: 8405837
},
losangeles: {
center: { lat: 34.052, lng: -118.243 },
population: 3857799
},
vancouver: {
center: { lat: 49.25, lng: -123.1 },
population: 603502
}
};
var testEvents = {
0: {
point: { lat: 85.09, lng: 15.91 },
magnitude: 17.3
},
1: {
point: { lat: 84.22, lng: 2.85 },
magnitude: 17.4
},
2: {
point: { lat: 85.04, lng: 11.79 },
magnitude: 15.4
},
3: {
point: { lat: 85.25, lng: 13.22 },
magnitude: 15.3
}
};
function initMap() {
map1 = new google.maps.Map(document.getElementById('map1'), {
zoom: 2,
center: new google.maps.LatLng(74.370702, 34.767772),
mapTypeId: 'satellite'
});
map2 = new google.maps.Map(document.getElementById('map2'), {
zoom: 2,
center: new google.maps.LatLng(74.370702, 34.767772),
mapTypeId: 'satellite'
});
WriteQuakeEvents();
}
function WriteQuakeEvents() {
for (var city in citymap) {
// Add the circle for this city to the map.
var cityCircle = new google.maps.Circle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map2,
center: citymap\[city\].center,
radius: Math.sqrt(citymap\[city\].population) * 100
});
}
for (var event in testEvents) {
var marker = new google.maps.Marker({
position: testEvents\[event\].point,
map: map1
});
var circle = new google.maps.Circle({
strokeColor: '#FFFFFF',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.2,
map: map1,
center: testEvents\[event\].point,
radius: Math.pow(2, testEvents\[event\].magnitude) / 2.0
});
}
}
</script>
</div>
</body>
</html>][1]][1]
//Fiddle here:

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>

Categories

Resources