Trying to add an infobox to each pin, each pin is loaded from a separate function and attaches the corresponding title, description, lat/lon, etc from an xml file. (source if needed)
In the function that receives the array of pins I'm trying to loop through each item and add infoboxes accordingly. Any ideas as to what I'm missing here?
function GeoRSSImportedCallback(items, bounds) {
map.entities.push(items);
for (var i = 0; i<items.length; i++) {
items.Title = items.title;
items.Description = items.description;
Microsoft.Maps.Events.addHandler(itmes, 'click', displayInfoBox);
}
map.entities.push(infoboxLayer);
map.setView({ bounds: bounds });
}
function displayInfoBox(e) {
pinInfoBox.setOptions({title: e.target.Title, description: e.target.Description, visible:true, offset: new Microsoft.Maps.Point(0,25)});
pinInfoBox.setLocation(e.target.getLocation());
}
I do initialize the following in the GetMap() function
pinInfoBox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false });
infoboxLayer.push(pinInfoBox);
Your code uses properties that are not part of the various Bing Maps objects, so I am going to assume that is your intent. There are also errors with your for loop, the following should be more correct:
function GeoRSSImportedCallback(items, bounds) {
map.entities.push(items);
for (var i = 0; i<items.length; i++) {
items[i].Title = items[i].title; // Assumes .title is defined
items[i].Description = items[i].description; // Assumes .description is defined
Microsoft.Maps.Events.addHandler(items[i], 'click', displayInfoBox);
}
map.entities.push(infoboxLayer);
map.setView({ bounds: bounds });
}
Related
I have looked all over but can't find an answer to this. I have a map that when I click on it adds markers to where I clicked. I am pushing those markers into an array but when I do one marker just seems to override the one that was in the array before instead of adding another index to the array. The array just always looks like this [me] no matter how many markers are on the map. Here is the code
addLatLng: function(event) {
var path = this.poly.getPath();
var markers = [];
path.push(event.latLng);
this.calcDistance(path);
var marker = new google.maps.Marker({
position: event.latLng,
title: '#' + path.getLength(),
map: this.map
});
markers.push(marker);
console.log(markers);
console.log(marker);
// debugger;
function removeMarkers(map) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(map);
}
markers = [];
}
$('#btn-clear-map').on('click', function(event) {
event.preventDefault();
removeMarkers(null);
});
$('#btn-clear-point').on('click', function(event) {
event.preventDefault();
markers[markers.length -1].setMap(null);
});
},
this is part of a backbone view if that makes any difference. I just have no idea why when I push a marker in it seems to override the one that was already in there.
Edit: Ok I just figured out why, every time I click to make a new marker, it is resetting the marker array. Any clever ways to get around this?
The problem is that you are re-declaring the markers array on each call to addLatLng method (Also you're new event handlers and creating removeMarkers function and a closure each time)
Instead, you should keep the markers array as a property of the view as shown below:
Backbone.View.extend({
initialize: function() {
this.markers = [];
},
events: {
'click #btn-clear-map': 'removeMarkers',
'click #btn-clear-point': 'clearPoint',
},
render: function() {},
addLatLng: function(event) {
var path = this.poly.getPath();
path.push(event.latLng);
this.calcDistance(path);
var marker = new google.maps.Marker({
position: event.latLng,
title: '#' + path.getLength(),
map: this.map
});
this.markers.push(marker);
},
removeMarkers: function(event) {
event.preventDefault();
for (var i = 0; i < this.markers.length; i++) {
this.markers[i].setMap(null);
}
this.markers = [];
},
clearPoint: function(event) {
event.preventDefault();
this.markers[this.markers.length - 1].setMap(null);
}
});
I have add the following code to a Google Map on a site of mine. The map contains many points pulling from coordinates set in the WordPress backend.
I also want to include some static points which will always stay on the map and am hardcoding their coordinates.
The following is the code I am using and what happens is that the code displays the first marker but not the infobox. Because of this, the code stops and does not continue through the for loop. The issue is at the return function() bit, but I am not sure how to get it working.
var infowindow = new google.maps.InfoWindow({maxWidth: 185});
var setMarker;
var setMarkers = new Array();
var setLocations = [
['<h4>Location1</h4>', 53.4264,-6.2499, '/wp-content/themes/path/to/airport_icon.png'],
['<h4>Location2</h4>', 53.3461,-6.2969, '/wp-content/themes/path/to/train_icon.png'],
['<h4>Location3</h4>', 53.3532,-6.2468, '/wp-content/themes/path/to/train_icon.png'],
['<h4>Location4</h4>', 53.4264,-6.2499, '/wp-content/themes/path/to/dvc_icon.png'],
['<h4>Location5</h4>', 53.4264,-6.2499, '/wp-content/themes/path/to/dvc_icon.png'],
];
for (var i = 0; i < setLocations.length; i++) {
marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(setLocations[i][1], setLocations[i][2]),
icon : setLocations[i][3],
});
setMarkers.push(setMarker);
google.maps.event.addListener(setMarker, 'click', (function(setMarker, i) {
return function() {
infowindow.setContent(setLocations[i][0]);
infowindow.open(map, setMarker);
}
})(setMarker, i));
}
Define your setMarker variable inside the for loop and push it to your markers array:
for (var i = 0; i < setLocations.length; i++) {
var setMarker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(setLocations[i][1], setLocations[i][2])
});
google.maps.event.addListener(setMarker, 'click', (function (setMarker, i) {
return function () {
infowindow.setContent(setLocations[i][0]);
infowindow.open(map, setMarker);
}
})(setMarker, i));
setMarkers.push(setMarker);
}
JSFiddle demo
I have a problem with removing a markers on google maps. These markers are created everytime the user creates a waypoint. They have the same position as the waypoint. These markers also have an InfoBox with a button to remove the correct waypoint and marker.
Everytime a waypoint is created I push a marker to one array and an infobox to the other.
This works if I have only one waypoint. The marker and waypoint are removed. But once I have 2 or more it does not work anymore. Once I try to remove one of the waypoints the marker stays on the map, even though I call .setMap(null) and/or .setPosition(null). Everytime I remove a marker I also remove it, the waypoint and info box from their corresponding arrays. Strangely enough, when I call a function to redraw the path, the waypoint does not exist anymore (as planned), but the marker stays.
Here is the code:
var markers = {
waypoints:{
p:[],
i:[],
m:[]
}
};
var saveWaypoints = function(){
removeWaypoints();
var points = directionsRenderer.getDirections().routes[0].legs[0].via_waypoints;
for(var i=0;i<points.length;i++){
var marker = new google.maps.Marker({
map:map,
position:points[i],
icon: 'http://maps.google.com/mapfiles/ms/icons/yellow-dot.png',
id: i
});
var infobox = new InfoBox({
id: i,
position: points[i],
disableAutoPan: true,
boxStyle: {
background: "white",
opacity: 1,
width: "289px",
border: 0,
padding: 0
},
zIndex: 1E4,
isHidden: false,
pane: "floatPane",
enableEventPropagation: false,
content: 'Pozicija: ' + points[i]
});
infobox.open(map,marker);
infobox.hide();
google.maps.event.addListener(infobox,'closeclick',function(){
markers.waypoints.m[this.id_].setMap(null);
markers.waypoints.m[this.id_].setPosition(null);
markers.waypoints.m.splice(this.id_,1);
markers.waypoints.p.splice(this.id_,1);
markers.waypoints.i.splice(this.id_,1);
drawPath();
});
google.maps.event.addListener(marker,'mouseover',function(){
markers.waypoints.i[this.id].show();
});
google.maps.event.addListener(marker,'mouseout',function(){
if(markers.waypoints.i[this.id] !== undefined){
if(!markers.waypoints.i[this.id].keepOpen()){
markers.waypoints.i[this.id].hide();
}
}
});
google.maps.event.addListener(marker,'click',function(){
if(waypointDialog !== null){
waypointDialog.doNotClose(false);
waypointDialog.hide();
}
console.log(this.id);
waypointDialog = markers.waypoints.i[this.id];
waypointDialog.doNotClose(true);
});
markers.waypoints.m.push(marker);
markers.waypoints.i.push(infobox);
markers.waypoints.p.push({
location: points[i],
stopover: false
});
};
};
var removeWaypoints = function(){
if(markers.waypoints !== (null||undefined)){
markers.waypoints.p = [];
markers.waypoints.m = [];
markers.waypoints.i = [];
}
};
I think its because every time its loop, it is creating a marker which is the reason why you cannot access the previous marker, in your code, i think only the last created marker is accessible, to access all marker you should put it inside array after declaration. Try this code
var markers=[]; //initialize it on global
//and on creating marker, inside for loop add this code.
markers.push(marker);
//and to clear the markers in map try the code below
for(var i=0; i< markers.length; i++)
{
markers[i].setMap(null);
}
I'm trying to make a map-based application, but I'm having bit of difficulty. The original code I had been working with added a separate InfoWindow for each marker, but I'd like to get it using a single InfoWindow for which I can set the content on the fly.
However, I still seem to be a little fuzzy on how JavaScript behaves, because each time any marker is clicked the InfoWindow pops up over the last marker and the alert indicates the ID of the last entry in locations.
Short snippet, problem highlighted:
function plotLocations(my_locations) {
locations = my_locations;
for(var i=0; i<locations.length; i++) {
var pos = new google.maps.LatLng(locations[i].loc_lat, locations[i].loc_lng);
var icon = new google.maps.MarkerImage(
"http://goo.gl/TQpwU",
new google.maps.Size(20,32),
new google.maps.Point(0,0),
new google.maps.Point(0,32)
);
var marker = new google.maps.Marker({
map: map,
position: pos,
animation: google.maps.Animation.DROP,
icon: icon
});
// ! -- trouble right here -- ! //
google.maps.event.addListener(marker, 'click', function() {
setPopInfo(pos, i);
});
// ! -- ------------------ -- ! //
}
}
function setPopInfo(pos, index) {
pop_info.setPosition(pos);
pop_info.open(map);
window.alert(pos+"::"+index);
}
Most of the rest of my code:
var map;
var mapBounds;
var locations;
var pop_info;
$(document).ready(init);
function init() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
pop_info = new google.maps.InfoWindow({
content: "I'm not populated!",
size: new google.maps.Size(100,25)
});
google.maps.event.addListener(map, 'bounds_changed', function() {
queryLocations(map.getBounds());
});
prepareGeolocation();
doGeolocation();
}
function queryLocations(bounds) {
jQuery.ajax({
url: 'http://mydomain.com/myapp/test2.php',
data: bounds.toString(),
dataType: 'json',
success: addLocations
});
}
function addLocations(new_locations) {
document.getElementById('footer').innerHTML = new_locations;
plotLocations(new_locations);
}
My reasoning for the single InfoWindow is that once a few hundred Markers and InfoWindows have been created the performance might take a nosedive. Is what I'm trying to do feasible/advisable?
The problem occurs because you're defining your event listener callback function inside the loop. Closures refer to their context dynamically rather than binding to a copy of the data at the time of definition, so you have effectively created locations.length number of functions that are all bound to the same values of marker, pos and i, which are whatever they happened to be when the loop terminated.
To work round this, you could create a function that calls addListener outside the body of the loop, like so:
function plotLocations (my_locations) {
locations = my_locations;
for(var i=0; i<locations.length; i++) {
var pos = new google.maps.LatLng(locations[i].loc_lat, locations[i].loc_lng);
var icon = new google.maps.MarkerImage(
"http://goo.gl/TQpwU",
new google.maps.Size(20,32),
new google.maps.Point(0,0),
new google.maps.Point(0,32)
);
var marker = new google.maps.Marker({
map: map,
position: pos,
animation: google.maps.Animation.DROP,
icon: icon
});
bindEvent(marker, pos, i);
}
}
function bindEvent (marker, pos, i) {
google.maps.event.addListener(marker, 'click', function() {
setPopInfo(pos, i);
});
}
We have a dynamic json feed that is parsed into markers on our google map.
the parsing function looks something like this:
function parse_json(json) {
// alert('start parse: '+json.length);
if (json.length > 0) {
var markers = [];
for (i=0; i<json.length; i++) {
var report = json[i];
//alert(report.longitude +','+report.latitude);
// addLocation(report);
markers[i] = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(report.latitude, report.longitude),
pop_title: report.area1.name,
pop_body: '<b>'+ report.spot.name +'</b>'+
'<br>'+ report.report_description,
draggable: false,
title: 'title',
zIndex: i,
icon: '/images/map_icon.png'
});
markers[i].metadata = {type: "point", id: report.id};
google.maps.event.addListener(markers[i], 'click', onMarkerClick);
}
};
i have added metadata info to the markers created so their id is the report.id - but i want to use the google.maps.event.trigger(SOMETHING_HERE, 'click'); construct to trigger a click event on a given marker when a button outside of the map is pressed. how do i get the object name, or is there a way to do this using the object's id?
thanks!
If you declare your markers array at a higher scope than your parse_json function, then you will be able to refer to it later, something like this:
var markers = new Array();
function parse_json(json) {
//code removed for brevity
}
Then later, when you need to find the marker you want to fire a click event against, you could use the id like this:
for ( var i = 0; i < markers.length; i++ ) {
var mkr = markers[i];
if ( mkr.metadata.id === idYouAreSearchingFor ) {
//do whatever is needed here and fire your event
}
}