Angular 2 Google Maps Javascript API, Route Service function doesn't exist - javascript

Trying to get my head around using the Javascript API from Google Maps in my Angular 2 Project.
The problem i have is based on this code:
#Injectable()
export class CalculateAndDisplayRouteService {
public durationTrafficSource = new ReplaySubject<string>();
public durationTraffic$ = this.durationTrafficSource.asObservable();
public changeDurationTraffic(string) {
this.durationTrafficSource.next(string);
}
public routeResponse(response, status) {
console.log(response);
let map = new google.maps.Map(document.getElementById('map'), {
center: {lat: lat, lng: lng},
zoom: 8
});
if (status === 'OK') {
let directionsDisplay = new google.maps.DirectionsRenderer({
suppressMarkers: false,
suppressInfoWindows: true
});
directionsDisplay.setMap(map);
directionsDisplay.setDirections(response);
this.changeDurationTraffic(response.routes[0].legs[0].duration.text); //Error is here
} else {
window.alert('Directions request failed due to ' + status);
}
}
private currentDate = new Date();
public route(directionsService, transportMode, origin, destination) {
if(transportMode === 'DRIVING') {
directionsService.route({
origin: origin,
destination: destination,
travelMode: transportMode,
drivingOptions: {
departureTime: new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), this.currentDate.getDate() + 1, 7, 45),
trafficModel: 'pessimistic'
}
}, this.routeResponse);
The problem I have is in the routeResponse function. I receive an error where the changeDurationTraffic function is called.
"Uncaught TypeError: this.changeDurationTraffic is not a function".
Is there something i am doing wrong? Thanks.

The this inside that function is not refering to your component because of this method:
public route(directionsService, transportMode, origin, destination) {
if(transportMode === 'DRIVING') {
directionsService.route({
origin: origin,
destination: destination,
travelMode: transportMode,
drivingOptions: {
departureTime: new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), this.currentDate.getDate() + 1, 7, 45),
trafficModel: 'pessimistic'
}
}, this.routeResponse); //<-- ****Error here.****
Change that line to
this.routeResponse.bind(this);
Suggested reading: How to access the correct `this` context inside a callback?

Related

Remove option from Google Maps embedded

frameborder="0" style="border:0" src="https://www.google.com/maps/embed/v1/directions?origin=rishra&destination=kolkata&key=MY-API-KEY&zoom=12" allowfullscreen>
Results>
enter image description here
Want to remove that box which shows location of two points and more options
You are using a Directions mode of Maps Embed API and it seems that the origin and destination information is part of the API and can't be removed. If you would only like to show the directions of your origin and destination, you can opt to use Maps Javascript APIs Directions Service. This API will enable you to make more dynamic changes in your map.
Here's a sample code and code snippet below:
function initMap() {
const directionsService = new google.maps.DirectionsService();
const directionsRenderer = new google.maps.DirectionsRenderer();
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 17,
center: {
lat: 22.572646,
lng: 88.363895
},
});
directionsRenderer.setMap(map);
calculateAndDisplayRoute(directionsService, directionsRenderer);
}
function calculateAndDisplayRoute(directionsService, directionsRenderer) {
directionsService
.route({
origin: 'rishra',
destination: 'kolkata',
travelMode: google.maps.TravelMode.DRIVING,
})
.then((response) => {
directionsRenderer.setDirections(response);
})
.catch((e) => window.alert("Directions request failed due to " + status));
}

Bad import in Typescript

I install this package: https://www.npmjs.com/package/#types/googlemaps, to create an function to get travel time from google maps, but after launch, my console throw me:
Error: Cannot find module 'googlemaps'
I try to import like this:
import * as google from 'googlemaps';
but it not work,
i also try to create index.d.ts:
declare module 'googlemaps';
but without success,
my code:
var google = require('googlemaps'); // another try
async calculateTravelTime() {
const directionsService = new google.maps.DirectionsService();
directionsService.route(
{
origin: { lat: 37.77, lng: -122.447 },
destination: { lat: 37.768, lng: -122.511 },
travelMode: google.maps.TravelMode.DRIVING
},
(response, status) => {
if(status == "OK") {
console.log(response);
} else {
console.log(response);
}
}
)
}
so, how to properly import googlemaps in typescript?
thanks for any help
Try to install the types of googlemaps.
npm install --save #types/googlemaps
then try again
import google from 'googlemaps';
or
import * as google from 'googlemaps';

Clear directions on Google Map with VueJS

I have the following code in my app:
createCargoRoute: function(cargo_id) {
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var storehouse = new google.maps.LatLng(53.243757, 50.269379);
var cargo_orders = this.orders.filter(order => this.cargos[cargo_id]['orders_ids'].includes(order.id));
var cargo_waypoints = cargo_orders.map(cargo_order => cargo_order['waypoint']);
directionsDisplay.setMap(this.$refs.olkonmap.$mapObject);
directionsService.route({
origin: storehouse,
destination: storehouse,
travelMode: 'DRIVING',
waypoints: cargo_waypoints,
optimizeWaypoints: true
}, function(result, status) {
if(status == 'OK') {
directionsDisplay.setDirections(result);
}
});
},
It works, but when I call it second time to draw another route, the first route doesn't removes from map. I read that I need to call directionsDisplay.setDirections(null) to clear directions and it works, for example, if I add setTimeout(function() { directionsDisplay.setDirections(null); }, 2000);
to createCargoRoute function.
But if I add directionsDisplay.setDirections(null); before any actions in createCargoRoute, it has no effect at second call. I think, it may be due to new DirectionsRenderer object which instantiates every time I call the function. Any advice would be appreciated. Thank you!
This is not good idea to create new DirectionsService and DirectionsRenderer on each call. Move them to mounted() and keep instances in component options (instead of putting them to data). Maybe it help:
export default {
// will be accessible via this.$options because no reactive data is needed
directionsService: null,
directionsDisplay: null,
mounted() {
this.$options.directionsService = new google.maps.DirectionsService();
this.$options.directionsDisplay = new google.maps.DirectionsRenderer();
this.$options.directionsDisplay.setMap(this.$refs.olkonmap.$mapObject);
},
methods: {
createCargoRoute: function(cargo_id) {
// clear existing directions
this.$options.directionsDisplay.set('directions', null);
var storehouse = new google.maps.LatLng(53.243757, 50.269379);
var cargo_orders = this.orders.filter(order => this.cargos[cargo_id]['orders_ids'].includes(order.id));
var cargo_waypoints = cargo_orders.map(cargo_order => cargo_order['waypoint']);
this.$options.directionsService.route({
origin: storehouse,
destination: storehouse,
travelMode: 'DRIVING',
waypoints: cargo_waypoints,
optimizeWaypoints: true
}, (result, status) => {
if(status == 'OK') {
this.$options.directionsDisplay.setDirections(result);
}
});
},
}
}

Removing directions overlay using angular-google-maps and angular2

Im using an api to populate a map with several markers, my desired functionality is for a user to click a button associated with a marker and it would plot directions from their current location. On the first instance it works perfectly but the current directions plotted just remain when trying to change the coordinates
Im using angular2-google-maps to plot the markers but I had to find a custom directive for directions. I think the problem is that I need to destroy the instance of the directions but using ngIf didnt help. I also tried resetting the instance of the direction in my directive using directionsDisplay.set('directions', null); but that didnt work either
/* directions.directive.ts */
import {GoogleMapsAPIWrapper} from '#agm/core/services/google-maps-api-wrapper';
import { Directive, Input} from '#angular/core';
declare var google: any;
#Directive({
selector: '<agm-map-directions [origin]="origin" [destination]="destination" #test></agm-map-directions>'
})
export class DirectionsMapDirective {
#Input() origin;
#Input() destination;
constructor (private gmapsApi: GoogleMapsAPIWrapper) {}
ngOnInit(){
this.gmapsApi.getNativeMap().then(map => {
var directionsService = new google.maps.DirectionsService;
var directionsDisplay = new google.maps.DirectionsRenderer;
console.log("test");
directionsDisplay.setMap(map);
directionsService.route({
origin: {lat: this.origin.latitude, lng: this.origin.longitude},
destination: {lat: this.destination.latitude, lng: this.destination.longitude},
waypoints: [],
optimizeWaypoints: true,
travelMode: 'DRIVING'
}, function(response, status) {
if (status === 'OK') {
directionsDisplay.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
});
}
}
Here is the html associated with it
<agm-map [zoom]="13" [latitude]="currentLocation.result.latitude" [longitude]="currentLocation.result.longitude">
<agm-marker [latitude]="currentLocation.result.latitude" [longitude]="currentLocation.result.latitude"></agm-marker>
<agm-marker *ngFor="let device of location.ChargeDevice; let i = index"
ngShow="device.SubscriptionRequiredFlag"
[latitude]="convertStringToNumber(device.ChargeDeviceLocation.Latitude)"
[longitude]="convertStringToNumber(device.ChargeDeviceLocation.Longitude)"
(markerClick)="clickedMarker(device)">
</agm-marker>
<div *ngIf="showDirections" >
<agm-map-directions [origin]="origin" [destination]="destination" #test></agm-map-directions>
</div>
</agm-map>
I had the same problem as you.
I solved it by creating a global object that holds the instantiation of directionsService and directionsDisplay, to be able to pass those as reference later. ( See javascript pass by reference )
public directions: any = {
directionsService: null,
directionsDisplay: null
}
Then, I created a function that initialize the map once and I called it within ngOnInit() function:
constructor(private _gmapsApi: GoogleMapsAPIWrapper) { }
ngOnInit() {
this.initalizeMap(this.directions);
}
initalizeMap(directions): void {
this._gmapsApi.getNativeMap().then(map => {
directions.directionsService = new google.maps.DirectionsService;
directions.directionsDisplay = new google.maps.DirectionsRenderer;
directions.directionsDisplay.setMap(map);
directions.directionsDisplay.addListener('directions_changed', function() {
this.displayRoute(this.origin, this.destination, directions.directionsService, directions.directionsDisplay);
});
this.displayRoute(this.origin, this.destination, directions.directionsService, directions.directionsDisplay);
})
}
I added a listener to directionsDisplay to displayRoute whenever a change is made in the directions. The function displayRoute take as parameters origin and destination passed through #Input and references to directionsService and directionsDisplay whose instances I saved in directions object. The waypoints I took are also through #Input.
displayRoute(origin, destination, service, display): void {
var myWaypoints = [];
for (var i = 0; i < this.waypoints.length; i++) {
console.log(this.waypoints[i].markerID);
console.log(this.waypoints[i].location);
}
for (var i = 0; i < this.waypoints.length; i++) {
myWaypoints.push({
location: new google.maps.LatLng(this.waypoints[i].location),
stopover: true
})
}
service.route({
origin: origin,
destination: destination,
waypoints: myWaypoints,
travelMode: 'WALKING',
avoidTolls: true
}, function(response, status) {
if (status === 'OK') {
console.log("Route OK.");
display.setDirections(response);
} else {
alert('Could not display directions due to: ' + status);
}
});
}
The last function and the most important is calculateRoute, which I call from the component I injected the service ( Map Component in my case ) whenever I want it to recalculate the route.
calculateRoute(): void {
this._gmapsApi.getNativeMap().then(map => {
this.displayRoute(this.origin, this.destination, this.directions.directionsService, this.directions.directionsDisplay);
});
}
Hope it helps!

Dotted route when travel mode for driving is not supported

I am trying to make the route for my map in ionic, and I can't seem to find a way to show the route as dotted when the travel mode for driving is not available - like on the google maps.
This is how my maps route looks like:
without the dotted route ->
This is how google maps route looks like:
with the dotted route ->
This is how the code for the route looks like for now:
function route(travel_mode, directionsService, directionsDisplay) {
console.log($scope.transfer.origin.place_id, $scope.transfer.destination.place_id);
if (!$scope.transfer.origin.place_id || !$scope.transfer.destination.place_id) {
return;
}
else if (ok == 0) {
ok = 1;
directionsService.route({
origin: {
'placeId': $scope.transfer.origin.place_id
}
, destination: {
'placeId': $scope.transfer.destination.place_id
}
, travelMode: travel_mode
}, function (response, status) {
if (status === 'OK') {
directionsDisplay.setDirections(response);
var origin1 = $scope.transfer.origin.place_title;
var destinationA = $scope.transfer.destination.place_title;
console.dir(origin1);
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
origins: [origin1]
, destinations: [destinationA]
, travelMode: 'DRIVING'
, unitSystem: google.maps.UnitSystem.METRIC
}, callback);
function callback(response, status) {
console.dir(response);
if (status == 'OK') {
origins = response.originAddresses[0];
destinations = response.destinationAddresses[0];
results = response.rows[0].elements[0];
distance = results.distance.text;
duration = results.duration.text;
DTransfer.setData('distance', distance);
DTransfer.setData('duration', duration);
}
}
}
else {
window.alert('Directions request failed due to ' + status);
}
});
}
}
}
If there is any fix, can anybody help?

Categories

Resources