diff --git a/src/app/auth/login/login.page.ts b/src/app/auth/login/login.page.ts index 74b06ec96280b621d660c3ae335893f18575065f..3435cc7954c3c5e525e0ffc4a3a1db81ded71d8e 100644 --- a/src/app/auth/login/login.page.ts +++ b/src/app/auth/login/login.page.ts @@ -1,11 +1,13 @@ import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; +import { Router, LoadChildrenCallback } from '@angular/router'; import { Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http'; import { RestService } from '../../rest.service'; import { UserService } from 'src/app/services/user.service'; +import { LocationService } from 'src/app/services/location.service'; +import { LoadingService } from 'src/app/services/loading.service'; @Component({ selector: 'app-login', @@ -15,12 +17,15 @@ import { UserService } from 'src/app/services/user.service'; export class LoginPage implements OnInit { username = ""; password = ""; - //username = ""; - //password = ""; correctCredentials = false; loginApi: Observable<any>; - constructor(private router: Router, public httpClient: HttpClient, public restService: RestService,public userService: UserService) { + constructor(private router: Router, + public httpClient: HttpClient, + public restService: RestService, + public userService: UserService, + public locationService: LocationService, + public loadingService: LoadingService) { } @@ -37,6 +42,7 @@ export class LoginPage implements OnInit { "email": this.username, "password": this.password }); + this.loadingService.showLoader(); this.loginApi .subscribe((data) => { //console.log('my data: ', data); @@ -44,9 +50,11 @@ export class LoginPage implements OnInit { this.restService.isLoginPage = false; this.userService.setUsername(this.username); this.router.navigateByUrl('/home'); + this.loadingService.hideLoader(); }, (error) => { console.log(JSON.stringify(error)); this.correctCredentials = true; + this.loadingService.hideLoader(); }); } register() { diff --git a/src/app/components/here-map/here-map.component.html b/src/app/components/here-map/here-map.component.html index cb232138cc58e375f6693bb7a2bd52bd639f5747..e1ac575cf00a433154f4aa7ad4301d5f2d7e391a 100644 --- a/src/app/components/here-map/here-map.component.html +++ b/src/app/components/here-map/here-map.component.html @@ -1,6 +1,6 @@ <div #mapElement style="width: 100%; height: 100%" id="mapContainer" *ngIf="!is3DChecked"></div> - <ion-fab class="get-position" vertical="bottom" horizontal="end" (click)="getCurrentPosition()" slot="fixed"> - <ion-fab-button> - <ion-icon name="locate"></ion-icon> - </ion-fab-button> - </ion-fab> \ No newline at end of file +<ion-fab class="get-position" vertical="bottom" horizontal="end" (click)="getCurrentPosition()" slot="fixed"> + <ion-fab-button> + <ion-icon name="locate"></ion-icon> + </ion-fab-button> +</ion-fab> \ No newline at end of file diff --git a/src/app/hirebike/hirebike.page.html b/src/app/hirebike/hirebike.page.html index a3a2cae519b9ddde3c3abe4d6703c642377b9418..f751de63af63648306a7f490a048a421954c5574 100644 --- a/src/app/hirebike/hirebike.page.html +++ b/src/app/hirebike/hirebike.page.html @@ -19,7 +19,13 @@ </ion-item> </div--> <!--div #mapElement style="width: 100%; height: 100%" id="mapContainer"></div--> - <app-here-map [startRideSubject]="startRideSubject" [gotReservedBikeSubject]="gotReservedBikeSubject"></app-here-map> + <!--app-here-map [startRideSubject]="startRideSubject" [gotReservedBikeSubject]="gotReservedBikeSubject"></app-here-map--> + <div #mapElement style="width: 100%; height: 100%" id="mapContainer" *ngIf="!is3DChecked"></div> + <ion-fab class="get-position" vertical="bottom" horizontal="end" (click)="getCurrentPosition()" slot="fixed"> + <ion-fab-button> + <ion-icon name="locate"></ion-icon> + </ion-fab-button> + </ion-fab> </ion-content> <ion-footer> <div class="bike-details-container"> diff --git a/src/app/hirebike/hirebike.page.ts b/src/app/hirebike/hirebike.page.ts index b0ccdd363eddb47a5f4c9d43d3eb0d2866ee02dd..789c3eea88a9eb1dbef50067bc75c0fc67bbcde2 100644 --- a/src/app/hirebike/hirebike.page.ts +++ b/src/app/hirebike/hirebike.page.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; +import { Component, OnInit, ViewChild, ElementRef, Input } from '@angular/core'; import { Geolocation } from '@ionic-native/geolocation/ngx'; import { RestService } from '../rest.service'; @@ -8,6 +8,8 @@ import { Storage } from '@ionic/storage'; import { ToastService } from '../services/toast.service'; import { Router } from '@angular/router'; import { MapDataService } from '../services/map-data.service'; +import { LocationService } from '../services/location.service'; +import { LoadingService } from '../services/loading.service'; declare var H: any; @Component({ @@ -33,16 +35,71 @@ export class HirebikePage implements OnInit { gotReservedBikeSubject: Subject<any> = new Subject(); maneuverList: any = []; + @ViewChild("mapElement", { static: false }) + public mapElement: ElementRef; + + private map: any; + private ui: any; + private defaultLayers: any; + private locationsGroup: any; + + private currentUserPosition = { lat: 48.783480, lng: 9.180319 }; + private bikePosition = { lat: 48.783480, lng: 9.180319 }; + private destinationPosition = { lat: 48.783480, lng: 9.180319 }; + + public currentLocationMarker: any; + public destinationMarker: any; + + public rideStarted = false; + constructor(private geolocation: Geolocation, public restService: RestService, public httpClient: HttpClient, private storage: Storage, private toastService: ToastService, private router: Router, - private mapDataService: MapDataService) { + private mapDataService: MapDataService, + public locationService: LocationService, + public loadingService: LoadingService) { + this.platform = new H.service.Platform({ 'apikey': 'tiVTgBnPbgV1spie5U2MSy-obhD9r2sGiOCbBzFY2_k' }); + } + + ngOnInit() { + + } + + ngAfterViewInit() { + window.addEventListener('resize', () => this.map.getViewPort().resize()); + } + + ionViewWillEnter() { + this.currentUserPosition.lat = this.locationService.currentUserPosition.lat; + this.currentUserPosition.lng = this.locationService.currentUserPosition.lng; + + this.initializeMap(); + + //get user location + if (this.currentLocationMarker) { + this.currentLocationMarker.setGeometry({ lat: this.currentUserPosition.lat, lng: this.currentUserPosition.lng }) + } else { + this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); + } + + this.locationService.liveLocationSubject.subscribe((position) => { + console.log('got location inside home subscription'); + this.currentUserPosition.lat = position.lat; + this.currentUserPosition.lng = position.lng; + if (this.currentLocationMarker) { + this.currentLocationMarker.setGeometry({ lat: this.currentUserPosition.lat, lng: this.currentUserPosition.lng }) + } else { + this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); + } + }); + this.getReservedBike(); + this.mapDataService.mapDataSubject.subscribe(receiveddata => { console.log('data received '); console.log(receiveddata); @@ -58,14 +115,34 @@ export class HirebikePage implements OnInit { } this.wayPointsInfo = waypointLabels.join(' - '); }); - } - ngOnInit() { - this.getReservedBike(); - } + this.gotReservedBikeSubject.subscribe(bikeDetails => { + console.log('Got Bike in map'); + console.log(bikeDetails); + this.bikePosition.lat = bikeDetails.lat; + this.bikePosition.lng = bikeDetails.lon; + var img = ['../../../assets/images/100_percent.png', '../../../assets/images/75_percent.png', '../../../assets/images/50_percent.png', '../../../assets/images/25_percent.png', '../../../assets/images/0_percent.png']; + if (bikeDetails.batteryPercentage < 100 && bikeDetails.batteryPercentage >= 75) { + this.addMarker(Number(bikeDetails.lat), Number(bikeDetails.lon), img[0]); + } + else if (bikeDetails.batteryPercentage < 75 && bikeDetails.batteryPercentage >= 50) { + this.addMarker(Number(bikeDetails.lat), Number(bikeDetails.lon), img[1]); + } + else if (bikeDetails.batteryPercentage < 50 && bikeDetails.batteryPercentage >= 25) { + this.addMarker(Number(bikeDetails.lat), Number(bikeDetails.lon), img[2]); + } else if (bikeDetails.batteryPercentage < 25 && bikeDetails.batteryPercentage >= 0) { + this.addMarker(Number(bikeDetails.lat), Number(bikeDetails.lon), img[3]); + } - ngAfterViewInit() { + this.setZoomLevelToPointersGroup(); + }); + this.startRideSubject.subscribe(event => { + console.log('start ride'); + //remove event listener + this.rideStarted = true; + this.calculateRoute(); + }); } showRouteInfoPanel(route) { @@ -76,17 +153,6 @@ export class HirebikePage implements OnInit { // Get the next maneuver. let maneuver = route.leg[i].maneuver[j]; maneuverList.push(maneuver); - - // var li = document.createElement('li'), - // spanArrow = document.createElement('span'), - // spanInstruction = document.createElement('span'); - - // spanArrow.className = 'arrow ' + maneuver.action; - // spanInstruction.innerHTML = maneuver.instruction; - // li.appendChild(spanArrow); - // li.appendChild(spanInstruction); - - // nodeOL.appendChild(li); } } @@ -94,6 +160,7 @@ export class HirebikePage implements OnInit { } getReservedBike() { + this.loadingService.showLoader(); this.storage.get('token').then((token) => { const headers = new HttpHeaders().set("Authorization", "Bearer " + token); //call reserved bike api @@ -115,24 +182,34 @@ export class HirebikePage implements OnInit { //pass reserved bike subject here map this.gotReservedBikeSubject.next(resp.data); - }, (reservedBikeError) => console.log(reservedBikeError)); + this.loadingService.hideLoader(); + }, (reservedBikeError) => { + console.log(reservedBikeError); + this.loadingService.hideLoader(); + }); } - }, (bikeDetailsError) => console.log(bikeDetailsError)); + }, (bikeDetailsError) => { + console.log(bikeDetailsError); + this.loadingService.hideLoader(); + }); }); } startTrip1() { + this.loadingService.showLoader(); this.storage.get('token').then((token) => { let url = 'http://193.196.52.237:8081/rent' + '?bikeId=' + this.bikeDetails.id; const headers = new HttpHeaders().set("Authorization", "Bearer " + token); let bikeApi = this.httpClient.get(url, { headers }); bikeApi.subscribe((resp) => { console.log('my data: ', resp); + this.loadingService.hideLoader(); this.toastService.showToast("Trip Started"); this.isBikeHired = true; }, (error) => { - console.log(error) - this.toastService.showToast("This is ongoing Trip") + console.log(error); + this.loadingService.hideLoader(); + this.toastService.showToast("This is ongoing Trip"); }); }); @@ -144,19 +221,307 @@ export class HirebikePage implements OnInit { } CancelTrip() { + this.loadingService.showLoader(); this.storage.get('token').then((token) => { let url = 'http://193.196.52.237:8081/rent' + '?bikeId=' + this.bikeDetails.id; const headers = new HttpHeaders().set("Authorization", "Bearer " + token); let bikeApi = this.httpClient.delete(url, { headers }); bikeApi.subscribe((resp) => { console.log('my data: ', resp); + this.loadingService.hideLoader(); this.toastService.showToast("Trip Ended!"); }, (error) => { - console.log(error) + console.log(error); + this.loadingService.hideLoader(); this.toastService.showToast("No Ongong Trip to End") }); }); } + + ngOnDestroy() { + // needed if child gets re-created (eg on some model changes) + // note that subsequent subscriptions on the same subject will fail + // so the parent has to re-create parentSubject on changes + this.startRideSubject.unsubscribe(); + } + + onSuccess(result) { + var route = result.response.route[0]; + /* + * The styling of the route response on the map is entirely under the developer's control. + * A representitive styling can be found the full JS + HTML code of this example + * in the functions below: + */ + this.addRouteShapeToMap(route); + this.addManueversToMap(route); + this.mapDataService.mapDataSubject.next(route); + + //addWaypointsToPanel(route.waypoint); + //addManueversToPanel(route); + //addSummaryToPanel(route.summary); + } + + /** + * This function will be called if a communication error occurs during the JSON-P request + * @param {Object} error The error message received. + */ + onError(error) { + alert('Can\'t reach the remote server'); + } + + bubble; + + /** + * Opens/Closes a infobubble + * @param {H.geo.Point} position The location on the map. + * @param {String} text The contents of the infobubble. + */ + openBubble(position, text) { + if (!this.bubble) { + this.bubble = new H.ui.InfoBubble( + position, + // The FO property holds the province name. + { content: text }); + this.ui.addBubble(this.bubble); + } else { + this.bubble.setPosition(position); + this.bubble.setContent(text); + this.bubble.open(); + } + } + + /** + * Creates a H.map.Polyline from the shape of the route and adds it to the map. + * @param {Object} route A route as received from the H.service.RoutingService + */ + addRouteShapeToMap(route) { + var lineString = new H.geo.LineString(), + routeShape = route.shape, + polyline; + + routeShape.forEach(function (point) { + var parts = point.split(','); + lineString.pushLatLngAlt(parts[0], parts[1]); + }); + + polyline = new H.map.Polyline(lineString, { + style: { + lineWidth: 4, + strokeColor: 'rgba(0, 128, 255, 0.7)' + } + }); + // Add the polyline to the map + this.map.addObject(polyline); + // And zoom to its bounding rectangle + this.map.getViewModel().setLookAtData({ + bounds: polyline.getBoundingBox() + }); + } + + /** + * Creates a series of H.map.Marker points from the route and adds them to the map. + * @param {Object} route A route as received from the H.service.RoutingService + */ + addManueversToMap(route) { + var svgMarkup = '<svg width="18" height="18" ' + + 'xmlns="http://www.w3.org/2000/svg">' + + '<circle cx="8" cy="8" r="8" ' + + 'fill="#1b468d" stroke="white" stroke-width="1" />' + + '</svg>', + dotIcon = new H.map.Icon(svgMarkup, { anchor: { x: 8, y: 8 } }), + group = new H.map.Group() + var group = new H.map.Group(); + + // Add a marker for each maneuver + for (let i = 0; i < route.leg.length; i += 1) { + for (let j = 0; j < route.leg[i].maneuver.length; j += 1) { + // Get the next maneuver. + var maneuver = route.leg[i].maneuver[j]; + // Add a marker to the maneuvers group + var marker = new H.map.Marker({ + lat: maneuver.position.latitude, + lng: maneuver.position.longitude + }, + { icon: dotIcon }); + marker.instruction = maneuver.instruction; + group.addObject(marker); + } + } + + group.addEventListener('tap', (evt) => { + this.map.setCenter(evt.target.getGeometry()); + this.openBubble( + evt.target.getGeometry(), evt.target.instruction); + }, false); + + // Add the maneuvers group to the map + this.map.addObject(group); + } + + calculateRoute() { + var waypoint0 = this.bikePosition.lat + ',' + this.bikePosition.lng; + var waypoint1 = this.destinationPosition.lat + ',' + this.destinationPosition.lng; + var router = this.platform.getRoutingService(), + routeRequestParams = { + mode: 'fastest;bicycle', + representation: 'display', + routeattributes: 'waypoints,summary,shape,legs', + maneuverattributes: 'direction,action', + waypoint0: waypoint0, // Brandenburg Gate + waypoint1: waypoint1 // Friedrichstraße Railway Station + }; + + router.calculateRoute( + routeRequestParams, + this.onSuccess.bind(this), + this.onError.bind(this) + ); + } + + + initializeMap() { + // Obtain the default map types from the platform object + this.defaultLayers = this.platform.createDefaultLayers(); + this.map = new H.Map( + this.mapElement.nativeElement, + this.defaultLayers.raster.normal.map, + { + center: { lat: this.locationService.preiousUserPosition.lat, lng: this.locationService.preiousUserPosition.lng }, + zoom: 17, + pixelRatio: window.devicePixelRatio || 1 + } + ); + + var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(this.map)); + this.ui = H.ui.UI.createDefault(this.map, this.defaultLayers); + this.ui.removeControl("mapsettings"); + // create custom map settings (icons on map) + var customMapSettings = new H.ui.MapSettingsControl({ + baseLayers: [ + { + label: "3D", layer: this.defaultLayers.vector.normal.map + }, { + label: "Normal", layer: this.defaultLayers.raster.normal.map + }, { + label: "Satellite", layer: this.defaultLayers.raster.satellite.map + }, { + label: "Terrain", layer: this.defaultLayers.raster.terrain.map + } + ], + layers: [ + { + label: "layer.traffic", layer: this.defaultLayers.vector.normal.traffic + }, + { + label: "layer.incidents", layer: this.defaultLayers.vector.normal.trafficincidents + } + ] + }); + this.ui.addControl("custom-mapsettings", customMapSettings); + var mapSettings = this.ui.getControl('custom-mapsettings'); + var zoom = this.ui.getControl('zoom'); + mapSettings.setAlignment('top-right'); + zoom.setAlignment('right-top'); + + this.map.getViewPort().setPadding(30, 30, 30, 30); + + // Listen for base layer change event (eg. from satellite to 3D) + this.map.addEventListener('baselayerchange', (evt) => { + let mapConfig = this.map.getBaseLayer().getProvider().getStyleInternal().getConfig(); + if (mapConfig === null || (mapConfig && mapConfig.sources && mapConfig.sources.omv)) { + this.map.getViewModel().setLookAtData({ tilt: 60 }); + } else { + this.map.getViewModel().setLookAtData({ tilt: 0 }); + } + }); + + // listen for map click event + this.map.addEventListener('tap', this.mapClickedEvent.bind(this)); + + if(!this.locationsGroup) { + this.locationsGroup = new H.map.Group(); + } + this.map.addObject(this.locationsGroup); + } + + mapClickedEvent(event) { + if(this.rideStarted) { + return; + } + //console.log(event.type, event.currentPointer.type); + var coord = this.map.screenToGeo(event.currentPointer.viewportX, + event.currentPointer.viewportY); + console.log(coord.lat + ', ' + coord.lng); + + this.destinationPosition = { lat: coord.lat, lng: coord.lng }; + + if (this.destinationMarker) { + this.destinationMarker.setGeometry({ lat: coord.lat, lng: coord.lng }) + } else { + let icon = new H.map.Icon('../../../assets/images/current_location.png'); + // Create a marker using the previously instantiated icon: + this.destinationMarker = new H.map.Marker({ lat: coord.lat, lng: coord.lng }, { icon: icon }); + // Add the marker to the map: + if(!this.locationsGroup) { + this.locationsGroup = new H.map.Group(); + } + this.locationsGroup.addObjects([this.destinationMarker]); + this.setZoomLevelToPointersGroup(); + } + } + + //TODO change this logic + getCurrentPosition() { + if (!this.currentLocationMarker) { + this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); + } + this.map.setZoom(17); + this.map.setCenter({ lat: this.currentUserPosition.lat, lng: this.currentUserPosition.lng }); + } + + setZoomLevelToPointersGroup() { + this.map.getViewModel().setLookAtData({ + bounds: this.locationsGroup.getBoundingBox() + }); + } + + showUserLocationOnMap(lat, lng) { + let svgMarkup = '<svg width="24" height="24" ' + + 'xmlns="http://www.w3.org/2000/svg">' + + '<circle cx="10" cy="10" r="10" ' + + 'fill="#007cff" stroke="white" stroke-width="2" />' + + '</svg>'; + let icon = new H.map.Icon(svgMarkup); + //let icon = new H.map.Icon('../../../assets/images/current_location.png'); + // Create a marker using the previously instantiated icon: + this.currentLocationMarker = new H.map.Marker({ lat: lat, lng: lng }, { icon: icon }); + // Add the marker to the map: + if(!this.locationsGroup) { + this.locationsGroup = new H.map.Group(); + } + this.locationsGroup.addObjects([this.currentLocationMarker]); + this.setZoomLevelToPointersGroup(); + + //this.map.addObject(marker); + //this.map.setCenter({ lat: lat, lng: lng }); + } + + addMarker(lat, lng, img) { + var icon = new H.map.Icon(img); + // Create a marker using the previously instantiated icon: + var marker = new H.map.Marker({ lat: lat, lng: lng }, { icon: icon }); + // Add the marker to the map: + //this.map.addObject(marker); + if(!this.locationsGroup) { + this.locationsGroup = new H.map.Group(); + } + this.locationsGroup.addObjects([marker]); + } + + enable3DMaps() { + this.map.setBaseLayer(this.defaultLayers.vector.normal.map); + } + reverseGeocode(platform, lat, lng) { var prox = lat + ',' + lng + ',56'; var geocoder = platform.getGeocodingService(), @@ -168,14 +533,11 @@ export class HirebikePage implements OnInit { }; geocoder.reverseGeocode(parameters, result => { - console.log(result); var streets = result.Response.View[0].Result[0].Location.Address.Street; var houseNumber = result.Response.View[0].Result[0].Location.Address.HouseNumber; var zipcode = result.Response.View[0].Result[0].Location.Address.PostalCode; - this.address = streets; - - + return streets + houseNumber + zipcode; }, (error) => { alert(error); }); diff --git a/src/app/home/home.page.ts b/src/app/home/home.page.ts index c5b2f4d4801efc94e8a980c1313f5674ac81a00a..c32e5e448051e4605b0eb9b3c9a7cd6fce1fdf13 100644 --- a/src/app/home/home.page.ts +++ b/src/app/home/home.page.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; +import { Component, OnInit, ViewChild, ElementRef, OnDestroy } from '@angular/core'; import { Geolocation } from '@ionic-native/geolocation/ngx'; import { RestService } from '../rest.service'; import { Observable } from 'rxjs'; @@ -6,6 +6,8 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Storage } from '@ionic/storage'; import { ToastService } from '../services/toast.service'; import { Router } from '@angular/router'; +import { LocationService } from '../services/location.service'; +import { LoadingService } from '../services/loading.service'; declare var H: any; @@ -15,12 +17,12 @@ declare var H: any; styleUrls: ['home.page.scss'], }) -export class HomePage implements OnInit { +export class HomePage implements OnInit, OnDestroy { private platform: any; private map: any; private defaultLayers: any; private locationsGroup: any; - private currentUserPosition = {lat: 48.783480, lng: 9.180319}; + private currentUserPosition = { lat: 48.783480, lng: 9.180319 }; bikes = []; bikeApi: Observable<any>; @@ -39,35 +41,43 @@ export class HomePage implements OnInit { public restService: RestService, public httpClient: HttpClient, private storage: Storage, - private toastService: ToastService) { + private toastService: ToastService, + public locationService: LocationService, + public loadingService: LoadingService) { this.platform = new H.service.Platform({ 'apikey': 'tiVTgBnPbgV1spie5U2MSy-obhD9r2sGiOCbBzFY2_k' }); - - let watch = this.geolocation.watchPosition({ enableHighAccuracy: true, maximumAge: 10000 }); - watch.subscribe((position) => { - console.log(position.coords.latitude); - console.log(position.coords.longitude); - this.currentUserPosition.lat = position.coords.latitude; - this.currentUserPosition.lng = position.coords.longitude; - this.currentLocationMarker.setGeometry( {lat:position.coords.latitude, lng:position.coords.longitude}) - }, (errorObj) => { - console.log(errorObj.code + ": " + errorObj.message); - }); } ngOnInit() { } ngAfterViewInit() { - this.initializeMap(); window.addEventListener('resize', () => this.map.getViewPort().resize()); - setTimeout(() => { - window.dispatchEvent(new Event('resize')); - },100); - this.getUserLocation(); + } + + ionViewWillEnter() { + this.currentUserPosition.lat = this.locationService.currentUserPosition.lat; + this.currentUserPosition.lng = this.locationService.currentUserPosition.lng; + this.initializeMap(); + if (this.currentLocationMarker) { + this.currentLocationMarker.setGeometry({ lat: this.currentUserPosition.lat, lng: this.currentUserPosition.lng }) + } else { + this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); + } this.getBikesList(); + + this.locationService.liveLocationSubject.subscribe((position) => { + console.log('got location inside home subscription'); + this.currentUserPosition.lat = position.lat; + this.currentUserPosition.lng = position.lng; + if (this.currentLocationMarker) { + this.currentLocationMarker.setGeometry({ lat: this.currentUserPosition.lat, lng: this.currentUserPosition.lng }) + } else { + this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); + } + }); } initializeMap() { @@ -77,6 +87,7 @@ export class HomePage implements OnInit { this.mapElement.nativeElement, this.defaultLayers.raster.normal.map, { + center: { lat: this.locationService.preiousUserPosition.lat, lng: this.locationService.preiousUserPosition.lng }, zoom: 17, pixelRatio: window.devicePixelRatio || 1 } @@ -126,7 +137,7 @@ export class HomePage implements OnInit { }); // listen for map click event - this.map.addEventListener('tap', (event) =>{ + this.map.addEventListener('tap', (event) => { console.log(event.type, event.currentPointer.type); }); @@ -134,34 +145,22 @@ export class HomePage implements OnInit { } getBikesList() { - this.geolocation.getCurrentPosition({ - maximumAge: 1000, timeout: 4000, - enableHighAccuracy: true - }).then((resp) => { - let lat = resp.coords.latitude; - let lng = resp.coords.longitude; - - this.currentUserPosition.lat = resp.coords.latitude; - this.currentUserPosition.lng = resp.coords.longitude; - - this.storage.get('token').then((token) => { - let url = 'http://193.196.52.237:8081/bikes' + '?lat=' + lat + '&lng=' + lng; - const headers = new HttpHeaders().set("Authorization", "Bearer " + token); - this.bikeApi = this.httpClient.get(url, { headers }); - this.bikeApi.subscribe((resp) => { - console.log("bikes response", resp); - this.bikes = resp; - for (let i = 0; i < this.bikes.length; i++) { - this.bikes[i].distance = this.bikes[i].distance.toFixed(2);; - this.reverseGeocode(this.platform, this.bikes[i].lat, this.bikes[i].lon, i); - } - this.showBikesOnMap(); - }, (error) => console.log(error)); - }); - }, er => { - //alert('Can not retrieve location'); - }).catch((error) => { - //alert('Error getting location - ' + JSON.stringify(error)); + this.loadingService.showLoader(); + this.storage.get('token').then((token) => { + let url = 'http://193.196.52.237:8081/bikes' + '?lat=' + this.currentUserPosition.lat + '&lng=' + this.currentUserPosition.lng; + const headers = new HttpHeaders().set("Authorization", "Bearer " + token); + this.bikeApi = this.httpClient.get(url, { headers }); + this.bikeApi.subscribe((resp) => { + console.log("bikes response", resp); + this.bikes = resp; + for (let i = 0; i < this.bikes.length; i++) { + this.bikes[i].distance = this.bikes[i].distance.toFixed(2);; + this.reverseGeocode(this.platform, this.bikes[i].lat, this.bikes[i].lon, i); + } + this.showBikesOnMap(); + this.loadingService.hideLoader(); + }, (error) => {console.log(error) + this.loadingService.hideLoader();}); }); } @@ -181,7 +180,7 @@ export class HomePage implements OnInit { } } - this.map.addObject(this.locationsGroup); + //this.map.addObject(this.locationsGroup); this.setZoomLevelToPointersGroup(); } @@ -197,39 +196,19 @@ export class HomePage implements OnInit { }); } - getUserLocation() { - this.geolocation.getCurrentPosition( - { - maximumAge: 1000, timeout: 4000, - enableHighAccuracy: true - } - ).then((resp) => { - let lat = resp.coords.latitude; - let lng = resp.coords.longitude; - this.currentUserPosition.lat = resp.coords.latitude; - this.currentUserPosition.lng = resp.coords.longitude; - this.showUserLocationOnMap(lat, lng); - }, er => { - //alert('Can not retrieve Location') - this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); - }).catch((error) => { - this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); - //alert('Error getting location - ' + JSON.stringify(error)) - }); - } - showUserLocationOnMap(lat, lng) { let svgMarkup = '<svg width="24" height="24" ' + - 'xmlns="http://www.w3.org/2000/svg">' + - '<circle cx="10" cy="10" r="10" ' + + 'xmlns="http://www.w3.org/2000/svg">' + + '<circle cx="10" cy="10" r="10" ' + 'fill="#007cff" stroke="white" stroke-width="2" />' + - '</svg>'; + '</svg>'; let icon = new H.map.Icon(svgMarkup); //let icon = new H.map.Icon('../../../assets/images/current_location.png'); // Create a marker using the previously instantiated icon: this.currentLocationMarker = new H.map.Marker({ lat: lat, lng: lng }, { icon: icon }); // Add the marker to the map: this.locationsGroup.addObjects([this.currentLocationMarker]); + this.map.addObject(this.locationsGroup); this.setZoomLevelToPointersGroup(); //this.map.addObject(marker); @@ -281,6 +260,7 @@ export class HomePage implements OnInit { reserveBike() { //this.selectedBike=bikeS; + this.loadingService.showLoader(); this.storage.get('token').then((token) => { let url = 'http://193.196.52.237:8081/reservation' + '?bikeId=' + this.selectedBike.id; const headers = new HttpHeaders().set("Authorization", "Bearer " + token); @@ -290,11 +270,17 @@ export class HomePage implements OnInit { this.isBikeReserved = true; this.toastService.showToast("Reservation Successful!"); this.router.navigateByUrl('/myreservation'); + this.loadingService.hideLoader(); }, (error) => { - console.log(error) - this.toastService.showToast("Only one bike may be reserved or rented at a time") + console.log(error); + this.loadingService.hideLoader(); + this.toastService.showToast("Only one bike may be reserved or rented at a time"); }); }); } + ngOnDestroy(){ + this.locationService.liveLocationSubject.unsubscribe(); + } + } diff --git a/src/app/myreservation/myreservation.page.html b/src/app/myreservation/myreservation.page.html index 341a202a6357ecb6e2ba3cd924f9754ddf036445..dc8c4e3bec0ef53bf1923041f387c15044ed5ada 100644 --- a/src/app/myreservation/myreservation.page.html +++ b/src/app/myreservation/myreservation.page.html @@ -10,16 +10,21 @@ </ion-header> <ion-content> - <ion-card *ngIf="noReservation"> + <ion-card *ngIf="!isBikeReserved"> <ion-card-content> No reservation found </ion-card-content> </ion-card> - <div #mapElement style="width: 100%; height: 100%" id="mapContainer" *ngIf="!noReservation"></div> + <div #mapElement style="width: 100%; height: 100%" id="mapContainer" *ngIf="isBikeReserved"></div> + <ion-fab class="get-position" vertical="bottom" horizontal="end" (click)="getCurrentPosition()" slot="fixed"> + <ion-fab-button> + <ion-icon name="locate"></ion-icon> + </ion-fab-button> + </ion-fab> </ion-content> <ion-footer> - <div class="bike-details-container" *ngIf="!noReservation"> + <div class="bike-details-container" *ngIf="isBikeReserved"> <div class="inner"> <div class="button-container"> <ion-grid> diff --git a/src/app/myreservation/myreservation.page.ts b/src/app/myreservation/myreservation.page.ts index b0a6ec302bb10925d3d50e09dfac88bfe6c8e826..899d0539e80c1453432060836f553a338ecd5d5b 100644 --- a/src/app/myreservation/myreservation.page.ts +++ b/src/app/myreservation/myreservation.page.ts @@ -7,6 +7,8 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Storage } from '@ionic/storage'; import { ToastService } from '../services/toast.service'; import { Router } from '@angular/router'; +import { LocationService } from '../services/location.service'; +import { LoadingService } from '../services/loading.service'; declare var H: any; @@ -20,14 +22,18 @@ export class MyreservationPage implements OnInit { private map: any; // Get an instance of the routing service: private mapRouter: any; + private ui: any; + private defaultLayers: any; reservedBike: any = {}; bikeDetails: any = {}; isBikeHired = false; - address="sample"; - noReservation = true; + address = "sample"; + isBikeReserved = true; - private currentLocation = { lat: 0, lng: 0 }; + private currentUserPosition = { lat: 48.783480, lng: 9.180319 }; + + public currentLocationMarker: any; // Create the parameters for the routing request: private routingParameters = { @@ -50,7 +56,9 @@ export class MyreservationPage implements OnInit { public httpClient: HttpClient, private storage: Storage, private toastService: ToastService, - private router: Router) { + private router: Router, + public locationService: LocationService, + public loadingService: LoadingService) { this.platform = new H.service.Platform({ 'apikey': 'tiVTgBnPbgV1spie5U2MSy-obhD9r2sGiOCbBzFY2_k' }); @@ -58,14 +66,72 @@ export class MyreservationPage implements OnInit { } ngOnInit() { - this.getReservedBike(); + } ngAfterViewInit() { } + ionViewWillEnter() { + this.currentUserPosition.lat = this.locationService.currentUserPosition.lat; + this.currentUserPosition.lng = this.locationService.currentUserPosition.lng; + + this.loadmap(); + + if (this.currentLocationMarker) { + this.currentLocationMarker.setGeometry({ lat: this.currentUserPosition.lat, lng: this.currentUserPosition.lng }) + } else { + this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); + } + + this.getReservedBike(); + + this.locationService.liveLocationSubject.subscribe((position) => { + console.log('got location inside home subscription'); + this.currentUserPosition.lat = position.lat; + this.currentUserPosition.lng = position.lng; + if (this.currentLocationMarker) { + this.currentLocationMarker.setGeometry({ lat: this.currentUserPosition.lat, lng: this.currentUserPosition.lng }) + } else { + this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); + } + }); + } + + showUserLocationOnMap(lat, lng) { + let svgMarkup = '<svg width="24" height="24" ' + + 'xmlns="http://www.w3.org/2000/svg">' + + '<circle cx="10" cy="10" r="10" ' + + 'fill="#007cff" stroke="white" stroke-width="2" />' + + '</svg>'; + let icon = new H.map.Icon(svgMarkup); + //let icon = new H.map.Icon('../../../assets/images/current_location.png'); + // Create a marker using the previously instantiated icon: + this.currentLocationMarker = new H.map.Marker({ lat: lat, lng: lng }, { icon: icon }); + // Add the marker to the map: + this.map.addObject(this.currentLocationMarker); + + this.map.setCenter({ lat: lat, lng: lng }); + } + + addBikeOnMap() { + var img = ['../../../assets/images/100_percent.png', '../../../assets/images/75_percent.png', '../../../assets/images/50_percent.png', '../../../assets/images/25_percent.png', '../../../assets/images/0_percent.png']; + if (this.bikeDetails.batteryPercentage < 100 && this.bikeDetails.batteryPercentage >= 75) { + this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[0]); + } + else if (this.bikeDetails.batteryPercentage < 75 && this.bikeDetails.batteryPercentage >= 50) { + this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[1]); + } + else if (this.bikeDetails.batteryPercentage < 50 && this.bikeDetails.batteryPercentage >= 25) { + this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[2]); + } else if (this.bikeDetails.batteryPercentage < 25 && this.bikeDetails.batteryPercentage >= 0) { + this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[3]); + } + } + getReservedBike() { + this.loadingService.showLoader(); this.storage.get('token').then((token) => { const headers = new HttpHeaders().set("Authorization", "Bearer " + token); //call reserved bike api @@ -81,18 +147,32 @@ export class MyreservationPage implements OnInit { let bikeDetailsApi = this.httpClient.get(bikeDetailsUrl, { headers }); bikeDetailsApi.subscribe((resp: any) => { console.log('Bike Details', resp); + this.loadingService.hideLoader(); this.bikeDetails = resp.data; this.reverseGeocode(this.platform, this.bikeDetails.lat, this.bikeDetails.lon); - this.noReservation = false; - - // display map - setTimeout(() => { - this.loadmap(); - }, 1000); - window.addEventListener('resize', () => this.map.getViewPort().resize()); - }, (reservedBikeError) => console.log(reservedBikeError)); + this.isBikeReserved = true; + this.addBikeOnMap(); + + // set routing params + this.routingParameters.waypoint1 = 'geo!' + this.bikeDetails.lat + ',' + this.bikeDetails.lon; + this.routingParameters.waypoint0 = 'geo!' + this.currentUserPosition.lat + ',' + this.currentUserPosition.lng; + + // show route on map + this.mapRouter.calculateRoute(this.routingParameters, this.onResult.bind(this), + (error) => { + console.log(error.message); + }); + }, (reservedBikeError) => { + this.loadingService.hideLoader(); + console.log(reservedBikeError); + this.isBikeReserved = false; + }); } - }, (bikeDetailsError) => console.log(bikeDetailsError)); + }, (bikeDetailsError) => { + this.loadingService.hideLoader(); + console.log(bikeDetailsError) + this.isBikeReserved = false; + }); }); } @@ -110,88 +190,58 @@ export class MyreservationPage implements OnInit { } loadmap() { - var defaultLayers = this.platform.createDefaultLayers(); + this.defaultLayers = this.platform.createDefaultLayers(); this.map = new H.Map( this.mapElement.nativeElement, - defaultLayers.raster.normal.map, + this.defaultLayers.raster.normal.map, { + center: { lat: this.locationService.preiousUserPosition.lat, lng: this.locationService.preiousUserPosition.lng }, zoom: 17, pixelRatio: window.devicePixelRatio || 1 } ); var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(this.map)); - var ui = H.ui.UI.createDefault(this.map, defaultLayers); - ui.removeControl("mapsettings"); + this.ui = H.ui.UI.createDefault(this.map, this.defaultLayers); + this.ui.removeControl("mapsettings"); // create custom one - var ms = new H.ui.MapSettingsControl({ + var customMapSettings = new H.ui.MapSettingsControl({ baseLayers: [{ - label: "3D", layer: defaultLayers.vector.normal.map + label: "3D", layer: this.defaultLayers.vector.normal.map }, { - label: "Normal", layer: defaultLayers.raster.normal.map + label: "Normal", layer: this.defaultLayers.raster.normal.map }, { - label: "Satellite", layer: defaultLayers.raster.satellite.map + label: "Satellite", layer: this.defaultLayers.raster.satellite.map }, { - label: "Terrain", layer: defaultLayers.raster.terrain.map + label: "Terrain", layer: this.defaultLayers.raster.terrain.map } ], layers: [{ - label: "layer.traffic", layer: defaultLayers.vector.normal.traffic + label: "layer.traffic", layer: this.defaultLayers.vector.normal.traffic }, { - label: "layer.incidents", layer: defaultLayers.vector.normal.trafficincidents + label: "layer.incidents", layer: this.defaultLayers.vector.normal.trafficincidents } ] }); - ui.addControl("customized", ms); - var mapSettings = ui.getControl('customized'); - var zoom = ui.getControl('zoom'); + this.ui.addControl("custom-mapsettings", customMapSettings); + var mapSettings = this.ui.getControl('custom-mapsettings'); + var zoom = this.ui.getControl('zoom'); mapSettings.setAlignment('top-right'); - zoom.setAlignment('left-top'); + zoom.setAlignment('right-top'); - //get user location - this.getLocation(this.map); + this.map.getViewPort().setPadding(30, 30, 30, 30); - var img = ['../../../assets/images/100_percent.png', '../../../assets/images/75_percent.png', '../../../assets/images/50_percent.png', '../../../assets/images/25_percent.png', '../../../assets/images/0_percent.png']; - if (this.bikeDetails.batteryPercentage < 100 && this.bikeDetails.batteryPercentage >= 75) { - this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[0]); - } - else if (this.bikeDetails.batteryPercentage < 75 && this.bikeDetails.batteryPercentage >= 50) { - this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[1]); - } - else if (this.bikeDetails.batteryPercentage < 50 && this.bikeDetails.batteryPercentage >= 25) { - this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[2]); - } else if (this.bikeDetails.batteryPercentage < 25 && this.bikeDetails.batteryPercentage >= 0) { - this.addMarker(Number(this.bikeDetails.lat), Number(this.bikeDetails.lon), img[3]); - } + this.map.getViewPort().setPadding(30, 30, 30, 30); } - getLocation(map) { - this.geolocation.getCurrentPosition( - { - maximumAge: 1000, timeout: 5000, - enableHighAccuracy: true - } - ).then((resp) => { - let lat = resp.coords.latitude - let lng = resp.coords.longitude - this.currentLocation.lat = resp.coords.latitude; - this.currentLocation.lng = resp.coords.longitude; - this.moveMapToGiven(map, lat, lng); - // set routing params - this.routingParameters.waypoint1 = 'geo!' + this.bikeDetails.lat + ',' + this.bikeDetails.lon; - this.routingParameters.waypoint0 = 'geo!' + this.currentLocation.lat + ',' + this.currentLocation.lng; - - // show route on map - this.mapRouter.calculateRoute(this.routingParameters, this.onResult.bind(this), - (error) => { - alert(error.message); - }); - }, er => { - console.log('Can not retrieve Location'); - }).catch((error) => { - console.log('Error getting location - ' + JSON.stringify(error)); - }); + //TODO change this logic + getCurrentPosition() { + if (!this.currentLocationMarker) { + this.showUserLocationOnMap(this.currentUserPosition.lat, this.currentUserPosition.lng); + } + this.map.setZoom(17); + this.map.setCenter({ lat: this.currentUserPosition.lat, lng: this.currentUserPosition.lng }); } moveMapToGiven(map, lat, lng) { @@ -225,9 +275,9 @@ export class MyreservationPage implements OnInit { var streets = result.Response.View[0].Result[0].Location.Address.Street; var houseNumber = result.Response.View[0].Result[0].Location.Address.HouseNumber; var zipcode = result.Response.View[0].Result[0].Location.Address.PostalCode; - + this.address = streets; - + }, (error) => { alert(error);