small refactors
This commit is contained in:
		@@ -12,8 +12,6 @@ export const MAP_COLLECTION = 'Maps';
 | 
				
			|||||||
    providedIn: 'root'
 | 
					    providedIn: 'root'
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class SyncService {
 | 
					export class SyncService {
 | 
				
			||||||
    private
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private location;
 | 
					    private location;
 | 
				
			||||||
    private locationChanged = false;
 | 
					    private locationChanged = false;
 | 
				
			||||||
    private locationDoc: AngularFirestoreDocument;
 | 
					    private locationDoc: AngularFirestoreDocument;
 | 
				
			||||||
@@ -72,20 +70,15 @@ export class SyncService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    delete(...symbols) {
 | 
					    delete(...symbols) {
 | 
				
			||||||
        let map = this.mapData.value;
 | 
					        let map = this.mapData.value;
 | 
				
			||||||
        symbols.forEach(s => {
 | 
					        Object.keys(map).filter(key => Array.isArray(map[key])).forEach(key => {
 | 
				
			||||||
            if(map.circles) map.circles = map.circles.filter(r => !_.isEqual(s, r));
 | 
					            symbols.forEach(s => map[key] = map[key].filter(ss => !_.isEqual(s, ss)))
 | 
				
			||||||
            if(map.markers) map.markers = map.markers.filter(r => !_.isEqual(s, r));
 | 
					 | 
				
			||||||
            if(map.measurements) map.measurements = map.measurements.filter(r => !_.isEqual(s, r));
 | 
					 | 
				
			||||||
            if(map.polygons) map.polygons = map.polygons.filter(r => !_.isEqual(s, r));
 | 
					 | 
				
			||||||
            if(map.polylines) map.polylines = map.polylines.filter(r => !_.isEqual(s, r));
 | 
					 | 
				
			||||||
            if(map.rectangles) map.rectangles = map.rectangles.filter(r => !_.isEqual(s, r));
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        this.mapData.next(map);
 | 
					        this.mapData.next(map);
 | 
				
			||||||
        this.mapChanged = true;
 | 
					        this.mapChanged = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    load(mapCode: string, username: string) {
 | 
					    load(mapCode: string, username: string) {
 | 
				
			||||||
        this.unload();
 | 
					        let ignore = this.unload();
 | 
				
			||||||
        this.mapDoc = this.db.collection(MAP_COLLECTION).doc(mapCode);
 | 
					        this.mapDoc = this.db.collection(MAP_COLLECTION).doc(mapCode);
 | 
				
			||||||
        this.locationDoc = this.mapDoc.collection(LOCATION_COLLECTION).doc(username);
 | 
					        this.locationDoc = this.mapDoc.collection(LOCATION_COLLECTION).doc(username);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -121,11 +114,6 @@ export class SyncService {
 | 
				
			|||||||
        return map;
 | 
					        return map;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    removeMyLocation() {
 | 
					 | 
				
			||||||
        this.location = null;
 | 
					 | 
				
			||||||
        return this.locationDoc.delete();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    save(locationOnly?) {
 | 
					    save(locationOnly?) {
 | 
				
			||||||
        if(this.locationDoc && this.locationChanged) {
 | 
					        if(this.locationDoc && this.locationChanged) {
 | 
				
			||||||
            let ignore = this.locationDoc.set(this.location);
 | 
					            let ignore = this.locationDoc.set(this.location);
 | 
				
			||||||
@@ -155,8 +143,8 @@ export class SyncService {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(this.locationDoc) {
 | 
					        if(this.locationDoc) {
 | 
				
			||||||
 | 
					            this.location = null;
 | 
				
			||||||
            this.locationChanged = false;
 | 
					            this.locationChanged = false;
 | 
				
			||||||
            await this.removeMyLocation();
 | 
					 | 
				
			||||||
            this.locationDoc = null;
 | 
					            this.locationDoc = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,8 +16,6 @@ import {MapData, Marker} from "../../models/mapSymbol";
 | 
				
			|||||||
import {Adjectives} from "../../adjectives";
 | 
					import {Adjectives} from "../../adjectives";
 | 
				
			||||||
import {Nouns} from "../../nounes";
 | 
					import {Nouns} from "../../nounes";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
declare const L;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
    selector: 'map',
 | 
					    selector: 'map',
 | 
				
			||||||
    templateUrl: 'map.component.html',
 | 
					    templateUrl: 'map.component.html',
 | 
				
			||||||
@@ -37,6 +35,110 @@ export class MapComponent implements OnDestroy, OnInit {
 | 
				
			|||||||
    showPalette = false;
 | 
					    showPalette = false;
 | 
				
			||||||
    sub: Subscription;
 | 
					    sub: Subscription;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    menu: ToolbarItem[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(public physicsService: PhysicsService, private syncService: SyncService, private snackBar: MatSnackBar, private bottomSheet: MatBottomSheet, private dialog: MatDialog, private route: ActivatedRoute) {
 | 
				
			||||||
 | 
					        this.name = Adjectives[Math.floor(Math.random() * Adjectives.length)] + ' ' + Nouns[Math.floor(Math.random() * Nouns.length)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.menu = [
 | 
				
			||||||
 | 
					            {name: 'Marker', icon: 'room', toggle: true, onEnabled: this.startMarker, onDisabled: this.unsub},
 | 
				
			||||||
 | 
					            {name: 'Draw', icon: 'create', toggle: true, onEnabled: this.startDrawing, onDisabled: this.unsub},
 | 
				
			||||||
 | 
					            {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, onEnabled: this.startPolygon, onDisabled: this.stopPolygon},
 | 
				
			||||||
 | 
					            {name: 'Measure', icon: 'straighten', toggle: true, onEnabled: this.startMeasuring, onDisabled: this.unsub},
 | 
				
			||||||
 | 
					            {name: 'Place Relative', icon: 'control_camera', click: this.placeRelative},
 | 
				
			||||||
 | 
					            {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)},
 | 
				
			||||||
 | 
					                    {name: 'ESRI:Satellite Clear', toggle: true, enabled: true, click: () => this.map.setMapLayer(MapLayers.ESRI_IMAGERY_CLARITY)}
 | 
				
			||||||
 | 
					                ]},
 | 
				
			||||||
 | 
					            {name: 'Weather', icon: 'cloud', subMenu: [
 | 
				
			||||||
 | 
					                    {name: 'None', toggle: true, enabled: true, click: () => this.map.setWeatherLayer()},
 | 
				
			||||||
 | 
					                    {name: 'Temperature', toggle: true, click: () => this.map.setWeatherLayer(WeatherLayers.TEMP_NEW)},
 | 
				
			||||||
 | 
					                    {name: 'Wind', toggle: true, click: () => this.map.setWeatherLayer(WeatherLayers.WIND_NEW)},
 | 
				
			||||||
 | 
					                    {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.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: 'delete all', icon: 'cancel', click: () => this.map.deleteAll(), hidden: !isDevMode()}
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ngOnDestroy(): void {
 | 
				
			||||||
 | 
					        let ignore = this.syncService.unload();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ngOnInit() {
 | 
				
			||||||
 | 
					        // Setup services
 | 
				
			||||||
 | 
					        this.map = new MapService('map');
 | 
				
			||||||
 | 
					        this.route.params.subscribe(params => {
 | 
				
			||||||
 | 
					            this.code = params['code'];
 | 
				
			||||||
 | 
					            this.syncService.load(this.code, this.name);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Setup map repainting on updates
 | 
				
			||||||
 | 
					        this.syncService.mapData.pipe(filter(s => !!s)).subscribe((map: MapData) => {
 | 
				
			||||||
 | 
					            this.map.deleteAll();
 | 
				
			||||||
 | 
					            if (map.circles) map.circles.forEach(c => this.map.newCircle(c));
 | 
				
			||||||
 | 
					            if (map.locations) Object.values(map.locations).forEach(l => this.map.newMarker(l));
 | 
				
			||||||
 | 
					            if (map.markers) map.markers.forEach(m => this.map.newMarker(m));
 | 
				
			||||||
 | 
					            if (map.measurements) map.measurements.forEach(m => this.map.newMeasurement(m));
 | 
				
			||||||
 | 
					            if (map.polygons) map.polygons.forEach(p => this.map.newPolygon(p));
 | 
				
			||||||
 | 
					            if (map.polylines) map.polylines.forEach(p => this.map.newPolyline(p));
 | 
				
			||||||
 | 
					            if (map.rectangles) map.rectangles.forEach(r => this.map.newRectangle(r));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Handle opening map symbols
 | 
				
			||||||
 | 
					        this.map.click.pipe(filter(e => !!e && e.item)).subscribe(ignore => {
 | 
				
			||||||
 | 
					            /*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.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);
 | 
				
			||||||
 | 
					                    this.map.newCircle(circle);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }*/
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Display location information & submit it
 | 
				
			||||||
 | 
					        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, noDeleteTool: 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, noDeleteTool: true, radius: pos.accuracy, interactive: false});
 | 
				
			||||||
 | 
					            this.syncService.addMyLocation({latlng: {lat: pos.latitude, lng: pos.longitude}, label: this.name, noDeleteTool: true});
 | 
				
			||||||
 | 
					            this.position = pos;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Request calibration if needed
 | 
				
			||||||
 | 
					        this.physicsService.requireCalibration.subscribe(() => {
 | 
				
			||||||
 | 
					            this.snackBar.open('Compass requires calibration', 'calibrate', {
 | 
				
			||||||
 | 
					                duration: 5000,
 | 
				
			||||||
 | 
					                panelClass: 'bg-warning,text-white'
 | 
				
			||||||
 | 
					            }).onAction().subscribe(() => this.startCalibrating());
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    center(pos?) {
 | 
				
			||||||
 | 
					        if (!pos) pos = {lat: this.position.latitude, lng: this.position.longitude};
 | 
				
			||||||
 | 
					        this.map.centerOn(pos);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    copyUrl() {
 | 
				
			||||||
 | 
					        copyToClipboard(window.location.href);
 | 
				
			||||||
 | 
					        this.snackBar.open('Copied to your clipboard! 📋', null, {duration: 3000})
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    placeRelative = () => {
 | 
					    placeRelative = () => {
 | 
				
			||||||
        this.dialog.open(DimensionsDialogComponent, {data: ['Distance (m)', 'Baring'], panelClass: 'pb-0'}).afterClosed().subscribe(dimensions => {
 | 
					        this.dialog.open(DimensionsDialogComponent, {data: ['Distance (m)', 'Baring'], panelClass: 'pb-0'}).afterClosed().subscribe(dimensions => {
 | 
				
			||||||
            if(!dimensions) return;
 | 
					            if(!dimensions) return;
 | 
				
			||||||
@@ -46,6 +148,17 @@ export class MapComponent implements OnDestroy, OnInit {
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    share() {
 | 
				
			||||||
 | 
					        this.shareDialog = true;
 | 
				
			||||||
 | 
					        if (navigator['share']) {
 | 
				
			||||||
 | 
					            navigator['share']({
 | 
				
			||||||
 | 
					                title: 'Map Alliance',
 | 
				
			||||||
 | 
					                text: 'A map alliance has been requested!',
 | 
				
			||||||
 | 
					                url: window.location.href,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    startCalibrating = () => {
 | 
					    startCalibrating = () => {
 | 
				
			||||||
        let calibration = this.bottomSheet.open(CalibrateComponent, {hasBackdrop: false, disableClose: true});
 | 
					        let calibration = this.bottomSheet.open(CalibrateComponent, {hasBackdrop: false, disableClose: true});
 | 
				
			||||||
        this.sub = calibration.afterDismissed().pipe(finalize(() => calibration.dismiss())).subscribe();
 | 
					        this.sub = calibration.afterDismissed().pipe(finalize(() => calibration.dismiss())).subscribe();
 | 
				
			||||||
@@ -164,134 +277,4 @@ export class MapComponent implements OnDestroy, OnInit {
 | 
				
			|||||||
            this.sub = null;
 | 
					            this.sub = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					 | 
				
			||||||
    menu: ToolbarItem[] = [
 | 
					 | 
				
			||||||
        {name: 'Marker', icon: 'room', toggle: true, onEnabled: this.startMarker, onDisabled: this.unsub},
 | 
					 | 
				
			||||||
        {name: 'Draw', icon: 'create', toggle: true, onEnabled: this.startDrawing, onDisabled: this.unsub},
 | 
					 | 
				
			||||||
        {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, onEnabled: this.startPolygon, onDisabled: this.stopPolygon},
 | 
					 | 
				
			||||||
        {name: 'Measure', icon: 'straighten', toggle: true, onEnabled: this.startMeasuring, onDisabled: this.unsub},
 | 
					 | 
				
			||||||
        {name: 'Place Relative', icon: 'control_camera', click: this.placeRelative},
 | 
					 | 
				
			||||||
        {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)},
 | 
					 | 
				
			||||||
            {name: 'ESRI:Satellite Clear', toggle: true, enabled: true, click: () => this.map.setMapLayer(MapLayers.ESRI_IMAGERY_CLARITY)}
 | 
					 | 
				
			||||||
        ]},
 | 
					 | 
				
			||||||
        {name: 'Weather', icon: 'cloud', subMenu: [
 | 
					 | 
				
			||||||
                {name: 'None', toggle: true, enabled: true, click: () => this.map.setWeatherLayer()},
 | 
					 | 
				
			||||||
                {name: 'Temperature', toggle: true, click: () => this.map.setWeatherLayer(WeatherLayers.TEMP_NEW)},
 | 
					 | 
				
			||||||
                {name: 'Wind', toggle: true, click: () => this.map.setWeatherLayer(WeatherLayers.WIND_NEW)},
 | 
					 | 
				
			||||||
                {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.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: 'delete all', icon: 'cancel', click: () => this.map.deleteAll(), hidden: !isDevMode()}
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    constructor(public physicsService: PhysicsService, private syncService: SyncService, private snackBar: MatSnackBar, private bottomSheet: MatBottomSheet, private dialog: MatDialog, private route: ActivatedRoute) {
 | 
					 | 
				
			||||||
        this.name = Adjectives[Math.floor(Math.random() * Adjectives.length)] + ' ' + Nouns[Math.floor(Math.random() * Nouns.length)];
 | 
					 | 
				
			||||||
        (window.onbeforeunload as any) = this.ngOnDestroy();
 | 
					 | 
				
			||||||
        this.route.params.subscribe(params => {
 | 
					 | 
				
			||||||
            this.code = params['code'];
 | 
					 | 
				
			||||||
            this.syncService.load(this.code, this.name);
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ngOnDestroy(): void {
 | 
					 | 
				
			||||||
        let ignore = this.syncService.unload();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ngOnInit() {
 | 
					 | 
				
			||||||
        this.map = new MapService('map');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Handle drawing the map after updates
 | 
					 | 
				
			||||||
        this.syncService.mapData.pipe(filter(s => !!s)).subscribe((map: MapData) => {
 | 
					 | 
				
			||||||
            this.map.deleteAll();
 | 
					 | 
				
			||||||
            if (map.circles) map.circles.forEach(c => this.map.newCircle(c));
 | 
					 | 
				
			||||||
            if (map.locations) Object.values(map.locations).forEach(l => this.map.newMarker(l));
 | 
					 | 
				
			||||||
            if (map.markers) map.markers.forEach(m => this.map.newMarker(m));
 | 
					 | 
				
			||||||
            if (map.measurements) map.measurements.forEach(m => this.map.newMeasurement(m));
 | 
					 | 
				
			||||||
            if (map.polygons) map.polygons.forEach(p => this.map.newPolygon(p));
 | 
					 | 
				
			||||||
            if (map.polylines) map.polylines.forEach(p => this.map.newPolyline(p));
 | 
					 | 
				
			||||||
            if (map.rectangles) map.rectangles.forEach(r => this.map.newRectangle(r));
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 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.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);
 | 
					 | 
				
			||||||
                    this.map.newCircle(circle);
 | 
					 | 
				
			||||||
                });*/
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 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.syncService.addMyLocation({latlng: {lat: pos.latitude, lng: pos.longitude}, label: this.name, noDeleteTool: true});
 | 
					 | 
				
			||||||
            this.positionMarker.arrow = this.map.newMarker({
 | 
					 | 
				
			||||||
                latlng: {lat: pos.latitude, lng: pos.longitude},
 | 
					 | 
				
			||||||
                noSelect: true,
 | 
					 | 
				
			||||||
                noDelete: true,
 | 
					 | 
				
			||||||
                noDeleteTool: 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,
 | 
					 | 
				
			||||||
                noDeleteTool: 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());
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    center(pos?) {
 | 
					 | 
				
			||||||
        if (!pos) pos = {lat: this.position.latitude, lng: this.position.longitude};
 | 
					 | 
				
			||||||
        this.map.centerOn(pos);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    copyUrl() {
 | 
					 | 
				
			||||||
        copyToClipboard(window.location.href);
 | 
					 | 
				
			||||||
        this.snackBar.open('Copied to your clipboard! 📋', null, {duration: 3000})
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    share() {
 | 
					 | 
				
			||||||
        this.shareDialog = true;
 | 
					 | 
				
			||||||
        if (navigator['share']) {
 | 
					 | 
				
			||||||
            navigator['share']({
 | 
					 | 
				
			||||||
                title: 'Map Alliance',
 | 
					 | 
				
			||||||
                text: 'A map alliance has been requested!',
 | 
					 | 
				
			||||||
                url: window.location.href,
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user