I want to delete a google map direction markers after a search without reloading the page. I've made an example but its not working :
//First of all testing if there is already a direction on the map
if(directionsService != null)
{
directionsService.setMap(null);
directionsService = null;
}
//Then display the new one
var origin = $('#de').val();
var destination = $('#en').val();
var request = {
origin : origin,
destination : destination,
travelMode : google.maps.DirectionsTravelMode.DRIVING
}
var directionsService = new google.maps.DirectionsService();
directionsService.route(request, function(response, status){
if(status == google.maps.DirectionsStatus.OK){
direction.setDirections(response);
showSteps(response);
}
});
all this code is on a function called by a click event
<button id="envoyer" id=="env" onclick="javascript:c()">Send</button>
so any one have an idea thanks !
Update
function showSteps(directionResult) {
var markerArray = [];
var myRoute = directionResult.routes[0].legs[0];
for (var i = 0; i < myRoute.steps.length; i++) {
var marker = new google.maps.Marker({
position: myRoute.steps[i].start_location,
map: map
});
attachInstructionText(marker, myRoute.steps[i].instructions);
markerArray[i] = marker;
}
}
When clearing the itinerary, using directionsService.setMap(null); you will have to remove the MapMarkers, which aren't directly connected to the Direction - Service, seperately too.
You have already stored them in markerArray inside of your showSteps - function, so you would need to move this variable out of the function into an outer scope or let the function return it to be able to access it.
By doing this, you can simply loop over the markerArray and call .setMap(null) on each stored Marker, thus removing them from the map.
var markerArray = [];
function showSteps(directionResult){
// your code
}
//function to remove MapMarkers
function removeMapMarkers(){
for(var i=0; i<markerArray.length; i+=1){
markerArray[i].setMap(null)
}
markerArray = [];
}
Related
I am getting back a ZERO RESULTS status when I make a call using the google directions service when I shouldn't, as far as I can see. I have walked through the debugger and it looks like my values are correct. I am using the directions service route method with waypoints. For origin, I need to use lat, lng vals because that is constantly changing, but for waypoints and destination, I use a full address. Waypoint addresses don't have country at end and stops at US state, but destination does have country value in the address. I wouldn't think that's a problem. All addresses are in the US, even in the same state.
Anybody see something wrong with my code and how it could be causing this, assuming the values being filled in are correct?
function setRoute() {
var wayPts = "";
var cAddress = $("#companyAddr").text();
//slice the zip code off
cAddress = cAddress.slice(0, -6);
var driverDisplay = $("#orders").find('.driverDisplay');
for (i = 0; i < driverDisplay.length; i++){
var directionsService = new google.maps.DirectionsService();
var dlats = $(driverDisplay[i]).find('.dLat');
var dlat = $(dlats[0]).text();
var dlngs = $(driverDisplay[i]).find('.dLng');
var dlng = $(dlngs[0]).text();
dLatLng = new google.maps.LatLng($('#driverLat').text(), $('#driverLng').text());
var stops = [];
var delAddrs = $(driverDisplay[i]).find('.dAddr');
for (var x = 0; x < delAddrs.length; x++) {
var delAddr = $(delAddrs[x]).text();
stops.push({ location: delAddr, stopover: true});
}
var request = {
origin: dLatLng,
destination: cAddress,
waypoints: stops,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
console.trace(status);
var data = response;
//$('#eta').text(response.routes[0].legs[0].duration.text);
}
//else { $('#eta').text("?") }
});
}
}
You create these variables but then don't seem to use them:
var dlats = $(driverDisplay[i]).find('.dLat');
var dlat = $(dlats[0]).text();
var dlngs = $(driverDisplay[i]).find('.dLng');
var dlng = $(dlngs[0]).text();
I think one problem might be here:
dLatLng = new google.maps.LatLng($('#driverLat').text(), $('#driverLng').text());
jQuery's text() function returns a string. Google Maps' LatLng constructor expects floating point numbers. Right now this is probably doing something like:
dLatLng = new google.maps.LatLng('1.234', '5.678');
You should make sure those are floats by doing:
dLatLng = new google.maps.LatLng(parseFloat($('#driverLat').text()), parseFloat($('#driverLng').text()));
This question already has answers here:
Google Maps JS API v3 - Simple Multiple Marker Example
(15 answers)
Closed 8 years ago.
I am trying to add 3 markers to a map and when click on the markers, an info window will be shown. But every array element inside google.maps.event.addListener becomes undefined.
What's the problem?
<div id="map-canvas2" style="width:100%;height:500px"></div>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script>
var num;
var marker;
var infoWindow;
var infoText;
var lat;
var lng;
var map;
function initialize() {
num = 3;
marker = [];
infoWindow = [];
infoText = [];
lat = [];
lng = [];
infoText[0] = "test1";
lat[0] = 22.420845;
lng[0] = 114.208705;
infoText[1] = "test2";
lat[1] = 22.416026;
lng[1] = 114.209321;
infoText[2] = "test3";
lat[2] = 22.420841;
lng[2] = 114.205188;
for (var i = 0; i < num; i++) {
marker[i]=new google.maps.Marker({
position:new google.maps.LatLng(lat[i], lng[i]),
});
infoWindow[i] = new google.maps.InfoWindow({
content:"<div>"+infoText[i]+"</div>"
});
}
var mapOptions = {
zoom: 17,
center: new google.maps.LatLng(22.420458,114.207482)
};
map = new google.maps.Map(document.getElementById('map-canvas2'), mapOptions);
for (var i = 0; i < num; i++) {
marker[i].setMap(map);
google.maps.event.addListener(marker[i], 'click', function() {
new google.maps.InfoWindow({
content:"<div>"+infoText[i]+"</div>"
}).open(map,marker[i]);
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
The problem:
Each event listener is referencing the same variable i which gets incremented on each pass of the for loop. So after the loop is finished the value of i is 3, but none of your arrays have an index of 3 so you get undefined. Because each event handler is referencing the same i variable they are all referencing the same undefined array values.
The solution: Create a closure so that the event handler for each marker has a it's own variable instead sharing reference to single variable.
for (var i = 0; i < num; i++) {
marker[i].setMap(map);
google.maps.event.addListener(marker[i], 'click', (function(index) {
return function() {
new google.maps.InfoWindow({
content: "<div>"+infoText[index]+"</div>"
}).open(map, marker[index]);
}
})(i));
}
What we're doing is creating a Immediately-Invoked Function Expression "IIFE". The IIFE has a parameter called index which is set to the value of i. Because variables have function scope, index belongs only to this function. Inside the IIFE we return a function that will do the actual work when the event is triggered, but it will reference index not i.
Don't send indexed parameters to an anonymous function:
for (var i = 0; i < num; i++) {
var mrk = marker[i];
var iwContent = infoText[i];
mrk.setMap(map);
google.maps.event.addListener(mrk, 'click', function() {
new google.maps.InfoWindow({
content:"<div>"+iwContent+"</div>"
}).open(map,mrk);
});
}
http://rca2.com/mapping/thispageblinks.htm
http://rca2.com/mapping/doesnotremove.htm
The second example really doesn't do anything without continuously updated xml data.
I'm converting (finally!) my map applications from Google v2 to v3. In v2, the application read in xml data every 5 seconds, cleared markers, then new markers were created and placed on the map. The ability to clear the map overlay using map.clearOverlays() no longer exists in v3. The suggested solution is to keep track of the old markers, then remove them. Clearing the markers in a loop prior to creating new markers is easy to do, and works. Except for the fact that the markers blink when replaced more often than not. This is very distracting, and highly undesirable since this did not happen in v2.
I decided that I should compare the new marker data to the old marker data. If the location and icon color stayed the same, both old and new markers are basically ignored. For the sake of clarity, the icon color signifies a status of the vehicle represented by the icon. In this case the application is to track ambulance activity, so green would be available, blue would be en-route, etc.
The code handles the checking of the new and old markers fine, but for some reason, it will never remove the old marker when a marker (unit) moves. I saw suggestions about setMap() being asynchronous. I also saw suggestions about the arrays not being google.maps.Marker objects. I believe that my code handles each of these issues correctly, however the old markers are still never removed.
I've also made sure that my marker arrays are global variables. I am also using the variable side_bar_html to display information about which markers were supposed to be removed, and which markers were supposed to be added. The added markers are being added just fine. I just don't know where to turn next. Any help you could offer would be greatly appreciated.
function getMarkers() {
// create a new connection to get our xml data
var Connect = new XMLHttpRequest();
// send the get request
Connect.open("GET", xml_file, false);
Connect.setRequestHeader("Content-Type", "text/xml");
Connect.send(null);
// Place the response in an XML document.
var xmlDoc = Connect.responseXML;
// obtain the array of markers and loop through it
var marker_data = xmlDoc.documentElement.getElementsByTagName("marker");
// hide the info window, otherwise it still stays open where a potentially removed marker used to be
infowindow.close();
// reset the side_bar and clear the arrays
side_bar_html = "";
markerInfo = [];
newMarkers = [];
remMarkers = [];
addMarkers = [];
// obtain the attributes of each marker
for (var i = 0; i < marker_data.length; i++) {
var latData = marker_data[i].getAttribute("lat");
var lngData = marker_data[i].getAttribute("lng");
var minfo = marker_data[i].getAttribute("html");
var name = marker_data[i].getAttribute("label");
var icontype = marker_data[i].getAttribute("icontype");
var unitNum = marker_data[i].getAttribute("unitNum");
var llIcon = latData + lngData + icontype;
zIndexNum = zIndexNum + 1;
// create the new marker data needed
var myLatLng = new google.maps.LatLng(parseFloat(latData), parseFloat(lngData));
var marker = {
position: myLatLng,
icon: gicons[icontype],
title: "",
unitIcon: unitNum,
unitLLIData: llIcon,
zIndex: zIndexNum
};
// add a line to the side_bar html
// side_bar_html += '<a href="javascript:myclick(' + i + ')">' + name + '<\/a><br />';
// add an event listeners on the marker
addInfoWindow(marker, minfo);
// save the current data for later comparison
markerInfo.push(minfo);
newMarkers.push(marker);
}
// now loop thru the old marker data and compare to the new, to see if we need to remove any old markers
var refreshIt = true;
var removeIt = true;
var currNumber = "";
var currLLIcon = "";
var lastNumber = "";
var lastLLIcon = "";
for (var i = 0; i < newMarkers.length; i++) {
currNumber = newMarkers[i].unitIcon;
currLLIcon = newMarkers[i].unitLLIData;
for (var j = 0; j < oldMarkers.length; j++) {
refreshIt = true;
lastNumber = oldMarkers[j].unitIcon;
lastLLIcon = oldMarkers[j].unitLLIData;
if (lastNumber == currNumber) {
if (currLLIcon == lastLLIcon) {
refreshIt = false;
} else {
refreshIt = true;
remMarkers.push(oldMarkers[j]);
}
break;
}
}
// if we need to refresh a marker, add it to our new array here
if (refreshIt == true) {
addMarkers.push(newMarkers[i]);
}
}
// then loop thru and see if any units are no longer on the map
for (var j = 0; j < oldMarkers.length; j++) {
removeIt = true;
lastNumber = oldMarkers[j].unitIcon;
for (var i = 0; i < newMarkers.length; i++) {
currNumber = newMarkers[i].unitIcon;
if (lastNumber == currNumber) {
removeIt = false;
break;
}
}
// if we need to refresh a marker, add it to our new array here
if (removeIt == true) {
remMarkers.push(oldMarkers[j]);
}
}
// now loop thru the old markers and remove them
for (var i = 0; i < remMarkers.length; i++) {
var marker = new google.maps.Marker(remMarkers[i]);
marker.setMap(null);
side_bar_html += 'removing ' + remMarkers[i].unitIcon + '<br />';
}
// then loop thru the new markers and add them
for (var i = 0; i < addMarkers.length; i++) {
var marker = new google.maps.Marker(addMarkers[i]);
marker.setMap(map);
side_bar_html += 'adding ' + addMarkers[i].unitIcon + '<br />';
}
// and last save the old markers array into oldMarkers
oldMarkers = [];
for (var i = 0; i < newMarkers.length; i++) {
oldMarkers.push(newMarkers[i]);
}
// put the assembled side_bar_html contents into the side_bar div, then sleep
document.getElementById("side_bar").innerHTML = side_bar_html;
setTimeout('getMarkers()', 5000);
}
For context purposes, here is the code that does clear the old markers, but many (not all) or the markers blink when refreshed, even if they don't in fact move loaction.
function getMarkers() {
// create a new connection to get our xml data
var Connect = new XMLHttpRequest();
// send the get request
Connect.open("GET", xml_file, false);
Connect.setRequestHeader("Content-Type", "text/xml");
Connect.send(null);
// Place the response in an XML document.
var xmlDoc = Connect.responseXML;
// obtain the array of markers and loop through it
var marker_data = xmlDoc.documentElement.getElementsByTagName("marker");
// hide the info window, otherwise it still stays open where the removed marker used to be
infowindow.close();
// now remove the old markers
for (var i = 0; i < oldMarkers.length; i++) {
oldMarkers[i].setMap(null);
}
oldMarkers.length = 0;
// reset the side_bar and clear the arrays
side_bar_html = "";
markerInfo = [];
newMarkers = [];
// obtain the attributes of each marker
for (var i = 0; i < marker_data.length; i++) {
var latData = marker_data[i].getAttribute("lat");
var lngData = marker_data[i].getAttribute("lng");
var minfo = marker_data[i].getAttribute("html");
var name = marker_data[i].getAttribute("label");
var icontype = marker_data[i].getAttribute("icontype");
var unitNum = marker_data[i].getAttribute("unitNum");
zIndexNum = zIndexNum + 1;
// create the new marker data needed
var myLatLng = new google.maps.LatLng(parseFloat(latData), parseFloat(lngData));
var marker = new google.maps.Marker({
position: myLatLng,
icon: gicons[icontype],
title: "",
unitIcon: unitNum,
zIndex: zIndexNum
});
// add a line to the side_bar html
side_bar_html += '<a href="javascript:myclick(' + i + ')">' + name + '<\/a><br />';
// add an event listeners on the marker
addInfoWindow(marker, minfo);
// save the current data for later comparison
markerInfo.push(minfo);
newMarkers.push(marker);
oldMarkers.push(marker);
}
// now add the new markers
for (var i = 0; i < newMarkers.length; i++) {
newMarkers[i].setMap(map);
}
// put the assembled side_bar_html contents into the side_bar div, then sleep
document.getElementById("side_bar").innerHTML = side_bar_html;
setTimeout('getMarkers()', 5000);
}
Finally figured out the solution. The process was reading in new xml data which was compared to the saved xml data, to determine if a marker needed to be moved or displayed in a different color on the map.
When I created a new marker object, I did not set the map: property, because I needed to compare the lat/lon/color of the new object to the old before I determined whether a marker needed to be moved. The problem was the map: property not being set. I save the marker data without the map: property set into the new marker array, then copied the new marker array into old marker array to do the next comparison. I should have copied the old marker object into the new marker array! The old marker object HAD the map: property set, and that allowed the Google mapping code to know which marker I wanted to remove.
Sorry for the stupid mistake, but I'm pretty new to Javascript.
Rich
I want to get back the elevation values from the code on the alert pop up like i am able to get the values of lat and lng. i am trying to get the three values (lat, lng and elevation heights) in an array so that i can later display the values using OpenGL but i am stuck on this part only as everything is working fine. This is the code i am using. thanks
var bounds = map.getBounds();
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
var nw = new google.maps.LatLng (ne.lat(), sw.lng());
var se = new google.maps.LatLng(sw.lat(), ne.lng());
for(var i = 0 ; i<= (ne.lat() - sw.lat()); i+=0.01)
{ for(var j =0 ; j<=(ne.lng() - sw.lng());j+=0.01)
{
var tmpele; //temp variable for elevation<br/>
lt.push(sw.lat()+i);<br/>
ln.push(sw.lng()+ j);<br/>
var d = new google.maps.LatLng((sw.lat()+i),(sw.lng()+ j));
loca.push(d);
el.push(pospoint(loca));
} }
alert(lt);
alert(ln);
alert(el);
}
function disp()
{
alert(el);
}
function pospoint(loca)
{
var tmp;
var positionalRequest = {
'locations': loca
}
elevationService.getElevationForLocations(positionalRequest, function(results, status) {
if (status == google.maps.ElevationStatus.OK) {
tmp=results;
// alert('got:'+tmp);
// return tmp;
}
});
return tmp;
}
The elevation service is asynchronous. You can't return anything from it, you can only use the data (when it is available) in the callback function.
This is create a Google map to pass n number of address one time in Google map that is not possible that's way I am passing function set interval (2 sections ) to each iteration function
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var n;
var j=1;
var array_list= new Array(n);
var array_storename=new Array(n);
function InitializeMap()
{
directionsDisplay = new google.maps.DirectionsRenderer();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions =
{
zoom: 11,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('directionpanel'));
var control = document.getElementById('control');
control.style.display = 'block';
document.getElementById('sorttable').style.display="none"
}
function calcRoute(dist,varab)
{
n=document.getElementById('Countnumbers').value;
var start = document.getElementById('startvalue').value;
var end = document.getElementById(dist).innerHTML;
// end=end.replace(/[!##$%&^*()-+=|\/:;><~]/gi," ");
var request = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function (response, status)
{
if (status == google.maps.DirectionsStatus.OK)
{
document.getElementById('sorttable').style.display="block";
document.getElementById("total").style.visibility="hidden";
directionsDisplay.setDirections(response);
var route = response.routes[0];
for (var i = 0; i < route.legs.length; i++)
{
var a=route.legs[i].distance.text;
var b=route.legs[i].duration.text;
var bc=a+",About :"+b;
var lblid="Labe"+varab;
document.getElementById(lblid).innerHTML=bc;
var store="lblstore"+varab;
document.getElementById(store).title=end;
var len=10.0;
var dd=route.legs[i].distance.value/1000;
array_list[varab]=dd;
array_list.sort(function(a,b){return a-b});
}
}
});
}
function Button1_onclick()
{
for(j=1;j<=n;j++)
{
document.getElementById('sorttable').style.display="block";
n=document.getElementById('Countnumbers').value;
var ss="lblstorename"+j;
var ss1 =document.getElementById(ss).innerHTML;
//this labels are store my addresss
calcRoute(ss,j);
}
}
//i am using google map in google map n number address are not go once thats way i am setTimeout (or) set interval method inside for loop
In order to add 2sec delay between each iteration, you need to recurrsively call ur calcRoute(..) and move your for-loop code inside calcRoute method.
Your code should look something like this -
function Button1_onclick() {
document.getElementById('sorttable').style.display="block";
n=document.getElementById('Countnumbers').value;
var ss="lblstorename"+n;//use n insteadof j
var ss1 =document.getElementById(ss).innerHTML;
calcRoute(ss,j);//only your first call is inside this method. rest all will be recurrsive
}
// making your calcRoute recurrsive
function calcRoute(ss, j){
//your code here
if(--j>0){
var ss="lblstorename"+j;
var ss1 =document.getElementById(ss).innerHTML;//not sure why are u using ss1
setTimeout(function(){calcRoute(ss, j)}, 2000);//here you set your time delay
}
}