polylines and infowindows with Google Maps? - google-maps

I have a map with multiple polylines and would like to open a line-specific-infowindow when clicking the line.
So far my code can't shown any infowindow when click the line,
Here is my code:
var poly;
var polyOptions = {
strokeColor: '#ff0000',
strokeOpacity: 1.0,
strokeWeight: 3
}
poly = new google.maps.Polyline(polyOptions);
poly.setMap(map);
for(var i=0; i<locations.length; i++){
var loc = locations[i].split(',');
var path = poly.getPath();
path.push(new google.maps.LatLng(loc[0], loc[1]));
createInfoWindow(poly,'polyinfo...test');
}
function createInfoWindow(poly,content) {
google.maps.event.addListener(poly, 'click', function(event) {
infowindow.content = content;
infowindow.position = event.latLng;
infowindow.open(map);
});
}

There is no need to call poly.getPath() and createInfoWindow(poly, 'polyinfo...test'); for each point. It could be called only once before and when the whole path is created:
var path = poly.getPath();
for (var i = 0; i < locations.length; i++) {
//var loc = locations[i].split(',');
var loc = locations[i];
path.push(new google.maps.LatLng(loc[0], loc[1]));
//createInfoWindow(poly, 'polyinfo...test');
}
createInfoWindow(poly, 'polyinfo...test');
To set content and position of infowindow you have to use methods for that:
function createInfoWindow(poly, content) {
google.maps.event.addListener(poly, 'click', function(event) {
// infowindow.content = content;
infowindow.setContent(content);
// infowindow.position = event.latLng;
infowindow.setPosition(event.latLng);
infowindow.open(map);
});
}
See whole example at jsbin.

Related

Google maps v3 - Add markers at the center of tiles

function initialize() {
var myLatlng;
var mapOptions;
myLatlng = new google.maps.LatLng(29.98439980, -95.34140015);
mapOptions = {
zoom: 16,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(
document.getElementById("map-canvas"), mapOptions);
google.maps.event.addListenerOnce(map, 'idle', function() {
drawRectangle(map);
var result = {"regionList":[{"centerLongitude":-95.34890747070312,"imageIcon":"../images/untested-icon.png","centerLatitude":29.980682373046875},{"centerLongitude":-95.34890747070312,"imageIcon":"../images/untested-icon.png","centerLatitude":29.988117218017578},{"centerLongitude":-95.33389282226562,"imageIcon":"../images/untested-icon.png","centerLatitude":29.980682373046875},{"centerLongitude":-95.33389282226562,"imageIcon":"../images/untested-icon.png","centerLatitude":29.988117218017578}]};
alert(result);
addMarkersAtRegionCenter(map, result);
});
function addMarkersAtRegionCenter(map, result) {
var length = result.regionList.length;
var regionUrl = "drilledDownToRegion.jsp?";
for(var i=0; i<length; i++)
{
var image = result.regionList[i].imageIcon;
//alert("Latitude : " + result.regionList[i].centerLatitude);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(result.regionList[i].centerLatitude,result.regionList[i].centerLongitude),
icon: 'http://maps.google.com/mapfiles/ms/icons/blue.png',
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() {
window.location.href = marker.url;
}
})(marker, i));
}
}
function drawRectangle(map) {
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var numberOfParts = 4;
var tileWidth = (northEast.lng() - southWest.lng()) / numberOfParts;
var tileHeight = (northEast.lat() - southWest.lat()) / numberOfParts;
for (var x = 0; x < numberOfParts; x++) {
for (var y = 0; y < numberOfParts; y++) {
var areaBounds = {
north: southWest.lat() + (tileHeight * (y+1)),
south: southWest.lat() + (tileHeight * y),
east: southWest.lng() + (tileWidth * (x+1)),
west: southWest.lng() + (tileWidth * x)
};
var area = new google.maps.Rectangle({
strokeColor: '#FF0000',
//strokeOpacity: 0.8,
strokeWeight: 2,
//fillColor: '#FF0000',
//fillOpacity: 0.35,
map: map,
bounds: areaBounds
});
}
}
}
}
google.maps.event.addDomListener(window, "load", initialize);
In the above code, I am trying to add markers at the center of each rectangle. But I am not able to add markers. I have hard coded image icon value since I don't have image mentioned in the array.
Thanks in advance for your help.
Related question: Google maps api v3 - divide region into equal parts using tiles
Simpler to add the markers to the centers of the rectangles when you create them:
var centerMark = new google.maps.Marker({
position: area.getBounds().getCenter(),
map: map
});
proof of concept fiddle
To add the markers from the response to the map (the positions in the posted response are not at the center of the squares), this is the same function you posted in your question, it works for me (the blue markers), I modified your click listener to open an infowindow (rather than do a redirect of the page):
function addMarkersAtRegionCenter(map, result) {
var length = result.regionList.length;
var regionUrl = "drilledDownToRegion.jsp?";
for (var i = 0; i < length; i++) {
var image = result.regionList[i].imageIcon;
var marker = new google.maps.Marker({
position: new google.maps.LatLng(result.regionList[i].centerLatitude, result.regionList[i].centerLongitude),
icon: 'http://maps.google.com/mapfiles/ms/icons/blue.png',
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
// window.location.href = marker.url;
infowindow.setContent("regionList:" + i + "<br>centLat=" + result.regionList[i].centerLatitude + "<br>centLng=" + result.regionList[i].centerLongitude + "<br>imageIcon=" + result.regionList[i].imageIcon + "<br>" + marker.getPosition().toUrlValue(6));
infowindow.open(map, marker);
}
})(marker, i));
}
}

Google maps v3 decode polygon(s) from MySQL database

I would like to draw one or more polygons which are saved encoded in the MySQL database. I've based my code on the known bermudatriangle script example. The XML from "polygon_xml.php" is OK. For now, there's only 1 encoded coordinate in the database. At: //alert1(decodedPolygon); the coordinates are shown, but at //alert2(decodedPolygon); it's not. It has something to do with the array decodedPolygon I guess. What makes me more confusing is that the polygon does show when I uncomment //alert2(decodedPolygon);. Alert2 is empty but after clicking "OK", the polygon is shown on the map!??? Finally I would like to add text to the XML and place it in the infowindow instead of the coordinates.
My 3 encoded coordinates are:
{zzfIsjmu#kHuczRrg{NxcsO}t{GtczR
a}~cIqcskBu|sEov{OoxNel}AfccMwfzG~q|#nknX}u~GvczR
cljkHmfoQl|J{hrV~syGzhrV
I hope somebody can help / explain.
Here's my code so far:
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry">
<script>
var map;
var infoWindow;
var decodedPolygon = [];
function initialize() {
var mapOptions = {
zoom: 3,
center: new google.maps.LatLng(49.724479, 17.578125),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
downloadUrl("polygon_xml.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
//var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
var encodedPath = markers[i].getAttribute("coords");
decodedPolygon = google.maps.geometry.encoding.decodePath(encodedPath);
//alert1(decodedPolygon);
//bounds.extend(decodedPolygon);
}
})
//alert2(decodedPolygon);
// Construct the polygon.
bermudaTriangle = new google.maps.Polygon({
paths: decodedPolygon,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
// Add a listener for the click event.
google.maps.event.addListener(bermudaTriangle, 'click', showArrays);
infoWindow = new google.maps.InfoWindow();
}
/** #this {google.maps.Polygon} */
function showArrays(event) {
// Since this polygon has only one path, we can call getPath()
// to return the MVCArray of LatLngs.
var vertices = this.getPath();
var contentString = '<b>Bermuda Triangle polygon</b><br>' +
'Clicked location: <br>' + event.latLng.lat() + ',' + event.latLng.lng() +
'<br>';
// Iterate over the vertices.
for (var i = 0; i < vertices.getLength(); i++) {
var xy = vertices.getAt(i);
contentString += '<br>' + 'Coordinate ' + i + ':<br>' + xy.lat() + ',' +
xy.lng();
}
// Replace the info window's content and position.
infoWindow.setContent(contentString);
infoWindow.setPosition(event.latLng);
infoWindow.open(map);
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body>
<div id="map-canvas"></div>
downloadUrl is asynchronous, you need to use the data returned inside the callback routine. Right now, the bermudaTriangle polygon is constructed before the data is returned (outside of the callback function).
function initialize() {
var mapOptions = {
zoom: 3,
center: new google.maps.LatLng(49.724479, 17.578125),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
downloadUrl("polygon_xml.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
var encodedPath = markers[i].getAttribute("coords");
var decodedPolygon = google.maps.geometry.encoding.decodePath(encodedPath);
for (var j = 0; j < decodedPolygon.length; j++) {
bounds.extend(decodedPolygon[j]);
}
// Construct the polygon.
var bermudaTriangle = new google.maps.Polygon({
paths: decodedPolygon,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
// Add a listener for the click event.
google.maps.event.addListener(bermudaTriangle, 'click', showArrays);
}
map.fitBounds(bounds);
})
infoWindow = new google.maps.InfoWindow();
}
proof of concept fiddle

Google Maps and RouteBoxer will not display polygon lines

Thanks in advance for any help you can provide! I'm using RouteBoxer in Google Maps API V3, but for some reason I can't get the lines to appear. I'm concerned that the function isn't running at all, and it's necessary for the next step of my project: passing lat and long to find pois along the route. Seeing the lines on the map will help me make sure it's running correctly.
Here is my code
<script>
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var routeBoxer = null;
var boxpolys = null;
var rdistance = 20; // km
function initialize() {
//directionspanelstuff
//directionsdisplaystuff
//mapoptions
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
directionsDisplay.setMap(map);
routeBoxer = new RouteBoxer();
}
function calcRoute() {
//startendwaypoints
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
var summaryPanel = document.getElementById("directions_panel");
// Box the overview path of the first route
var path = result.routes[0].overview_path;
var boxes = routeBoxer.box(path, rdistance);
clearBoxes();
drawBoxes(boxes);
for (var i = 0; i < boxes.length; i++) {
var bounds = box[i];
// Perform search over this bounds
}
}
});
}
// Draw the array of boxes as polylines on the map
function drawBoxes(boxes) {
boxpolys = new Array(boxes.length);
for (var i = 0; i < boxes.length; i++) {
boxpolys[i] = new google.maps.Rectangle({
bounds: boxes[i],
fillOpacity: 0,
strokeOpacity: 1.0,
strokeColor: '#000000',
strokeWeight: 1,
map: map
});
}
}
// Clear boxes currently on the map
function clearBoxes() {
if (boxpolys != null) {
for (var i = 0; i < boxpolys.length; i++) {
boxpolys[i].setMap(null);
}
}
boxpolys = null;
}
</script>
There are 4 javascript errors pointed out by the javascript console:
mapOptions is not defined (probably not a real problem)
directionsDisplay is null (not initialized)
result is undefined (typo, or cut and paste error)
box is undefined (typo)
working example
code snippet:
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var routeBoxer = null;
var boxpolys = null;
var rdistance = 20; // km
function initialize() {
//directionspanelstuff
//directionsdisplaystuff
//mapoptions
map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 10,
center: new google.maps.LatLng(41.084951, 29.016048),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
routeBoxer = new RouteBoxer();
calcRoute();
}
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var request = {
origin: start,
destination: end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
//startendwaypoints
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
var summaryPanel = document.getElementById("directions_panel");
// Box the overview path of the first route
var path = response.routes[0].overview_path;
var boxes = routeBoxer.box(path, rdistance);
clearBoxes();
drawBoxes(boxes);
for (var i = 0; i < boxes.length; i++) {
var bounds = boxes[i];
// Perform search over this bounds
}
}
});
}
// Draw the array of boxes as polylines on the map
function drawBoxes(boxes) {
boxpolys = new Array(boxes.length);
for (var i = 0; i < boxes.length; i++) {
boxpolys[i] = new google.maps.Rectangle({
bounds: boxes[i],
fillOpacity: 0,
strokeOpacity: 1.0,
strokeColor: '#000000',
strokeWeight: 1,
map: map
});
}
}
// Clear boxes currently on the map
function clearBoxes() {
if (boxpolys != null) {
for (var i = 0; i < boxpolys.length; i++) {
boxpolys[i].setMap(null);
}
}
boxpolys = null;
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map_canvas {
margin: 0;
padding: 0;
height: 100%;
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/routeboxer/src/RouteBoxer.js"></script>
<input id="start" type="text" onchange="calcRoute();" value="chicago, il"></input>
<input id="end" type="text" onchange="calcRoute();" value="st louis, mo"></input>
<div id="map_canvas" style="height: 400px; width:500px;"></div>
<div id="info"></div>

Draggable snap to road distance markers

I am using some helpful code I found at http://exploregooglemaps.blogspot.com.br/2012/02/measuring-distance-with-markers.html to add markers and measure distance.
I would like the markers to snap to road by default, but when the users holds the shift key a direct line is used.
I have managed to implement the if statement for the shift key, and a path is drawn when I hold the shift key, however no snap to road path is drawn by default.
I am calling two functions, one to draw a straight line drawPath and one to draw a snap to road line drawPathD
Any help would be much appreciated.
<code>
var map,
service = new google.maps.DirectionsService(),
shiftPressed = false,
poly;
var path = [];
shiftPressed = false;
var markers = [];
var routePoints = [];
google.maps.event.addDomListener(document, "keydown", function () {
shiftPressed = true;
});
google.maps.event.addDomListener(document, "keyup", function () {
shiftPressed = false;
});
function $(id) {
return document.getElementById(id);
}
var map;
var mapOptions = {
center: new google.maps.LatLng(-23.5489433, - 46.6388182),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var markers = [];
var line;
function initialize() {
map = new google.maps.Map($("map_canvas"), mapOptions);
line = new google.maps.Polyline({
map: map,
strokeColor: "#FF3333",
strokeOpacity: 0.5,
strokeWeight: 8
});
google.maps.event.addListener(map, 'click', function (event) {
var marker = new google.maps.Marker({
map: map,
position: event.latLng,
draggable: true
});
if (shiftPressed) {
markers.push(marker);
drawPath();
} else {
markers.push(marker);
drawPathD();
}
google.maps.event.addListener(marker, 'dblclick', function (event) {
marker.setMap(null);
drawPath();
});
google.maps.event.addListener(marker, 'drag', function (event) {
drawPath();
});
});
}
function countMarkers() {
count = 0;
for (var i = routePoints.length - 1; i >= 0; i--) {
if (markers[i].getMap() == null) {
routePoints.splice(i, 1);
} else {
count++;
}
}
return count;
}
function drawPath() {
countMarkers();
var coords = [];
for (var i = 0; i < markers.length; i++) {
coords.push(markers[i].getPosition());
}
line.setPath(coords);
meters = google.maps.geometry.spherical.computeLength(coords);
$("distKm").value = Math.round(meters / 1000 * 100) / 100;
$("distMi").value = Math.round(meters / 1609 * 100) / 100;
}
function drawPathD(event) {
countMarkers();
var coords = [];
service.route({
origin: path[path.length - 1],
destination: event.latLng,
travelMode: google.maps.DirectionsTravelMode.WALKING
}, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
path = path.concat(result.routes[0].overview_path);
routePoints.setPath(path);
}
});
meters = google.maps.geometry.spherical.computeLength(coords);
$("distKm").value = Math.round(meters / 1000 * 100) / 100;
$("distMi").value = Math.round(meters / 1609 * 100) / 100;
}
function clearMarkers() {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null)
}
drawPath();
}
google.maps.event.addDomListener(window, 'load', initialize);
</code>
Here's how to implement the "Snap to Road" functionality in Google Maps API v3:
polyline snap to road using google maps api v3

Multiple polylines and infowindows with Google Maps V3

I have a map with multiple polylines and would like to open a line-specific-infowindow when clicking the line.
So far my code only shows the content of the last iteration.
I found two very nice examples of what I want but after hours of trying I am still no further.
Example 1: http://srsz750.appspot.com/api3/polylines-multiple.html
Example 2: http://www.geocodezip.com/v3_GenericMapBrowser.asp?filename=flights090414.xml
So your are my last shot :-S
Here is my code that shows only the content of the last iteration:
for (var i = 0; i < locations.length; i++) {
var route = locations[i]; // locations is an array of route-arrays.
//route is an array with details. route[0] contains the description.
var imageStart = 'img/rijder.png';
var polyOptions = {
strokeColor: '#0000FF',
strokeOpacity: 1.0,
strokeWeight: 3
}
poly = new google.maps.Polyline(polyOptions, info);
var path = poly.getPath();
//line text
var info = route[0];
google.maps.event.addListener(poly, 'click', function(event) {
infowindow.setContent(info);
infowindow.position = event.latLng;
infowindow.open(map);
});
//startmarker
var startLatLng = new google.maps.LatLng(route[1], route[2]);
var smarker = new google.maps.Marker({
position: startLatLng,
map: map,
icon: imageStart,
title: route[7],
html: route[0]
});
path.push(startLatLng);
//starttext
google.maps.event.addListener(smarker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
//endmarker
var endLatLng = new google.maps.LatLng(route[4], route[5]);
var emarker = new google.maps.Marker({
position: endLatLng,
map: map,
icon: imageEnd,
title: route[8],
html: route[3]
});
path.push(endLatLng);
//endtext
google.maps.event.addListener(emarker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
//close line and put on the map
poly.setMap(map);
}
}
And here is the code I would expect to work but all lines disappeared (only the relevant code, I also added a mouseover function):
//line text
google.maps.event.addListener(poly, 'click', (function(event,index){
return function(){
var routeinfw = locations[index];
var inf = routeinfw[0];
infowindow.setContent(inf);
infowindow.position = mouselocation;
infowindow.open(map);
};
})(event,i));
//starticon
Just like in the example you posted, create a function to create the click events listeners and call it from inside the locations loop:
function createInfoWindow(poly,content) {
google.maps.event.addListener(poly, 'click', function(event) {
infowindow.content = content;
infowindow.position = event.latLng;
infowindow.open(map);
});
}
And you can call this at the end of the loop:
createInfoWindow(poly,info);