I am trying to delete markers from my own google maps, but my code didnt work and I don't know why. Would you like to help me? Thanks!
Data in function removeMarkers() - markers.length, is stil empty, if I try to debug by console.log(markers.length);
var map;
var markers = [];
var infowindow = new google.maps.InfoWindow();
function initialize() {
var mapOptions = {
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(49.8037633, 15.4749126)
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
google.maps.event.addDomListener(document.getElementById('add-markers'), 'click', addMarkers);
google.maps.event.addDomListener(document.getElementById('remove-markers'), 'click', removeMarkers);
}
function addMarkers() {
var markerCluster;
$.ajax({
type: 'GET',
url: 'get-places.php',
dataType: 'json',
success: function(data) {
var markers = [];
$.each(data, function(index, element) {
var latLng = new google.maps.LatLng(element.lat, element.lng);
var marker = new google.maps.Marker({
position: latLng,
map: map,
// icon: icon,
title: element.title
});
markers.push(marker);
var details = element.name;
bindInfoWindow(marker, map, infowindow, details);
});
markerCluster = new MarkerClusterer(map, markers, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
}
});
}
function removeMarkers() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
}
function bindInfoWindow(marker, map, infowindow, strDescription) {
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(strDescription);
infowindow.open(map, marker);
});
}
initialize();
Function addMarkers() works well, but removeMarkers() not.
You have a global variable as var markers = []; but you do not populate this when you get AJAX response back. What you do in function addMarkers() is populate the variable markers inside this function which is local to this function.
You will need to remove var markers = []; from function addMarkers() and instead use the global variable to populate markers from your AJAX response. Then you will be able to remove markers in removeMarkers function.
var markers = []; // this is global scope
function addMarkers(){
var markers = []; // remove this declaration in this function as it creates local scope
}
function removeMarkers(){
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = []; // do not forget to set this empty
}
You should remove the re-declaration of markers array. Your removeMarkers function does not know about the markers array you're populating inside your success callback.
var markers = [];
...
success: function(data) {
var markers = []; // <- remove that redeclaration
Related
I have the following Ajax request on a select drop down change which simply gets the records from the controller, Loop through each one and get the latitude | longitude and pushes it to an array.
Then in the same ajax success i pass that lat and lng array to google map.
But the map doesn't shows up..
$(document).ready(function() {
$('.selectCity').change(function() {
var city = $(this).val();
$.ajax({
type: 'GET',
url: '/riders/location/track',
data: {
'city': city
},
success: function(data) {
var lat = [];
var lng = [];
//Get Locations and push it to lat and lng
$.each(data, function(index, value) {
$.each(value, function(index1, value1) {
console.log(value1.rider_location.lat);
lat.push(value1.rider_location.lat);
lng.push(value1.rider_location.lng);
});
});
//Google Map
google.maps.event.addDomListener(window, 'load', init);
function init() {
var locations = [
['Rider', lat, lng]
];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(lat, lng),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
}
});
});
});
Plus please suggest best practice also.
Of course I can make my comment above as an answer.
You can also listen to the "google-maps-ready"-event in the script-url by using the callback-parameter (HTML):
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?libraries=geometry,places&callback=initialize">
</script>
JS:
// In this way you have to define a function called initialize which should be defined globally otherwise it can not be found by the google-library.
// unfortunately this map-variable is defined globally here but you can also wrap the whole code below by using an IIFE.
var map;
function initialize() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
// you might set a center here or wait untill you have got some markers fetched via ajax, you can then use the first/last or some other marker respecetive it's position(lat,long) to set as "starting point"
//center: {lat: LAT, lng: LONG }
mapTypeId: google.maps.MapTypeId.ROADMAP
});
}
// Although I have no access to your website to test this code below, it might be done in this way:
$(document).ready(function () {
$('.selectCity').change(function () {
var city = $(this).val();
$.ajax({
type: 'GET',
url: '/riders/location/track',
data: {
'city': city
},
success: function (data) {
var positions = [];
//Get Locations and push it to lat and lng
// you can also use just one array to insert all locations and "labels" into
$.each(data, function (index, value) {
$.each(value, function (index1, value1) {
console.log(value1.rider_location.lat);
positions.push({
lat: value1.rider_location.lat,
lng: value1.rider_location.lng,
content: 'Rider' // do you get some text with each location?
});
});
});
// set "starting point" afterwards
map.setCenter({
lat: positions[0].lat,
lng: positions[0].lng
});
var infowindow = new google.maps.InfoWindow();
var marker,
i;
for (i = 0; i < positions.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(positions[i].lat, positions[i].lng),
map: map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(positions[i].content);
infowindow.open(map, marker);
}
}) (marker, i));
}
}
});
});
});
Hope it helps!
I have a map-making tool that is built with the Google Maps API V3. It allows users to enter two or more locations and produce a map and route. I also have a checkbox that, when clicked, shows markers indicating nearby points of interest.
When I first built the tool, I think it worked well every time. Recently, though, I've noticed that the markers do not always appear when the checkbox is clicked. The map and routing work fine, but the markers only work occasionally. This error seems to occur when they don't work:
Uncaught ReferenceError: map is not defined
It references a section of the "cmarkers" section of javascript (see below).
Background detail: This is part of a Rails web app and a webpage / layout called "Itineraries". When you land on the itineraries webpage and click on the "Map Maker" icon, the map-making tool appears. It's loaded in an i-frame, it's called "map.html.erb", and the map view lives in /views/itineraries. All of the javascript for the map maker lives in the Itineraries layout file, however.
Based on reviewing these posts, I think it might be something in the way that I've ordered or initialized the code, and I think the main culprit is likely in that "cmarkers" section of the code.
Google Maps API Sometimes Not Showing Markers
Google maps api(v3) doesn't show markers
Google Maps API v3 javascript Markers don't always load
I've tried several different changes, but each has either not worked or stopped the map from initializing. Here is the javascript; please note that the API key and other small sections are redacted. Below it is the code for the markers.
<script src="https://maps.googleapis.com/maps/api/js?key=MYAPIKEY&sensor=false"></script>
<script type='text/javascript'>
$(function(){
var directionsDisplay;
var map;
function overlaysClear() {
if (markersArray) {
for( var i = 0, n = markersArray.length; i < n; ++i ) {
markersArray[i].setVisible(false);
}
}
}
function overlaysShow() {
if (markersArray) {
for( var i = 0, n = markersArray.length; i < n; ++i ) {
markersArray[i].setVisible(true);
}
}
}
$("#showmapview").click(function() {
overlaysClear();
$('#mapeach').attr('checked', false);
});
$('#mapeach').change(function() {
if( $('#mapeach').attr("checked")) {
overlaysShow();
}
else {
overlaysClear();
}
});
cmarkers();
google.maps.event.addDomListener(window, 'load', initialize);
});
var directionsService = new google.maps.DirectionsService();
var markersArray = [];
var arrInfoWindows = null;
function initialize() {
var rendererOptions = {
draggable: true,
panel:document.getElementById('directions_panel')
};
directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var chicago = new google.maps.LatLng(41.850033, -87.6500523);
var mapOptions = {
zoom: 6,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
directionsDisplay.setMap(map);
}
function calcRoute() {
var start = document.getElementById("start").value;
var end = document.getElementById("end").value;
var waypts = [];
var checkboxArray = document.getElementById("waypoints");
for (var i = 0; i < checkboxArray.length; i++) {
waypts.push({
location:checkboxArray[i].value,
stopover:true
});
}
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: optimize,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
}
});
};
function cmarkers() {
$.getJSON( "/mapeach.js", {}, function( data ) {
$.each( data, function( i, item ) {
var loc = item.mainlocation;
$("#markers").append('<li>' + loc.nickname + '</li>');
var marker = new google.maps.Marker({
position: new google.maps.LatLng(+loc.latitude, +loc.longitude),
map: map,
title: loc.nickname,
});
markersArray.push(marker);
var infowindow = new google.maps.InfoWindow({
content: '<a class="clink" href="/spots/'+ loc.id +'/'+ loc.nickname +'" target="_blank">'+ loc.nickname +'</a>'
});
google.maps.event.addListener(marker, 'click', function() {
if (arrInfoWindows != null) {
arrInfoWindows.close();
}
infowindow.open(map,marker);
arrInfoWindows = infowindow;
});
});
});
};
</script>
The mapeach.js file is formatted as below:
[{"mainlocation":{"latitude":"40.706352","nickname":"First Location","id":100000,"longitude":"-73.987650"}},{"mainlocation":{"latitude":"34.061148","nickname":"Second Location","id":100001,"longitude":"-118.273067"}}]
I was able to solve this problem by moving the cmarkers code inside the initialize. I think that the javascript wasn't making clear that the map variable in the initialize was also the map variable in the cmarkers function (sorry if the language isn't precise; I'm not great in js). See below:
function initialize() {
var rendererOptions = {
draggable: true,
panel:document.getElementById('directions_panel')
};
directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var chicago = new google.maps.LatLng(41.850033, -87.6500523);
var mapOptions = {
zoom: 6,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
directionsDisplay.setMap(map);
cmarkers();
function cmarkers() {
$.getJSON( "/mapeach.js", {}, function( data ) {
$.each( data, function( i, item ) {
var loc = item.mainlocation;
$("#markers").append('<li>' + loc.nickname + '</li>');
var marker = new google.maps.Marker({
position: new google.maps.LatLng(+loc.latitude, +loc.longitude),
map: map,
title: loc.nickname,
});
markersArray.push(marker);
var infowindow = new google.maps.InfoWindow({
content: '<a class="clink" href="/spots/'+ loc.id +'/'+ loc.nickname +'" target="_blank">'+ loc.nickname +'</a>'
});
google.maps.event.addListener(marker, 'click', function() {
if (arrInfoWindows != null) {
arrInfoWindows.close();
}
infowindow.open(map,marker);
arrInfoWindows = infowindow;
});
});
});
};
Special credit to this post for giving me the idea: can't see google marker
I am trying to display markers on Google Maps which refresh periodically.
I found this piece of code which will add them to the map but I need to know how to delete them every refresh so that it stops displaying on the map when they are no longer in the xml file.
< script >
var map = null;
function initialize() {
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng(53.3478, -6.2597) //center over dublin
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
loadXMLFile();
}
function loadXMLFile() {
var filename = 'data.xml';
$.ajax({
type: "GET",
url: filename,
dataType: "xml",
success: parseXML,
error: onXMLLoadFailed
});
function onXMLLoadFailed() {
alert("An Error has occurred.");
}
function parseXML(xml) {
var bounds = new google.maps.LatLngBounds();
$(xml).find("marker").each(function() {
//Read the name, address, latitude and longitude for each Marker
var nme = $(this).find('name').text();
var address = $(this).find('address').text();
var lat = $(this).find('lat').text();
var lng = $(this).find('lng').text();
var markerCoords = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
bounds.extend(markerCoords);
var marker = new google.maps.Marker({
position: markerCoords,
map: map
});
});
map.fitBounds(bounds);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
< /script>
This works great when new markers are added by calling the function loadXMLFile() but if they are removed then they stay on the map. I think I need to remove them https://developers.google.com/maps/documentation/javascript/examples/marker-remove but I don't know how to apply this.
This has been driving me nuts for days. Can anyone help me out?
EDIT:
My full code is not rendering the map:
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
#map-canvas {
height: 400px;
margin-bottom: 10px;
} }
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script>
var map;
var markers = [];
function initialize() {
var mapOptions = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(59.76522, 18.35002)
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
google.maps.event.addDomListener(document.getElementById('add-markers'), 'click', addMarkers);
google.maps.event.addDomListener(document.getElementById('remove-markers'), 'click', removeMarkers);
}
function addMarkers() {
var coords = [
new google.maps.LatLng(59.32522, 18.07002),
new google.maps.LatLng(59.45522, 18.12002),
new google.maps.LatLng(59.86522, 18.35002),
new google.maps.LatLng(59.77522, 18.88002),
new google.maps.LatLng(59.36344, 18.36346),
new google.maps.LatLng(59.56562, 18.33002)];
for (var i = 0; i < coords.length; i++) {
var marker = new google.maps.Marker({
map: map,
position: coords[i]
});
markers.push(marker);
}
}
function removeMarkers() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
}
initialize();
</script>
</head>
<body>
<div id="map-canvas"></div>
<button id="add-markers">Add markers</button>
<button id="remove-markers">Remove markers</button>
</body>
</html>
1) Create an array to hold your markers
var markers = [];
2) Push each marker to the array when you add them to the map
var marker = new google.maps.Marker({
position: markerCoords,
map: map
});
markers.push(marker);
3) When you need to remove them, iterate through your array and call setMap(null) on each marker
for (var i=0; i<markers.length; i++) {
markers[i].setMap(null);
}
Hope this helps.
JSFiddle demo
Edit:
Here is your code updated with my modifications. I guess you periodically call the loadXMLFile() function (?).
var map = null;
var markers = [];
function initialize() {
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng(53.3478, -6.2597) //center over dublin
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
loadXMLFile();
}
function loadXMLFile() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
var filename = 'data.xml';
$.ajax({
type: "GET",
url: filename,
dataType: "xml",
success: parseXML,
error: onXMLLoadFailed
});
function onXMLLoadFailed() {
alert("An Error has occurred.");
}
function parseXML(xml) {
var bounds = new google.maps.LatLngBounds();
$(xml).find("marker").each(function () {
//Read the name, address, latitude and longitude for each Marker
var nme = $(this).find('name').text();
var address = $(this).find('address').text();
var lat = $(this).find('lat').text();
var lng = $(this).find('lng').text();
var markerCoords = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
bounds.extend(markerCoords);
var marker = new google.maps.Marker({
position: markerCoords,
map: map
});
markers.push(marker);
});
map.fitBounds(bounds);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
function checkPostServer(){
$.ajax({
type : "POST",
url : "/getIngo/",
data : {
msg: chkToServer
},
dataType: 'json',
async: false,
success: function(data) {
disMarker(data)
}
});
}
function disMarker(data){
if (data) {
$.each(data, function (i, item) {
createMarker(item);
});
}
}
function createMarker(data){
var latLng = new google.maps.LatLng(data.lat, data.lng);
// ...and add the Marker to your map
var marker = new google.maps.Marker({
position: latLng,
map: map
});
//console.log(data);
markers2[data.key] = marker;
marker.setMap(map);
}
}, 2000);
setInterval(function() {
markers2[2].setMap(null);
alert("Here");
}, 4000);
You should do something like this
var markers = []; // this variable must be within a scope where the functions can read it (for example global scope)
// ...
function disMarker(data) {
if (data) {
// first clear all markers
clearMarkers();
$.each(data, function (i, item) {
createMarker(item);
});
}
}
function createMarker(data) {
var latLng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: latLng,
map: map // this line replaces marker.setMap(map); you don't need both
});
// now we add this object to the markers array
markers.push(marker);
}
function clearMarkers() {
for (var i=0; i<markers.length; i++) {
markers[i].setMap(null); // this removes the marker from the map
}
markers = []; // now this variable is an empty array again; and we can fill it with new marker-orbects
}
I don't know what markers2 is all about; I don't use it
I have a forloop that has a call to a function inside of it. Within that function, I'm pushing values to an array called markers.
Is there a way to access the values of the markers array outside of the forloop?
Here's the code:
<script type="text/javascript">
// arrays to hold copies of the markers and html used by the side_bar
// because the function closure trick doesnt work there
var map = null;
geocoder = new google.maps.Geocoder();
var side_bar_html = "";
var icon = '';
var markers = [];
function codeAddress(this_address,index,callback) {
geocoder.geocode( { 'address': this_address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
callback.call(window,index,results[0].geometry.location)
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function initialize() {
// create the map
var myOptions = {
zoom: 3,
center: new google.maps.LatLng(46.90, -121.00),
mapTypeControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
for (var i = 0; i < businesses.length; i++) {
codeAddress(businesses[i].address,i,function(i,point){
var description = businesses[i].description;
if(businesses[i].business_type == "Wine"){
//http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=A|00CC99|000000
icon = 'http://google-maps-icons.googlecode.com/files/wineyard.png';
}else if(businesses[i].business_type == "Golf"){
icon = 'http://google-maps-icons.googlecode.com/files/golf.png';
}else{
icon = 'http://google-maps-icons.googlecode.com/files/festival.png';
}
var marker = createMarker(point,businesses[i].name,description,icon);
// put the assembled side_bar_html contents into the side_bar div
document.getElementById("side_bar").innerHTML = side_bar_html;
});//End codeAddress-function
}//End for-loop
console.log(markers);
var markerCluster = new MarkerClusterer(map, markers);
}
// A function to create the marker and set up the event window function
function createMarker(latlng, name, html,icon) {
var contentString = html;
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: icon,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
// save the info we need to use later for the side_bar
markers.push(marker);
// add a line to the side_bar html
side_bar_html += '<a href="javascript:myclick(' + (markers.length-1) + ')">' + name + '<\/a><br />'+html+'<br />';
}
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150,50)
});
// This function picks up the click and opens the corresponding info window
function myclick(i) {
google.maps.event.trigger(markers[i], "click");
}
</script>
As you can see, the last line says "var markerCluster = new MarkerClusterer(map, markers);" This is where I want to be able to access the information from.
Thanks!
The problem is you're not accounting for the asynchronous nature of the call to codeAddress. You're calling that function in a loop, which is triggering a series of calls to the Google Maps API.
You are running this line:
var markerCluster = new MarkerClusterer(map, markers);
...even before the callbacks have been triggered.
To fix, maintain a counter. Each time the callback is triggered increase that counter by 1. Once it is equal to businesses.length you know all the addresses have been geo-coded, and all markers have been added to the array. Now you can create the MarkerCluster.
Yes, Declare it before the for loop.
var markers
for(....
Bring the definition of the marker outside of the for loop ...
var markers = new Array ();
for (var i = 0; i < businesses.length; i++) {
markers[i] = ...