My Google Map is showing correctly, also centering the map is working like a charm. But when I want to add some marker (just the marker, don't want to reload the whole map) nothing happens (there are no visible markers on the map).
My script looks like this:
function g_maps(){
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(48.2136522, 16.386172),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
}
function g_maps_marker(coordinates){
var locations = [ coordinates ];
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,
visible: true
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
The (important) part of my ajax request looks like that:
...
success:function(data){
$('#pagination_content table').empty();
data = $.parseJSON(data);
i = 1;
coordinates = "";
for(var i in data.results) {
$('#content_table').append("blablabla");
coordinates += "['" + data.results[i].title + "', " + data.results[i].lat + ", " + data.results[i].lat + ", " + i++ + "], ";
};
coordinates = coordinates.slice(0, -2)
g_maps_marker(coordinates);
},
...
The output of coordinates is this:
['abc', 48.1857442, 48.1857442, 0], ['xyz', 48.2136522, 48.2136522, 1]
The function g_maps is called at the document.ready() event.
I'm using the API v3.
You are slicing coordinates = coordinates.slice(0, -2); and then again making an array out of coordinates like this var locations = [ coordinates ];.
I' am confused a bit. slice already gives you an array so why making an array again? Are you sure that your loop gets executed?
Maybe you should remove var locations = [ coordinates ]; from g_maps_marker and then try again. I hope it will work.
** Edit **
After analyzing code a bit further I found that you are trying to use string which looks like an array and then trying to loop around it. This will not work.
For example
a = "[1, 2, 3]";
b = [a];
b[0][0]; // => will result in [ and not in your desired element
You should use following code in-order to make array objects for coordinates.
i = 1;
coordinates = [];
for(var i in data.results)
{
$('#content_table').append("blablabla");
var coordinate = [];
coordinate.push(data.results[i].title);
coordinate.push(data.results[i].lat);
coordinate.push(data.results[i].lon);
coordinates.push(coordinate);
};
Also it seems that you forgot to use longitude while creating coordinates array and used latitude two times. I have fixed this in my code.
Related
I'm starting to learn Google Map. It's strange that when statically declared, markers are working and being displayed, but when they come from DB, they aren't being drawn on map.
// var markers = [[15.054419, 120.664785, 'Device1'], [15.048203, 120.692186, 'Device 2'], [15.033303, 120.694611, 'Device 3']];
var markers = [];
I have the entire code here, maybe I am missing something? I even used console log and I successfully pass all data from ajax to markers variable.
I think I got this code somewhere here in SO and modified it to fit in for my DB calls for records. I hope you can help me out on this one. Thank you!
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initialize"></script>
<script type="text/javascript">
var map;
var global_markers = [];
// var markers = [[15.054419, 120.664785, 'Device1'], [15.048203, 120.692186, 'Device 2'], [15.033303, 120.694611, 'Device 3']];
var markers = [];
var infowindow = new google.maps.InfoWindow({});
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(15.058607, 120.660884);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
$.ajax({
type: 'GET',
url: 'control_panel/get_device_list_ajax',
success:
function (data) {
data = JSON.parse(data);
if (data['success']){
var device = data['device_list'];
device.forEach(function (dev) {
markers.push([dev['dev_geolat'], dev['dev_geolng'], dev['dev_name']]);
//console.log(markers);
});
addMarker();
} else {
}
}
});
}
function addMarker() {
console.log(markers);
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i][0]);
var lng = parseFloat(markers[i][1]);
var trailhead_name = markers[i][2];
var myLatlng = new google.maps.LatLng(lat, lng);
var contentString = "<html><body><div><p><h2>" + trailhead_name + "</h2></p></div></body></html>";
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: "Coordinates: " + lat + " , " + lng + " | Trailhead name: " + trailhead_name
});
marker['infowindow'] = contentString;
global_markers[i] = marker;
google.maps.event.addListener(global_markers[i], 'click', function() {
infowindow.setContent(this['infowindow']);
infowindow.open(map, this);
});
}
}
window.onload = initialize;
</script>
EDIT
Here is the jsfiddle I used to work with this one http://jsfiddle.net/kjy112/ZLuTg/ (thank you to the one that lead me to this)
Could be related to the way you accessing to json rendered by ajax
markers.push([dev.dev_geolat, dev.dev_geolng, dev.dev_name]);
or the json content
I don't know how to close this question as I overlooked some problems on my DB but I'll be posting my answer if someone may come with the same problem (well, I am not sure about that hehe)
I get the same response from AJAX of the values in DB and I am not able to draw markers on MAP, I found that db->table->fields LAT LNG are referenced with a data type of DECIMAL (7,5) and changed it to FLOAT (10, 6) as to what is found in this GOOGLE MAP Tutorial - Using PHP/MySQL with Google Maps.
The issue at the field before was that higher values tend to be saved as 99.999999 instead of the actual value (e.g. 120.XXXXX) .
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;
}
This script can be used as a standalone javascript or greasemonkey script. What I am trying to fix is the hover title and on-click's info-window (it should display the address). here is a jsFiddle
// ==UserScript==
// #name mapMarkers
// #namespace mapMarkers
// #include https://www.example.com/*
// #description map markers of addresses in table
// #version 1
// #grant none
// ==/UserScript==
// find the table and loop through each rows to get the 11th, 12th, 13th cell's content (street address, city and zip respectively
// convert to lat/lon and show markers on map
if (document.getElementById('main_report') !== null) {
API_js_callback = 'https://maps.googleapis.com/maps/api/js?v=3.exp&callback=initialize';
var script = document.createElement('script');
script.src = API_js_callback;
var head = document.getElementsByTagName("head")[0];
(head || document.body).appendChild(script);
var Table_1 = document.getElementById('main_report');
var DIVmap = document.createElement('div');
DIVmap.id = 'DIVmap';
DIVmap.style.border = '2px coral solid';
DIVmap.style.cursor = 'pointer';
DIVmap.style.display = '';
DIVmap.style.height = '35%';
DIVmap.style.margin = '1';
DIVmap.style.position = 'fixed';
DIVmap.style.padding = '1';
DIVmap.style.right = '1%';
DIVmap.style.bottom = '1%';
DIVmap.style.width = '35%';
DIVmap.style.zIndex = '99';
var DIVinternal = document.createElement('div');
DIVinternal.id = 'DIVinternal';
DIVinternal.style.height = '100%';
DIVinternal.style.width = '100%';
DIVinternal.style.zIndex = '999';
document.body.appendChild(DIVmap);
DIVmap.appendChild(DIVinternal);
//Adds a button which allows the user to re-run calcRoute
var reloadMapButton = document.createElement("button");
reloadMapButton.setAttribute("type", "button");
reloadMapButton.setAttribute("href", "#");
reloadMapButton.textContent="Reload map";
reloadMapButton.id="calcRoute";
reloadMapButton.style.zIndex = '1000';
document.getElementById('Content_Title').appendChild(reloadMapButton);
window.initialize = setTimeout(function () {
var myWindow;
try{
myWindow = unsafeWindow;
}catch(e){
myWindow = window;
}
google = myWindow.google;
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
var myLoc = new google.maps.LatLng(28.882193,-81.317936);
var myOptions = {
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: myLoc
}
map = new google.maps.Map(document.getElementById("DIVinternal"), myOptions);
var infoWindow1 = new google.maps.InfoWindow();
//var bounds = new google.maps.LatLngBounds();
var geocoder = new google.maps.Geocoder();
function codeAddress(address,i) {
setTimeout( function () { // timer to avoid google geocode limits
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
//map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}, i * 350);
}
function calcRoute() {
if (Table_1.rows.length > 1) { // table has 1 empty row if no search results are returned and first row is always empty
var newPoint;
for (var i = 1, row; row = Table_1.rows[i]; i++) {
newPoint = codeAddress(row.cells[10].title + ', ' + row.cells[11].innerHTML + ', ' + row.cells[12].innerHTML, i);
// bounds.extend(newPoint);
marker = new google.maps.Marker({
position: newPoint,
map: map,
title: row.cells[10].title + ', ' + row.cells[11].innerHTML + ', ' + row.cells[12].innerHTML
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow1.setContent(row.cells[10].title + ', ' + row.cells[11].innerHTML + ', ' + row.cells[12].innerHTML);
infoWindow1.open(map, this);
});
// Automatically center the map fitting all markers on the screen
// map.fitBounds(bounds);
}
}
}
//reloadMapButton.addEventListener('click', calcRoute);
document.getElementById("calcRoute").onclick = calcRoute;
calcRoute();
}, 1000);
} // if (document.getElementById('main_report') !== null)
sample data
Answer copied from the Reddit post:
If you carefully think through the code step by step, you can see why the infowindow isn't assigning itself to the markers. Starting from the calcRoute function:
if the table is more than one row
create newPoint variable
for each row in the table starting with the second one:
call the codeAddress function and assign it to newPoint
Let me cut in here. This is where your confusion is starting. codeAddress has no return statement (and even if it did, it would be asynchronous and wouldn't matter [AJAX]), so it isn't actually doing anything to newPoint. The whole marker is being created inside the codeAddress function, rendering the lines below this useless -- there is no position stored in newPoint so no marker is created, and thus no infoWindow is created.
Instead, you have to create the infoWindow inside the geocoding callback, right after you create the marker. You also have to assign that infoWindow to the marker using a click event. Also, if you want the hover title, just add it as a property of the marker called title.
The final code is here: http://pastebin.com/3rpWEnrp
You'll notice I cleaned it up a bit to make it more readable and clear:
The document's head can be accessed using document.head -- no need for getting it by the tag name
There is a shorthand for assigning two variables the same value: x = y = 3
No need for the z-index on the internal div; the external div already has it. (think of this like hold a piece of cardboard over something--anything on the cardboard is also lifted)
No need for the unsafeWindow; this is literally unsafe
Shorthand for definining multiple variables at once is var x = 3, y = 4;
You don't need the codeAddress function because you only call it once, so the whole contents of this just gets put into the calcRoute function.
It's less intrusive to use the console instead of alert, unless you really want the user to know, and in that case you need a simpler message
Why check if the table is longer than one row when the if statement won't fire in that case because it starts on row 2?
Change your calcRoute() function to call another function for each loop iteration. This will capture that function's parameters and local variables in a closure, so they will remain valid in the asynchronous event handler nested inside it.
You have a lengthy string expression repeated three times. Pull that out into a common variable so you only have to do it once.
Use var on your local variables. You're missing one on marker.
Be careful of your indentation. It is not consistent in your code: the marker click listener is not indented the same as the rest of the function it is nested inside. This makes it hard to see what is nested inside what.
Do not use this loop style:
for( var i = 1, row; row = Table_1.rows[i]; i++ ) { ... }
I used to advocate this type of loop, but it turned out to not be such a good idea. In an optimizing JavaScript environment, it is likely to force the array to become de-optimized. That may or may not happen in your particular code, and the array may be short enough that it just doesn't matter, but it's not a good habit these days. You're better off with a conventional loop with an i < xxx.length test.
So putting those tips together, we have this for your calcRoute():
function calcRoute() {
// table has 1 empty row if no search results are returned,
// and first row is always empty
if( Table_1.rows.length < 2 )
return;
for( var i = 1; i < Table_1.rows.length; i++ ) {
addMarker( i );
}
}
function addMarker( i ) {
var row = Table_1.rows[i];
var title =
row.cells[10].title + ', ' +
row.cells[11].innerHTML + ', ' +
row.cells[12].innerHTML;
var newPoint = codeAddress( title, i );
var marker = new google.maps.Marker({
position: newPoint,
map: map,
title: title
});
google.maps.event.addListener( marker, 'click', function () {
infoWindow1.setContent( title );
infoWindow1.open( map, this );
});
}
There are other problems here. You're calling this function:
var newPoint = codeAddress( ... );
But codeAddress() does not return a value! Nor could it return any useful value, because the function issues an asynchronous geocoder request. If you want to use the location provided by the geocoder, you will need to call a function from within the geocoder callback. I don't understand what you're trying to well enough to make a more specific suggestion here.
Thanks mostly to IanSan5653 on Reddit, I used mostly his code but had to change it a little. Here is working version on jsFiddle and the code below:
// ==UserScript==
// #name mapMarkers
// #namespace mapMarkers
// #include https://www.volusia.realforeclose.com/*
// #description map markers of addresses in table
// #version 1
// #grant none
// ==/UserScript==
// find the table and loop through each rows to get the 11th, 12th, 13th cell's content (street address, city and zip respectively
// convert to lat/lon and show markers on map
if (document.getElementById('main_report') != null) {
var script = document.createElement('script');
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&callback=initialize';
(document.head || document.body).appendChild(script);
var Table_1 = document.getElementById('main_report');
var DIVmap = document.createElement('div');
DIVmap.id = 'DIVmap';
DIVmap.style.border = '2px coral solid';
DIVmap.style.height = DIVmap.style.width = '35%';
DIVmap.style.margin = DIVmap.style.padding = '1';
DIVmap.style.position = 'fixed';
DIVmap.style.right = DIVmap.style.bottom = '1%';
DIVmap.style.zIndex = '999';
var DIVinternal = document.createElement('div');
DIVinternal.id = 'DIVinternal';
DIVinternal.style.height = DIVinternal.style.width = '100%';
document.body.appendChild(DIVmap);
DIVmap.appendChild(DIVinternal);
//Adds a button which allows the user to re-run calcRoute
var reloadMapButton = document.createElement("button");
reloadMapButton.setAttribute("type", "button");
reloadMapButton.textContent="Reload map";
reloadMapButton.id="calcRoute";
reloadMapButton.style.zIndex = '1000';
document.getElementById('Content_Title').appendChild(reloadMapButton);
// reloadMapButton.onclick = calcRoute;
window.initialize = function () {
var google = window.google,
directionsService = new google.maps.DirectionsService(),
directionsDisplay = new google.maps.DirectionsRenderer(),
myLoc = new google.maps.LatLng(28.882193,-81.317936),
myOptions = {
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: myLoc
},
infoWindow1 = new google.maps.InfoWindow(),
map = new google.maps.Map(document.getElementById("DIVinternal"), myOptions),
geocoder = new google.maps.Geocoder();
function calcRoute() {
for (var i = 1, row; row = Table_1.rows[i]; i++) {
console.log("processing row " + i);
address = row.cells[10].title + ', ' + row.cells[11].innerHTML + ', ' + row.cells[12].innerHTML,
setTimeout( function(addr) { // timer to avoid google geocode limits
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title: addr
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow1.setContent(addr);
infoWindow1.open(map,this);
});
} else {
console.error("Geocode was not successful for the following reason: " + status);
}
});
}(address), i * 400);
}
}
document.getElementById("calcRoute").onclick = calcRoute;
calcRoute();
}
}
I have implemented Google Maps JavaScript API v3 to contrive a custom store locator for my company's website. Let me start by saying that the code I have works for the two stores, but it would not be efficient or feasible if I added any more stores because of the "hacky" code used to make it work.
I am using the Google Maps Places Library to send "place details" requests to Google using the getDetails() method. On the callback, I am receiving the InfoWindow information (name, address, location) for each of my store locations.
I create a marker for each place, then use google.maps.event.addListener to coordinate the Place, Marker, and InfoWindow objects. This is where I encounter problems. The place details requests are not always received in the same order they are sent which throws off the indexing of my buttons that have a data-marker attribute set to 0 and 1, respectively, to correlate to the map markers.
Is there anyway to delay the second request until the first is finished? or write the script in a way that maintains ordinal integrity?
The first snippet of code below is my event handler to bind the click listener to each button using the .place.placeId property of the marker rather than the preferred technique of using the index of the markers array (the markers array holds the place details for the two stores).
None of the demos or examples in the Google Maps API documentation (Places Library) delineate the procedure for multiple places. Any tips, resources, or suggestions will be much appreciated
Website: http://m.alliancepointe.com/locate.html
Event Handler
$(".loc-btn").on('click', function () {
var me = $(this).data('marker');
var place1 = markers[0].place.placeId;
var myIndex = me == place1 ? 0 : 1;
google.maps.event.trigger(markers[myIndex], 'click');
});
Full JS
var markers = [];
var map;
var infowindow;
var service;
function initialize() {
var index;
var daddr;
var idVA = 'ChIJKezXgqmxt4kRXrAnqIwIutA';
var geoVA = '38.80407,-77.062881/Alliance+Pointe,+LLC';
var idDC = 'ChIJDQlqOLG3t4kRqDU3uNoy4hs';
var geoDC = '38.90188,-77.049161/Alliance+Pointe,+LLC';
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
center: {lat: 38.90188, lng: -77.049161},
zoom: 10,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
};
map = new google.maps.Map(document.getElementById('map'),
mapOptions);
var request = [
{placeId: idVA, location: {lat: 38.80407, lng: -77.062881}},
{placeId: idDC, location: {lat: 38.90188, lng: -77.049161}}
];
var office = [
"Main Office",
"Principal Office"
];
infowindow = new google.maps.InfoWindow();
service = new google.maps.places.PlacesService(map);
for (var i = 0; i < request.length; i++) {
service.getDetails(request[i], function (placeResult, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var id = placeResult.place_id;
var location = placeResult.geometry.location;
var trimAddr = placeResult.formatted_address.split(", ");
var image = {
url: 'images/icons/AP-marker_large.png',
scaledSize: new google.maps.Size(32, 54)
};
var marker = new google.maps.Marker({
map: map,
place: {
placeId: id,
location: location
},
icon: image,
title: "Get directions"
});
google.maps.event.addListener(marker, 'click', function () {
if (id == idVA) {
index = 0;
daddr = geoVA;
trimAddr[0] = "1940 Duke St #200";
} else {
index = 1;
daddr = geoDC;
trimAddr[0] = "2200 Pennsylvannia Ave NW";
}
infowindow.setContent('<div class="info-window title">' + placeResult.name + "</div><div class='info-window sub-title'>" + office[index] + '</div><div class="info-window">' + trimAddr[0] + '<br>' + trimAddr[1] + ", " + trimAddr[2] + '</div><div class="info-window direction-div"><div class="direction-icon"></div><a class="google-link save-button-link" target="_blank" href="https://www.google.com/maps/dir/Current+Location/' + daddr + '">Get Directions</a></div>');
infowindow.open(map, marker);
});
markers.push(marker);
//bounds.extend(location);
}
});
}
if (!bounds.isEmpty()) {
map.fitBounds(bounds);
}
$(".loc-btn").on('click', function () {
var me = $(this).data('marker');
var place1 = markers[0].place.placeId;
var myIndex = me == place1 ? 0 : 1;
google.maps.event.trigger(markers[myIndex], 'click');
//console.log("PlaceId = " + me);
//console.log("Adj index = " + myIndex);
//console.log("0:VA array index = " + markers[0].place.placeId);
//console.log("1:DC array index = " + markers[1].place.placeId);
});
google.maps.event.addListenerOnce(map, 'idle', function () {
$.mobile.loading("hide");
$(".loc-btn").prop("disabled",false);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
HTML: Map & Buttons
<div data-role="content" class="full-width">
<figure id="map"></figure>
<div class="loc-btn-set">
<button disabled data-role="none" data-theme="a" data-marker="ChIJKezXgqmxt4kRXrAnqIwIutA" class="loc-btn nightly-button">VA <span>- Alexandria</span></button>
<button disabled data-role="none" data-theme="b" data-marker="ChIJDQlqOLG3t4kRqDU3uNoy4hs" class="loc-btn nightly-button">DC <span>- Washington</span></button>
</div>
</div>
The simpliest approach based on the given code would be to add the click-handler for the buttons inside the getDetails-callback.
Add this after the creation of the marker:
$('.loc-btn[data-marker="'+id+'"]').click(function(){
google.maps.event.trigger(marker,'click');
});
I am trying to parse my kml files to get the locations of the placemarks and add html links to those locations so that when clicked the map will pan to the location the user clicked on. However with the code I have now it will not parse the file correctly, and gives me this error
Uncaught NotFoundError: Failed to execute 'appendChild' on 'Node': The new child element is null.
I assume this error mens that when it was going to add the link for the location the parser returned a null value. I am pretty sure that I am doing the calls correctly but still not sure why this error is popping up, can anyone help?
var map = null;
var KMLLayer = null;
var KMLayer2 = null;
var item = "";
var nav = [];
$(document).ready(function(){
//initialise a map
initialize();
$.get("/img/Keenelandlayer2.kml", function(data){
var html = "";
//loop through placemarks tags
$(data).find("Placemark").each(function(index, value){
//get coordinates and place name
coords = $(this).find("coordinates").text();
place = $(this).find("name").text();
test = "test";
//store as JSON
c = coords.split(",")
nav.push({
"place": place,
"lat": c[0],
"lng": c[1]
});
//output as a navigation
html += "<li>" + place + test + "</li>";
item = "<li>" + place + test + "</li>";
document.getElementById("list").appendChild(item);
})
//output as a navigation
$(".navigation").append(html);
//bind clicks on your navigation to scroll to a placemark
$(".navigation li").bind("click", function(){
panToPoint = new google.maps.LatLng(nav[$(this).index()].lng, nav[$(this).index()].lat);
map.panTo(panToPoint);
});
});
});
function initialize() {
var mapOptions = {
center: new google.maps.LatLng( 38.04798015658998, -84.59683381523666),
zoom: 16,
disableDefaultUI: true,
zoomControl: true,
mapTypeId: google.maps.MapTypeId.SATELLITE
};
var kmlOptions = {
suppressInfoWindows: true,
preserveViewport: false,
map: map
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
KMLLayer = new google.maps.KmlLayer({url: 'https://sites.google.com/site/cs499fbt/files/Keenelandlayer1.kml'}, kmlOptions);
KMLLayer2 = new google.maps.KmlLayer({url:'https://sites.google.com/site/cs499fbt/files/Keenelandlayer2.kml'},kmlOptions);
KMLLayer.setMap(map);
google.maps.event.addListener(map, "zoom_changed",function() {
//below is the line that prevents the labels to appear, needs to be there to allow the second kml layer to be displayed
event.preventDefault();
if (!!map){
var zoom = map.getZoom();
if (zoom < 16){
if (!!KMLLayer2.getMap()) KMLLayer2.setMap(null);
if (!KMLLayer.getMap()) KMLLayer.setMap(map);
}
else{
if (!KMLLayer2.getMap()) KMLLayer2.setMap(map);
if (!!KMLLayer.getMap()) KMLLayer.setMap(null);
}
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
item is not a node, it's simply a string which may not be used as argument for appendChild.
Create a node:
item = document.createElement('li');
item.appendChild(document.createTextNode(place + test));
document.getElementById("list").appendChild(item);
or use jQuery(like you do it a few lines later):
$('#list').append($("<li>" + place + test + "</li>"));