Using a bunch of device information to fill gps data holes
This commit is contained in:
parent
041d6aed07
commit
c546e0e064
@ -1 +0,0 @@
|
|||||||
<h1>404</h1>
|
|
@ -1,9 +0,0 @@
|
|||||||
import {Component} from "@angular/core";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'not-found',
|
|
||||||
templateUrl: '404.component.html'
|
|
||||||
})
|
|
||||||
export class NotFoundComponent {
|
|
||||||
|
|
||||||
}
|
|
@ -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<any>(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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -32,7 +32,7 @@
|
|||||||
<div *ngIf="position" class="text-white">
|
<div *ngIf="position" class="text-white">
|
||||||
Heading:
|
Heading:
|
||||||
<span *ngIf="!position.heading" class="text-danger">No Heading</span>
|
<span *ngIf="!position.heading" class="text-danger">No Heading</span>
|
||||||
<span *ngIf="position.heading">{{position.heading | number : '0.0'}}°</span>
|
<span *ngIf="position.heading">{{position.heading | number : '0.0-0'}}°</span>
|
||||||
<br>
|
<br>
|
||||||
Latitude: {{position.latitude | number : '0.0-5'}}
|
Latitude: {{position.latitude | number : '0.0-5'}}
|
||||||
<br>
|
<br>
|
||||||
@ -40,11 +40,11 @@
|
|||||||
<br>
|
<br>
|
||||||
Altitude:
|
Altitude:
|
||||||
<span *ngIf="!position.altitude" class="text-danger">No Altitude</span>
|
<span *ngIf="!position.altitude" class="text-danger">No Altitude</span>
|
||||||
<span *ngIf="position.altitude">{{position.altitude | number : '0.0'}} m</span>
|
<span *ngIf="position.altitude">{{position.altitude | number : '0.0-0'}} m</span>
|
||||||
<br>
|
<br>
|
||||||
Speed:
|
Speed:
|
||||||
<span *ngIf="!position.speed" class="text-danger">No Speed</span>
|
<span *ngIf="!position.speed" class="text-danger">No Speed</span>
|
||||||
<span *ngIf="position.speed">{{position.speed * 60 * 60 / 1000 | number : '1.1'}} km/h</span>
|
<span *ngIf="position.speed">{{position.speed * 60 * 60 / 1000 | number : '1.0-1'}} km/h</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button mat-fab class="gps" (click)="center()"><mat-icon>gps_fixed</mat-icon></button>
|
<button mat-fab class="gps" (click)="center()"><mat-icon>gps_fixed</mat-icon></button>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {Component} from "@angular/core";
|
import {Component} from "@angular/core";
|
||||||
import {GeolocationService} from "../geolocation/geolocation.service";
|
import {PhysicsService} from "../physics/physics.service";
|
||||||
import {filter} from "rxjs/operators";
|
import {filter} from "rxjs/operators";
|
||||||
import {version} from "../../../package.json";
|
import {version} from "../../../package.json";
|
||||||
import {BreakpointObserver, Breakpoints} from "@angular/cdk/layout";
|
import {BreakpointObserver, Breakpoints} from "@angular/cdk/layout";
|
||||||
@ -22,9 +22,9 @@ export class MapComponent {
|
|||||||
style: 'satellite' | 'terrain' | 'roadmap' | 'hybrid' = 'terrain';
|
style: 'satellite' | 'terrain' | 'roadmap' | 'hybrid' = 'terrain';
|
||||||
version = version;
|
version = version;
|
||||||
|
|
||||||
constructor(bpObserver: BreakpointObserver, geolocation: GeolocationService) {
|
constructor(bpObserver: BreakpointObserver, physicsService: PhysicsService) {
|
||||||
bpObserver.observe([Breakpoints.Handset]).subscribe(results => this.mobile = results.matches);
|
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) {
|
if(this.mapApi) {
|
||||||
console.log(pos);
|
console.log(pos);
|
||||||
if(!this.position) this.center(pos);
|
if(!this.position) this.center(pos);
|
||||||
|
49
src/app/physics/physics.service.ts
Normal file
49
src/app/physics/physics.service.ts
Normal file
@ -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<DeviceMotionEvent>(null);
|
||||||
|
speed = new BehaviorSubject(null);
|
||||||
|
orientation = new BehaviorSubject<DeviceOrientationEvent>(null);
|
||||||
|
position = new BehaviorSubject<Coordinates>(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),
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user