diff --git a/src/app/404/404.component.html b/src/app/404/404.component.html
deleted file mode 100644
index ffa6f66..0000000
--- a/src/app/404/404.component.html
+++ /dev/null
@@ -1 +0,0 @@
-
404
diff --git a/src/app/404/404.component.ts b/src/app/404/404.component.ts
deleted file mode 100644
index f7e6dd3..0000000
--- a/src/app/404/404.component.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import {Component} from "@angular/core";
-
-@Component({
- selector: 'not-found',
- templateUrl: '404.component.html'
-})
-export class NotFoundComponent {
-
-}
diff --git a/src/app/geolocation/geolocation.service.ts b/src/app/geolocation/geolocation.service.ts
deleted file mode 100644
index 2edbd8c..0000000
--- a/src/app/geolocation/geolocation.service.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import {Injectable, OnDestroy} from '@angular/core';
-import {BehaviorSubject} from "rxjs";
-import {MatSnackBar} from "@angular/material";
-
-@Injectable({
- providedIn: 'root'
-})
-export class GeolocationService implements OnDestroy {
- private readonly watchRegistrationID;
- private orientation: DeviceOrientationEvent;
-
- location = new BehaviorSubject(null);
-
- constructor(snackBar: MatSnackBar) {
- window.addEventListener('deviceorientation', (orientation) => this.orientation = orientation, true);
-
- if(navigator.geolocation) {
- this.watchRegistrationID = navigator.geolocation.watchPosition(pos => {
- this.location.next({
- accuracy: pos.coords.accuracy,
- altitude: pos.coords.altitude,
- altitudeAccuracy: pos.coords.altitudeAccuracy,
- heading: pos.coords.heading || this.orientation.alpha,
- latitude: pos.coords.latitude,
- longitude: pos.coords.longitude,
- speed: pos.coords.speed
- });
- }, (error) => {
- switch(error.code) {
- case error.PERMISSION_DENIED:
- snackBar.open('Geolocation permission denied', null, {duration: 3000, horizontalPosition: 'right', panelClass: ['bg-warning', 'text-white']});
- break;
- case error.POSITION_UNAVAILABLE:
- snackBar.open('Geolocation unavailable', null, {duration: 3000, horizontalPosition: 'right', panelClass: ['bg-warning', 'text-white']});
- break;
- case error.TIMEOUT:
- snackBar.open('Geolocation timeout', null, {duration: 3000, horizontalPosition: 'right', panelClass: ['bg-warning', 'text-white']});
- break;
- default:
- snackBar.open('Geolocation experienced an unknown error', null, {duration: 3000, horizontalPosition: 'right', panelClass: ['bg-warning', 'text-white']});
- }
- }, {enableHighAccuracy: true});
- } else {
- snackBar.open('Geolocation is not supported', null, {duration: 3000, horizontalPosition: 'right', panelClass: ['bg-warning', 'text-white']});
- }
- }
-
- ngOnDestroy() {
- if(this.watchRegistrationID) navigator.geolocation.clearWatch(this.watchRegistrationID);
- }
-}
diff --git a/src/app/map/map.component.html b/src/app/map/map.component.html
index a2f1176..aee5c09 100644
--- a/src/app/map/map.component.html
+++ b/src/app/map/map.component.html
@@ -32,7 +32,7 @@
Heading:
No Heading
- {{position.heading | number : '0.0'}}°
+ {{position.heading | number : '0.0-0'}}°
Latitude: {{position.latitude | number : '0.0-5'}}
@@ -40,11 +40,11 @@
Altitude:
No Altitude
- {{position.altitude | number : '0.0'}} m
+ {{position.altitude | number : '0.0-0'}} m
Speed:
No Speed
- {{position.speed * 60 * 60 / 1000 | number : '1.1'}} km/h
+ {{position.speed * 60 * 60 / 1000 | number : '1.0-1'}} km/h
diff --git a/src/app/map/map.component.ts b/src/app/map/map.component.ts
index 3348c22..a7d10a0 100644
--- a/src/app/map/map.component.ts
+++ b/src/app/map/map.component.ts
@@ -1,5 +1,5 @@
import {Component} from "@angular/core";
-import {GeolocationService} from "../geolocation/geolocation.service";
+import {PhysicsService} from "../physics/physics.service";
import {filter} from "rxjs/operators";
import {version} from "../../../package.json";
import {BreakpointObserver, Breakpoints} from "@angular/cdk/layout";
@@ -22,9 +22,9 @@ export class MapComponent {
style: 'satellite' | 'terrain' | 'roadmap' | 'hybrid' = 'terrain';
version = version;
- constructor(bpObserver: BreakpointObserver, geolocation: GeolocationService) {
+ constructor(bpObserver: BreakpointObserver, physicsService: PhysicsService) {
bpObserver.observe([Breakpoints.Handset]).subscribe(results => this.mobile = results.matches);
- geolocation.location.pipe(filter(coord => !!coord)).subscribe(pos => {
+ physicsService.info.pipe(filter(coord => !!coord)).subscribe(pos => {
if(this.mapApi) {
console.log(pos);
if(!this.position) this.center(pos);
diff --git a/src/app/physics/physics.service.ts b/src/app/physics/physics.service.ts
new file mode 100644
index 0000000..ae5b37f
--- /dev/null
+++ b/src/app/physics/physics.service.ts
@@ -0,0 +1,49 @@
+import {Injectable} from '@angular/core';
+import {BehaviorSubject, combineLatest} from "rxjs";
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PhysicsService {
+ private motionTimestamp;
+
+ info = new BehaviorSubject(null);
+ motion = new BehaviorSubject(null);
+ speed = new BehaviorSubject(null);
+ orientation = new BehaviorSubject(null);
+ position = new BehaviorSubject(null);
+
+ constructor() {
+ // Gather physical data
+ window.addEventListener('deviceorientation', orientation => this.orientation.next(orientation));
+ window.addEventListener('devicemotion', motion => this.motion.next(motion));
+ navigator.geolocation.watchPosition(pos => this.position.next(pos.coords));
+
+ // Calculate speed from motion events
+ this.motion.subscribe(event => {
+ if (!this.motionTimestamp) return this.motionTimestamp = new Date().getTime();
+
+ let currentTime = new Date().getTime();
+ let {speedX, speedY, speedZ} = this.speed.value;
+ this.speed.next({
+ speedX: speedX + event.acceleration.x / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600,
+ speedY: speedY + event.acceleration.y / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600,
+ speedZ: speedZ + event.acceleration.z / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600
+ });
+ this.motionTimestamp = currentTime;
+ });
+
+ // Combine data into one nice package
+ combineLatest(this.position, this.orientation, this.speed).subscribe(data => {
+ this.info.next({
+ accuracy: data[0].accuracy,
+ altitude: data[0].altitude,
+ altitudeAccuracy: data[0].altitudeAccuracy,
+ heading: data[0].heading || data[1].alpha,
+ latitude: data[0].latitude,
+ longitude: data[0].longitude,
+ speed: data[0].speed || Math.sqrt(data[2].x**2 + data[2].y**2 + data[2].z**2),
+ });
+ })
+ }
+}