Link Multiple Markers from XML on Google Maps [duplicate] - javascript

This question already has answers here:
Google Maps JS API v3 - Simple Multiple Marker Example
(15 answers)
Closed 9 years ago.
I was able to pull in my markers from an XML file and place them on a Google Map, but now I want each marker to link to its respective url once clicked. Can someone please let me know what I'm doing wrong? For some reason I'm only getting the last entry's url.
downLoad("phpsqlajax.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var city = markers[i].getAttribute("city");
var state = markers[i].getAttribute("state");
var country = markers[i].getAttribute("country");
var markerUrl = markers[i].getAttribute("url");
var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
var marker = new google.maps.Marker({
position: point,
map: googleMap,
icon: 'map-pin.png',
url: markerUrl
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href = marker.url;
});
}
});

Make a create Marker function like this (not tested):
function createMarker(point, url) {
var marker = new google.maps.Marker({
position: point,
map: googleMap,
icon: 'map-pin.png',
url: markerUrl
});
google.maps.event.addListener(marker, 'click', function() {
window.location.href = marker.url;
});
}
Then call it like this:
downLoad("phpsqlajax.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var city = markers[i].getAttribute("city");
var state = markers[i].getAttribute("state");
var country = markers[i].getAttribute("country");
var markerUrl = markers[i].getAttribute("url");
var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
createMarker(point, markerUrl);
}
});

Related

Loading Latitude longitude data using Google maps API using CSV data

I am trying to load Map data using a CSV file using Google's Map API. I tried following this example: https://wrightshq.com/playground/placing-multiple-markers-on-a-google-map-using-api-3/
I was trying to load it which shows some information on clicking the markers.
My CSV data looks something like this
LGA_NAME Lat Long Information
DANDENONG -37.98862 145.21805 something crashed
DANDENONG -37.98862 145.21805 something crashed
DANDENONG -37.98862 145.21805 something crashed
DANDENONG -37.98862 145.21805 something crashed
DANDENONG -37.98862 145.21805 something crashed
https://jsfiddle.net/sourabhtewari/ye96s94c/2/
I cant seem to load any of the data. It shows up a blank. Not sure what could be the problem. If someone could correct it, I would be thankful.
function initialize() {
var map;
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: 'roadmap'
};
// Display a map on the page
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Multiple Markers
var markers = [];
// Info Window Content
var infoWindowContent = [];
$.get('https://dl.dropboxusercontent.com/u/97162408/crashdata.csv', function(data) {
var data = csvToArray(data);
data.forEach(function(item) {
{
markers.push([item.LGA_NAME, parseFloat(item.Lat), parseFloat(item.Long)]);
infoWindowContent.push([item.Information]);
}
});
});
console.log(infoWindowContent);
function csvToArray(csvString) {
// The array we're going to build
var csvArray = [];
// Break it into rows to start
var csvRows = csvString.split(/\n/);
// Take off the first line to get the headers, then split that into an array
var csvHeaders = csvRows.shift().split(',');
// Loop through remaining rows
for (var rowIndex = 0; rowIndex < csvRows.length; ++rowIndex) {
var rowArray = csvRows[rowIndex].split(',');
// Create a new row object to store our data.
var rowObject = csvArray[rowIndex] = {};
// Then iterate through the remaining properties and use the headers as keys
for (var propIndex = 0; propIndex < rowArray.length; ++propIndex) {
// Grab the value from the row array we're looping through...
var propValue = rowArray[propIndex];
// ...also grab the relevant header (the RegExp in both of these removes quotes)
var propLabel = csvHeaders[propIndex];
rowObject[propLabel] = propValue;
}
}
return csvArray;
}
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow(),
marker, i;
// Loop through our array of markers & place each one on the map
for (i = 0; i < markers.length; i++) {
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
// Automatically center the map fitting all markers on the screen
map.fitBounds(bounds);
}
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
this.setZoom(14);
google.maps.event.removeListener(boundsListener);
});
}
$.get was out of scope for the needed objects. Silly mistake but a fix is easy.
fiddle: https://jsfiddle.net/sourabhtewari/aLk0c2fa/
$.get('https://dl.dropboxusercontent.com/u/97162408/crashdata.csv', function(data) {
function initialize() {
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Display a map on the page
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Multiple Markers
var markers = [];
// Info Window Content
var infoWindowContent = [];
data = csvToArray(data);
data.forEach(function(item) {
markers.push([item.LGA_NAME, parseFloat(item.Lat), parseFloat(item.Long)]);
infoWindowContent.push([item.Information]);
});
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow(),
marker, i;
// Loop through our array of markers & place each one on the map
for (i = 0; i < markers.length - 1; i++) {
console.log(markers[i][1]);
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
// Automatically center the map fitting all markers on the screen
map.fitBounds(bounds);
}
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
this.setZoom(8);
google.maps.event.removeListener(boundsListener);
});
}
initialize();
});
function csvToArray(csvString) {
// The array we're going to build
var csvArray = [];
// Break it into rows to start
var csvRows = csvString.split(/\n/);
// Take off the first line to get the headers, then split that into an array
var csvHeaders = csvRows.shift().split(',');
// Loop through remaining rows
for (var rowIndex = 0; rowIndex < csvRows.length; ++rowIndex) {
var rowArray = csvRows[rowIndex].split(',');
// Create a new row object to store our data.
var rowObject = csvArray[rowIndex] = {};
// Then iterate through the remaining properties and use the headers as keys
for (var propIndex = 0; propIndex < rowArray.length; ++propIndex) {
// Grab the value from the row array we're looping through...
var propValue = rowArray[propIndex];
// ...also grab the relevant header (the RegExp in both of these removes quotes)
var propLabel = csvHeaders[propIndex];
rowObject[propLabel.trim()] = propValue;
}
}
return csvArray;
}

How to prevent overriding an event listener

I want to create a map using Google Maps API, and connect a number of markers to individual event listeners.
My JS file looks like this (abbreviated):
var MainObject = (function($) {
return {
init: function() {
this.set_up_map();
},
set_up_map: function() {
//...
var map = new google.maps.Map(map_div, map_props);
function add_click_events(row_id) {
$(row_id).addClass('highlight');
}
function draw_rows(rows) {
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
var row_latlng = new google.maps.LatLng(
row.lat,
row.long);
var marker = new google.maps.Marker(
{
position: row_latlng,
map: map,
});
google.maps.event.addListener(marker,
"click",
function() {add_click_events(row);}
);
}
}
// call data
draw_rows(rows);
}
})(jQuery);
I would like to have it iterate over the markers and connect each to its callback (having an individual row_id that should get highlighted). But with the structure above I overwrite all the event listeners with the last (so only the last row is highlighted no matter which marker is clicked).
What is a good way of debugging or even solving this?
You should use function closure for that.
function draw_rows(rows) {
for (var i = 0; i < rows.length; i++) {
(function(row){
var row_latlng = new google.maps.LatLng(
row.lat,
row.long);
var marker = new google.maps.Marker(
{
position: row_latlng,
map: map,
});
google.maps.event.addListener(marker,
"click",
function() {add_click_events(row);}
);
})(rows[i]);
}
}
Also you can use let, but it is supported only in newest browsers
let row = rows[i];
you need to use a closure:-
(function(i) {
var row = rows[i];
var row_latlng = new google.maps.LatLng(
row.lat,
row.long);
var marker = new google.maps.Marker({
position: row_latlng,
map: map,
});
google.maps.event.addListener(marker,
"click",
function() {
add_click_events(row);
}
);
})(i);

Checkbox Filters on XML Generated Google Map

I am having a hard time trying to setup checkbox filters for the following code, which is reduced because the whole thing is massive. Everything works, except these checkbox filters. The markers are all being pulled from a php generated xml file like in Googles example.
I think it's because of the marker file being a object HTMLCollection and I'm getting markers[i].setVisible is not a function I've tried many things but it's beyond my knowledge. I'd really appreciate some help with this one, the last step for me.
Example XML data
<marker name="Some Shop" id="2" type="shops" description="Great shop" street_number="350" street_name="Main Road" suburb="Lovely ville" lat="-23.9544011" lng="156.1895873" from="2014-01-01 01:00:00" to="2015-10-01 01:00:00"/>
Javascript
downloadUrl("xml_generator.php", function (data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var type = markers[i].getAttribute("type");
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon
});
bindInfoBox(marker, map, ib, myOptions);
}
$(document).ready(function(){
// == shows all markers of a particular category, and ensures the checkbox is checked ==
function show(category) {
window.alert("Show " + category + markers);
for (var i=0; i<markers.length; i++) {
if (markers[i].getAttribute("type") == category) {
markers[i].setVisible(true);
}
}
}
// == hides all markers of a particular category, and ensures the checkbox is cleared ==
function hide(category) {
window.alert("Hide " + category);
for (var i=0; i<markers.length; i++) {
if (markers[i].getAttribute("type") == category) {
markers[i].setVisible(true);
}
}
}
$(".toggle").click(function(){
var cat = $(this).attr("value");
// If checked
if ($(this).is(":checked"))
{
show(cat);
} else
{
hide(cat);
}
});
});
});
Then the HTML checkbox
<input value="shops" class="toggle" type="checkbox" checked="yes">
markers[i] is an HTMLElement object (or XMLElement). It doesn't have a setVisible method.
You want a different "gmarkers" array of google.maps.Marker objects like is created below:
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var type = markers[i].getAttribute("type");
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon
});
bindInfoBox(marker, map, ib, myOptions);
gmarkers.push(marker); //*****
}

How can I create Google Map markers in a loop like "Marker1", "Marker2"

Sorry for that newbie's question, but I didn't found any idea for that issue...
I would to create 4 markers (or more, but here it's 4) on a Google Map. I get the informations with a GET ajax request, responding with JSON. I'm able to create those markers, but I have a problem with the information window for each marker.
here the code I tried :
function readDevices(output){
// Get an array for the 4 devices with guid 42421 42422 42423 and 42424
var arrayOfDevices = new Array();
$.each(output.data, function(key, value){
$.each(value, function(deviceKey, deviceValue){
if(deviceKey == 'guid' && deviceValue >= 42421 && deviceValue <= 42424){
arrayOfDevices.push(value); // add the entire object in the tab
}
});
});
for(var i = 0; i < arrayOfDevices.length; i++){
var guid = arrayOfDevices[i]["guid"];
var latitude = arrayOfDevices[i]["latitude"];
var longitude = arrayOfDevices[i]["longitude"];
var name = arrayOfDevices[i]["name"];
var coord = new google.maps.LatLng(latitude, longitude);
var contentString = '<div id="content">'+
'<form method="get" action="manual" id="form-new">'+
'<button type="submit" id="new-button" name="'+guid+'" class="btn new-btn">Manual</button>'+
'</form>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: coord,
title: name
});
marker.setMap(map);
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
}
}
This code put 4 markers, at the right place. But when I click on one of those markers, the "pop up window" appears near from the LAST marker that I have created. I would like to set information window for each marker.
I can't do something like :
var marker+i = new google.maps.Marker();
... But maybe there is tips for do some stuff like that ?
I hope it was clear ^^'
Thanks for helping, guys ! :-)
CORRECT CODE AFTER KhorneHoly answer ! Thanks to him.
function addMarker(markerData, map){
var contentString = '<div id="content">'+
'<form method="get" action="manual" id="form-new">'+
'<button type="submit" id="new-button" name="'+markerData["guid"]+'" class="btn new-btn">Manual</button>'+
'</form>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var LatLng = new google.maps.LatLng(markerData["latitude"], markerData["longitude"]);
var marker = new google.maps.Marker({
position: LatLng,
map: map
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
}
function readDevices(output){
var arrayOfDevices = new Array();
var markers = new Array();
$.each(output.data, function(key, value){
$.each(value, function(deviceKey, deviceValue){
if(deviceKey == 'guid' && deviceValue >= 42421 && deviceValue <= 42424){
arrayOfDevices.push(value);
}
});
});
for(var i = 0; i < arrayOfDevices.length; i++){
var guid = arrayOfDevices[i]["guid"];
var latitude = arrayOfDevices[i]["latitude"];
var longitude = arrayOfDevices[i]["longitude"];
var name = arrayOfDevices[i]["name"];
var coord = new google.maps.LatLng(latitude, longitude);
markers.push(addMarker(arrayOfDevices[i], map));
}
}
What you want to do is not possible because you can't generate variables like this. But what you can do is to generate an array you fill with the markers in an for loop like this:
var markers = new Array();
for (var i = 0; i < ArrayWithYourResultYouWantGenerateTheMarkersFrom.length; ++i) {
markers.push(addMarker(ArrayWithYourResultYouWantGenerateTheMarkersFrom.[i], map));
}
public function addMarker(markerData, map){
var LatLng = new google.maps.LatLng(markerData.lat, markerData.lon);
var marker = new google.maps.Marker({
position: LatLng,
map: map,
}

Google Maps - Creating multiple markers

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(','));

Categories