I am trying to clean up google maps polylines once I render other ones. It works with the markers but with the polylines they stayed. I check google maps api google maps api
and couldn't make it work. It looks for me I am doing something wrong in the order but I have tried many ways and I can't find the solution.
function addMarkers(markerPosition: any, id?: number) {
// Creating markers
const position = { lat: markerPosition._latitude, lng: markerPosition._longitude };
marker = map && new window.google.maps.Marker({
map,
position,
id,
});
// Add listener to markers
marker.addListener('click', () => {
dispatch(getStop(id));
});
// Creating poliLine route
pathToRender.push(position);
// Focus on the markers
loc = map && new window.google.maps.LatLng(marker.position.lat(), marker.position.lng());
bounds.extend(loc);
return markers.push(marker);
}
useEffect(() => {
setStopInfo(stop.stop);
// stop.stop.userName !== '' && setPopUp(stop.stop);
}, [stop]);
function setPolyLine(pathRout: any) {
routePath = new window.google.maps.Polyline({
path: pathToRender,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2,
});
routePath.setMap(pathRout);
}
function setMapOnAll(mapToRender: any) {
for (let i = 0; i < markers.length; i += 1) {
markers[i].setMap(mapToRender);
}
map.fitBounds(bounds);
map.panToBounds(bounds);
}
function clearMarkers() {
setMapOnAll(null);
setPolyLine(null);
}
function markersAdministration(routeChoose: number) {
const route = showRoutes[routeChoose];
setMapConfig({ center: { lat: 40, lng: 10 }, zoom: 5, disableDefaultUI: false });
// Clear Markers
clearMarkers();
markers = [];
pathToRender = [];
// Add stops, destination and origin to the markers
addMarkers(route.origin.point);
route.stops && route.stops.map((routeStop: IStops) => addMarkers(routeStop.point, routeStop.id));
addMarkers(route.destination.point);
// Setting up markers and lines layers
setMapOnAll(map);
setPolyLine(map);
}
Thank you for the help.
I solve it, I don't know why it didn't work before but it is working now.
function setMapOnAll(mapToRender: any) {
// Create Markers
for (let i = 0; i < markers.length; i += 1) {
markers[i].setMap(mapToRender);
}
// Create Polyline
routePath = new window.google.maps.Polyline({
path: pathToRender,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2,
});
routePath.setMap(mapToRender);
// Map focus on Bounds
map.fitBounds(bounds);
map.panToBounds(bounds);
}
function clearMarkers() {
routePath && routePath.setMap(null);
setMapOnAll(null);
}
Related
Hi I'm New to Google maps Api , I created polygons in google maps, i want to find out which polygon i clicked, I tried but i'm not able to find out , here is my code
function initialize() {
var mapOptions = {
zoom: 14,
center: new google.maps.LatLng(12.9648451,77.5741997),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var arr = new Array();
var polygons = [];
var bounds = new google.maps.LatLngBounds();
var coordinates = [];
// downloadUrl("subdivision-coordinates.php", function(data) {
var xmlString = '<subdivisions><subdivision name="Auburn Hills"><coord lat="12.973111130721453" lng="77.54373550415039"/><coord lat="12.929112653428087" lng="77.53360748291016"/><coord lat="12.936306851970127" lng="77.57635116577148"/></subdivision><subdivision name="Vanderveen"><coord lat="12.97227473026135" lng="77.59489059448242"/><coord lat="12.952200275819832" lng="77.58750915527344"/><coord lat="12.95487696326559" lng="77.60536193847656"/></subdivision></subdivisions>';
//var xmlString =$('#xml_values').val();
var xml = xmlParse(xmlString);
var subdivision = xml.getElementsByTagName("subdivision");
for (var i = 0; i < subdivision.length; i++) {
arr = [];
var coordinates = xml.documentElement.getElementsByTagName("subdivision")[i].getElementsByTagName("coord");
//console.log("coordinates="+xml.documentElement.getElementsByTagName("subdivision")[i].getElementsByTagName("coord"));
for (var j=0; j < coordinates.length; j++) {
arr.push(new google.maps.LatLng(
parseFloat(coordinates[j].getAttribute("lat")),
parseFloat(coordinates[j].getAttribute("lng"))
));
bounds.extend(arr[arr.length-1])
//console.log("arr lenghth="+arr.length+"___"+arr[arr.length-1]+"|___|"+coordinates[j])
}
polygons.push(new google.maps.Polygon({
paths: arr,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
}));
polygons[polygons.length-1].setMap(map);
google.maps.event.addListener(polygons[polygons.length-1], 'click', function (event) {
alert(JSON.stringify(event));
});
}
map.fitBounds(bounds);
function xmlParse(str) {
if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
}
if (typeof DOMParser != 'undefined') {
return (new DOMParser()).parseFromString(str, 'text/xml');
}
return createElement('div', null);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
How to identify which polygon is clicked using polygon number in google maps api
When you create the polygon, add an additional property to identify the polygon, e.g.
polygons.push(new google.maps.Polygon({
id: i,
paths: arr,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
}));
Then in your event listener, you should be able to get this from the this scope of that polygon:
polygons[polygons.length-1].addListener('click', function (event) {
console.log(this.id);
});
Below is a map to demonstrate the type of output I would like to achieve.
However, when I fetch the coordinates from the database I don't know how to draw them on Google Maps in order to get this type of output. I use this code but I don't how to put coordinates in this code from the database.
var MapPoints = '[{"address":{"address":"plac Grzybowski, Warszawa, Polska","lat":"52.2360592","lng":"21.002903599999968"},"title":"Warszawa"},{"address":{"address":"Jana Paw\u0142a II, Warszawa, Polska","lat":"52.2179967","lng":"21.222655600000053"},"title":"Wroc\u0142aw"},{"address":{"address":"Wawelska, Warszawa, Polska","lat":"52.2166692","lng":"20.993677599999955"},"title":"O\u015bwi\u0119cim"}]';
var MY_MAPTYPE_ID = 'custom_style';
function initialize() {
if (jQuery('#map').length > 0) {
var locations = jQuery.parseJSON(MapPoints);
window.map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
});
var infowindow = new google.maps.InfoWindow();
var flightPlanCoordinates = [];
var bounds = new google.maps.LatLngBounds();
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].address.lat, locations[i].address.lng),
map: map
});
flightPlanCoordinates.push(marker.getPosition());
bounds.extend(marker.position);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i]['title']);
infowindow.open(map, marker);
}
})(marker, i));
}
map.fitBounds(bounds);
var flightPath = new google.maps.Polyline({
map: map,
path: flightPlanCoordinates,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
You're adding markers to the map so you can extract their coordinates to make a polyline. You can cut out the middleman and use the LatLngs to make the polyline.
$('document').ready(function() {
initialize();
});
// You don't need google.maps.event.addDomListener(window, 'load', initialize);
// if you use jQuery's $(document).ready() function.
function initialize() {
var flightPathCoordinates = [];
// Get the data from the server.
$.get(
"url/of/serverScript.php", // Wherever you're getting your var MapPoints JSON.
function(response) {
var locations = $.parseJSON(response);
var coordinatePair;
for (i = 0; i < locations.length; i++) {
coordinatePair = new google.maps.LatLng(locations[i].address.lat,
locations[i].address.lng);
flightPathCoordinates.push(coordinatePair);
}
}); // end $.get()
// Create the map.
map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
});
// Create the polyline.
var flightPath = new google.maps.Polyline({
map: map,
path: flightPlanCoordinates,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2
});
// Add it to the map.
flightPath.setMap(map);
}
Note: You can use $ instead of jQuery. e.g. these are equivalent: jQuery('#map') $('#map')
I am loading a data layer in a google map, over a certain country (it's a drawing over a country):
map.data.addGeoJson(geoJsonObject);
I am pretty sure there isn't, but... is there a way to check that the bounds of the map are inside the bounds of the data layer?
(basically, I want to know, when the user navigates on the map, if the current viewport is inside data layer);
var bounds = this.map.getBounds();
var sw = bounds.getSouthWest();
Maybe I can query the data layer in the position of the south west bound and check for some props. indicating that I am inside that data layer?
Or at least:
Does anyone know a way how to get a certain feature object programmatically, knowing the lat and long?
Here the google maps uses events to get to the feature object:
map.data.addListener('click', function(event) {
event.feature.setProperty('isColorful', true);
});
But I do not want to use events. Is there a method to supply the coordinates of a point and get to the feature object?
Something like:
map.getFeature(lat, long).setProperty('isColorful', true);
google.maps.LatLngBounds.contains function could be utilized for that purpose, but since it accepts a single location, the following solution is suggested:
1) initialize data layer bounds from GeoJSON coordinates:
var dataLayer = map.data;
var layerBounds = new google.maps.LatLngBounds();
//1.collect all coordinates from data layer
dataLayer.forEach(function(f) {
var geometry = f.getGeometry();
processCoordinates(geometry, layerBounds.extend, layerBounds);
});
2) determine whether map bounds are within a layer bounds:
if (layerBounds.contains(map.getBounds().getNorthEast()) && layerBounds.contains(map.getBounds().getSouthWest())) {
//...
}
Working example
In the provided example green colored area will be displayed if map
bounds are within a layer bounds, and the red colored in
the opposite case:
var area;
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 53.349248,
lng: -6.255323
},
zoom: 6,
mapTypeId: google.maps.MapTypeId.TERRAIN
});
displayDataLayer(map);
document.getElementById("btnShow").onclick = function() {
var result = displayDataLayerBoundsArea(map);
};
}
function displayDataLayer(map) {
var dataLayer = map.data;
dataLayer.loadGeoJson('https://gist.githubusercontent.com/vgrem/440708612b574764c309/raw/2a4e2feadc204806440c51a14c2ef1f54f4fc3d8/Census2011_Province_generalised20m.json');
dataLayer.setMap(map);
}
function displayDataLayerBoundsArea(map) {
var dataLayer = map.data;
var layerBounds = new google.maps.LatLngBounds();
//1.collect all coordinates from data layer
dataLayer.forEach(function(f) {
var geometry = f.getGeometry();
processCoordinates(geometry, layerBounds.extend, layerBounds);
});
if (area != null) {
area.setMap(null);
}
//2.determine whether map bounds are contained within a layer bounds
if (layerBounds.contains(map.getBounds().getNorthEast()) && layerBounds.contains(map.getBounds().getSouthWest())) {
//map.fitBounds(bounds);
area = new google.maps.Rectangle({
strokeColor: '#00FF00',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#00FF00',
fillOpacity: 0.35,
map: map,
bounds: {
north: layerBounds.getNorthEast().lat(),
south: layerBounds.getSouthWest().lat(),
east: layerBounds.getNorthEast().lng(),
west: layerBounds.getSouthWest().lng()
}
});
} else {
//map.fitBounds(bounds);
area = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
bounds: {
north: layerBounds.getNorthEast().lat(),
south: layerBounds.getSouthWest().lat(),
east: layerBounds.getNorthEast().lng(),
west: layerBounds.getSouthWest().lng()
}
});
}
}
function processCoordinates(geometry, callback, thisArg) {
if (geometry instanceof google.maps.LatLng) {
callback.call(thisArg, geometry);
} else if (geometry instanceof google.maps.Data.Point) {
callback.call(thisArg, geometry.get());
} else {
geometry.getArray().forEach(function(g) {
processCoordinates(g, callback, thisArg);
});
}
}
#map {
width: 800px;
height: 640px;
}
<button id="btnShow">Show</button>
<div id="map"></div>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
JSFiddle
I have some sample polylines here where I am trying to fire double click event on each polylines.
I tried with,
google.maps.event.addListener(poly, 'dblclick', (function (poly, i) {
alert();
})(poly, i));
Butit gives the alert on loading the map only. So how can I fire double click event on polylines?
Two issues:
There is no function for your dblclick listener as written, the alert is run immediately and its return value is used as the click listener function.
Once the infowindow opens on the click listener, it blocks the polyline so it doesn't get the second click
If I move the infowindow so it doesn't block the second click and fix the dblclick event listener function, it works.
proof of concept fiddle
code snippet:
(note that alert doesn't work in the code snippet, produces this error: Ignored call to 'alert()'. The document is sandboxed, and the 'allow-modals' keyword is not set.)
var map;
var infowindow = new google.maps.InfoWindow();
function initialize() {
var mapOptions = {
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var bounds = new google.maps.LatLngBounds();
var polygons = [];
var arr = new Array();
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
for (var i in coordinates) {
arr = [];
for (var j = 0; j < coordinates[i].length; j++) {
arr.push(new google.maps.LatLng(
parseFloat(coordinates[i][j][0]),
parseFloat(coordinates[i][j][1])));
bounds.extend(arr[arr.length - 1])
}
var lineSymbol = {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
// strokeWeight: 1,
scale: 4
};
var strOp = 1;
var icons = [];
if (i == "feed5") {
icons = [{
icon: lineSymbol,
offset: '0',
repeat: '20px'
}];
strOp = 0;
}
// Construct the polygon.
polygons.push(new google.maps.Polyline({
path: arr,
strokeColor: '#FF0000',
strokeOpacity: strOp,
strokeWeight: 2,
icons: icons,
}));
var poly = polygons[polygons.length - 1];
poly.setMap(map);
google.maps.event.addListener(poly, 'dblclick', (function(poly, i) {
return function() {
alert();
}
})(poly, i));
google.maps.event.addListener(poly, 'click', (function(poly, i) {
return function(event) {
infowindow.setContent("" + i);
infowindow.setPosition(google.maps.geometry.spherical.computeOffset(event.latLng, 90, 10000));
infowindow.open(map);
};
})(poly, i));
}
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, 'load', initialize);
// Define the LatLng coordinates for the polygon's path.
var coordinates = {
"feed1": [
[12.991838, 77.70851],
[12.9912195, 77.707405],
[12.989732, 77.705246],
[12.989732, 77.70416]
],
"feed2": [
[12.999084, 77.71209],
[13.004616, 77.71334]
],
"feed3": [
[12.993468, 77.711845],
[12.992951, 77.71133],
[12.992114, 77.71015],
[12.99217, 77.708626],
[12.991289, 77.70722],
[12.989901, 77.70519],
[12.989763, 77.70434]
],
"feed4": [
[13.298387, 77.55231],
[13.297882, 77.552536],
[13.295542, 77.55311],
[13.293249, 77.55186],
[13.29154, 77.551544],
[13.290586, 77.55115],
[13.290111, 77.54973],
[13.288905, 77.54885],
[13.286778, 77.54691],
[13.28569, 77.54599],
[13.283473, 77.54516],
[13.28245, 77.54316],
[13.279767, 77.54178],
[13.278179, 77.541046],
[13.276475, 77.540146],
[13.276237, 77.53926]
],
"feed5": [
[13.295467, 77.55559],
[13.296861, 77.55374],
[13.298651, 77.55295]
]
};
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map-canvas"></div>
Remove click listener and try like this:
google.maps.event.addListener(poly, 'dblclick', function() {
alert("test");
});
Listener won't work both click and dblclick
i am calling initialize function on parks tag class then club tag class then map reload again i want to stop map reload and print parks when click on parks class and print clubs when click clubs class.the same functionality works on some other types.
function initialize(lat, lon, typ) {
var pyrmont = new google.maps.LatLng(lat,lon);
map = new google.maps.Map(document.getElementById('map'), {
center: pyrmont,
zoom: 15
});
//var latlng = new google.maps.LatLng(-24.397, 140.644);
var request = {
location: pyrmont,
radius: 400,
types: [typ]
};
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
var myCity = new google.maps.Circle({
center: pyrmont,
radius: 500,
strokeColor: "#0000FF",
strokeOpacity: 0.8,
strokeWeight: 1,
fillColor: "#0000FF",
fillOpacity: 0.1,
editable: true
});
myCity.setMap(map);
}
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location,
icon:'icone/'+typ+'.png',
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
You won't want to run your initialize function again, because it will try to create another map.
To find the new set of places, you simply need to change your request array and call the nearbySearch function again. Here is the order of things you need to do when the user changes the 'Type'.
Request array is changed to have the new type (request = {......})
searchNearby function is called again to pull in the new Places
In the callback function, clear the markers from the old 'Type' off of the map
To do all of this, you should make your map a global variable so that you can reference it from any function. Similarly, you should store your Markers in a global array so that you can loop through it to easily remove them when a new type is selected.