Syncing drawings!
This commit is contained in:
		@@ -7,6 +7,7 @@ export interface MapData {
 | 
			
		||||
    circles?: Circle[];
 | 
			
		||||
    markers?: Marker[];
 | 
			
		||||
    measurements?: Measurement[];
 | 
			
		||||
    polylines?: Polyline[];
 | 
			
		||||
    rectangles?: Rectangle[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -35,6 +36,7 @@ export interface Rectangle extends MapSymbol {
 | 
			
		||||
 | 
			
		||||
export interface Polyline extends MapSymbol {
 | 
			
		||||
    latlng: LatLng[];
 | 
			
		||||
    weight?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Marker extends MapSymbol {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import {BehaviorSubject} from "rxjs";
 | 
			
		||||
import {latLngDistance} from "../utils";
 | 
			
		||||
import {environment} from "../../environments/environment";
 | 
			
		||||
import {Circle, LatLng, MapSymbol, Marker, Measurement, Rectangle} from "../models/mapSymbol";
 | 
			
		||||
import {Circle, LatLng, MapSymbol, Marker, Measurement, Polyline, Rectangle} from "../models/mapSymbol";
 | 
			
		||||
 | 
			
		||||
declare const L;
 | 
			
		||||
 | 
			
		||||
@@ -24,22 +24,26 @@ const MARKER = L.icon({iconUrl: '/assets/images/marker.png', iconSize: [40, 55],
 | 
			
		||||
const MEASURE = L.icon({iconUrl: '/assets/images/measure.png', iconSize: [75, 50], iconAnchor: [25, 25]});
 | 
			
		||||
 | 
			
		||||
export class MapService {
 | 
			
		||||
    private readonly map;
 | 
			
		||||
 | 
			
		||||
    private circles = [];
 | 
			
		||||
    private drawListener;
 | 
			
		||||
    private markers = [];
 | 
			
		||||
    private measurements = [];
 | 
			
		||||
    private mapLayer;
 | 
			
		||||
    private polyline = [];
 | 
			
		||||
    private rectangles = [];
 | 
			
		||||
    private weatherLayer;
 | 
			
		||||
 | 
			
		||||
    click = new BehaviorSubject<{latlng: LatLng, symbol?: MapSymbol, item?: any}>(null);
 | 
			
		||||
    drawingColor = '#ff4141';
 | 
			
		||||
    drawingWeight = 10;
 | 
			
		||||
    map;
 | 
			
		||||
    touch = new BehaviorSubject<{type: string, latlng: LatLng}>(null);
 | 
			
		||||
 | 
			
		||||
    constructor(private elementId: string) {
 | 
			
		||||
        this.map = L.map(elementId, {attributionControl: false, editable: true, tap: true, zoomControl: false, maxBoundsViscosity: 1, doubleClickZoom: false}).setView({lat: 0, lng: 0}, 10);
 | 
			
		||||
        this.map.on('click', (e) => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}}));
 | 
			
		||||
        this.map.on('touchstart', (e) => this.touch.next({type: 'start', latlng: {lat: e.latlng.lat, lng: e.latlng.lng}}));
 | 
			
		||||
        this.map.on('touchmove', (e) => this.touch.next({type: 'move', latlng: {lat: e.latlng.lat, lng: e.latlng.lng}}));
 | 
			
		||||
        this.map.on('touchend', (e) => this.touch.next({type: 'end', latlng: {lat: e.latlng.lat, lng: e.latlng.lng}}));
 | 
			
		||||
        this.setMapLayer();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -64,6 +68,7 @@ export class MapService {
 | 
			
		||||
            this.circles = this.circles.filter(c => c != c);
 | 
			
		||||
            this.markers = this.markers.filter(m => m != s);
 | 
			
		||||
            this.measurements = this.measurements.filter(m => m != s);
 | 
			
		||||
            this.polyline = this.polyline.filter(p => p != s);
 | 
			
		||||
            this.rectangles = this.rectangles.filter(r => r != s);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
@@ -72,6 +77,7 @@ export class MapService {
 | 
			
		||||
        this.circles.forEach(c => this.delete(c));
 | 
			
		||||
        this.markers.forEach(m => this.delete(m));
 | 
			
		||||
        this.measurements.forEach(m => this.delete(m));
 | 
			
		||||
        this.polyline.forEach(p => this.delete(p));
 | 
			
		||||
        this.rectangles.forEach(r => this.delete(r));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -89,6 +95,52 @@ export class MapService {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newCircle(c: Circle) {
 | 
			
		||||
        let circle = L.circle(c.latlng, Object.assign({}, c)).addTo(this.map);
 | 
			
		||||
        if(c.label) circle.bindTooltip(c.label, {permanent: true, direction: 'center'});
 | 
			
		||||
        circle.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: c, item: circle}));
 | 
			
		||||
        if(!c.noDelete) this.circles.push(circle);
 | 
			
		||||
        return circle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newMarker(m: Marker) {
 | 
			
		||||
        let marker = L.marker(m.latlng, Object.assign({}, m, {icon: m.icon ? this.getIcon(m.icon) : MARKER})).addTo(this.map);
 | 
			
		||||
        if(m.label) marker.bindTooltip(m.label, {permanent: true, direction: 'bottom'});
 | 
			
		||||
        marker.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: m, item: marker}));
 | 
			
		||||
        if(!m.noDelete) this.markers.push(marker);
 | 
			
		||||
        return marker;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newMeasurement(m: Measurement) {
 | 
			
		||||
        let line = L.polyline([m.latlng, m.latlng2], Object.assign({}, m));
 | 
			
		||||
        let decoration = L.polylineDecorator(line, {patterns: [
 | 
			
		||||
            {offset: '100%', repeat: 0, symbol: L.Symbol.arrowHead({pixelSize: 10, polygon: false, headAngle: 180, pathOptions: m})},
 | 
			
		||||
            {offset: '-100%', repeat: 0, symbol: L.Symbol.arrowHead({pixelSize: 10, polygon: false, headAngle: 180, pathOptions: m})}
 | 
			
		||||
        ]});
 | 
			
		||||
        let group = new L.LayerGroup([line, decoration]).addTo(this.map);
 | 
			
		||||
        if(!m.noDelete) this.measurements.push(group);
 | 
			
		||||
 | 
			
		||||
        let distance = latLngDistance(m.latlng, m.latlng2);
 | 
			
		||||
        line.bindPopup(`${distance > 1000 ? Math.round(distance / 100) / 10 : Math.round(distance)} ${distance > 1000 ? 'k' : ''}m`, {autoClose: false, closeOnClick: false}).openPopup();
 | 
			
		||||
        line.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: m, item: group}));
 | 
			
		||||
        return group;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newPolyline(p: Polyline) {
 | 
			
		||||
        let polyline = new L.Polyline(p.latlng, Object.assign({}, p)).addTo(this.map);
 | 
			
		||||
        polyline.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: p, item: polyline}));
 | 
			
		||||
        if(!p.noDelete) this.polyline.push(polyline);
 | 
			
		||||
        return polyline;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newRectangle(r: Rectangle) {
 | 
			
		||||
        let rect = new L.Rectangle([r.latlng, r.latlng2], Object.assign({}, r)).addTo(this.map);
 | 
			
		||||
        if(r.label) rect.bindTooltip(r.label, {permanent: true, direction: 'center'});
 | 
			
		||||
        rect.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: r, item: rect}));
 | 
			
		||||
        if(!r.noDelete) this.rectangles.push(rect);
 | 
			
		||||
        return rect;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setMapLayer(layer?: MapLayers) {
 | 
			
		||||
        if(this.mapLayer) this.map.removeLayer(this.mapLayer);
 | 
			
		||||
        if(layer == null) layer = MapLayers.ESRI_IMAGERY;
 | 
			
		||||
@@ -131,62 +183,4 @@ export class MapService {
 | 
			
		||||
        }
 | 
			
		||||
        if(this.weatherLayer) this.weatherLayer.layer.addTo(this.map);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newCircle(c: Circle) {
 | 
			
		||||
        let circle = L.circle(c.latlng, Object.assign({}, c)).addTo(this.map);
 | 
			
		||||
        if(c.label) circle.bindTooltip(c.label, {permanent: true, direction: 'center'});
 | 
			
		||||
        circle.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: c, item: circle}));
 | 
			
		||||
        if(!c.noDelete) this.circles.push(circle);
 | 
			
		||||
        return circle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newMarker(m: Marker) {
 | 
			
		||||
        let marker = L.marker(m.latlng, Object.assign({}, m, {icon: m.icon ? this.getIcon(m.icon) : MARKER})).addTo(this.map);
 | 
			
		||||
        if(m.label) marker.bindTooltip(m.label, {permanent: true, direction: 'bottom'});
 | 
			
		||||
        marker.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: m, item: marker}));
 | 
			
		||||
        if(!m.noDelete) this.markers.push(marker);
 | 
			
		||||
        return marker;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newMeasurement(m: Measurement) {
 | 
			
		||||
        let line = L.polyline([m.latlng, m.latlng2], Object.assign({}, m));
 | 
			
		||||
        let decoration = L.polylineDecorator(line, {patterns: [
 | 
			
		||||
            {offset: '100%', repeat: 0, symbol: L.Symbol.arrowHead({pixelSize: 10, polygon: false, headAngle: 180, pathOptions: m})},
 | 
			
		||||
            {offset: '-100%', repeat: 0, symbol: L.Symbol.arrowHead({pixelSize: 10, polygon: false, headAngle: 180, pathOptions: m})}
 | 
			
		||||
        ]});
 | 
			
		||||
        let group = new L.LayerGroup([line, decoration]).addTo(this.map);
 | 
			
		||||
        if(!m.noDelete) this.measurements.push(group);
 | 
			
		||||
 | 
			
		||||
        let distance = latLngDistance(m.latlng, m.latlng2);
 | 
			
		||||
        line.bindPopup(`${distance > 1000 ? Math.round(distance / 100) / 10 : Math.round(distance)} ${distance > 1000 ? 'k' : ''}m`, {autoClose: false, closeOnClick: false}).openPopup();
 | 
			
		||||
        line.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: m, item: group}));
 | 
			
		||||
        return group;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    newRectangle(r: Rectangle) {
 | 
			
		||||
        let rect = new L.Rectangle([r.latlng, r.latlng2], Object.assign({}, r)).addTo(this.map);
 | 
			
		||||
        if(r.label) rect.bindTooltip(r.label, {permanent: true, direction: 'center'});
 | 
			
		||||
        rect.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: r, item: rect}));
 | 
			
		||||
        if(!r.noDelete) this.rectangles.push(rect);
 | 
			
		||||
        return rect;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    startDrawing() {
 | 
			
		||||
        this.lock();
 | 
			
		||||
        this.drawListener = e => {
 | 
			
		||||
            let poly = L.polyline([e.latlng], {interactive: true, color: this.drawingColor, weight: this.drawingWeight}).addTo(this.map);
 | 
			
		||||
            poly.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, item: poly}));
 | 
			
		||||
            let pushLine = e => poly.addLatLng(e.latlng);
 | 
			
		||||
            this.map.on('touchmove', pushLine);
 | 
			
		||||
            this.map.on('touchend', () => this.map.off('touchmove', pushLine));
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        this.map.on('touchstart', this.drawListener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stopDrawing() {
 | 
			
		||||
        this.lock(true);
 | 
			
		||||
        this.map.setMaxBounds(null);
 | 
			
		||||
        this.map.off('touchstart', this.drawListener);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import {Injectable} from "@angular/core";
 | 
			
		||||
import {AngularFirestore, AngularFirestoreCollection} from "@angular/fire/firestore";
 | 
			
		||||
import {BehaviorSubject, Subscription} from "rxjs";
 | 
			
		||||
import {Circle, MapData, Marker, Measurement, Rectangle} from "../models/mapSymbol";
 | 
			
		||||
import {Circle, MapData, Marker, Measurement, Polyline, Rectangle} from "../models/mapSymbol";
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
@@ -43,6 +43,13 @@ export class SyncService {
 | 
			
		||||
        this.save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addPolyline(polyline: Polyline) {
 | 
			
		||||
        let map = this.mapSymbols.value;
 | 
			
		||||
        if(!map.polylines) map.polylines = [];
 | 
			
		||||
        map.polylines.push(polyline);
 | 
			
		||||
        this.save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addRectangle(rect: Rectangle) {
 | 
			
		||||
        let map = this.mapSymbols.value;
 | 
			
		||||
        if(!map.rectangles) map.rectangles = [];
 | 
			
		||||
@@ -55,6 +62,7 @@ export class SyncService {
 | 
			
		||||
        if(map.circles) symbols.forEach(s => map.circles = map.circles.filter(c => !_.isEqual(s, c)));
 | 
			
		||||
        if(map.markers) symbols.forEach(s => map.markers = map.markers.filter(m => !_.isEqual(s, m)));
 | 
			
		||||
        if(map.measurements) symbols.forEach(s => map.measurements = map.measurements.filter(m => !_.isEqual(s, m)));
 | 
			
		||||
        if(map.polylines) symbols.forEach(s => map.polylines = map.polylines.filter(p => !_.isEqual(s, p)));
 | 
			
		||||
        if(map.rectangles) symbols.forEach(s => map.rectangles = map.rectangles.filter(r => !_.isEqual(s, r)));
 | 
			
		||||
        this.save();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,11 @@ export class MapComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
            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);
 | 
			
		||||
@@ -49,11 +53,31 @@ export class MapComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
    startDelete = () => {
 | 
			
		||||
        this.sub = this.map.click.pipe(skip(1), filter(e => !!e.symbol)).subscribe(e => {
 | 
			
		||||
            if(!!e.symbol && e.symbol.noDelete) return;
 | 
			
		||||
            if (!!e.symbol && e.symbol.noDelete) return;
 | 
			
		||||
            this.syncService.delete(e.symbol)
 | 
			
		||||
        });
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    startDrawing = () => {
 | 
			
		||||
        this.showPalette = true;
 | 
			
		||||
        this.map.lock();
 | 
			
		||||
        this.sub = this.map.touch.pipe(skip(1), filter(e => e.type == 'start'), finalize(() => {
 | 
			
		||||
            this.showPalette = false;
 | 
			
		||||
            this.map.lock(true);
 | 
			
		||||
        })).subscribe(e => {
 | 
			
		||||
            let p = {latlng: [e.latlng], noDelete: true, color: this.drawColor, weight: 8};
 | 
			
		||||
            let polyline = this.map.newPolyline(p);
 | 
			
		||||
            let drawingSub = this.map.touch.pipe(filter(e => e.type == 'move')).subscribe(e => polyline.addLatLng(e.latlng));
 | 
			
		||||
            this.map.touch.pipe(filter(e => e.type == 'end'), take(1)).subscribe(() => {
 | 
			
		||||
                drawingSub.unsubscribe();
 | 
			
		||||
                p.noDelete = false;
 | 
			
		||||
                p.latlng = polyline.getLatLngs().map(latlng => ({lat: latlng.lat, lng: latlng.lng}));
 | 
			
		||||
                this.map.delete(polyline);
 | 
			
		||||
                this.syncService.addPolyline(p);
 | 
			
		||||
            });
 | 
			
		||||
        })
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    startMarker = menuItem => {
 | 
			
		||||
        this.sub = this.map.click.pipe(skip(1), take(1)).subscribe(e => {
 | 
			
		||||
            menuItem.enabled = false;
 | 
			
		||||
@@ -65,9 +89,14 @@ export class MapComponent implements OnInit {
 | 
			
		||||
    startMeasuring = menuItem => {
 | 
			
		||||
        let lastPoint;
 | 
			
		||||
        this.sub = this.map.click.pipe(skip(1), take(2), finalize(() => this.map.delete(lastPoint))).subscribe(e => {
 | 
			
		||||
            if(lastPoint) {
 | 
			
		||||
            if (lastPoint) {
 | 
			
		||||
                menuItem.enabled = false;
 | 
			
		||||
                let measurement = {latlng: {lat: lastPoint.getLatLng().lat, lng: lastPoint.getLatLng().lng}, latlng2: e.latlng, color: '#ff4141', weight: 8};
 | 
			
		||||
                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);
 | 
			
		||||
            }
 | 
			
		||||
@@ -78,9 +107,13 @@ export class MapComponent implements OnInit {
 | 
			
		||||
    startRectangle = menuItem => {
 | 
			
		||||
        let lastPoint;
 | 
			
		||||
        this.sub = this.map.click.pipe(skip(1), take(2), finalize(() => this.map.delete(lastPoint))).subscribe(e => {
 | 
			
		||||
            if(lastPoint) {
 | 
			
		||||
            if (lastPoint) {
 | 
			
		||||
                menuItem.enabled = false;
 | 
			
		||||
                let rect = {latlng: {lat: lastPoint.getLatLng().lat, lng: lastPoint.getLatLng().lng}, latlng2: e.latlng, color: '#ff4141'};
 | 
			
		||||
                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);
 | 
			
		||||
            }
 | 
			
		||||
@@ -89,7 +122,7 @@ export class MapComponent implements OnInit {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    unsub = () => {
 | 
			
		||||
        if(this.sub) {
 | 
			
		||||
        if (this.sub) {
 | 
			
		||||
            this.sub.unsubscribe();
 | 
			
		||||
            this.sub = null;
 | 
			
		||||
        }
 | 
			
		||||
@@ -97,26 +130,51 @@ export class MapComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
    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.stopDrawing()},
 | 
			
		||||
        {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},
 | 
			
		||||
        {name: 'Measure', icon: 'straighten', toggle: true, onEnabled: this.startMeasuring, onDisabled: () => this.unsub},
 | 
			
		||||
        {
 | 
			
		||||
            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)},
 | 
			
		||||
            {name: 'ESRI:Satellite Clear', toggle: true, enabled: true, click: () => this.map.setMapLayer(MapLayers.ESRI_IMAGERY_CLARITY)}
 | 
			
		||||
        ]},
 | 
			
		||||
        {name: 'Weather', icon: 'cloud', subMenu: [
 | 
			
		||||
        {
 | 
			
		||||
            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: '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: '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},
 | 
			
		||||
@@ -131,10 +189,11 @@ export class MapComponent implements OnInit {
 | 
			
		||||
            // 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));
 | 
			
		||||
                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.polylines) map.polylines.forEach(p => this.map.newPolyline(p));
 | 
			
		||||
                if (map.rectangles) map.rectangles.forEach(r => this.map.newRectangle(r));
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
@@ -144,11 +203,11 @@ export class MapComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
        // 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;
 | 
			
		||||
            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;
 | 
			
		||||
            } 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);
 | 
			
		||||
@@ -159,23 +218,40 @@ 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', noSelect: true, noDelete: true, radius: pos.accuracy, interactive: false});
 | 
			
		||||
            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',
 | 
			
		||||
                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'})
 | 
			
		||||
            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};
 | 
			
		||||
        if (!pos) pos = {lat: this.position.latitude, lng: this.position.longitude};
 | 
			
		||||
        this.map.centerOn(pos);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -186,7 +262,7 @@ export class MapComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
    share() {
 | 
			
		||||
        this.shareDialog = true;
 | 
			
		||||
        if(navigator['share']) {
 | 
			
		||||
        if (navigator['share']) {
 | 
			
		||||
            navigator['share']({
 | 
			
		||||
                title: 'Map Alliance',
 | 
			
		||||
                text: 'A map alliance has been requested!',
 | 
			
		||||
@@ -194,14 +270,4 @@ export class MapComponent implements OnInit {
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    startDrawing() {
 | 
			
		||||
        this.showPalette = true;
 | 
			
		||||
        this.map.startDrawing();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    stopDrawing() {
 | 
			
		||||
        this.showPalette = false;
 | 
			
		||||
        this.map.stopDrawing()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user