I'm having trouble getting my map to clear the clusters on a new search. Any ideas?
function clearLocations() {
//infoWindow.close();
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers.length = 0;
// clear #side_bar bottom text
document.getElementById("side_bar").innerHTML = "";
// clear .alertBox text
$('.alertBox').html('');
}
function searchLocationsNear(center) {
clearLocations();
var searchUrl = 'phpsqlsearch_genxml.php?lat=' + center.lat() + '&lng=' + center.lng();
downloadUrl(searchUrl, function (data) {
var xml = parseXml(data);
var markerNodes = xml.documentElement.getElementsByTagName("marker");
if (markerNodes.length > 0) {
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markerNodes.length; i++) {
var name = markerNodes[i].getAttribute("name");
var address = markerNodes[i].getAttribute("address");
var distance = parseFloat(markerNodes[i].getAttribute("distance"));
var category = markerNodes[i].getAttribute("category");
var latlng = new google.maps.LatLng(
parseFloat(markerNodes[i].getAttribute("lat")),
parseFloat(markerNodes[i].getAttribute("lng")));
// createOption(name, distance, i);
createMarker(latlng, name, address, category);
bounds.extend(latlng);
}
map.fitBounds(bounds);
var markerclusterer = new MarkerClusterer(map, markers);
// markerclusterer.setMap(null);
makeSidebar();
} else {
$('.alertBox').html('Sorry, there are no jobs that are close to your location.');
}
});
}
You should try this :
if (markers) {
for (i in markers) {
markers[i].setMap(null);
}
markers = [];
markerclusterer.clearMarkers()
}
According to the docs the clusterer can be clear with clearMarkers() method.
UPDATE
Call clear only when we have already create the MarkerClusterer.
if(markerclusterer)
{
clearLocations();
}
Related
Hi everyine please help me, I am trying to do a search filter on my vehicle tracking, the flow is, the servlet queries all data when there is no parameter filter is being sent by ajax. for example, I do have 5 data on query result so there will be 5 markers on the map, the ajax runs every two seconds so when I request a parameter for example only this spesific vehicle would be shown the query result would only be one, supposedly only marker on the screen, but the previous markers are not vanishing and keep up on the screen. how can I reset the markers into 0? can anyone please help me thanks! here is my code
<script type="text/javascript">
var values = [];
var map;
var markers = [];
function initMap()
{
var options = {
center: {lat: -33.890542, lng: 151.274856},
zoom: 4
};
map = new google.maps.Map(document.getElementById('map'), options);
var count = 0;
setInterval(function() {
getGps();
for(var i = 0; i <= markers.length; i++){
markers[i].setPosition(new google.maps.LatLng(values[count][1],values[count][2]));
count++;
}
}, 2000);
}
function removeMarkers(){
for(var i=0; i<markers.length; i++){
markers[i].setMap(null);
}
markers=[];
}
function getGps() {
xmlhttp.onreadystatechange=function() {
if( xmlhttp.readyState==4 && xmlhttp.status==200 ) {
removeMarkers();
var res = xmlhttp.responseText;
console.log(res);
var split1 = res.split("|");
if(split1[0] != "NOK"){
for(var i = 0; i < split1.length; i++){
var split2 = split1[i].split(",");
String(split2);
var holder1 = holder = [split2[0],split2[1],split2[2]];
values.push(holder1);;
var marker1 = marker = new google.maps.Marker({map: map, icon: 'images/mapvehicle.png', draggable: true});
markers.push(marker1);
}
}
}
};
xmlhttp.open("POST","GpsPost",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("txtTerminal="+document.getElementById('txtTerminal').value+"&txtMerchant="+document.getElementById('txtMerchant').value+"&txtAccount="+document.getElementById('txtAccount').value);
}
add this function and call it after this line .
if( xmlhttp.readyState==4 && xmlhttp.status==200 ) {
function removeMarkers(){
for(i=0; i<markers.length; i++){
markers[i].setMap(null);
}
markers=[]
values=[]
}
Hello I have a question.
I draw a polyline and set markers on every point of the polyline. But my code doesn't set markers every point. Like the picture below, markers are just on some parts of polyline.
How can I set markers on every polyline?
function initMap() {
var markerArray = [];
// Instantiate a directions service.
var directionsService = new google.maps.DirectionsService;
// Create a map and center it on Manhattan.
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: {lat: 32.224759, lng: 60.298827},
});
// Create a renderer for directions and bind it to the map.
var directionsDisplay = new google.maps.DirectionsRenderer({map: map});
// Instantiate an info window to hold step text.
var stepDisplay = new google.maps.InfoWindow;
// Display the route between the initial start and end selections.
calculateAndDisplayRoute(directionsDisplay, directionsService, markerArray, stepDisplay, map);
// Listen to change events from the start and end lists.
var onChangeHandler = function() {
calculateAndDisplayRoute(directionsDisplay, directionsService, markerArray, stepDisplay, map);
};
document.getElementById('start').addEventListener('change', onChangeHandler);
document.getElementById('end').addEventListener('change', onChangeHandler);
directionsDisplay.addListener('directions_changed', function() {
computeTotalDistance(directionsDisplay.getDirections());
});
}
function calculateAndDisplayRoute(directionsDisplay, directionsService, markerArray, stepDisplay, map) {
// First, remove any existing markers from the map.
for (var i = 0; i < markerArray.length; i++) {
markerArray[i].setMap(null);
}
// Retrieve the start and end locations and create a DirectionsRequest using
// DRIVING directions.
directionsService.route({
origin: document.getElementById('start').value,
destination: document.getElementById('end').value,
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
// Route the directions and pass the response to a function to create
// markers for each step.
if (status === google.maps.DirectionsStatus.OK) {
var polyline = new google.maps.Polyline({
path: [],
strokeColor: '#0000FF',
strokeWeight: 3
});
var bounds = new google.maps.LatLngBounds();
var legs = response.routes[0].legs;
for (var i = 0; i < legs.length; i++) {
var steps = legs[i].steps;
for (var j = 0; j < steps.length; j++) {
var nextSegment = steps[j].path;
for (var k = 0; k < nextSegment.length; k++) {
polyline.getPath().push(nextSegment[k]);
var marker = markerArray[k] = markerArray[k] || new google.maps.Marker;
marker.setPosition(nextSegment[k]);
bounds.extend(nextSegment[k]);
marker.setMap(map);
}
}
}
polyline.setMap(map);
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
function computeTotalDistance(result) {
var total = 0;
var myroute = result.routes[0];
for (var i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000;
document.getElementById('total').innerHTML = total + ' km';
}
I think that I found your mistake which is in this piece of code:
for (var i = 0; i < legs.length; i++) {
...
for (var j = 0; j < steps.length; j++) {
...
for (var k = 0; k < nextSegment.length; k++) {
...
// Here you add the marker to the array if there is no marker set yet
var marker = markerArray[k] = markerArray[k] || new google.maps.Marker;
...
}
}
}
The mistake you did is, that you just look at the array's index k. However, the value of k is reset to 0 every time the for-loop starts again. Therefore, you have to add the array's length to the index:
for (var i = 0; i < legs.length; i++) {
...
for (var j = 0; j < steps.length; j++) {
...
for (var k = 0; k < nextSegment.length; k++) {
...
// This is the real index you want to look at
var marker = markerArray[markerArray.length + k] = markerArray[markerArray.length + k] || new google.maps.Marker;
...
}
}
}
However, I think that actually this reaches out and makes your code also lighter and more readable:
for (var i = 0; i < legs.length; i++) {
...
for (var j = 0; j < steps.length; j++) {
...
for (var k = 0; k < nextSegment.length; k++) {
...
// This looks much easier IMHO
var marker = new google.maps.Marker;
...
markerArray.push(marker);
}
}
}
I'm having a bit of trouble trying to loop out multiple markers onto a map using information stored in an array.
The code creates the map no problem, but it's not displaying the markers I'm trying to loop out...
As you can see from the code below, there are two functions that are creating markers. The first is simply using two values. This marker displays fine.
The second function however, is grabbing the data from an array (the array has been set up to "squish" the latitude and longitude data together, in that order, as Google Maps requires it to be) and does not display anything when run.
Any ideas? I'm stumped!
Thanks in advance!
Here's the code:
Initial "locations" array:
var locations = new Array();
for (var i = 0; i < data.length; i++)
{
var row = data[i];
var longitude = row[0];
var latitude = row[1];
locations[i] = latitude + longitude;
}
callMap(locations, locationFilename, userLatitude, userLongitude);
Google Maps Functions
function callMap(locations, locationFilename, userLatitude, userLongitude) {
var mapOptions = {
zoom:16,
center: new google.maps.LatLng(userLatitude, userLongitude),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('mapView'),mapOptions);
setMarkers(map, locations, locationFilename);
currentPosition(map, userLatitude, userLongitude);
}
function currentPosition(map, userLatitude, userLongitude)
{
var userLatLng = new google.maps.LatLng(userLatitude, userLongitude);
var marker = new google.maps.Marker({
position: userLatLng,
map: map
});
}
function setMarkers(map, locations, locationFilename) {
for (var i = 0; i < locations.length; i++) {
var markerLatLng = new google.maps.LatLng(locations[i]);
var marker = new google.maps.Marker({
position: markerLatLng,
map: map
});
}
}
A google.maps.LatLng takes two numbers for arguments.
This is not correct:
var markerLatLng = new google.maps.LatLng(locations[i]);
This should work:
for (var i = 0; i < data.length; i++)
{
var row = data[i];
var longitude = row[0];
var latitude = row[1];
locations[i] = new google.maps.LatLng(latitude,longitude);
}
Then
function setMarkers(map, locations, locationFilename) {
for (var i = 0; i < locations.length; i++) {
var markerLatLng = locations[i];
var marker = new google.maps.Marker({
position: markerLatLng,
map: map
});
}
}
}
You're just adding strings together, it needs to be an array:
for (var i = 0; i < data.length; i++) {
var row = data[i];
var longitude = row[0];
var latitude = row[1];
locations[i] = [latitude, longitude];
}
var markerLatLng = new google.maps.LatLng(locations[i].join(','));
I am new to JavaScript.
Writing a script that uses GooogleMaps API
Working OK. Get Lat Lngs from Database, Make markers, put on Map.
Decided to move a function call up a level, (it was in the OnSuccess method of a PageMethod call). Stopped working.
Put in alerts to diagnose. Starts working.
Narrowed down to having alert at top of called function MakeLatLngs().
MakeLatLngs code appears to execute regardless of alert being present or commented out.
It is just that the map displays with alert statement in and doesn't display with alert statement commented out.
The alert is just text and not using any variable. So I am at a loss to understand what is going on here.
The same thing is happening in the function that draws the map DrawMap(). I put an informative alert at the start of the function and the map draws. Leave it out and the map doesn't.
Any clues as to what is going on would be appreciated?
The script is below.
Flow starts at function Initialise at bottom of script.
thanks
var myPositions = [];
var myRoutes = [];
var myString = [];
var myLatLngs = [];
var myTitles = [];
var NumPoints;
var map;
var poly;
var RouteName;
var myMarkers = [];
var myMapCentre = new google.maps.LatLng(-41.2954168187213, 174.767133718655);
function DrawMap() {
alert("Generating Points for " + RouteName);// Need this to display
var thisLatLng = myLatLngs[0];
var myOptions = {
zoom: 8,
center: thisLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
myOptions);
MakeMarkers();
RouteLine();
}
function OnSuccess1(response) {
myPositions = new Array();
myString = response;
NumPoints = response.length;
for (var i = 0; i < NumPoints; i++) {
myPositions[i] = response[i];
}
}
function OnError1(response) {
}
function Marker()
{
this.meterId=0;
this.latLng="";
}
function OnSuccess(response) {
myPositions = new Array();
myString = response;
NumPoints = response.length;
alert("Numpoints is " + NumPoints);
for (var i = 0; i < NumPoints; i++) {
myPositions[i] = response[i];
}
alert("Exiting OnSuccess");
//MakeLatLngs(); //ORIGINAL POSITION OF LATLNG CALL
return true;
}
function setRoute() {
RouteName = prompt(' What route?', '');
}
function OnError(error) {
alert("In Error");
}
function RouteLine() {
var polyOptions = {
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 3
}
poly = new google.maps.Polyline(polyOptions);
poly.setMap(map);
var path = poly.getPath();
for (var i = 0; i < NumPoints; i++) {
path.push(myLatLngs[i]);
}
}
function MakeLatLngs() {
alert("You need me now " );//Got to have this to display OK when called from LoadData
myLatLngs = new Array();
for (var i = 0; i < NumPoints; i++) {
var sMarker = myPositions[i];
var SeqPos = sMarker.indexOf(";");
var latLngPos = sMarker.indexOf(";", SeqPos + 1);
var marker = sMarker.substring(0, latLngPos);
//alert("Marker is " + marker);
//var Seq = sMarker.substring(latLngPos + 1, SeqPos - latLngPos);
myTitles[i] = marker;
//alert("MeterId is " + marker);
var sLatLng = sMarker.substring(latLngPos + 1)
//alert("SLatLng is " + sLatLng);
var pos = sLatLng.indexOf(",");
//alert("pos is " + pos);
var sLat = sLatLng.substring(0, pos);
//alert("sLat is " + sLat);
var sLng = sLatLng.substring(pos + 1, sLatLng.length - 1);
//alert("sLng is " + sLng);
var lat = parseFloat(sLat);
var lng = parseFloat(sLng);
//alert("Lat is " + lat + " Long is " + lng);
if (!isNaN(lng) && !isNaN(lat) && lat != 0 && lng != 0 ) {
var latlng = new google.maps.LatLng(lat, lng);
myLatLngs[i] = latlng;
}
}
alert("Exiting MakeLatLngs")
}
function MakeMarkers() {
for (var i = 0; i < NumPoints; i++) {
var sTitle = "MyValue " + i;
var marker = new google.maps.Marker({
position: myLatLngs[i],
map: map,
title: myTitles[i]
});
}
}
function LoadData() {
setRoute();//Get the desired route from the user
PageMethods.GetMarkers(RouteName, OnSuccess, OnError);
MakeLatLngs(); //Works here ONLY WHEN AN ALERT IS FIRST LINE in FUNCTION. Orginal call was at end of OnSuccess
//PageMethods.GetRouteBoundaries(OnSuccess1, OnError1);
return false;
}
function initialize() {
LoadData();
DrawMap();
}
google.maps.event.addDomListener(window, 'load', initialize);//yes you do need this with or without <body onload="initialise">
The reason is that your PageMethods.GetMarkers is asynchronous, so the data hasn't loaded when you invoke DrawMap. I guess when you use the alert, it pauses execution long enough for the data to load. Put the DrawMap method inside the OnSuccess of the page method, and that should solve the problem.
I've been using the code from this V3 example to set up a links bar that dynamically populates when different category filters are selected, but have two problems at the moment. Firstly, I've put the the initial makeSidebar function in the map's idle event, but the sidebar is only created when the map is moved, not on loading of the page. Secondly, I can't seem to get the marker infowindow to open when the corresponding link is clicked in the sidebar. My code is below:
var map;
var infowindow;
var image = [];
var gmarkers = [];
var place;
var side_bar_html = "";
image['attraction'] = 'http://google-maps-icons.googlecode.com/files/beach.png';
image['food'] = 'http://google-maps-icons.googlecode.com/files/restaurant.png';
image['hotel'] = 'http://google-maps-icons.googlecode.com/files/hotel.png';
image['city'] = 'http://google-maps-icons.googlecode.com/files/smallcity.png';
function mapInit(){
var placeLat = jQuery("#placelat").val();
var placeLng = jQuery("#placelng").val();
var centerCoord = new google.maps.LatLng(placeLat, placeLng);
var mapOptions = {
zoom: 15,
center: centerCoord,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), mapOptions);
google.maps.event.addListener(map, 'idle', function() {
var bounds = map.getBounds();
var ne = bounds.getNorthEast();
var sw = bounds.getSouthWest();
var yMaxLat = ne.lat();
var xMaxLng = ne.lng();
var yMinLat = sw.lat();
var xMinLng = sw.lng();
//alert("bounds changed");
updateMap(yMaxLat, xMaxLng, yMinLat, xMinLng);
show("attraction");
show("food");
show("hotel");
show("city");
makeSidebar();
});
function updateMap(yMaxLat, xMaxLng, yMinLat, xMinLng) {
jQuery.getJSON("/places", { "yMaxLat": yMaxLat, "xMaxLng": xMaxLng, "yMinLat": yMinLat, "xMinLng": xMinLng }, function(json) {
if (json.length > 0) {
for (i=0; i<json.length; i++) {
var place = json[i];
var category = json[i].tag;
var name = json[i].name;
addLocation(place,category,name);
//makeSidebar();
}
}
});
}
function addLocation(place,category,name) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(place.geom.y, place.geom.x),
map: map,
title: place.name,
icon: image[place.tag]
});
//var iwNode = document.getElementById("infowindow");
marker.mycategory = category;
marker.myname = name;
gmarkers.push(marker);
google.maps.event.addListener(marker, 'click', function() {
if (infowindow) infowindow.close();
infowindow = new google.maps.InfoWindow({
content: "<div id='infowindow'><div id='infowindow_name'><p>"+ place.name +"</p></div><div id='infowindow_contents'><p>" + place.tag +"</p><a href='/places/"+place.id+"' id='place_link'>Show more!</a></div></div>"
});
infowindow.open(map, marker);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
});
}
function show(category) {
for (var i=0; i<gmarkers.length; i++) {
if (gmarkers[i].mycategory == category) {
gmarkers[i].setVisible(true);
}
}
document.getElementById(category+"box").checked = true;
}
function hide(category) {
for (var i=0; i<gmarkers.length; i++) {
if (gmarkers[i].mycategory == category) {
gmarkers[i].setVisible(false);
}
}
document.getElementById(category+"box").checked = false;
infowindow.close();
}
function boxclick(box,category) {
if (box.checked) {
show(category);
} else {
hide(category);
}
makeSidebar();
}
jQuery('#attractionbox').click(function() {
boxclick(this, 'attraction');
});
jQuery('#foodbox').click(function() {
boxclick(this, 'food');
});
jQuery('#hotelbox').click(function() {
boxclick(this, 'hotel');
});
jQuery('#citybox').click(function() {
boxclick(this, 'city');
});
function myclick(i) {
google.maps.event.trigger(gmarkers[i],"click");
}
function makeSidebar() {
//var html = "";
for (var i=0; i<gmarkers.length; i++) {
if (gmarkers[i].getVisible()) {
side_bar_html += '<a href="javascript:myclick(' + i + ')">' + gmarkers[i].myname + '<\/a><br>';
}
}
document.getElementById("side_bar").innerHTML = side_bar_html;
}
}
jQuery(document).ready(function(){
mapInit();
//makeSidebar();
});
Any help would be much appreciated - what can I do to get the sidebar loaded when the page loads, and to get the link click event working? Thanks!
The reason your links are not working is that you are defining your my_click and makeSidebar functions inside of your mapInit function and so they are not available outside of the scope of mapInit. Simply move them outside of mapInit and everything should just work.
As for the load event ... what you are looking for is the addDomListener method of google.maps.event. Simply use
google.maps.event.addDomListener(window, 'load', name_of_your_inital_function);
// e. g. google.maps.event.addDomListener(window, 'load', mapInit);
Finally; notta bene ... don't do this:
var image = [];
image['attraction'] = 'data';
image['food'] = 'more data';
Arrays are not meant to be used as hashes in Javascript. Use objects for dictionaries / hashes instead -- it's what you are actually doing (Array "subclasses" Object) and it will make it easier for others to use your code (and save you from headaches down the line).
var image = {};
image['attraction'] = 'data';
image['food'] = 'more data';