How to define dynamic variables in JSP loop? - google-maps

I have written the following code to display markers and have respective info windows displaying name of the policestation.
The policestation class has name, latitude and longitude.
<script>
function initialize()
{
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
var myCenter = new google.maps.LatLng(28.6523605,77.0910645);
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var mapProp = {
center: myCenter,
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scaleControl: true
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var marker = [];
var info= [];
<%
ArrayList<PoliceStation> stationList = new PoliceStation().loadclass();
for (int i=0 ; i < stationList.size() ; i++) {
%>
var pos = new google.maps.LatLng(
<%= stationList.get(i).getLatitude()%>,
<%= stationList.get(i).getLongitude()%>
);
marker = new google.maps.Marker({
position: pos,
map: map
});
marker.setMap(map);
var MarkerContent = "<div class=\"marker\">" +
"<h2>"+ "<%=stationList.get(i).getstationName()%>"
+"</h2>"+
"</div>";
info=new google.maps.InfoWindow();
info.setOptions({
content: MarkerContent,
size: new google.maps.Size(50, 50),
position: pos
});
google.maps.event.addListener(marker, 'click', function () {
info.setOptions({
content: MarkerContent
});
info.open(map, marker);
});
<%
}
%>
All the markers are set as expected. However clicking any marker results in opening the infowindow of only the last marker drawn.
I get that this is because all the marker, infoWindow names are redundant and in the end only the last infoWindow gets saved to the last marker.
I have come across solutions that encapsulate the content inside the for loop with
(function() {var marker = ...; google.maps.event.addListener...;})();
However, I'm looking for a solution to dynamically distinctly define each variable name.
like for example append the value of a counter incremented at each iteration to each marker and info variable.
Kindly do not provide JSTP solution. looking for a specific JSP solution

Surprisingly it was really easy...
JSP is basically used to print HTML dynamically.
so, instead of using marker variable as
var marker = new google.maps.Marker({
position: pos,
map: map
});
use -
var <%out.print("marker"+i);%> = new google.maps.Marker({
position: pos,
map: map
});
It is to be noted that-
var <%out.print("marker["+i+"]");%> = new google.maps.Marker({
position: pos,
map: map
});
did not work for me.
The correct code above creates new variables with values marker1, marker2... etc
also the content update function inside the event listener-
info.setOptions({
content: MarkerContent
});
is not required.

Related

How to refresh latitude and longitude without refresh MAP

We have a Google map on our website. We want to update latitude and longitude every 5 seconds (Call from MySQL) and change the marker place on the map, while the MAP or page don't reload with it.
Our JAVASCRIPT code is:
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var mapOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
// To add the marker to the map, use the 'map' property
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title:"Hello World!"
});
You have to use an AJAX call to a backend script that will return something like a JSON string with new marker data.
jQuery code:
setInterval(function () {
$.post('your-file.php', { }, function (r) {
var result = eval('(' + r + ')');
var newLatLng = new google.maps.LatLng(result.latitude, result.longitude);
marker.setMap(null);
/* Recreate the marker here or update coordinates from result.latitude and result.longitude */
});
}, 5000);
And this is your-file.php:
/* MySQL Query here */
echo json_encode('latitude' => $latitude, 'longitude' => $longitude);
Using marker.setMap(null) you can remove the marker from your map and then create it again with the correct coordinates otherwise just use marker.setPosition(newLatLng);

Google maps infowindow

I am trying to create listeners for some map markers. I can create the markers and they are on the map but, no matter which marker I click on it tells me "Uncaught TypeError: Cannot call method 'open' of undefined" . When I break at the open code it is showing markers[46] which is one more that the highest index. And it doesnt matter which marker I click on its always the same index.
EDIT: I edited the code and pasted all of it. No errors, but nothing happens when I click a marker. I am looking in Chrome and it looks like there isnt a event handler registered
<script>
var map;
var nav = [];
$(document).ready(function () {
//initialise a map
init();
var infowindow = new google.maps.InfoWindow({});
$.get("xxxxxx.kml", function (data) {
html = "";
//loop through placemarks tags
i = 1;
$(data).find("Placemark").each(function (index, value) {
//get coordinates and place name
coords = $(this).find("coordinates").text();
contentString = $(this).find("description").text();
var partsOfStr = coords.split(',');
var lat = parseFloat(partsOfStr[0]);
var lng = parseFloat(partsOfStr[1]);
var myLatLng = new google.maps.LatLng(lng, lat);
place = $(this).find("name").text();
createMarker(myLatLng, place, contentString, i)
//store as JSON
c = coords.split(",")
nav.push({
"place": place,
"lat": c[0],
"lng": c[1]
})
//output as a navigation
html += "<li>" + place + "</li>";
i++;
});
//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);
})
});
markers = [];
function createMarker(myLatLng, title, contentString, i) {
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: title
});
google.maps.event.addListener(markers, 'click', function () {
infoWindow.setContent(contentString);
infowindow.open(map, markers[i]);
});
markers[i] = marker;
return marker
}
function init() {
//google.maps.event.addDomListener(window, 'init', Initialize);
var latlng = new google.maps.LatLng(39.047050, -77.131409);
var myOptions = {
zoom: 4,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
}
})
This is almost a FAQ. When your loop ends, the value of i is 46 (based on your statement). There is no marker 46, so all the click listeners fail. It can be solved with function closure (a createMarker function which holds the association between the marker and the infowindow contents).
Something like this in your example (not tested), call it from inside your marker creation loop, requires a global markers array, but doesn't require the global infowindow array:
//global markers array
markers = [];
// global infowindow
var infowindow = new google.maps.InfoWindow({});
// createMarker function
function createMarker(myLatLng, title, contentString, i)
{
var marker = new google.maps.Marker({
position: myLatlng ,
map: map,
title:title
});
google.maps.event.addListener(markers, 'click', function() {
infoWindow.setContent(contentString);
infowindow.open(map,markers[i]);
});
markers[i] = marker;
return marker
}

Close open InfoBubble when open a new (gMap v3)

I do not know what to do... I just want to close all opened infoBubbles if I'm going to open a new one. I am using the following code. Ideas? I tried a lot and googled a lot but it shouldn't be so complicated, should it? I thought to create an array and save id for the open one, but I think that there must be another, quite easier way to fix this.
$(document).ready(function(){
createmap();
function createmap(lat,lng){
var latlng = new google.maps.LatLng(50, 10);
var myOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
bounds = new google.maps.LatLngBounds();
createMarker();
}
function createMarker(){
var markers = [];
var cm = window.cm = new ClusterManager(
map,
{
objClusterIcon: new google.maps.MarkerImage('images/map/flag_cluster.png', false, false, false, new google.maps.Size(20,20)),
objClusterImageSize: new google.maps.Size(20,20)
}
);
var json = [];
var x1 = -85;
var x2 = 85;
var y1 = -180;
var y2 = 180;
for (var i=0; i<20; ++i) {
json.push(
'{'+
'"longitude":'+(x1+(Math.random()*(x2-x1)))+','+
'"latitude":'+(y1+(Math.random()*(y2-y1)))+','+
'"title":"test"'+
'}'
);
}
json = '['+json.join()+']';
// eval is ok here.
eval('json = eval(json);');
infos = [];
$.each(json, function(i,item){
var contentString = '<div id="content"><a onclick="createdetailpage('+i+');">'+item.title+'<br /></a></div>';
console.log(item.latitude);
var myLatlng = new google.maps.LatLng(item.latitude,item.longitude);
var marker = new google.maps.Marker({
position: myLatlng,
//map: map,
flat: true,
title:item.title,
//animation: google.maps.Animation.DROP,
//icon: myIcon
});
var infoBubble = new InfoBubble({
content: '<div class="phoneytext">'+contentString+'</div>'
});
google.maps.event.addListener(marker, 'click', function() {
if (!infoBubble.isOpen()) {
infoBubble.open(map, marker);
}
});
cm.addMarker(marker, new google.maps.Size(50, 50));
});
map.fitBounds(bounds);
}
});
The simplest approach to only have one infoBubble open is to only have one infoBubble and open it with different contents depending on the marker that is clicked.
InfoWindow example with custom markers (same concept applies to InfoBubble)
The InfoBubble is an OverlayView. As far as I can see, an overlaycomplete event is emitted when an overlay is added. Maybe all your InfoBubbles could listen to that event and close if the added overlay is a different one than "this".
It's just a thought, though, I haven't tried it myself. Feedback appreciated if you try it out!

InfoWindow on Marker using MarkerClusterer

This is my html code. I've try anything to add an infowindow on the markers but it don't wanna work. My data is loading from the "Alle_Ortswahlen.page1.xml" file.
Do anyone have an idea how can I add infoWindow to each marker?
<script type="text/javascript">
google.load('maps', '3', {
other_params: 'sensor=false'
});
google.setOnLoadCallback(initialize);
function initialize() {
var stack = [];
var center = new google.maps.LatLng(48.136, 11.586);
var options = {
'zoom': 5,
'center': center,
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), options);
GDownloadUrl("Alle_Ortswahlen.page1.xml", function(doc) {
var xmlDoc = GXml.parse(doc);
var markers = xmlDoc.documentElement.getElementsByTagName("ROW");
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i].getAttribute("Field4"));
var lng = parseFloat(markers[i].getAttribute("Field6"));
var marker = new google.maps.Marker({
position : new google.maps.LatLng(lat, lng),
map: map,
title:"This is a marker"
});
stack.push(marker);
}
var mc = new MarkerClusterer(map,stack);
});
}
</script>
Before the for cycle, make an empty infowindow object.
var infowindow = new google.maps.InfoWindow();
Than in the for cycle, after the marker, add an event listener, like this:
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent("You might put some content here from your XML");
infowindow.open(map, marker);
}
})(marker, i));
There is some closure magic happening when passing the callback argument to the addListener method. If you are not familiar with it, take a look at here:
Mozilla Dev Center: Working with Closures
So, your code should look something like this:
google.load('maps', '3', {
other_params: 'sensor=false'
});
google.setOnLoadCallback(initialize);
function initialize() {
var stack = [];
var center = new google.maps.LatLng(48.136, 11.586);
var options = {
'zoom': 5,
'center': center,
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), options);
var infowindow = new google.maps.InfoWindow();
GDownloadUrl("Alle_Ortswahlen.page1.xml", function(doc) {
var xmlDoc = GXml.parse(doc);
var markers = xmlDoc.documentElement.getElementsByTagName("ROW");
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i].getAttribute("Field4"));
var lng = parseFloat(markers[i].getAttribute("Field6"));
var marker = new google.maps.Marker({
position : new google.maps.LatLng(lat, lng),
map: map,
title:"This is a marker"
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent("You might put some content here from your XML");
infowindow.open(map, marker);
}
})(marker, i));
stack.push(marker);
}
var mc = new MarkerClusterer(map,stack);
});
}
So what you need to do is add some code, inside your for-loop, associating an infowindow onclick event handler with each marker. I'm assuming you only want to have 1 infowindow showing at a time, i.e. you click on a marker, the infowindow appears with relevant content. If you then click on another marker, the first infowindow disappears, and a new one reappears attached to the other marker. Rather than having multiple infowindows all visible at the same time.
GDownloadUrl("Alle_Ortswahlen.page1.xml", function(doc) {
var xmlDoc = GXml.parse(doc);
var markers = xmlDoc.documentElement.getElementsByTagName("ROW");
// just create one infowindow without any content in it
var infowindow = new google.maps.InfoWindow({
content: ''
});
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i].getAttribute("Field4"));
var lng = parseFloat(markers[i].getAttribute("Field6"));
var marker = new google.maps.Marker({
position : new google.maps.LatLng(lat, lng),
map: map,
title:"This is a marker"
});
// add an event listener for this marker
google.maps.event.addListener(marker , 'click', function() {
// assuming you have some content in a field called Field123
infowindow.setContent(markers[i].getAttribute("Field123"));
infowindow.open(map, this);
});
stack.push(marker);
}
var mc = new MarkerClusterer(map,stack);
});

Toggle on/off Google map markers by category

I have the below and want to sort the markers by the various category type being pulled under cat: dataMarkers.cat. Im a bit lost as to how to actually do this the best way. I'm thinking markerManager for each category? Would I need each category to be in its own markerManager array? How does this factor in with markerClusterer?
var map;
function initialize() {
var center = new google.maps.LatLng(39.632906,-106.524591);
var options = {
'zoom': 8,
'center': center,
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), options);
<!--Load Markers-->
var markers = [];
for (var i = 0, dataMarkers; dataMarkers = data.markers[i]; i++) {
var latLng = new google.maps.LatLng(dataMarkers.lat, dataMarkers.lng);
var marker = new google.maps.Marker({
position: latLng,
title: dataMarkers.title,
date: dataMarkers.date,
time: dataMarkers.time,
desc: dataMarkers.desc,
img: dataMarkers.img,
add: dataMarkers.address,
cat: dataMarkers.cat,
map: map
});
<!--Display InfoWindows-->
var infowindow = new google.maps.InfoWindow({
content: " "
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('<div id="mapCont"><img class="mapImg" src="'+this.img+'"/>' +
'<div class="mapTitle">'+this.title+'</div>' +
'<div class="mapHead">Date: <div class="mapInfo">'+this.date+'</div>' +
'<div class="mapHead">Time: <div class="mapInfo">'+this.time+'</div>' +
'<p>'+this.desc+'</p></div>');
infowindow.open(map, this);
});
markers.push(marker);
}
<!--Cluster Markers-->
var markerClusterer = new MarkerClusterer(map, markers, {
maxZoom: 15,
gridSize: 50
});
}
I recommend you store all the markers in an array. Create a field called category on each marker and give it the correct value.
Whenever the category changes, you run through your array of markers and set marker.visible = true on the ones in the correct category, and marker.visible = false on all the others.
In JavaScript, it is easy to dynamically assign new fields to an object. You would simply say:
var marker = new google.maps.Marker({
position: latLng,
title: dataMarkers.title,
date: dataMarkers.date,
time: dataMarkers.time,
desc: dataMarkers.desc,
img: dataMarkers.img,
add: dataMarkers.address,
cat: dataMarkers.cat,
map: map
});
marker.category = THE_CATEGORY_IT_BELONGS_TO;
The marker will then have a field called category as long as it exists.