I successfully display my direction on the google map with markers but I'm having trouble to change the alphabet inside of markers to numbers.
My method looks like,
directionDisplay(direction) {
this.DirectionsRenderer = new google.maps.DirectionsRenderer({ preserveViewport: true });
this.DirectionsRenderer.setMap(this.props.map);
return this.DirectionsRenderer.setDirections(direction);
}
and using it
DirectionsService.route({
origin,
destination,
waypoints,
optimizeWaypoints: true,
travelMode: this.props.maps.DirectionsTravelMode.DRIVING
}, (result, status) => {
if (status == this.props.maps.DirectionsStatus.OK) {
this.directionDisplay(result);
} else {
console.error(`error fetching directions ${result}`);
}
});
I tried something like this.DirectionsRenderer = new google.maps.DirectionsRenderer({ preserveViewport: true, markerOptions: {label: '1'} }); but '1' just overlays on the alphabets instead of replacing them.
Does anyone know how to figure this out?
Thank you,
Related
I need to display a map on the screen, where there is an itinerary of the places I need to go.
I need it to be displayed in sequence, and for the map to show me the full route of the places I need to go in sequence.
I know that markers can be created, but I would like to create points on the map in sequence starting from a starting location and an ending location, there may be multiple locations but I want the map to trace the full route between the locations in the visit sequence.
I didn't find anything that would allow me to do this in the Google Maps API documentation, is it possible to do this?
In this example, i've done 2 waypoints that the map need to go, and then render the map with those, solving TSP problem (Travelling salesman problem)
loadMap(){
// create a new map by passing HTMLElement
let mapEle: HTMLElement = document.getElementById('map_canvas');
let directionsService = new google.maps.DirectionsService();
let directionsDisplay = new google.maps.DirectionsRenderer();
// create map
this.map = new google.maps.Map(mapEle, {
center: this.start,
zoom: 13
});
directionsDisplay.setMap(this.map);
var request = {
origin:{lat: -34.6496604, lng: -58.4047352},
destination:{lat: -34.650078, lng: -58.402425},
waypoints: //your array of waypoints, example [{
location:{lat: -34.597353,lng: -58.415832},
stopover: true
},
{
location:{lat: -34.608441,lng: -58.406194},
stopover: true
}],
optimizeWaypoints:true,
provideRouteAlternatives: false,
travelMode: 'DRIVING'
};
directionsService.route(request, function(response, status) {
if (status == 'OK') {
directionsDisplay.setDirections(response);
}
});
}
Solved with Javascript API from google maps, for further information check : https://developers.google.com/maps/documentation/javascript/directions
I am trying to build a live tracking with the route using Google Map JS version in ionic 4.
What I am trying to achieve is to give the route to the user from source to destination and update the route if the user chooses a new path other than the google provided one. The source is the user and destination is some point in the map.
I am able to draw route and update it if the user change the provided path using
startNavigation(){
this.geolocation.getCurrentPosition({ enableHighAccuracy: true })
.then((position) => {
this.userPosition = position;
this.userVehicleMarker = new google.maps.Marker({
map: this.map,
position: { lat: position.coords.latitude, lng: position.coords.longitude },
icon: this.vehicleIcon
});
this.addInfoWindow(this.userVehicleMarker, 'me')
this.watchVehicle = this.geolocation.watchPosition({ enableHighAccuracy: true })
.subscribe(async (pos) =>
{
// Calling the redraw function on every 25 meters distance travelled
this.drawRouteFromVehicleToDestination(pos.coords.latitude, pos.coords.longitude)
}
}, (err: PositionError) => {
// alert(err.message)
console.log("error : " + err.message);
});
})
)
drawRouteFromVehicleToDestination(lat, lng) {
let _self = this;
let directionsService = new google.maps.DirectionsService;
let directionsRenderer = new google.maps.DirectionsRenderer({
polylineOptions: {
strokeColor: "#428BE8",
strokeWeight: 2
},
suppressMarkers: true,
preserveViewport: true
});
directionsRenderer.addListener('directions_changed', function () {
let _data = directionsRenderer.getDirections();
let _newData = _data['routes'][0]['legs'][0]
console.log(_newData)
});
directionsService.route({
origin: { lat: lat, lng: lng},
destination: { lat: 27.673586, lng: 85.435131},
travelMode: 'DRIVING',
optimizeWaypoints: true,
provideRouteAlternatives: false,
avoidTolls: true,
}, (res, status) => {
if (status == 'OK') {
directionsRenderer.setDirections(res);
directionsRenderer.setMap(this.map);
} else {
console.warn(status);
}
});
}
But the issue is, it is sending a lot of requests to google API and which does not look like a practical approach to follow.
Is there any other approach I should follow using which I could track the route and update it as per user location change and also minimize the google ping?
Thank you in advance for your help.
I think the issue is that you call drawRouteFromVehicleToDestination() very frequently (every time the vehicle position changes, from this.geolocation.watchPosition). One way to reduce the number of calls would be to "debounce" this calls, limiting them to every X ms at most, since probably it's acceptable to update every 200/300 ms. For example, you could use the lodash _.debounce function. For an in-depth explanation, see also the article Debouncing and Throttling Explained Through Examples.
this.watchVehicle = this.geolocation.watchPosition({ enableHighAccuracy: true })
.subscribe(async (pos) => {
_.debounce(() => {
this.drawRouteFromVehicleToDestination(pos.coords.latitude, pos.coords.longitude);
}, 300, { leading: true });
}, (err: PositionError) => {
// alert(err.message)
console.log("error : " + err.message);
});
I am currently trying to find a way how to get a straight route with Google Maps Api V3.
I already managed it to use geocode and the directions service to get a route from point A to point B, including two alternative routes. I also experimented with "No highways" and "No tolls" but nothing appears to solve this problem entirely...
At the moment I check the three given routes for lowest miles but this has to be proven not really to be the shortest route.
I am not searching the fastest or quickest route but just a straight route with as low miles as possible.
As I did not find any thread by using google explaining something like I need I ask you. Maybe somebody has a solution here...
P.S.: I also can't use the "Pedestrian Mode" as this is used as a navigation help for our local fire trucks when our mounted navigation systems do not work again.
This is also the reason why we need as low kilometers as possible - when driving a firetruck round here the fastest route is 99% the one with lowest miles but the Api won't let me decide that and insist on using principal roads
To obtain the shortest route from A to B I would suggest to make different queries with the “alternatives=true” parameter, playing with the “avoid” parameter between avoid=toll, avoid=highways, and then I would compare all results to pick the shortest route.
directionsService = new google.maps.DirectionsService;
//avoiding tolls
directionsService.route({
origin: {
'placeId': originId
},
destination: {
'placeId': destinationId
},
provideRouteAlternatives: true,
avoidTolls: true,
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
routesResponses.push(response);
}
else {
window.alert('Directions request failed due to ' + status);
}
});
//avoiding highways
directionsService.route({
origin: {
'placeId': originId
},
destination: {
'placeId': destinationId
},
provideRouteAlternatives: true,
avoidHighways: true,
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
routesResponses.push(response);
}
else {
window.alert('Directions request failed due to ' + status);
}
//Results analysis and drawing of routes
var fastest = Number.MAX_VALUE,
shortest = Number.MAX_VALUE;
routesResponses.forEach(function(res) {
res.routes.forEach(function(rou, index) {
console.log("distance of route " +index+": " , rou.legs[0].distance.value);
console.log("duration of route " +index+": " , rou.legs[0].duration.value);
if (rou.legs[0].distance.value < shortest) shortest = rou.legs[0].distance.value ;
if (rou.legs[0].duration.value < fastest) fastest = rou.legs[0].duration.value ;
})
})
console.log("shortest: ", shortest);
console.log("fastest: ", fastest);
//painting the routes in green blue and red
routesResponses.forEach(function(res) {
res.routes.forEach(function(rou, index) {
new google.maps.DirectionsRenderer({
map:map,
directions:res,
routeIndex:index,
polylineOptions:{
strokeColor: rou.legs[0].duration.value == fastest? "red":rou.legs[0].distance.value == shortest?"darkgreen":"blue",
strokeOpacity: rou.legs[0].duration.value == fastest? 0.8:rou.legs[0].distance.value == shortest? 0.9: 0.5,
strokeWeight: rou.legs[0].duration.value == fastest? 9:rou.legs[0].distance.value == shortest? 8: 3,
}
})
})
})
});
}
}
I use a solution, as I said here, that calls route service once and filters the results in a way that you find usefull. In my example, I'm calculating the shortest route.
``In my requirement,I have a set of way points passed as json object to map. From those waypoints , the start and end have to shown in alphabets and the in-between markers should be in numbers. How can I implement this scenario?
Also I found that google maps support a max of 8 wayspoints and one start and end .Is there any way to add more waypoints to my map? I am using google maps DirectionsService for waypoint renderng.
The code I used is
function calcRoute() {
var start = wayPointArray[0];
var end = wayPointArray[1];
var waypts = [];
for (var i = 2; i <= wayPointArray.length-1; i++) {
waypts.push({
location: wayPointArray[i],
stopover: true
});
}
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var mapOptions = {
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
directionsDisplay.setMap(map);
}
wayPontArray contains all lats and long for the waypoints. The first and second will be the start and end respectively and all others are the waypoints. The start and end should be in alphabets ie A and B. The in between waypoints should be in numbers.
Thanks in advance
Boney.
If you know the coordinates of your waypoints, you can use custom markers with numbers or lettersas labels as in this example:
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
icon: 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=A|FF0000|000000'
});
I am making a taxi fare calculator. One of the business requirements is that, the company wants the shortest and fastest route options. I know Google directionService by default searched for the fastest route. I set the "avoidhighways" option in request parameter to true in order to get the shortest route, but I am not quite happy with the result.
Anyone have a better solution than that??
To obtain the shortest route from A to B I would suggest to make different queries with the “alternatives=true” parameter, playing with the “avoid” parameter between avoid=toll, avoid=highways, and then I would compare all results to pick the shortest route.
directionsService = new google.maps.DirectionsService;
//avoiding tolls
directionsService.route({
origin: {
'placeId': originId
},
destination: {
'placeId': destinationId
},
provideRouteAlternatives: true,
avoidTolls: true,
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
routesResponses.push(response);
}
else {
window.alert('Directions request failed due to ' + status);
}
});
//avoiding highways
directionsService.route({
origin: {
'placeId': originId
},
destination: {
'placeId': destinationId
},
provideRouteAlternatives: true,
avoidHighways: true,
travelMode: google.maps.TravelMode.DRIVING
}, function(response, status) {
if (status === google.maps.DirectionsStatus.OK) {
routesResponses.push(response);
}
else {
window.alert('Directions request failed due to ' + status);
}
//Results analysis and drawing of routes
var fastest = Number.MAX_VALUE,
shortest = Number.MAX_VALUE;
routesResponses.forEach(function(res) {
res.routes.forEach(function(rou, index) {
console.log("distance of route " +index+": " , rou.legs[0].distance.value);
console.log("duration of route " +index+": " , rou.legs[0].duration.value);
if (rou.legs[0].distance.value < shortest) shortest = rou.legs[0].distance.value ;
if (rou.legs[0].duration.value < fastest) fastest = rou.legs[0].duration.value ;
})
})
console.log("shortest: ", shortest);
console.log("fastest: ", fastest);
//painting the routes in green blue and red
routesResponses.forEach(function(res) {
res.routes.forEach(function(rou, index) {
new google.maps.DirectionsRenderer({
map:map,
directions:res,
routeIndex:index,
polylineOptions:{
strokeColor: rou.legs[0].duration.value == fastest? "red":rou.legs[0].distance.value == shortest?"darkgreen":"blue",
strokeOpacity: rou.legs[0].duration.value == fastest? 0.8:rou.legs[0].distance.value == shortest? 0.9: 0.5,
strokeWeight: rou.legs[0].duration.value == fastest? 9:rou.legs[0].distance.value == shortest? 8: 3,
}
})
})
})
});
}
}
You get three options with the alternatives=true option set. You can then search through those for both the shortest and fastest of the routes returned.
See http://codepen.io/jasonmayes/pen/DupCH.
var shortestDistance = function() {
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var size = 0;
var currentPosition;
// An array of interesting places we want to potentially visit.
var interestingPlaces = [
{'title': 'Regents Park', 'latLng': new google.maps.LatLng(51.530686, -0.154753)},
{'title': 'Hyde Park', 'latLng': new google.maps.LatLng(51.507293, -0.164022)},
{'title': 'Green Park', 'latLng': new google.maps.LatLng(51.504088, -0.141706)},
{'title': 'Regents Park', 'latLng': new google.maps.LatLng(51.479185, -0.159903)}
];
// An array to store results from Google routing API.
var routeResults = [];
// Call this upon page load to set everything in motion!
function initialize(currentLat, currentLng) {
currentPosition = new google.maps.LatLng(currentLat, currentLng);
directionsDisplay = new google.maps.DirectionsRenderer();
var mapOptions = {
zoom: 13,
center: currentPosition
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
directionsDisplay.setMap(map);
var marker = new google.maps.Marker({
position: currentPosition,
map: map,
title: 'Currrently location.'
});
var i = interestingPlaces.length;
while (i--) {
interestingPlaces[i].marker = new google.maps.Marker({
position: interestingPlaces[i].latLng,
map: map,
title: interestingPlaces[i].title,
icon: 'http://maps.google.com/mapfiles/ms/icons/green.png'
});
}
findNearestPlace();
}
// Loops through all inteesting places to calculate route between our current position
// and that place.
function findNearestPlace() {
var i = interestingPlaces.length;
size = interestingPlaces.length;
routeResults = [];
while (i--) {
calcRoute(interestingPlaces[i].latLng, storeResult);
}
}
// A function to calculate the route between our current position and some desired end point.
function calcRoute(end, callback) {
var request = {
origin: currentPosition,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
callback(response);
} else {
size--;
}
});
}
// Stores a routing result from the API in our global array for routes.
function storeResult(data) {
routeResults.push(data);
if (routeResults.length === size) {
findShortest();
}
}
// Goes through all routes stored and finds which one is the shortest. It then
// sets the shortest route on the map for the user to see.
function findShortest() {
var i = routeResults.length;
var shortestIndex = 0;
var shortestLength = routeResults[0].routes[0].legs[0].distance.value;
while (i--) {
if (routeResults[i].routes[0].legs[0].distance.value < shortestLength) {
shortestIndex = i;
shortestLength = routeResults[i].routes[0].legs[0].distance.value;
}
}
directionsDisplay.setDirections(routeResults[shortestIndex]);
}
// Expose the initialize function publicly as "init".
return {
init: initialize
};
}();
// Upon page load, lets start the process!
google.maps.event.addDomListener(window, 'load', shortestDistance.init(51.489554, -0.12969));
DISCLAIMER
THIS IS NOT MY PEN!!! I AM JUST REFERRING TO A USEFUL RESOURCE THAT MIGHT HELP
First of all, sorry for my solution being in TS, you can easily convert it to JS.
The "avoidhighways" attribute is not there to get the fastest or shortest route, it's there for what the name suggests, avoiding highways.
I've made my own solution by always getting multiple routs with this attribute:
directionsService.route({
[...]
provideRouteAlternatives: true
[...]
}, (response, status) => {
if (status === google.maps.DirectionsStatus.OK) {
var shortest: google.maps.DirectionsResult = this.shortestRoute(response);
this.directionsDisplay.setDirections(shortest);
[...]
And I made this function that returns the DirectionsResult with just the one route. In this case it's the shortest, but you can tweek it so it returns what ever route suits your needs.
shortestRoute = (routeResults: google.maps.DirectionsResult): google.maps.DirectionsResult => {
var shortestRoute: google.maps.DirectionsRoute = routeResults.routes[0];
var shortestLength = shortestRoute.legs[0].distance.value;
for (var i = 1; i < routeResults.routes.length; i++) {
if (routeResults.routes[i].legs[0].distance.value < shortestLength) {
shortestRoute = routeResults.routes[i];
shortestLength = routeResults.routes[i].legs[0].distance.value;
}
}
routeResults.routes = [shortestRoute];
return routeResults;
}
I took code from Soldeplata Saketos answer and edited it since it wasn't working. Added params so you can just call it with it like.
shortestRoute(origin, destination, map);
Works for me all though I'm not sure how correct it is.
Here:
function shortestRoute(origin, destination, map) {
directionsService = new google.maps.DirectionsService();
var routesResponses = [];
//avoiding tolls
directionsService.route({
origin: origin,
destination: destination,
provideRouteAlternatives: true,
avoidTolls: true,
travelMode: google.maps.TravelMode.DRIVING
}, function (response, status) {
if (status === google.maps.DirectionsStatus.OK) {
routesResponses.push(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
//avoiding highways
directionsService.route({
origin: origin,
destination: destination,
provideRouteAlternatives: true,
avoidHighways: true,
travelMode: google.maps.TravelMode.DRIVING
}, function (response, status) {
if (status === google.maps.DirectionsStatus.OK) {
routesResponses.push(response);
} else {
window.alert('Directions request failed due to ' + status);
}
//Results analysis and drawing of routes
var fastest = Number.MAX_VALUE,
shortest = Number.MAX_VALUE;
routesResponses.forEach(function (res) {
res.routes.forEach(function (rou, index) {
console.log("distance of route " + index + ": ", rou.legs[0].distance.value);
console.log("duration of route " + index + ": ", rou.legs[0].duration.value);
if (rou.legs[0].distance.value < shortest) shortest = rou.legs[0].distance.value;
if (rou.legs[0].duration.value < fastest) fastest = rou.legs[0].duration.value;
})
})
console.log("shortest: ", shortest);
console.log("fastest: ", fastest);
//painting the routes in green blue and red
routesResponses.forEach(function (res) {
res.routes.forEach(function (rou, index) {
new google.maps.DirectionsRenderer({
map: map,
directions: res,
routeIndex: index,
polylineOptions: {
strokeColor: rou.legs[0].duration.value == fastest ? "red" : rou.legs[0].distance.value == shortest ? "darkgreen" : "blue",
strokeOpacity: rou.legs[0].duration.value == fastest ? 0.8 : rou.legs[0].distance.value == shortest ? 0.9 : 0.5,
strokeWeight: rou.legs[0].duration.value == fastest ? 9 : rou.legs[0].distance.value == shortest ? 8 : 3,
}
});
});
});
});
}