Records are selected from a database and animated on a map. I am getting a TypeError in firebug console and i cannot find what is causing the error. No markers get plotted and no animation is occurring. Error is occuring in the makeRouteCallback function.
Using console.log() has revealed that rNum has the correct values 0,1,2,3,4.
Error
TypeError: polyline[rNum] is undefined
polyline[rNum].setMap(map);
I also did a console.log for 'status' in the makeRouteCallback function and it printed NOT_FOUND instead of OK
Code
<%@ include file="/WEB-INF/jsp/include.jsp" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix = "fmt" uri= "http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix = "c" uri= "http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<link href="<c:url value="/resources/css/crimeTrackMap.css" />" rel="stylesheet" type="text/css" media="screen" />
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyAuJC5ega61cLlvCB14uKxoheUmh61Wwmc&sensor=true"></script>
<script src="/crimeTrack/resources/js/markermanager.js"></script>
<script src="/crimeTrack/resources/js/v3_epoly.js"></script>
<script src="/crimeTrack/resources/js/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/jquery-1.9.0.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.0.0.js"></script>
<script type="text/javascript">
var map;
var directionDisplay;
var directionsService;
var stepDisplay;
var position;
var marker = [];
var polyline = [];
var poly = [];
var poly2 = [];
var startLocation = [];
var endLocation = [];
var timerHandle = [];
var speed = 0.000005, wait = 1;
var infowindow = null;
var myPano;
var panoClient;
var nextPanoId;
var global_citizens = new Array();
var Colors = ["#FF0000", "#00FF00", "#0000FF"];
//------------------------------------------------------------
function GetCitizensForTracking(){
$.ajax({
type: 'GET',
async : false,
global: 'false',
url: 'getListOfMarkers.htm',
headers : {Accept: 'application/json'},
dataType: 'json'
}).done(function(citizens) {
global_citizens = citizens;
$.each(citizens, function(i, c) {
//console.log(c.name + ' | ' + c.socialSecurityNumber + ' | ' + c.lat+ ' | ' +c.lng);
//citizen.push(c.name);
console.log(global_citizens[i].name+','+global_citizens[i].citizenType);
});
});
}
//---------------------------------------------------------------------
function initialize() {
infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
});
var myOptions = {
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
address = 'Trinidad and Tobago'
geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
map.fitBounds(results[0].geometry.viewport);
});
}
//------------------------------------------------------------------------------
function createMarker(latlng, label, html,citizenType) {
var contentString = '<b>'+label+'</b><br>'+html;
//console.log('Citizen icon is '+citizenType);
//replaces if...then..else...else if. Icon source are placed in an array that corresponds to value of the citizenType.
//array starts from 0 . The first value of the citizens type is 2 so array should have a value at the 2 location
//so jquery will map the icon to the citizenType based on its matching location in the array
var markerSource = [null,
null,
'resources/icons/criminal_new.ico',
'resources/icons/victim_new.ico',
'resources/icons/suspect_new.ico'];
var icon = markerSource[citizenType];
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: label,
icon: new google.maps.MarkerImage(icon),
zIndex: Math.round(latlng.lat()*-100000)<<5
});
marker.myname = label;
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
return marker;
}
//---------------------------------------------------------------------------------
function setRoutes(){
var directionsDisplay = new Array();
for (var i=0; i< global_citizens.length; i++){
var rendererOptions = {
map: map,
suppressMarkers : true,
preserveViewport: true
}
directionsService = new google.maps.DirectionsService();
var travelMode = google.maps.DirectionsTravelMode.DRIVING;
var request = {
origin: global_citizens[i].startLat+','+global_citizens[i].startLng,
destination: global_citizens[i].endLat+','+global_citizens[i].endLng,
travelMode: travelMode
};
directionsService.route(request,makeRouteCallback(i,directionsDisplay[i],global_citizens[i].citizenType));
console.log("Set Routes "+global_citizens[i].name +' - '+global_citizens[i].citizenType);
}
//------------------------------------------------------------------------------------
function makeRouteCallback(rNum, disp,ctype){
if (polyline[rNum] && (polyline[rNum].getMap() != null)) {
startAnimation(rNum);
return;
}
return function(response, status){
if (status == google.maps.DirectionsStatus.OK){
var bounds = new google.maps.LatLngBounds();
var route = response.routes[0];
startLocation[rNum] = new Object();
endLocation[rNum] = new Object();
polyline[rNum] = new google.maps.Polyline({
path: [],
strokeColor: '#FFFF00',
strokeWeight: 3
});
poly2[rNum] = new google.maps.Polyline({
path: [],
strokeColor: '#FFFF00',
strokeWeight: 3
});
// For each route, display summary information.
var path = response.routes[0].overview_path;
var legs = response.routes[0].legs;
disp = new google.maps.DirectionsRenderer(rendererOptions);
disp.setMap(map);
disp.setDirections(response);
//Markers
for (i=0;i<legs.length;i++) {
if (i == 0) {
startLocation[rNum].latlng = legs[i].start_location;
startLocation[rNum].address = legs[i].start_address;
// marker = google.maps.Marker({map:map,position: startLocation.latlng});
//console.log('(i) The Citizen Type Is : '+ global_citizens[i].citizenType);
marker[rNum] = createMarker(legs[i].start_location,"start",legs[i].start_address,ctype);
}
endLocation[rNum].latlng = legs[i].end_location;
endLocation[rNum].address = legs[i].end_address;
var steps = legs[i].steps;
for (j=0;j<steps.length;j++) {
var nextSegment = steps[j].path;
var nextSegment = steps[j].path;
for (k=0;k<nextSegment.length;k++) {
polyline[rNum].getPath().push(nextSegment[k]);
//bounds.extend(nextSegment[k]);
}
}
}
}
polyline[rNum].setMap(map);
//map.fitBounds(bounds);
startAnimation(rNum);
}
}
}
var lastVertex = 1;
var stepnum=0;
var step = 90; //0.9 metres
var tick = 100; // milliseconds
var eol = [];
//----------------------------------------------------------------------
function updatePoly(i,d) {
// Spawn a new poly line every 20 vertices, because updating a 100-vertex poly is too slow
if (poly2[i].getPath().getLength() > 20) {
poly2[i]=new google.maps.Polyline([polyline[i].getPath().getAt(lastVertex-1)]);
// map.addOverlay(poly2)
}
if (polyline[i].GetIndexAtDistance(d) < lastVertex+2) {
if (poly2[i].getPath().getLength()>1) {
poly2[i].getPath().removeAt(poly2[i].getPath().getLength()-1)
}
poly2[i].getPath().insertAt(poly2[i].getPath().getLength(),polyline[i].GetPointAtDistance(d));
} else {
poly2[i].getPath().insertAt(poly2[i].getPath().getLength(),endLocation[i].latlng);
}
}
//----------------------------------------------------------------------------
function animate(index,d) {
if (d>eol[index]) {
marker[index].setPosition(endLocation[index].latlng);
return;
}
var p = polyline[index].GetPointAtDistance(d);
//map.panTo(p);
marker[index].setPosition(p);
updatePoly(index,d);
timerHandle[index] = setTimeout("animate("+index+","+(d+step)+")", tick);
if(marker[0].getPosition() == endLocation[0].latlng){
console.log('Completed');
//alert("Marker One Complete");
}
}
//-------------------------------------------------------------------------
function startAnimation(index) {
if (timerHandle[index]) clearTimeout(timerHandle[index]);
eol[index]=polyline[index].Distance();
map.setCenter(polyline[index].getPath().getAt(0));
poly2[index] = new google.maps.Polyline({path: [polyline[index].getPath().getAt(0)], strokeColor:"#FFFF00", strokeWeight:3});
timerHandle[index] = setTimeout("animate("+index+",50)",2000); // Allow time for the initial map display
}
//----------------------------------------------------------------------------
$(document).ready(function(){
$('#getCitizens').on('click', function() {
if(global_citizens == undefined || global_citizens.length == 0 ){
GetCitizensForTracking();
setRoutes();
}else{alert("Tracking In Progress");}
});
});
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:90%">
<!-- MAP GOES IN HERE -->
</div>
<div id="toolbar">
<button class="btn" id="getCitizens" onclick="" type="button">Get Citizens</button>
<button class="btn" id="startTracking" onclick="" type="button">Start Tracking</button>
<button class="btn" id="pauseTracking" onclick="" type="button">Pause Tracking</button>
</div>
</body>
</html>