I have a script that adds markers one by one to a map
var marker = new google.maps.Marker({
position: new google.maps.LatLng(51,-117)
});
marker.setIcon(getIconFile(initialIconId));
markers.push(new Array(id,marker)); // id, marker
marker.setMap(map);
later on in the script when I press a custom button I want to be able to change the markers icons. So I grab the marker by the id from the markers array and call:
markers[markerIndex].setIcon(getIconFile(newIconId)); // which returns a string url of the icon
However I receive: TypeError: markers[markerId].setIcon is not a function
I print the markerId and it is valid, I also print the result of indexing the marker markers[markerId] and it returns a marker object. I have no other way to debug this I am lost!
Thanks
It seems like you're pushing an Array into the markers, instead of just one element.
Why not:
markers = []
markers.push(marker)
markers[markerIndex].setIcon(getIconFile(newIconId));
or if you insist inserting an array:
markers.push(new Array(id,marker));
markers[markerIndex][1].setIcon(getIconFile(newIconId));
Related
I have a Google Map object available on my window object like so:
var map = window.site.map.el;
That Map also also has a bunch of markers placed on it, I'd like to hide a Marker on that Map where the marker's place_id property is equal to "123" for example.
However I don't see a function I can call on the Map class that will return me an array of all markers placed on the map that I can then loop through and hide depending on the marker's place_id.
Google maps does not provide a way to get all Markers, you need to do it yourself
while adding marker to the map keep it in array
var myMarkers = [];
....
for(...) {
var marker = new google.maps.Marker({...});
myMarkers.push(marker);
}
Than you can hide any marker, just by setting map to null
myMarker[i].setMap(null);
Or bring it back
myMarker[i].setMap(map);
I created a prototype for a project I'm working on, in which the user should create various markers in a map, be able to remove them, calculate a route with the markers, and go back to manage the markers.
I used some code found here in geocodezip.com to calculate the route, and wrote some for the markers, etc.
My problem is that once the user calculates the route, no matter how he edits the markers, when clicking the button to calculate the route, the map only returns the route with the markers that were there on the first time he clicked the button. And the strangest thing is that I checked the coordinates that are being passed to the script that generates the route and the function is sending the markers as it should, but no matter the coordinates sent, it only works correctly on the first time.
Js Fiddle: https://jsfiddle.net/1kmg2u65/2/
The code is really really long so it's all in the Fiddle, but this is what it does:
1. User clicks on map, generate marker, marker goes to an array
2. If user deletes marker, it becomes null in array, to maintain the indexes
3. 'Clean' markers array receives all the markers in order, without the items that are null
4. A function is called with all the markers, this function creates the route
5. To manage the markers, a function reload the map just like it was in the start, but render all the markers that already are in the markers array
it works fine if you remove the conditional if (!window.tour) in Tour_startUp function definition.
So here is what I believe is going on.
In the function markMap() you are instantiating new markers that belong to the google map object.
for (var i = 0; i < markerElements.length; i++){ //Loop para gerar os marcadores
if (markerElements[i] != null){
marker = new google.maps.Marker({
position: markerElements[i].position,
map: map,
title: markerElements[i].title
});
}
}
This if fine, but you are not storing that constructed object anywhere. You need to be able to reference that marker to UN-associate it from the map.
At the end of the this for loop you need to add THAT mark to a global array so you can manage it later in the script.
EXAMPLE
// defined at the top of the script
var markerGlobal = [];
for (var i = 0; i < markerElements.length; i++){ //Loop para gerar os marcadores
if (markerElements[i] != null){
marker = new google.maps.Marker({
position: markerElements[i].position,
map: map,
title: markerElements[i].title
});
// push marker onto global array
markerGlobal.push(marker);
}
}
Now we can loop through the array and setMap to null
// un-reference marker from map
markerGlobal[2].setMap(null);
I see you tried to do this with the removeMarker() function, but it doesn't have the handles to the markers already added to the map.
Some Suggestions
If I was you, I would think about refactoring the code to have one multi dimensional object that holds all the markers, their row info, variables etc.
You could take it one step further and create a constructor function that handles the map and its associated markers. It would be most efficient.
Good luck.
Let's say I have the following objects:
var map = new google.maps.Map(...)
var marker = new google.maps.Marker(...);
I can add marker to map with:
marker.setMap(map);
If the marker already exists on the map, and I call marker.setMap(map) again, does the API actually redraw the marker? Or does it know the marker already exists on the map, so it doesn't take any further actions?
I am listening for events and need to either add or remove markers from the map when those events occur. I'm wondering if I can simply keep calling setMap(map) even if the marker already exists without performance suffering significantly, or do I need to be smarter and not call setMap in the first place if the marker is already on the map.
If you don't know the answer, do you have any idea how I could figure this out?
If the marker already exists on the map, and I call marker.setMap(map)
again, does the API actually redraw the marker? Or does it know the
marker already exists on the map, so it doesn't take any further
actions?
The setMap function work on the visibility of the marker... assing to the marker in which map object this marker must be place/visibile..
If you set marker.setMap(null) you don't destroy the marker simply is not more showed in the "map".
when you manage event on marker you can use setMap(null) for make the marker invisible.. if you have previuosly stored the marker object in some var..eg
var store_marker = marker;
you can simply turn it on again doing
store_marke.setMap(map);
You can use array for manage collection of markers
I was helped out by an SO member with the following code which allows me to use multiple markers from a PHP array and plot them on a map:
for (i = 0; i < locations.length; i++)
{
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][0], locations[i][1]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function()
{
infowindow.setContent(locations[i][2]);
infowindow.open(map, marker);
}
})(marker, i));
}
So that code is grabbing my array and putting my markers on the map and in the infowindow, printing out the customer name.
I quickly came across an issue however. If a customer share's the same lat/long (they're derived from postcode), only one of the customers appear - e.g. Customer1 at LN1 7HQ and Customer2 at LN1 7HQ, only customer 1 will appear in the info window.
A few solutions I found include clustering markers and offsetting them - but what I would like is the have 1 infowindow for each postcode and then list the customers located there in the window.
I haven't found a way to do it but would assume it will involve altering the For loop below and adding something like "If lat, long === lat, long, then locations[i][2] ++ ..." but I'm just about grasping PHP and javascript is still new to me.
Any help would be much appreciated.
One possible solution: track created markers using array
var markers = [];
with information about location indexes using following object:
function MarkerInfo(marker, idx) {
this.marker = marker;
this.locations = [idx];
}
There are two loops. The 1st loop build array of MarkerInfo with marker and list of indexes from locations array. The 2nd loop prepares content string for infowindow and creates listeners.
See example at jsbin.
Note: for the future changes: solution won't work properly if you change locations array with information about customers between those two loops.
I wonder whether someone may be able to help me please.
I'm using this page to allow users to view markers saved in a MySQL database and to geocode/reverse geocode new marker positions.
I'm able to correctly center the map on the marker which is being loaded from the database, but the problem I'm having is that the map zooms in to it's maximum setting, whereas I would like to be able to set this manually.
I've tried adding another zoom control into my script here:
// add marker
var bounds = new google.maps.LatLngBounds();
var loc = new google.maps.LatLng(las[i],lgs[i]);
var marker = new google.maps.Marker({
position: loc,
map: window.map,
zoom: 8,
title: nms[i]
});
bounds.extend(loc);
map.fitBounds(bounds);
Unfortunately this has no affect. I appreciate that to some this may be a very minor fix, but I've been looking at this for sometime and I just can't seem to find a solution.
I just wondered whether someone may be able to look at this please and let me know where I've gone wrong?
POST UPDATE
I have worked out a solution using exisitng code and that suggested by #Andrew Leach. The working solution is:
// add marker
var bounds = new google.maps.LatLngBounds();
var loc = new google.maps.LatLng(las[i],lgs[i]);
var marker = new google.maps.Marker({
position: loc,
map: window.map,
title: nms[i]
});
bounds.extend(loc);
map.fitBounds(bounds);
map.setZoom(16);
Remove the references to the bounds.
You add a marker to the map, and create a LatLngBounds object which contains only that single point. You then ask the map to zoom in to fit the bounds into the map's viewport. Fitting a single location into the viewport will always zoom in as far as it can, and even then a single point can never fill the entire viewport.
However, adding zoom to the marker options won't work either, because zoom is not a valid option. Documentation
Instead, set the map's zoom explicitly, either with map.setZoom(8) or by including the zoom option in the map's options when you set it up.