Google Markers array bug - selecting the wrong marker element - javascript

I have made a API meant to fetch Electrical Vehicles Charging Points on a map and create a route.
The route should automatically add charging points if the vehicle's capacity is not enough to finish the trip.
I fetch a Json and create an array of Marker objects. This works fine.
I then pass it through a loop that should splice all markers too far from the starting point to be reached and then another loop selecting the marker closest to destination.
For a reason I do not understand, though the array seems to have been trimed correctly, the result is a marker just next to destination and totally out of range from the starting point.
I am using the following libraries from Google: Directions, Geocoding, Maps Javascript...
I hope someone can help me because I am totally stuck here.
EDIT (further explanations:
The program is meant to add a charging stopover when the travel gets longer than the vehicle capacity (which is is 220 km.)
All the eligible stopovers are shown on the map and pushed in an array (as marker objects).
The function first splice all the stopovers further than 220 km. from the array, then in another loop I chose the stopover closest to destination.
But, if you look closer at the route you will see the charging stopover (point B) is actually 550 km. from departure and 2 km. from arrival.
This Marker should have been spliced and not be in the array anymore.
function selectMarkerClosestToDestination(vehicle) {
//Selecting the closest marker to destination as long as it is not out of the vehicle capacity range
//CURRENTLY BUGGED
let waypoints = chargingPointsMarkers;
for (let x = waypoints.length -1; x > 0; x--) {
if(calculateDistance(waypoints[x], start) > (vehicle.status*vehicle.consumption)){
console.log(calculateDistance(waypoints[x], start))
console.log(vehicle.status*vehicle.consumption)
waypoints.splice(x, 1)
console.log(waypoints)
}
}
console.log(waypoints)
for (let x = waypoints.length - 1; x > 0; x--) {
if (calculateDistance(waypoints[x], end) > (calculateDistance(waypoints[x-1], end))) {
waypoints.splice(x, 1);
} else {
waypoints.splice(x - 1, 1);
}
}
console.log(waypoints)
return waypoints[0];
}
function calculateDistance(p1, p2) {
//Uses the Google geometry library to calculate distance between two Markers
let a = p1.getPosition();
let b = p2.getPosition();
let distance = (google.maps.geometry.spherical.computeDistanceBetween(a, b) / 1000).toFixed(2);
return distance;
}
This is the full code (code snippet):
let map;
let mapCenter = { lat: 59.428, lng: 24.76};
let start;
let end;
let chargingPointsMarkers = [];
let markerArray = [];
let stopoverMarkers = []
let vehicle1 = {capacity: 33, status: 33, consumption: 6.6666} //1KW = 6.6666 Km; Capacity in KM = status*consumption;
function initMap(listener) {
//Create the map, the DirectionsService, the DirectionsRenderer and an eventListener for the GO button
//If I chose to implement a detailed steps display it would also be created here
const directionsService = new google.maps.DirectionsService();
const mapOptions = {
center: mapCenter,
zoom: 7,
}
map = new google.maps.Map(document.getElementById("map"), mapOptions);
const directionsRenderer = new google.maps.DirectionsRenderer({map: map});
//const stepDisplay = new google.maps.InfoWindow();
const geocoder = new google.maps.Geocoder();
document.getElementById("submit").addEventListener("click", () => {
launcher(geocoder, directionsRenderer, directionsService);
});
}
async function launcher(geocoder, directionsRenderer, directionsService){
//the method is used to be launched by the eventListener
//it sets up the start and end points, fetches the EV markers and launches the route calculation process though a callback function
resetMarkers();
const startEndPointsArray = await setupRoutingProcess(geocoder);
await callbackHandler(startEndPointsArray,directionsRenderer,
directionsService, calculateAndDisplayRoute);
}
function setMapOnAll(map){
// Sets the map on all markers in the array.
for (let i = 0; i < markerArray.length; i++) {
markerArray[i].setMap(map);
}
}
function clearMarkers() {
// Removes the markers from the map, but keeps them in the array.
setMapOnAll(null);
}
function resetMarkers(){
// Pushes all visible markers to a same array,
// launches the different reset processes and
// deletes all markers in the arrays by removing references to them.
for (let i = 0; i < chargingPointsMarkers.length; i++) {
markerArray.push(chargingPointsMarkers[i])
}
chargingPointsMarkers = [];
for (let j = 0; j < stopoverMarkers.length; j++) {
markerArray.push(stopoverMarkers[j])
}
stopoverMarkers = [];
clearMarkers();
markerArray = []
}
async function setupRoutingProcess(geocoder){
//launches the setGeocodeAddress method for both start and end points and stores them in an array
start = await setGeocodeAddress(geocoder, map, "start");
end = await setGeocodeAddress(geocoder, map, "end");
let startEndPointsArray = [start];
startEndPointsArray.push(end);
return startEndPointsArray;
}
async function setGeocodeAddress(geocoder, resultsMap, elementId) {
//Retrieve the addresses (strings) from the html text boxes and uses Geocoder to Google Markers objects.
//it pushes those markers in an array later used to delete the markers on the map
const address = document.getElementById(elementId).value;
return new Promise(resolve => geocoder.geocode({address: address},
(results, status) => {
if (status === "OK") {
resultsMap.setCenter(results[0].geometry.location);
const marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location,
title: elementId,
});
resolve(marker)
markerArray.push(marker);
} else {
alert("Trip Route finder was not successful for the following reason: " + status);
}
}));
}
async function callbackHandler (startEndPointsArray,
directionsRenderer,
directionsService,
calculateAndDisplayRoute){
//
let jsonChargingPoints = await setChargingStationsMarkers(startEndPointsArray, directionsRenderer,
directionsService, calculateAndDisplayRoute);
await createChargerPointMarkers(jsonChargingPoints)
calculateAndDisplayRoute(
directionsRenderer,
directionsService,
jsonChargingPoints
);
}
async function setChargingStationsMarkers(startEndPointsArray, directionsRenderer,
directionsService, calculateAndDisplayRoute) {
//Creates an encoded polyline to be passed as an Url argument to limit the results
//fetches the EV Charging Points as Json response
const polyline = await createPolyline(startEndPointsArray);
const baseUrl = 'https://api.openchargemap.io/v3/poi/?output=json&maxresults=200&includecomments=true';
const queryUrl = baseUrl + '&polyline=' + polyline + '&distance=50';
let data = await fetch(queryUrl)
.then((response) => response.json())
.then((data) => {return data})
return data;
}
async function createPolyline(startEndPointsArray){
//Creates a polyline and encodes it
try {
position = startEndPointsArray[0].getPosition();
position2 = startEndPointsArray[1].getPosition();
const initialPath = [position, position2];
const poly = new google.maps.Polyline({
path: initialPath,
strokeColor: '#ff0000',
strokeOpacity: 0.00001,
strokeWeight: 0,
});
const path = poly.getPath();
const encodedPath = await google.maps.geometry.encoding.encodePath(path);
return encodedPath;
}catch (error){
throw error ('Failed to create polyline');
}
}
function createChargerPointMarkers(jsonChargingPoints) {
//Loop through the Json response and launch the PlaceMarkers function
for (let x = 0; x < jsonChargingPoints.length; x++) {
const LatLng = new google.maps.LatLng(parseFloat(jsonChargingPoints[x].AddressInfo.Latitude), parseFloat(jsonChargingPoints[x].AddressInfo.Longitude));
placeMarker(LatLng);
}
}
function placeMarker(location) {
//Convert the Json response elements to Google Markers, places them on the Map and pushes them to an array.
let marker = new google.maps.Marker({
position: location,
map,
draggable: false,
});
chargingPointsMarkers.push(marker)
}
async function calculateAndDisplayRoute(
directionsRenderer,
directionsService,
jsonChargingPoints,
stepDisplay,
map) {
if (!compareVehicleCapacityToDistance(vehicle1, start)) {
setChargeCheckpoint(vehicle1)
}
directionsService.route(setRequest(),
function (result, status) {
if (status === "OK") {
directionsRenderer.setDirections(result);
// showSteps(result, markerArray, stepDisplay, map);
} else {
window.alert("Directions request failed due to " + status);
}
});
}
function setRequest(){
//prepares the request sent to the Directions service
let stopovers = [];
for (let x = 0; x < stopoverMarkers.length; x++){
let latLng = stopoverMarkers[x].getPosition();
let waypoint = {
location: latLng,
stopover: true
};
stopovers.push(waypoint)
}
const request = {
origin: start.getPosition(),
destination: end.getPosition(),
waypoints: stopovers,
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC
};
return request;
}
function compareVehicleCapacityToDistance(vehicle, p1){
//Checks if the distance to destination is greater than the vehicle capacity
if (calculateDistance(p1, end) > (vehicle.status*vehicle.consumption)){
return false
}return true;
}
function setChargeCheckpoint(vehicle){
//launches the function selecting the closest marker to destination
//Setting a marker of the selected marker on the map (might be redundant)
//Pushes it to markerArray for later deletion (might be redundant)
//Pushes it to stopoverMarkers to be used by the Directions service to setup a route
let waypoint = selectMarkerClosestToDestination(vehicle);
const waypointLocation = waypoint.getPosition();
const marker = new google.maps.Marker({
position: waypointLocation,
stopover: true,
draggable: false,
title: "EV charging stopover"
});
markerArray.push(marker)
stopoverMarkers.push(marker)
}
function selectMarkerClosestToDestination(vehicle) {
//Selecting the closest marker to destination as long as it is not out of the vehicle capacity range
//CURRENTLY BUGGED
let waypoints = chargingPointsMarkers;
for (let x = waypoints.length -1; x > 0; x--) {
if(calculateDistance(waypoints[x], start) > (vehicle.status*vehicle.consumption)){
console.log(calculateDistance(waypoints[x], start))
console.log(vehicle.status*vehicle.consumption)
waypoints.splice(x, 1)
console.log(waypoints)
}
}
console.log(waypoints)
for (let x = waypoints.length - 1; x > 0; x--) {
if (calculateDistance(waypoints[x], end) > (calculateDistance(waypoints[x-1], end))) {
waypoints.splice(x, 1);
} else {
waypoints.splice(x - 1, 1);
}
}
console.log(waypoints)
return waypoints[0];
}
function calculateDistance(p1, p2) {
//Uses the Google geometry library to calculate distance between two Markers
let a = p1.getPosition();
let b = p2.getPosition();
let distance = (google.maps.geometry.spherical.computeDistanceBetween(a, b) / 1000).toFixed(2);
return distance;
}
function showSteps(directionResult, stepDisplay, map) {
// For each step, place a marker, and add the text to the marker's infowindow.
// Also attach the marker to an array so we can keep track of it and remove it
// when calculating new routes.
//NOT CURRENTLY IMPLEMENTED/USED
const myRoute = directionResult.routes[0].legs[0];
for (let i = 0; i < myRoute.steps.length; i++) {
const 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", () => {
// Open an info window when the marker is clicked on, containing the text
// of the step.
//NOT CURRENTLY IMPLEMENTED/USED
stepDisplay.setContent(text);
stepDisplay.open(map, marker);
});
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#floating-panel {
position: absolute;
top: 10px;
left: 25%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
text-align: center;
font-family: "Roboto", "sans-serif";
line-height: 30px;
padding-left: 10px;
}
#warnings-panel {
width: 100%;
height: 10%;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<title>EV Trip Route Finder</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=&v=weekly"
defer
></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="floating-panel" >
<b>Start: </b>
<input id="start" type="text" value="Tallinn">
<b>End: </b>
<input id="end" type="text" value="Vilnius">
<input id="submit" type="button" value="GO" />
</div>
<div id="map"></div>
<div id="warnings-panel"></div>
</body>
</html>

There is only one small mistake in your code, that is in your for loop where you exclude waypoints that are over the vehicle capacity.
Basically, you are doing the following, which as you can see doesn't output what you'd expect:
const a = [1, 2, 3, 4, 5];
for (let i = a.length - 1; i > 0; i--) {
console.log(a[i])
}
Instead, you want to use i >= 0 to loop through all elements within your array:
const a = [1, 2, 3, 4, 5];
for (let i = a.length - 1; i >= 0; i--) {
console.log(a[i])
}
Changing this one statement seems to correct the issue because you were not iterating through the entire array and therefore you were leaving 1 element at 528km from start in the first loop, which would end up being the one you select in the second loop (in the selectMarkerClosestToDestination() function).
let map;
let mapCenter = { lat: 59.428, lng: 24.76};
let start;
let end;
let chargingPointsMarkers = [];
let markerArray = [];
let stopoverMarkers = []
let vehicle1 = {capacity: 33, status: 33, consumption: 6.6666} //1KW = 6.6666 Km; Capacity in KM = status*consumption;
function initMap(listener) {
//Create the map, the DirectionsService, the DirectionsRenderer and an eventListener for the GO button
//If I chose to implement a detailed steps display it would also be created here
const directionsService = new google.maps.DirectionsService();
const mapOptions = {
center: mapCenter,
zoom: 7,
}
map = new google.maps.Map(document.getElementById("map"), mapOptions);
const directionsRenderer = new google.maps.DirectionsRenderer({map: map});
//const stepDisplay = new google.maps.InfoWindow();
const geocoder = new google.maps.Geocoder();
document.getElementById("submit").addEventListener("click", () => {
launcher(geocoder, directionsRenderer, directionsService);
});
}
async function launcher(geocoder, directionsRenderer, directionsService){
//the method is used to be launched by the eventListener
//it sets up the start and end points, fetches the EV markers and launches the route calculation process though a callback function
resetMarkers();
const startEndPointsArray = await setupRoutingProcess(geocoder);
await callbackHandler(startEndPointsArray,directionsRenderer,
directionsService, calculateAndDisplayRoute);
}
function setMapOnAll(map){
// Sets the map on all markers in the array.
for (let i = 0; i < markerArray.length; i++) {
markerArray[i].setMap(map);
}
}
function clearMarkers() {
// Removes the markers from the map, but keeps them in the array.
setMapOnAll(null);
}
function resetMarkers(){
// Pushes all visible markers to a same array,
// launches the different reset processes and
// deletes all markers in the arrays by removing references to them.
for (let i = 0; i < chargingPointsMarkers.length; i++) {
markerArray.push(chargingPointsMarkers[i])
}
chargingPointsMarkers = [];
for (let j = 0; j < stopoverMarkers.length; j++) {
markerArray.push(stopoverMarkers[j])
}
stopoverMarkers = [];
clearMarkers();
markerArray = []
}
async function setupRoutingProcess(geocoder){
//launches the setGeocodeAddress method for both start and end points and stores them in an array
start = await setGeocodeAddress(geocoder, map, "start");
end = await setGeocodeAddress(geocoder, map, "end");
let startEndPointsArray = [start];
startEndPointsArray.push(end);
return startEndPointsArray;
}
async function setGeocodeAddress(geocoder, resultsMap, elementId) {
//Retrieve the addresses (strings) from the html text boxes and uses Geocoder to Google Markers objects.
//it pushes those markers in an array later used to delete the markers on the map
const address = document.getElementById(elementId).value;
return new Promise(resolve => geocoder.geocode({address: address},
(results, status) => {
if (status === "OK") {
resultsMap.setCenter(results[0].geometry.location);
const marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location,
title: elementId,
});
resolve(marker)
markerArray.push(marker);
} else {
alert("Trip Route finder was not successful for the following reason: " + status);
}
}));
}
async function callbackHandler (startEndPointsArray,
directionsRenderer,
directionsService,
calculateAndDisplayRoute){
//
let jsonChargingPoints = await setChargingStationsMarkers(startEndPointsArray, directionsRenderer,
directionsService, calculateAndDisplayRoute);
await createChargerPointMarkers(jsonChargingPoints)
calculateAndDisplayRoute(
directionsRenderer,
directionsService,
jsonChargingPoints
);
}
async function setChargingStationsMarkers(startEndPointsArray, directionsRenderer,
directionsService, calculateAndDisplayRoute) {
//Creates an encoded polyline to be passed as an Url argument to limit the results
//fetches the EV Charging Points as Json response
const polyline = await createPolyline(startEndPointsArray);
const baseUrl = 'https://api.openchargemap.io/v3/poi/?output=json&maxresults=200&includecomments=true';
const queryUrl = baseUrl + '&polyline=' + polyline + '&distance=50';
let data = await fetch(queryUrl)
.then((response) => response.json())
.then((data) => {return data})
return data;
}
async function createPolyline(startEndPointsArray){
//Creates a polyline and encodes it
try {
position = startEndPointsArray[0].getPosition();
position2 = startEndPointsArray[1].getPosition();
const initialPath = [position, position2];
const poly = new google.maps.Polyline({
path: initialPath,
strokeColor: '#ff0000',
strokeOpacity: 0.00001,
strokeWeight: 0,
});
const path = poly.getPath();
const encodedPath = await google.maps.geometry.encoding.encodePath(path);
return encodedPath;
}catch (error){
throw error ('Failed to create polyline');
}
}
function createChargerPointMarkers(jsonChargingPoints) {
//Loop through the Json response and launch the PlaceMarkers function
for (let x = 0; x < jsonChargingPoints.length; x++) {
const LatLng = new google.maps.LatLng(parseFloat(jsonChargingPoints[x].AddressInfo.Latitude), parseFloat(jsonChargingPoints[x].AddressInfo.Longitude));
placeMarker(LatLng);
}
}
function placeMarker(location) {
//Convert the Json response elements to Google Markers, places them on the Map and pushes them to an array.
let marker = new google.maps.Marker({
position: location,
map,
draggable: false,
});
chargingPointsMarkers.push(marker)
}
async function calculateAndDisplayRoute(
directionsRenderer,
directionsService,
jsonChargingPoints,
stepDisplay,
map) {
if (!compareVehicleCapacityToDistance(vehicle1, start)) {
setChargeCheckpoint(vehicle1)
}
directionsService.route(setRequest(),
function (result, status) {
if (status === "OK") {
directionsRenderer.setDirections(result);
// showSteps(result, markerArray, stepDisplay, map);
} else {
window.alert("Directions request failed due to " + status);
}
});
}
function setRequest(){
//prepares the request sent to the Directions service
let stopovers = [];
for (let x = 0; x < stopoverMarkers.length; x++){
let latLng = stopoverMarkers[x].getPosition();
let waypoint = {
location: latLng,
stopover: true
};
stopovers.push(waypoint)
}
const request = {
origin: start.getPosition(),
destination: end.getPosition(),
waypoints: stopovers,
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC
};
return request;
}
function compareVehicleCapacityToDistance(vehicle, p1){
//Checks if the distance to destination is greater than the vehicle capacity
if (calculateDistance(p1, end) > (vehicle.status*vehicle.consumption)){
return false
}return true;
}
function setChargeCheckpoint(vehicle){
//launches the function selecting the closest marker to destination
//Setting a marker of the selected marker on the map (might be redundant)
//Pushes it to markerArray for later deletion (might be redundant)
//Pushes it to stopoverMarkers to be used by the Directions service to setup a route
let waypoint = selectMarkerClosestToDestination(vehicle);
const waypointLocation = waypoint.getPosition();
const marker = new google.maps.Marker({
position: waypointLocation,
stopover: true,
draggable: false,
title: "EV charging stopover"
});
markerArray.push(marker)
stopoverMarkers.push(marker)
}
function selectMarkerClosestToDestination(vehicle) {
//Selecting the closest marker to destination as long as it is not out of the vehicle capacity range
//CURRENTLY BUGGED
let waypoints = chargingPointsMarkers;
for (let x = waypoints.length -1; x >= 0; x--) {
if(calculateDistance(waypoints[x], start) > (vehicle.status*vehicle.consumption)){
console.log(calculateDistance(waypoints[x], start))
console.log(vehicle.status*vehicle.consumption)
waypoints.splice(x, 1)
console.log(waypoints)
}
}
console.log(waypoints)
for (let x = waypoints.length - 1; x > 0; x--) {
if (calculateDistance(waypoints[x], end) > (calculateDistance(waypoints[x-1], end))) {
waypoints.splice(x, 1);
} else {
waypoints.splice(x - 1, 1);
}
}
console.log(waypoints)
return waypoints[0];
}
function calculateDistance(p1, p2) {
//Uses the Google geometry library to calculate distance between two Markers
let a = p1.getPosition();
let b = p2.getPosition();
let distance = (google.maps.geometry.spherical.computeDistanceBetween(a, b) / 1000).toFixed(2);
return distance;
}
function showSteps(directionResult, stepDisplay, map) {
// For each step, place a marker, and add the text to the marker's infowindow.
// Also attach the marker to an array so we can keep track of it and remove it
// when calculating new routes.
//NOT CURRENTLY IMPLEMENTED/USED
const myRoute = directionResult.routes[0].legs[0];
for (let i = 0; i < myRoute.steps.length; i++) {
const 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", () => {
// Open an info window when the marker is clicked on, containing the text
// of the step.
//NOT CURRENTLY IMPLEMENTED/USED
stepDisplay.setContent(text);
stepDisplay.open(map, marker);
});
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#floating-panel {
position: absolute;
top: 10px;
left: 25%;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
text-align: center;
font-family: "Roboto", "sans-serif";
line-height: 30px;
padding-left: 10px;
}
#warnings-panel {
width: 100%;
height: 10%;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<title>EV Trip Route Finder</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=&v=weekly"
defer
></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="floating-panel" >
<b>Start: </b>
<input id="start" type="text" value="Tallinn">
<b>End: </b>
<input id="end" type="text" value="Vilnius">
<input id="submit" type="button" value="GO" />
</div>
<div id="map"></div>
<div id="warnings-panel"></div>
</body>
</html>

Related

How to stop set Interval flickering using angular 2+

Here i am displaying the dynamic data i.e lat and long on the google maps and here i am applying the setInterval() below is my code:
this.timer = setInterval(()=>{this.getMapData();},30000);
here the issue is when ever the data is updating or calling the this.getMapData() then the map is also flickering.Is It possible to update the data for every 30 sec with out flickering the div/map
getMapData() {
this.spinner.show();
this.serv.getMapData(this.ds, this.ln).subscribe(res => {
this.spinner.hide();
this.deleteMarkers();
if (res.Data && res.Data.length > 0) {
this.mapData = res.Data;
console.log(JSON.stringify(this.mapData));
if (this.mapData != null && this.mapData.length > 0) {
for (var i = 0; i < this.mapData.length; i++) {
var latlng = {lat: parseFloat(this.mapData[i].latitude), lng: parseFloat(this.mapData[i].longitude)};
this.addMarker(latlng, this.mapObject, this.mapData[i].Name);
this.markerName = this.mapData[i].Name;
}
}
} else {
this.toastr.error('No Data Found', 'Oops!');
}
},err=>{
this.spinner.hide();
});
}
addMarker(latlng, mapobj, markerLabel) {
var marker = new google.maps.Marker({
position: latlng,
label: '',
map: mapobj,
animation: google.maps.Animation.DROP,
});
var infowindow = new google.maps.InfoWindow({
content: markerLabel
});
google.maps.event.addListener(marker, 'click', function() {
// infowindow.open(Map,marker);
});
infowindow.open(Map,marker);
// This is for set postion for the marker after getting dynamic data it posittions to the point
mapobj.setZoom(17);
mapobj.panTo(marker.position);
this.markers.push(marker);
}
// Sets the map on all markers in the array.
setMapOnAll(map) {
for (var i = 0; i < this.markers.length; i++) {
this.markers[i].setMap(map);
}
}
// Removes the markers from the map, but keeps them in the array.
clearMarkers() {
this.setMapOnAll(null);
}
// Deletes all markers in the array by removing references to them.
deleteMarkers() {
this.clearMarkers();
this.markers = [];
}
Based on our discussion :
inside the addMarker() ,
if(this.marker != null){
this.marker = new google.maps.Marker({
position: latlng,
label: '',
map: mapobj,
animation: google.maps.Animation.DROP,
});
}
else{
this.marker.setPosition(latlng);
}
So at first it will check if marker is null .If it is null then a new marker object is created . If not , then the marker's position is changed to the dynamic latlng.
So your , map flickering issue will be resolved as only the marker position is changing . Also remove the this.deleteMarkers() as you are changing position now , there is no need of deleting the marker from map.
Now , instead of using a setInterval , you can use rxjs operator interval to call the service and fetch data once in 30 seconds or whatever your time is .
To do this , inside your service do something like this :
return Observable.interval(30000).flatMap(()=>{
return this.http.get(url + data+'/LocationId='+ param).map(res => {
return res.json();
});
)};
EDIT
You'll need the following imports :
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/mergeMap`;

Google Map Direction Render Alternate Route How To Select Desired Path

I am working on google map directions I am following the google's navigation app.
I am able to get all the possible alternative routes by DirectionsService and can give the polylines different colors I want the user to be able to select his desired path just bu clicking on the poly lines some how have have not found any thing for this.
My code:
directionsService.route(request, function(response, status) {
var points = [];
if (status == google.maps.DirectionsStatus.OK) {
try {
var polycolour = "";
var Opacity = 0;
//var PolyLine = '';
for (var i = 0, len = response.routes.length; i < len; i++) {
if (i == 0) {
polycolour = "Blue";
Opacity = 5;
}
else {
polycolour = "grey";
Opacity = 2;
}
directionsDisplay = new google.maps.DirectionsRenderer({
map: map,
directions: response,
routeIndex: i,
draggable : true,
polylineOptions: {
strokeColor: polycolour,
strokeWeight: Opacity
}
});
var infowindow2 = new google.maps.InfoWindow();
//var step = 10;
//alert(angular.toJson(response.routes[0].legs[0].steps[i]));
infowindow2.setContent(""+((response.routes[i].legs[0].distance.value)/1000)+" KM");
infowindow2.setPosition(response.routes[i].legs[0].steps[8].end_location);
infowindow2.open(map);
}
//directionsDisplay.setMap(map);
google.maps.event.addListener(directionsDisplay, 'click', function(){
alert("helo");
});
//for (var k = 0, len = response.routes.length; k < len; k++) {
//var myRoute = response.routes[k].legs[0];
//for (var i = 0; i < myRoute.steps.length; i++) {
//for (var j = 0; j < myRoute.steps[i].lat_lngs.length; j++) {
// points.push(myRoute.steps[i].lat_lngs[j]);
//}
//}
//var routLine = new google.maps.Polyline(
//{
//path: points,
//strokeColor: "Red",
//strokeOpacity: 0.5,
// strokeWeight: 10
// }
// );
// }
// routLine.setMap(map)
// Add a listener for the rightclick event on the routLine
//google.maps.event.addListener(routLine, 'click', function(e){
//try {
//alert(angular.toJson(e));
//}
//catch (err)
//{
// alert(err);
//}
// });
//alert(angular.toJson(response.routes[0].legs[0].steps));
//google.maps.event.addListener(PolyLine, 'routeindex_changed', function() {
//alert("Bingo");
//computeTotalDistance(directionsDisplay.getRouteIndex());
//});
//alert(response.routes.length);
//directionsDisplay.setDirections(response);
}
catch (err)
{
alert(err);
}
}
});
First you need to tell the request that you want alternative routes, like this
// for example
var request = {
origin: start,
destination: end,
provideRouteAlternatives: true,
travelMode: google.maps.TravelMode[DRIVING]
};
Then you have multiple response.routes objects (notice, sometimes you only get 1 route).
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
for(var i in response.routes ) {
// ...
}
}
}
Now you can use response.routes[i] as the source for direction render.
Or you make your own polyline. Use response.routes[i].overview_path as the path
var line = new google.maps.Polyline({
path: response.routes[i].overview_path,
strokeColor: "#ff0000", // you might want different colors per suggestion
strokeOpacity: 0.7,
strokeWeight: 3
});
line.setMap(map);
Here is an functioning example.
Just change your API key.
As you asked for, clicking on a route highlights it
UPDATE: I like it this way.
Both grey lines and colored lines are generated. But highlighting only shows 1 of the suggestions on the map.
The big, grey line is nice to click on. So it gets the click event instead of the colored line.
This is also the easiest way to avoid the Z-index problem.
And I store data (duration, distance), that I show on an infoWindow
<!DOCTYPE html>
<html>
<head>
<title>Google Map Direction Render Alternate Route How To Select Desired Path</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 90%;
}
</style>
</head>
<body>
<form id="form">
<input id="from" placeholder="From" value="Brussel" />
<input id="to" placeholder="To" value="Antwerpen" />
<input type="submit" value="GO" />
</form>
<div id="map"></div>
<div id="info">
Stackoverflow
</div>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
<script>
var map;
var directionsService;
var polylines = [];
var shadows = [];
var data = [];
var infowindow;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 50.84659376378408, lng: 4.3531406857355215},
zoom: 12,
mapTypeId: 'terrain'
});
google.maps.event.addDomListener(document.getElementById('form'), 'submit', function(e) {
calcRoute(
document.getElementById('from').value,
document.getElementById('to').value
);
// prevent the form from really submitting
e.preventDefault();
return false;
});
directionsService = new google.maps.DirectionsService();
// get the bounds of the polyline
// http://stackoverflow.com/questions/3284808/getting-the-bounds-of-a-polyine-in-google-maps-api-v3
google.maps.Polyline.prototype.getBounds = function(startBounds) {
if(startBounds) {
var bounds = startBounds;
}
else {
var bounds = new google.maps.LatLngBounds();
}
this.getPath().forEach(function(item, index) {
bounds.extend(new google.maps.LatLng(item.lat(), item.lng()));
});
return bounds;
};
}
// this function calculates multiple suggested routes.
// We will draw 3 (broad stroke) suggested routs in grey. These are broad to click on them easier.
// We duplicate these routes with a thin, colored line; only route 0 is shown.
function calcRoute(start, end) {
var request = {
origin: start,
destination: end,
provideRouteAlternatives: true,
unitSystem: google.maps.UnitSystem.METRIC,
travelMode: google.maps.TravelMode['DRIVING']
};
directionsService.route(request, function(response, status) {
// clear former polylines
for(var j in polylines ) {
polylines[j].setMap(null);
shadows[j].setMap(null);
}
polylines = [];
shadows = [];
data = [];
if (status == google.maps.DirectionsStatus.OK) {
var bounds = new google.maps.LatLngBounds();
for(var i in response.routes) {
// let's make the first suggestion highlighted;
var hide = (i==0 ? false : true);
var shadow = drawPolylineShadow(response.routes[i].overview_path, '#666666');
var line = drawPolyline(response.routes[i].overview_path, '#0000ff', hide);
polylines.push(line);
shadows.push(shadow);
// let's add some data for the infoWindow
data.push({
distance: response.routes[i].legs[0].distance,
duration: response.routes[i].legs[0].duration,
end_address: response.routes[i].legs[0].end_address,
start_address: response.routes[i].legs[0].start_address,
end_location: response.routes[i].legs[0].end_location,
start_location: response.routes[i].legs[0].start_location
});
bounds = line.getBounds(bounds);
google.maps.event.addListener(shadow, 'click', function(e) {
// detect which route was clicked on
var index = shadows.indexOf(this);
highlightRoute(index, e);
});
}
map.fitBounds(bounds);
}
});
}
// this makes one of the colored routes visible.
function highlightRoute(index, e) {
for(var j in polylines ) {
if(j==index) {
//var color = '#0000ff';
polylines[j].setMap(map);
// feel free to customise this string
var contentString =
'<span>'+ data[j].distance.text +'</span><br/>'+
'<span>'+ data[j].duration.text +'</span><br/>'+
'<span>route: '+ j +'</span><br/>'+
//'From: <span>'+ data[j].start_address +'</span><br/>'+
//'To: <span>'+ data[j].end_address +'</span><br/>'+
'';
if(e) {
var position = new google.maps.LatLng(e.latLng.lat(), e.latLng.lng());
// it may be needed to close the previous infoWindow
if(infowindow) {
infowindow.close();
infowindow = null;
}
infowindow = new google.maps.InfoWindow({
content: contentString,
position: position,
map: map
});
//infowindow.open(map, polylines[j]);
}
}
else {
polylines[j].setMap(null);
}
}
}
// returns a polyline.
// if hide is set to true, the line is not put on the map
function drawPolyline(path, color, hide) {
var line = new google.maps.Polyline({
path: path,
strokeColor: color,
strokeOpacity: 0.9,
strokeWeight: 3
});
if(! hide) {
line.setMap(map);
}
return line;
}
function drawPolylineShadow(path, color, hide) {
var line = new google.maps.Polyline({
path: path,
strokeColor: color,
strokeOpacity: 0.4,
strokeWeight: 7
});
if(! hide) {
line.setMap(map);
}
return line;
}
google.maps.event.addDomListener(window, 'load', initMap);
</script>
</body>
</html>
earlier code. this changes the color of the polyLine
<!DOCTYPE html>
<html>
<head>
<title>Suggested routes</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 90%;
}
</style>
</head>
<body>
<form id="form">
<input id="from" placeholder="From" value="Brussel" />
<input id="to" placeholder="To" value="Antwerpen" />
<input type="submit" value="GO" />
</form>
<div id="map"></div>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
<script>
var map;
var directionsService;
var polylines = [];
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 50.84659376378408, lng: 4.3531406857355215},
zoom: 12,
mapTypeId: 'terrain'
});
google.maps.event.addDomListener(document.getElementById('form'), 'submit', function(e) {
calcRoute(
document.getElementById('from').value,
document.getElementById('to').value
);
// prevent the form from really submitting
e.preventDefault();
return false;
});
directionsService = new google.maps.DirectionsService();
// get the bounds of the polyline
// http://stackoverflow.com/questions/3284808/getting-the-bounds-of-a-polyine-in-google-maps-api-v3
google.maps.Polyline.prototype.getBounds = function(startBounds) {
if(startBounds) {
var bounds = startBounds;
}
else {
var bounds = new google.maps.LatLngBounds();
}
this.getPath().forEach(function(item, index) {
bounds.extend(new google.maps.LatLng(item.lat(), item.lng()));
});
return bounds;
};
}
function calcRoute(start, end) {
var request = {
origin: start,
destination: end,
provideRouteAlternatives: true,
unitSystem: google.maps.UnitSystem.METRIC,
travelMode: google.maps.TravelMode['DRIVING']
};
directionsService.route(request, function(response, status) {
// clear former polylines
for(var j in polylines ) {
polylines[j].setMap(null);
}
polylines = [];
if (status == google.maps.DirectionsStatus.OK) {
var bounds = new google.maps.LatLngBounds();
// draw the lines in reverse orde, so the first one is on top (z-index)
for(var i=response.routes.length - 1; i>=0; i-- ) {
// let's make the first suggestion highlighted;
if(i==0) {
var color = '#0000ff';
}
else {
var color = '#999999';
}
var line = drawPolyline(response.routes[i].overview_path, color);
polylines.push(line);
bounds = line.getBounds(bounds);
google.maps.event.addListener(line, 'click', function() {
// detect which route was clicked on
var index = polylines.indexOf(this);
highlightRoute(index);
});
}
map.fitBounds(bounds);
}
});
}
function highlightRoute(index) {
for(var j in polylines ) {
if(j==index) {
var color = '#0000ff';
}
else {
var color = '#999999';
}
polylines[j].setOptions({strokeColor: color});
}
}
function drawPolyline(path, color) {
var line = new google.maps.Polyline({
path: path,
strokeColor: color,
strokeOpacity: 0.7,
strokeWeight: 3
});
line.setMap(map);
return line;
}
google.maps.event.addDomListener(window, 'load', initMap);
</script>
</body>
</html>

returning object from a javascript function with database query inside

I am trying to return the markers as the object but when i run the function it just returns [ ], but printing it inside i can see the object data, can anyone explain how to return the object batch2 please?
google.maps.event.addListener(mgr, 'loaded', function(){
mgr.addMarkers(getMarkers(),6); //add all the markers! documentation for viewports with totals for city count, look at viewport
mgr.addMarkers(getMarkers2(),14); //get markers for zoomed out place, add click function to zoom in
//mgr.addMarkers(getMarkers(1000), 8);
console.log("added");
mgr.refresh();
});
function getMarkers2() {
var batch2 = [];
var clusters = new Parse.Query("cityfreqcoords");
var clusterresults = new Parse.Object("cityfreqcoords");
clusters.find({
success: function (results) {
for (i = 1; i < results.length; i++) {
var city = (results[i]["attributes"]["city"]);
var count = (results[i]["attributes"]["count"]);
var lat = (results[i]["attributes"]["lat"]);
var lng = (results[i]["attributes"]["lng"]);
var markerLatlong = new google.maps.LatLng(lat, lng);
//icon =
//adding the marker
var marker2 = new google.maps.Marker({
position: markerLatlong,
title: city,
clickable: true,
animation: google.maps.Animation.DROP
//icon:icon
});
//adding the click event and info window
google.maps.event.addListener(marker2, 'click', function () {
map.setZoom(6);
map.setCenter(marker2.getPosition());
});
batch2.push(marker2);
}
}
})
return batch2;
}
It would appear that clusters.find is asynchronous. You return batch2 before cluster.find succeeds. There are a handful of patterns for working with asynchronous code in JavaScript -- one common one is to use a callback. You would need to rewrite your code like so:
function getMarkers2(callback) {
var batch2 = [];
var clusters = new Parse.Query("cityfreqcoords");
var clusterresults = new Parse.Object("cityfreqcoords");
clusters.find({
success: function (results) {
for (i = 1; i < results.length; i++) {
var city = (results[i]["attributes"]["city"]);
var count = (results[i]["attributes"]["count"]);
var lat = (results[i]["attributes"]["lat"]);
var lng = (results[i]["attributes"]["lng"]);
var markerLatlong = new google.maps.LatLng(lat, lng);
//icon =
//adding the marker
var marker2 = new google.maps.Marker({
position: markerLatlong,
title: city,
clickable: true,
animation: google.maps.Animation.DROP
//icon:icon
});
//adding the click event and info window
google.maps.event.addListener(marker2, 'click', function () {
map.setZoom(6);
map.setCenter(marker2.getPosition());
});
batch2.push(marker2);
}
}
callback(batch2);
})
}
Then call it like so:
getMarkers2(function(markers) {
mgr.addMarkers(markers, 14);
});
If you're interested, take a look at how promises work as you might prefer that approach over using callbacks.
With callbacks in javascript, you generally don't return data. You pass in another function reference into the handler as a callback.
EG:
function getMarkers2(f) {
// do stuff
//when done
f(batch2)
}
Ended up just passing making the marker manager global and passing mgr into the query which worked, probably not the most efficient way to do it
function getMarkers2(mgr) {
Parse.initialize("X", "Y");
var batch2 = [];
var clusters = new Parse.Query("cityfrequency2");
var clusterresults = new Parse.Object("cityfrequency2");
clusters.find({
success: function (results) {
for (i = 0; i < (results.length); i++) {
var city = (results[i]["attributes"]["city"]);
var lat = (results[i]["attributes"]["lat"]);
var lng = (results[i]["attributes"]["lng"]);
var markerLatlong = new google.maps.LatLng(lat, lng);
var image = {
url: 'warning.png',
size: new google.maps.Size(50, 46),
// The origin
origin: new google.maps.Point(0, 0),
// The anchor
anchor: new google.maps.Point(25, 0)
};
//adding the marker
var marker2 = new google.maps.Marker({
position: markerLatlong,
title: city,
clickable: true,
animation: google.maps.Animation.DROP,
icon:image
});
//adding the click event and info window
google.maps.event.addListener(marker2, 'click', function () {
map.setZoom(6);
map.setCenter();
});
batch2.push(marker2);
mgr.addMarkers(batch2,0,6);
mgr.refresh();
}
}
})
}
function setupMarkers() {
var mgrOptions = { borderPadding: 50, maxZoom: 15, trackMarkers: true };
mgr = new MarkerManager(map,mgrOptions);
google.maps.event.addListener(mgr, 'loaded', function(){
getMarkers2(mgr);
getMarkers(mgr);
console.log("added");
});
}

Markers image are not displaying, only the last one because of css

I have a google map which was working well until a few weeks ago.
My problem is that now, all the label markers appears in the right place but only the last image appears.
I see in the generated html code that all images are here but all of them have the same position (that's why i can just see the last one).
I say again : it was working before, i'm sure! Maybe google has changed something (i'm calling the script : https://maps.googleapis.com/maps/api/js?sensor=false).
Here is my code :
jQuery(function() {
var stops = [];
var nbPoints = $('#nbPoints').val();
for (var i = 1; i <= nbPoints; i++) {
if($('#latitude'+i).val() && $('#longitude'+i).val())
stops.push({"Geometry":{"Latitude":$('#latitude'+i).val(),"Longitude":$('#longitude'+i).val()}});
}
var map = new window.google.maps.Map(document.getElementById("map_canvas"));
// new up complex objects before passing them around
var directionsDisplay = new window.google.maps.DirectionsRenderer({suppressMarkers: true});
var directionsService = new window.google.maps.DirectionsService();
Tour_startUp(stops);
window.tour.loadMap(map, directionsDisplay);
window.tour.fitBounds(map);
if (stops.length > 1)
window.tour.calcRoute(directionsService, directionsDisplay);
else $("#message").html("Erreur : Aucune coordonnée renseignée!");
});
function Tour_startUp(stops) {
if (!window.tour) window.tour = {
updateStops: function (newStops) {
stops = newStops;
},
// map: google map object
// directionsDisplay: google directionsDisplay object (comes in empty)
loadMap: function (map, directionsDisplay) {
var myOptions = {
zoom: 13,
center: new window.google.maps.LatLng($('#latitudeInit').val(),$('#longitudeInit').val()),
mapTypeId: window.google.maps.MapTypeId.ROADMAP
};
map.setOptions(myOptions);
directionsDisplay.setMap(map);
},
fitBounds: function (map) {
var bounds = new window.google.maps.LatLngBounds();
// extend bounds for each record
jQuery.each(stops, function (key, val) {
var myLatlng = new window.google.maps.LatLng(val.Geometry.Latitude, val.Geometry.Longitude);
bounds.extend(myLatlng);
});
map.fitBounds(bounds);
},
calcRoute: function (directionsService, directionsDisplay) {
var batches = [];
var itemsPerBatch = 10; // google API max = 10 - 1 start, 1 stop, and 8 waypoints
var itemsCounter = 0;
var wayptsExist = stops.length > 0;
while (wayptsExist) {
var subBatch = [];
var subitemsCounter = 0;
for (var j = itemsCounter; j < stops.length; j++) {
subitemsCounter++;
subBatch.push({
location: new window.google.maps.LatLng(stops[j].Geometry.Latitude, stops[j].Geometry.Longitude),
stopover: true
});
if (subitemsCounter == itemsPerBatch)
break;
}
itemsCounter += subitemsCounter;
batches.push(subBatch);
wayptsExist = itemsCounter < stops.length;
// If it runs again there are still points. Minus 1 before continuing to
// start up with end of previous tour leg
itemsCounter--;
}
// now we should have a 2 dimensional array with a list of a list of waypoints
var combinedResults;
var unsortedResults = [{}]; // to hold the counter and the results themselves as they come back, to later sort
//var directionsResultsReturned = 0;
var directionsResultsReturned = new Array();
directionsResultsReturned[0]=0;
for (var k = 0; k < batches.length; k++) {
var lastIndex = batches[k].length - 1;
var start = batches[k][0].location;
var end = batches[k][lastIndex].location;
// trim first and last entry from array
var waypts = [];
waypts = batches[k];
waypts.splice(0, 1);
waypts.splice(waypts.length - 1, 1);
var request = {
origin: start,
destination: end,
waypoints: waypts,
travelMode: window.google.maps.TravelMode.DRIVING
};
creerRoute(k,request,batches,directionsService,unsortedResults,combinedResults,directionsResultsReturned,directionsDisplay);
}
}
};
}
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
});
var icons = new Array();
icons["red"] = new google.maps.MarkerImage("mapIcons/marker_red.png",
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(20, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 9,34.
new google.maps.Point(9, 34));
function getMarkerImage(numero, type, anomalie) {
var url_img = "../img/";
var type = new String(type);
if(anomalie) url_img+="anomalie.png";
else{
switch(type.toUpperCase()){
case "LAVAGE" : url_img+="shower.png"; break;
case "EAU" : url_img+="waterdrop.png"; break;
default : url_img+="stop.png"; break;
}
}
icons[numero] = new google.maps.MarkerImage(url_img,
new google.maps.Size(34, 34),
new google.maps.Point(0,0),
new google.maps.Point(9, 34));
return icons[numero];
}
// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.
// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var iconImage = new google.maps.MarkerImage('mapIcons/marker_red.png',
// This marker is 20 pixels wide by 34 pixels tall.
new google.maps.Size(34, 34),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is at 9,34.
new google.maps.Point(9, 34));
var iconShadow = new google.maps.MarkerImage('http://www.google.com/mapfiles/shadow50.png',
// The shadow image is larger in the horizontal dimension
// while the position and offset are the same as for the main image.
new google.maps.Size(37, 34),
new google.maps.Point(0,0),
new google.maps.Point(9, 34));
// Shapes define the clickable region of the icon.
// The type defines an HTML <area> element 'poly' which
// traces out a polygon as a series of X,Y points. The final
// coordinate closes the poly by connecting to the first
// coordinate.
var iconShape = {
coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0],
type: 'poly'
};
function createMarker(map, latlng, label, html, numero, type, anomalie) {
var contentString = '<b>'+label+'</b><br>'+html;
var marker = new MarkerWithLabel({
position: latlng,
map: map,
draggable: false,
raiseOnDrag: true,
icon : getMarkerImage(numero,type,anomalie),
labelContent: numero,
labelAnchor: new google.maps.Point(0, 0),
labelClass: "labels",
labelInBackground: false
});
marker.myname = label;
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
return marker;
}
function creerRoute(kk,request,batches,directionsService,unsortedResults,combinedResults,directionsResultsReturned,directionsDisplay) {
directionsService.route(request, function (result, status) {
if (status == window.google.maps.DirectionsStatus.OK) {
var unsortedResult = { order: kk, result: result };
unsortedResults.push(unsortedResult);
directionsResultsReturned[0]++;
if (directionsResultsReturned[0] == batches.length) // we've received all the results. put to map
{
// sort the returned values into their correct order
unsortedResults.sort(function (a, b) { return parseFloat(a.order) - parseFloat(b.order); });
var count = 0;
for (var key in unsortedResults) {
if (unsortedResults[key].result != null) {
if (unsortedResults.hasOwnProperty(key)) {
if (count == 0) // first results. new up the combinedResults object
combinedResults = unsortedResults[key].result;
else {
// only building up legs, overview_path, and bounds in my consolidated object. This is not a complete
// directionResults object, but enough to draw a path on the map, which is all I need
combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs);
combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path);
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast());
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest());
}
count++;
}
}
}
directionsDisplay.setDirections(combinedResults);
var legs = combinedResults.routes[0].legs;
for (var i=0; i < legs.length;i++){
var j = i + 1;
var markerletter = $('#ordre'+j).val();
var anomalie=false;
var html = $('#infospoint'+j).val();
if($('#infoschocspoint'+j).length){
anomalie = true;
html+="<br/>"+$('#infoschocspoint'+j).val();
}
createMarker(directionsDisplay.getMap(),legs[i].start_location,$('#titrepoint'+j).val(),html,markerletter,$('#type'+j).val(),anomalie);
}
var i=legs.length + 1;
var markerletter = $('#ordre'+i).val();
var anomalie=false;
var html = $('#infospoint'+i).val();
if($('#infoschocspoint'+i).length){
anomalie = true;
html+="<br/>"+$('#infoschocspoint'+i).val();
}
createMarker(directionsDisplay.getMap(),legs[legs.length-1].end_location,$('#titrepoint'+i).val(),html,markerletter,$('#type'+i).val(),anomalie);
}
}else {
if (status == window.google.maps.DirectionsStatus.OVER_QUERY_LIMIT) {
setTimeout( function(){
creerRoute(kk,request,batches,directionsService,unsortedResults,combinedResults,directionsResultsReturned,directionsDisplay);
}, 200);
}else{
$("#message").html("Erreur : Code "+status);
}
}
});
}
Has anyone the same problem?
Thanks for your help!
You can use new one
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&v=3.3"></script>

IE Issue of Google Maps Marker Animation

I am using google maps api v3.
The Below code i am trying to run , It is working on all Browsers except IE.
Can u please suggest any changes needed to work in IE.
Fiddle Link
My Code is :
var map;
var mapOptions = { center: new google.maps.LatLng(0.0, 0.0), zoom: 2,
mapTypeId: google.maps.MapTypeId.ROADMAP };
var markers = [];
function initialize() {
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
from1 = new google.maps.LatLng(0,0);
to1 = new google.maps.LatLng(30,12);
from2 = new google.maps.LatLng(-30,15);
to2 = new google.maps.LatLng(10,-100);
from3 = new google.maps.LatLng(0,-50);
to3 = new google.maps.LatLng(0,50);
addMarker(from1,to1);
addMarker(from2,to2);
addMarker(from3,to3);
}
function addMarker(pos, dest) {
var marker = new google.maps.Marker({
map: map,
position: pos,
destination: dest
});
google.maps.event.addListener(marker, 'click', function(event) {
fromLat = this.position.lat();
fromLng = this.position.lng();
toLat = this.destination.lat();
toLng = this.destination.lng();
// store a LatLng for each step of the animation
frames = [];
for (var percent = 0; percent < 1; percent += 0.01) {
curLat = fromLat + percent * (toLat - fromLat);
curLng = fromLng + percent * (toLng - fromLng);
frames.push(new google.maps.LatLng(curLat, curLng));
}
move = function(marker, latlngs, index, wait, newDestination) {
marker.setPosition(latlngs[index]);
if(index != latlngs.length-1) {
// call the next "frame" of the animation
setTimeout(function() {
move(marker, latlngs, index+1, wait, newDestination);
}, wait);
}
else {
// assign new route
marker.position = marker.destination;
marker.destination = newDestination;
}
}
// begin animation, send back to origin after completion
move(marker, frames, 0, 20, marker.position);
});
markers.push(marker);
}
google.maps.event.addDomListener(window, 'load', initialize);
After some fiddling it looks like a typing issue. Because you haven't implicitly declared the variable frames as a var ie is unsure that it is an array, thus the error "Object does not support method push".
You simply need to change:
frames = [];
to:
var frames = [];
Tested in ie 8- 10.

Categories

Resources