Проблема в:
function clickPanel(polyline, directionsDisplay, index) {
google.maps.event.addListener(directionsDisplay, 'routeindex_changed', function() {
for (var i = 0; i < polyline.length; i++) {
polyline[i].setOptions({
strokeOpacity: 1.0,
strokeColor: "#16a085",
zIndex: 0
});
}
polyline[this.getRouteIndex()].setOptions({//<= this line (as you indicated in your question)
strokeOpacity: 1.0,
strokeColor: "#c0392b",
zIndex: 1
});
});
}
Индекс маршрута в этом случае больше, чем размер массива ломаной линии, если я защищу от этого, ошибка исчезнет:
function clickPanel(polyline, directionsDisplay, index) {
google.maps.event.addListener(directionsDisplay, 'routeindex_changed', function() {
for (var i = 0; i < polyline.length; i++) {
polyline[i].setOptions({
strokeOpacity: 1.0,
strokeColor: "#16a085",
zIndex: 0
});
}
// protect against out of range error
if (this.getRouteIndex() < polyline.length) {
polyline[this.getRouteIndex()].setOptions({
strokeOpacity: 1.0,
strokeColor: "#c0392b",
zIndex: 1
});
}
});
}
Возможно, вы захотите установить для него последнюю запись в массиве ломаных, но просто игнорировать ее в этом случае, похоже, все в порядке.
подтверждение концепции скрипта
фрагмент кода:
function initMap() {
var polyOptions = [];
var markerArray = [];
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var stepDisplay = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 7,
center: {
lat: 0.50404,
lng: 102.4579712
}
});
var onChangeHandler = function() {
removeLine(polyOptions, directionsDisplay);
polyOptions = [];
calculateAndDisplayRoute(directionsDisplay, directionsService, markerArray, stepDisplay, map, polyOptions);
};
document.getElementById('start').addEventListener('change', onChangeHandler);
document.getElementById('finish').addEventListener('change', onChangeHandler);
}
function calculateAndDisplayRoute(directionsDisplay, directionsService, markerArray, stepDisplay, map, polyOptions) {
for (var i = 0; i < markerArray.length; i++) {
markerArray[i].setMap(null);
}
directionsService.route({
origin: document.getElementById('start').value,
destination: document.getElementById('finish').value,
travelMode: 'DRIVING',
optimizeWaypoints: false,
provideRouteAlternatives: true,
}, function(response, status) {
if (status === 'OK') {
var pathPoints;
var routeLeg;
for (var i = 0, len = response.routes.length; i < len; i++) {
routeLeg = response.routes[i].legs[0];
pathPoints = response.routes[i].overview_path;
var polyPath = new google.maps.Polyline({
path: pathPoints,
strokeColor: "#16a085",
strokeOpacity: 1.0,
strokeWeight: 5,
map: map,
clickable: true,
});
polyOptions.push(polyPath);
if (i == 0) polyOptions[0].setOptions({
strokeColor: '#c0392b',
strokeOpacity: 1.0,
zIndex: 1
});
polyOptions[polyOptions.length - 1].setPath(pathPoints);
directionsDisplay.setRouteIndex(i);
directionsDisplay.setDirections(response);
directionsDisplay.setOptions({
polylineOptions: polyOptions,
suppressPolylines: true,
});
directionsDisplay.setPanel(document.getElementById('panel'));
directionsDisplay.setMap(map);
clickLine(polyOptions, directionsDisplay, i);
}
clickPanel(polyOptions, directionsDisplay);
$("#error").empty();
$("#error").removeClass();
} else {
directionsDisplay.setMap(null);
directionsDisplay.setPanel(null);
$("#error").addClass("badge badge-danger");
$("#error").text("Tidak dapat menemukan nama lokasi, status error: " + status);
}
});
}
function showSteps(directionResult, markerArray, stepDisplay, map) {
var myRoute = directionResult.routes[0].legs[0];
for (var i = 0; i < myRoute.steps.length; i++) {
var marker = markerArray[i] = markerArray[i] || new google.maps.Marker;
marker.setMap(map);
marker.setPosition(myRoute.steps[i].start_location);
attachInstructionText(
stepDisplay, marker, myRoute.steps[i].instructions, map);
}
}
function attachInstructionText(stepDisplay, marker, text, map) {
google.maps.event.addListener(marker, 'click', function() {
stepDisplay.setContent(text);
stepDisplay.open(map, marker);
});
}
function removeLine(options, directionsDisplay) {
for (var i = 0; i < options.length; i++) {
options[i].setMap(null);
options[i].setVisible(false);
directionsDisplay.setMap(null);
}
}
function clickPanel(polyline, directionsDisplay, index) {
google.maps.event.addListener(directionsDisplay, 'routeindex_changed', function() {
for (var i = 0; i < polyline.length; i++) {
polyline[i].setOptions({
strokeOpacity: 1.0,
strokeColor: "#16a085",
zIndex: 0
});
}
if (this.getRouteIndex() < polyline.length) {
polyline[this.getRouteIndex()].setOptions({
strokeOpacity: 1.0,
strokeColor: "#c0392b",
zIndex: 1
});
}
});
}
function clickLine(polyline, directionsDisplay, index) {
google.maps.event.addListener(polyline[polyline.length - 1], 'click', function(evt) {
for (var i = 0; i < polyline.length; i++) {
polyline[i].setOptions({
strokeOpacity: 1.0,
strokeColor: "#16a085",
zIndex: 0
});
}
this.setOptions({
strokeOpacity: 1.0,
strokeColor: "#c0392b",
zIndex: 1
});
directionsDisplay.setRouteIndex(index);
});
}
google.maps.event.addDomListener(window, "load", initMap);
html,
body {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
#map {
height: 90%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<input id="start" value="Dumai" />
<input id="finish" value="Pekanbaru" />
<div id="error"></div>
<div id="map"></div>
<div id="panel"></div>