Everything but user location & drawings are saving
This commit is contained in:
@ -1,17 +1,18 @@
|
||||
import {Component, OnInit} from "@angular/core";
|
||||
import {Component, isDevMode, OnInit} from "@angular/core";
|
||||
import {PhysicsService} from "../../services/physics.service";
|
||||
import {filter, skip, take} from "rxjs/operators";
|
||||
import {filter, finalize, skip, take} from "rxjs/operators";
|
||||
import {MatBottomSheet, MatSnackBar} from "@angular/material";
|
||||
import {CalibrateComponent} from "../../components/calibrate/calibrate.component";
|
||||
import {ToolbarItem} from "../../models/toolbarItem";
|
||||
import {flyInRight, flyOutRight} from "../../animations";
|
||||
import {ARROW, MapLayers, MapService, MEASURE, WeatherLayers} from "../../services/map.service";
|
||||
import {MapLayers, MapService, WeatherLayers} from "../../services/map.service";
|
||||
import {Subscription} from "rxjs";
|
||||
import {MatBottomSheetRef} from "@angular/material/bottom-sheet";
|
||||
import {copyToClipboard} from "../../utils";
|
||||
import {ActivatedRoute} from "@angular/router";
|
||||
import {DimensionsDialogComponent} from "../../components/dimensionsDialog/dimensionsDialog.component";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {SyncService} from "../../services/sync.service";
|
||||
import {MapData, Marker} from "../../models/mapSymbol";
|
||||
|
||||
declare const L;
|
||||
|
||||
@ -22,7 +23,6 @@ declare const L;
|
||||
animations: [flyInRight, flyOutRight]
|
||||
})
|
||||
export class MapComponent implements OnInit {
|
||||
calibration: MatBottomSheetRef;
|
||||
code: string;
|
||||
drawColor = '#ff4141';
|
||||
isNaN = isNaN;
|
||||
@ -31,17 +31,78 @@ export class MapComponent implements OnInit {
|
||||
positionMarker = {arrow: null, circle: null};
|
||||
shareDialog = false;
|
||||
showPalette = false;
|
||||
lastMeasuringPoint;
|
||||
measuringSubscription: Subscription;
|
||||
sub: Subscription;
|
||||
|
||||
startCalibrating = () => {
|
||||
let calibration = this.bottomSheet.open(CalibrateComponent, {hasBackdrop: false, disableClose: true});
|
||||
this.sub = calibration.afterDismissed().pipe(finalize(() => calibration.dismiss())).subscribe();
|
||||
};
|
||||
|
||||
startCircle = menuItem => {
|
||||
this.sub = this.map.click.pipe(skip(1), take(1)).subscribe(async e => {
|
||||
let dimensions = await this.dialog.open(DimensionsDialogComponent, {data: ['Radius (m)'], disableClose: true, panelClass: 'pb-0'}).afterClosed().toPromise();
|
||||
menuItem.enabled = false;
|
||||
let circle = {latlng: e.latlng, radius: dimensions[0] || 500, color: '#ff4141'};
|
||||
this.syncService.addCircle(circle);
|
||||
});
|
||||
};
|
||||
|
||||
startDelete = () => {
|
||||
this.sub = this.map.click.pipe(skip(1), filter(e => !!e.symbol)).subscribe(e => {
|
||||
if(!!e.symbol && e.symbol.noDelete) return;
|
||||
this.syncService.delete(e.symbol)
|
||||
});
|
||||
};
|
||||
|
||||
startMarker = menuItem => {
|
||||
this.sub = this.map.click.pipe(skip(1), take(1)).subscribe(e => {
|
||||
menuItem.enabled = false;
|
||||
let marker: Marker = {latlng: e.latlng, color: '#ff4141'};
|
||||
this.syncService.addMarker(marker);
|
||||
});
|
||||
};
|
||||
|
||||
startMeasuring = menuItem => {
|
||||
let lastPoint;
|
||||
this.sub = this.map.click.pipe(skip(1), take(2), finalize(() => this.map.delete(lastPoint))).subscribe(e => {
|
||||
if(lastPoint) {
|
||||
menuItem.enabled = false;
|
||||
let measurement = {latlng: {lat: lastPoint.getLatLng().lat, lng: lastPoint.getLatLng().lng}, latlng2: e.latlng, color: '#ff4141', weight: 8};
|
||||
this.syncService.addMeasurement(measurement);
|
||||
return this.map.delete(lastPoint);
|
||||
}
|
||||
lastPoint = this.map.newMarker({latlng: e.latlng, color: '#ff4141'});
|
||||
})
|
||||
};
|
||||
|
||||
startRectangle = menuItem => {
|
||||
let lastPoint;
|
||||
this.sub = this.map.click.pipe(skip(1), take(2), finalize(() => this.map.delete(lastPoint))).subscribe(e => {
|
||||
if(lastPoint) {
|
||||
menuItem.enabled = false;
|
||||
let rect = {latlng: {lat: lastPoint.getLatLng().lat, lng: lastPoint.getLatLng().lng}, latlng2: e.latlng, color: '#ff4141'};
|
||||
this.syncService.addRectangle(rect);
|
||||
return this.map.delete(lastPoint);
|
||||
}
|
||||
lastPoint = this.map.newMarker({latlng: e.latlng, color: '#ff4141'});
|
||||
})
|
||||
};
|
||||
|
||||
unsub = () => {
|
||||
if(this.sub) {
|
||||
this.sub.unsubscribe();
|
||||
this.sub = null;
|
||||
}
|
||||
};
|
||||
|
||||
menu: ToolbarItem[] = [
|
||||
{name: 'Marker', icon: 'room', toggle: true, click: () => this.addMarker()},
|
||||
{name: 'Marker', icon: 'room', toggle: true, onEnabled: this.startMarker, onDisabled: this.unsub},
|
||||
{name: 'Draw', icon: 'create', toggle: true, onEnabled: () => this.startDrawing(), onDisabled: () => this.stopDrawing()},
|
||||
{name: 'Circle', icon: 'panorama_fish_eye', toggle: true, click: () => this.addCircle()},
|
||||
{name: 'Square', icon: 'crop_square', toggle: true, click: () => this.addRectangle()},
|
||||
{name: 'Circle', icon: 'panorama_fish_eye', toggle: true, onEnabled: this.startCircle, onDisabled: this.unsub},
|
||||
{name: 'Square', icon: 'crop_square', toggle: true, onEnabled: this.startRectangle, onDisabled: this.unsub},
|
||||
{name: 'Polygon', icon: 'details', toggle: true},
|
||||
{name: 'Measure', icon: 'straighten', toggle: true, onEnabled: () => this.startMeasuring(), onDisabled: () => this.stopMeasuring()},
|
||||
{name: 'Delete', icon: 'delete', toggle: true},
|
||||
{name: 'Measure', icon: 'straighten', toggle: true, onEnabled: this.startMeasuring, onDisabled: () => this.unsub},
|
||||
{name: 'Delete', icon: 'delete', toggle: true, onEnabled: this.startDelete, onDisabled: this.unsub},
|
||||
{name: 'Map Style', icon: 'terrain', subMenu: [
|
||||
{name: 'ESRI:Topographic', toggle: true, click: () => this.map.setMapLayer(MapLayers.ESRI_TOPOGRAPHIC)},
|
||||
{name: 'ESRI:Satellite', toggle: true, click: () => this.map.setMapLayer(MapLayers.ESRI_IMAGERY)},
|
||||
@ -54,33 +115,40 @@ export class MapComponent implements OnInit {
|
||||
{name: 'Sea Level Pressure', toggle: true, click: () => this.map.setWeatherLayer(WeatherLayers.SEA_LEVEL_PRESSURE)},
|
||||
{name: 'Clouds', toggle: true, click: () => this.map.setWeatherLayer(WeatherLayers.CLOUDS_NEW)},
|
||||
]},
|
||||
{name: 'Calibrate', icon: 'explore', toggle: true, onEnabled: () => this.startCalibrating(), onDisabled: () => this.stopCalibrating()},
|
||||
{name: 'Calibrate', icon: 'explore', toggle: true, onEnabled: this.startCalibrating, onDisabled: this.unsub},
|
||||
{name: 'Share', icon: 'share', toggle: true, onEnabled: () => this.share(), onDisabled: () => this.shareDialog = false},
|
||||
{name: 'Messages', icon: 'chat', hidden: true},
|
||||
{name: 'Identity', icon: 'perm_identity', hidden: true},
|
||||
{name: 'Settings', icon: 'settings', hidden: true}
|
||||
{name: 'Settings', icon: 'settings', hidden: true},
|
||||
{name: 'delete all', icon: 'cancel', click: () => this.map.deleteAll(), hidden: !isDevMode()}
|
||||
];
|
||||
|
||||
constructor(public physicsService: PhysicsService, private snackBar: MatSnackBar, private bottomSheet: MatBottomSheet, private dialog: MatDialog, private route: ActivatedRoute) {
|
||||
constructor(public physicsService: PhysicsService, private syncService: SyncService, private snackBar: MatSnackBar, private bottomSheet: MatBottomSheet, private dialog: MatDialog, private route: ActivatedRoute) {
|
||||
this.route.params.subscribe(params => {
|
||||
this.code = params['code'];
|
||||
this.syncService.load(this.code);
|
||||
|
||||
// Handle drawing the map after updates
|
||||
this.syncService.mapSymbols.pipe(filter(s => !!s)).subscribe((map: MapData) => {
|
||||
this.map.deleteAll();
|
||||
if(map.circles) map.circles.forEach(c => this.map.newCircle(c));
|
||||
if(map.markers) map.markers.forEach(m => this.map.newMarker(m));
|
||||
if(map.measurements) map.measurements.forEach(m => this.map.newMeasurement(m));
|
||||
if(map.rectangles) map.rectangles.forEach(r => this.map.newRectangle(r));
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.map = new MapService('map');
|
||||
|
||||
// Handle click actions
|
||||
this.map.click.pipe(filter(e => !!e && e.symbol)).subscribe(e => {
|
||||
let symbol = e.symbol.symbol;
|
||||
if(this.menu[6].enabled) {
|
||||
if(!!symbol && symbol.noDelete) return;
|
||||
return this.map.delete(e.symbol);
|
||||
} else if(e.symbol instanceof L.Marker) {
|
||||
if(symbol.noSelect) return;
|
||||
// Handle opening symbols
|
||||
this.map.click.pipe(filter(e => !!e && e.item)).subscribe(e => {
|
||||
if(e.item instanceof L.Marker) {
|
||||
if(e.symbol.noSelect) return;
|
||||
/*this.bottomSheet.open(MarkerComponent, {data: e.symbol, hasBackdrop: false, disableClose: true});*/
|
||||
} else if(e.symbol instanceof L.Circle) {
|
||||
if(symbol.noSelect) return;
|
||||
} else if(e.item instanceof L.Circle) {
|
||||
if(e.symbol.noSelect) return;
|
||||
/*this.bottomSheet.open(CircleComponent, {data: e.symbol, hasBackdrop: false, disableClose: true}).afterDismissed().subscribe(c => {
|
||||
let circle = c['_symbol'];
|
||||
this.map.delete(c);
|
||||
@ -89,52 +157,23 @@ export class MapComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
|
||||
// Display location
|
||||
this.physicsService.info.pipe(filter(coord => !!coord)).subscribe(pos => {
|
||||
if(!this.position) this.center({lat: pos.latitude, lng: pos.longitude});
|
||||
if(this.positionMarker.arrow) this.map.delete(this.positionMarker.arrow);
|
||||
if(this.positionMarker.circle) this.map.delete(this.positionMarker.circle);
|
||||
this.positionMarker.arrow = this.map.newMarker({latlng: {lat: pos.latitude, lng: pos.longitude}, noSelect: true, noDelete: true, icon: ARROW, rotationAngle: pos.heading, rotationOrigin: 'center'});
|
||||
this.positionMarker.circle = this.map.newCircle({latlng: {lat: pos.latitude, lng: pos.longitude}, color: '#2873d8', radius: pos.accuracy, interactive: false});
|
||||
this.positionMarker.arrow = this.map.newMarker({latlng: {lat: pos.latitude, lng: pos.longitude}, noSelect: true, noDelete: true, icon: 'arrow', rotationAngle: pos.heading, rotationOrigin: 'center'});
|
||||
this.positionMarker.circle = this.map.newCircle({latlng: {lat: pos.latitude, lng: pos.longitude}, color: '#2873d8', noSelect: true, noDelete: true, radius: pos.accuracy, interactive: false});
|
||||
this.position = pos;
|
||||
});
|
||||
|
||||
// Calibration popup
|
||||
this.physicsService.requireCalibration.subscribe(() => {
|
||||
this.snackBar.open('Compass requires calibration', 'calibrate', {
|
||||
duration: 5000,
|
||||
panelClass: 'bg-warning,text-white'
|
||||
}).onAction().subscribe(() => this.startCalibrating());
|
||||
this.snackBar.open('Compass requires calibration', 'calibrate', {duration: 5000, panelClass: 'bg-warning,text-white'})
|
||||
.onAction().subscribe(() => this.startCalibrating());
|
||||
});
|
||||
}
|
||||
|
||||
addCircle() {
|
||||
this.map.click.pipe(skip(1), take(1), filter(() => this.menu[2].enabled)).subscribe(async e => {
|
||||
let dimensions = await this.dialog.open(DimensionsDialogComponent, {data: ['Radius (m)'], disableClose: true, panelClass: 'pb-0'}).afterClosed().toPromise();
|
||||
this.menu[2].enabled = false;
|
||||
this.map.newCircle({latlng: e.event.latlng, radius: dimensions[0]});
|
||||
});
|
||||
}
|
||||
|
||||
addMarker() {
|
||||
this.map.click.pipe(skip(1), take(1), filter(() => this.menu[0].enabled)).subscribe(e => {
|
||||
this.menu[0].enabled = false;
|
||||
this.map.newMarker({latlng: e.event.latlng});
|
||||
});
|
||||
}
|
||||
|
||||
addRectangle() {
|
||||
let lastPoint;
|
||||
this.map.click.pipe(skip(1), take(2)).subscribe(e => {
|
||||
if(lastPoint) {
|
||||
this.menu[3].enabled = false;
|
||||
console.log({latlng: lastPoint.getLatLng(), latlng2: e.event.latlng});
|
||||
this.map.newRectangle({latlng: lastPoint.getLatLng(), latlng2: e.event.latlng});
|
||||
this.map.delete(lastPoint);
|
||||
return;
|
||||
}
|
||||
lastPoint = this.map.newMarker({latlng: e.event.latlng});
|
||||
})
|
||||
}
|
||||
|
||||
center(pos?) {
|
||||
if(!pos) pos = {lat: this.position.latitude, lng: this.position.longitude};
|
||||
this.map.centerOn(pos);
|
||||
@ -156,50 +195,13 @@ export class MapComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
startCalibrating() {
|
||||
this.menu[9].enabled = true;
|
||||
this.calibration = this.bottomSheet.open(CalibrateComponent, {
|
||||
hasBackdrop: false,
|
||||
disableClose: true
|
||||
});
|
||||
this.calibration.afterDismissed().subscribe(() => {
|
||||
this.menu[9].enabled = false;
|
||||
this.calibration = null;
|
||||
});
|
||||
}
|
||||
|
||||
startDrawing() {
|
||||
this.showPalette = true;
|
||||
this.map.startDrawing();
|
||||
}
|
||||
|
||||
startMeasuring() {
|
||||
this.measuringSubscription = this.map.click.pipe(skip(1)).subscribe(e => {
|
||||
if(this.lastMeasuringPoint) {
|
||||
this.map.newMeasurement({latlng: this.lastMeasuringPoint.getLatLng(), latlng2: e.event.latlng});
|
||||
this.map.delete(this.lastMeasuringPoint);
|
||||
}
|
||||
this.lastMeasuringPoint = this.map.newMarker({latlng: e.event.latlng, icon: MEASURE});
|
||||
})
|
||||
}
|
||||
|
||||
stopCalibrating() {
|
||||
if(this.calibration) this.calibration.dismiss();
|
||||
}
|
||||
|
||||
stopDrawing() {
|
||||
this.showPalette = false;
|
||||
this.map.stopDrawing()
|
||||
}
|
||||
|
||||
stopMeasuring() {
|
||||
if(this.measuringSubscription) {
|
||||
this.measuringSubscription.unsubscribe();
|
||||
this.measuringSubscription = null;
|
||||
}
|
||||
if(this.lastMeasuringPoint) {
|
||||
this.map.delete(this.lastMeasuringPoint);
|
||||
this.lastMeasuringPoint = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user