/** * ng2-gm - Angular 2 components for Google Maps * @version v0.0.2 * @link https://github.com/williampaulo/angular2-google-maps#readme * @license MIT */ import {Injectable, NgZone} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import {Observer} from 'rxjs/Observer'; import * as mapTypes from './google-maps-types'; import {MapsAPILoader} from './maps-api-loader/maps-api-loader'; // todo: add types for this declare var google: any; /** * Wrapper class that handles the communication with the Google Maps Javascript * API v3 */ @Injectable() export class GoogleMapsAPIWrapper { private _map: Promise; private _mapResolver: (value?: mapTypes.GoogleMap) => void; private _directionsDisplay: any; private _directionsService: any; constructor(private _loader: MapsAPILoader, private _zone: NgZone) { this._map = new Promise((resolve: () => void) => { this._mapResolver = resolve; }); this._directionsDisplay = this._initRouteRenderer(); this._directionsService = this._initRouteService(); } createMap(el: HTMLElement, mapOptions: mapTypes.MapOptions): Promise { return this._loader.load().then(() => { const map = new google.maps.Map(el, mapOptions); this._mapResolver(map); return; }); } setMapOptions(options: mapTypes.MapOptions) { this._map.then((m: mapTypes.GoogleMap) => { m.setOptions(options); }); } /** * Creates a google map marker with the map context */ createMarker(options: mapTypes.MarkerOptions = {}): Promise { return this._map.then((map: mapTypes.GoogleMap) => { options.map = map; return new google.maps.Marker(options); }); } createInfoWindow(options?: mapTypes.InfoWindowOptions): Promise { return this._map.then(() => { return new google.maps.InfoWindow(options); }); } subscribeToMapEvent(eventName: string): Observable { return Observable.create((observer: Observer) => { this._map.then((m: mapTypes.GoogleMap) => { m.addListener(eventName, (arg: E) => { this._zone.run(() => observer.next(arg)); }); }); }); } setCenter(latLng: mapTypes.LatLngLiteral): Promise { return this._map.then((map: mapTypes.GoogleMap) => map.setCenter(latLng)); } getZoom(): Promise { return this._map.then((map: mapTypes.GoogleMap) => map.getZoom()); } setZoom(zoom: number): Promise { return this._map.then((map: mapTypes.GoogleMap) => map.setZoom(zoom)); } getCenter(): Promise { return this._map.then((map: mapTypes.GoogleMap) => map.getCenter()); } getMap(): Promise { return this._map; } /** * Triggers the given event name on the map instance. */ triggerMapEvent(eventName: string): Promise { return this._map.then((m) => google.maps.event.trigger(m, eventName)); } /** * Router */ private _initRouteRenderer() { return this._map.then((map: mapTypes.GoogleMap) => { let directionsDisplay = new google.maps.DirectionsRenderer(); directionsDisplay.setMap(map); return directionsDisplay; }); } private _initRouteService() { return this._map.then(() => { return new google.maps.DirectionsService(); }); } /** * Create a google routes map */ createRoute(options: mapTypes.RouterOptions = {}): Promise { return this._map.then(() => { options.travelMode = google.maps.DirectionsTravelMode.DRIVING; options.unitSystem = google.maps.UnitSystem.METRIC; var _directionsDisplay = this._directionsDisplay; this._directionsService.then((dService: any) => { dService.route(options, function(response: any, status: any) { if (status === google.maps.DirectionsStatus.OK) { _directionsDisplay.then((dDisplay: any) => { // console.log('seta a nova rota, ol.', response); dDisplay.setDirections(response); // console.log('origem: ' + options.origin); // console.log('destinations:' + options.destination); }); } else { console.log('Unable to retrieve your route'); } }); }); }); } updateRoute(options: mapTypes.RouterOptions = {}): Promise { return this.createRoute(options); } infoPanel(content: any): Promise { return this._map.then( () => { this._directionsDisplay.then( (dDisplay: any) => { dDisplay.setPanel(content); console.log(content); }, () => { console.log('painel não setado.'); }); }, () => { console.log('eeeeeeeee.'); }); } infoDistacePanel(content: any, origin: any, destination: any): Promise { return this._map.then(() => { // console.log('origem: ' + origin); // console.log('destinations:' + destination); var service = new google.maps.DistanceMatrixService(); service.getDistanceMatrix( { origins: [origin], destinations: [destination], travelMode: google.maps.TravelMode.DRIVING, unitSystem: google.maps.UnitSystem.METRIC, // avoidHighways: false, // avoidTolls: false }, (response: any, status: any) => { if (status === google.maps.DistanceMatrixStatus.OK && response.rows[0].elements[0].status !== 'ZERO_RESULTS') { var distance = response.rows[0].elements[0].distance.text; var duration = response.rows[0].elements[0].duration.text; content.innerHTML = ''; content.innerHTML += 'Distance: ' + distance + '
'; content.innerHTML += 'Duration:' + duration; // console.log(response.rows[0].elements[0]); // console.log('Distância: ' + distance); // console.log('Duration:' + duration); // we only have one origin so there should only be one row /*var routes = response.rows[0]; var sortable: any = []; var resultText = 'Origin: ' + origin + '
'; resultText += 'Possible Routes:
'; for (var i = routes.elements.length - 1; i >= 0; i--) { var rteLength = routes.elements[i].duration.value; resultText += 'Route: ' + destination[i] + ', ' + 'Route Length: ' + rteLength + '
'; sortable.push([destination[i], rteLength]); } // sort the result lengths from shortest to longest. sortable.sort((a: any, b: any) => { return a[1] - b[1]; }); // build the waypoints. var waypoints: any = []; for (var j: any = 0; j < sortable.length - 1; j++) { console.log(sortable[j][0]); waypoints.push({location: sortable[j][0], stopover: true}); }*/ // start address == origin // var start = origin; // end address is the furthest desitnation from the origin. // var end = sortable[sortable.length - 1][0]; // calculate the route with the waypoints // calculateRoute(start, end, waypoints); // log the routes and duration. // console.log(resultText); } else { alert('Unable to find the distance via road.'); } }); }); } }