Added ID's and update times for more accurate map merging during updates.
This commit is contained in:
parent
088777d742
commit
eceb85569e
@ -44,6 +44,7 @@
|
||||
"ng-click-outside": "^5.0.0",
|
||||
"ngx-color-picker": "^8.1.0",
|
||||
"rxjs": "~6.4.0",
|
||||
"ts-md5": "^1.2.5",
|
||||
"tslib": "^1.9.0",
|
||||
"web-animations-js": "^2.3.2",
|
||||
"whatwg-fetch": "^3.0.0",
|
||||
|
@ -15,26 +15,24 @@ import {PermissionsComponent} from "./components/permissions/permissions.compone
|
||||
import {AngularFireModule} from "@angular/fire";
|
||||
import {AngularFirestoreModule} from "@angular/fire/firestore";
|
||||
import {ToolbarComponent} from "./components/toolbar/toolbar.component";
|
||||
import {PaletteComponent} from "./components/palette/palette.component";
|
||||
import {MarkerComponent} from "./components/marker/marker.component";
|
||||
import {PaletteComponent} from "./components/palette/palette.component"
|
||||
import {AnimatedBackgroundComponent} from "./components/animatedBackground/animatedBackground.component";
|
||||
import {ClickOutsideModule} from "ng-click-outside";
|
||||
import {CircleComponent} from "./components/circle/circle.component";
|
||||
import {ColorPickerModule} from "ngx-color-picker";
|
||||
import {ColorPickerDialogComponent} from "./components/colorPickerDialog/colorPickerDialog.component";
|
||||
import {DimensionsDialogComponent} from "./components/dimensionsDialog/dimensionsDialog.component";
|
||||
import {EditSymbolComponent} from "./components/editSymbol/editSymbol.component";
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AnimatedBackgroundComponent,
|
||||
AppComponent,
|
||||
CalibrateComponent,
|
||||
CircleComponent,
|
||||
ColorPickerDialogComponent,
|
||||
DimensionsDialogComponent,
|
||||
EditSymbolComponent,
|
||||
HomeComponent,
|
||||
MapComponent,
|
||||
MarkerComponent,
|
||||
PaletteComponent,
|
||||
PermissionsComponent,
|
||||
ToolbarComponent
|
||||
@ -53,7 +51,7 @@ import {DimensionsDialogComponent} from "./components/dimensionsDialog/dimension
|
||||
MatInputModule,
|
||||
],
|
||||
providers: [],
|
||||
entryComponents: [CalibrateComponent, CircleComponent, ColorPickerDialogComponent, DimensionsDialogComponent, MarkerComponent, PermissionsComponent],
|
||||
entryComponents: [CalibrateComponent, ColorPickerDialogComponent, DimensionsDialogComponent, EditSymbolComponent, PermissionsComponent],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule {
|
||||
|
@ -4,7 +4,7 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 600;
|
||||
z-index: 6000;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
|
@ -1,37 +0,0 @@
|
||||
import {Component, Inject} from "@angular/core";
|
||||
import {MatBottomSheetRef} from "@angular/material";
|
||||
import {MAT_BOTTOM_SHEET_DATA} from "@angular/material/bottom-sheet";
|
||||
import {Circle} from "../../models/mapSymbol";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {ColorPickerDialogComponent} from "../colorPickerDialog/colorPickerDialog.component";
|
||||
|
||||
@Component({
|
||||
selector: 'calibrate',
|
||||
templateUrl: 'circle.component.html'
|
||||
})
|
||||
export class CircleComponent {
|
||||
symbol: any;
|
||||
circle: Circle;
|
||||
|
||||
constructor(private dialog: MatDialog, private bottomSheetRef: MatBottomSheetRef, @Inject(MAT_BOTTOM_SHEET_DATA) circle) {
|
||||
this.symbol = circle;
|
||||
this.circle = this.symbol.symbol;
|
||||
|
||||
this.symbol.enableEdit();
|
||||
|
||||
this.bottomSheetRef.afterDismissed().subscribe(() => this.symbol.disableEdit());
|
||||
}
|
||||
|
||||
close() {
|
||||
this.circle.latlng = this.symbol.getLatLng();
|
||||
this.circle.radius = this.symbol.getRadius();
|
||||
this.bottomSheetRef.dismiss(this.symbol);
|
||||
}
|
||||
|
||||
colorPicker() {
|
||||
this.dialog.open(ColorPickerDialogComponent, {data: this.circle.color, hasBackdrop: false, panelClass: 'p-0'}).afterClosed()
|
||||
.subscribe(color => {
|
||||
this.circle.color = color
|
||||
});
|
||||
}
|
||||
}
|
@ -2,14 +2,14 @@
|
||||
<div class="row">
|
||||
<mat-form-field appearance="fill" class="col-12 col-md-6">
|
||||
<mat-label>Label</mat-label>
|
||||
<input matInput [(ngModel)]="circle.label">
|
||||
<input matInput [(ngModel)]="symbol.label">
|
||||
</mat-form-field>
|
||||
<div class="ml-auto mt-1 mr-3 rounded-circle border" (click)="colorPicker()" style="width: 46px; height: 46px;" [style.background]="circle.color"></div>
|
||||
<div class="ml-auto mt-1 mr-3 rounded-circle border curs-pointer" (click)="colorPicker()" style="width: 46px; height: 46px;" [style.background]="symbol.color"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-form-field appearance="fill" class="col-12">
|
||||
<mat-label>Notes</mat-label>
|
||||
<textarea matInput rows="3"></textarea>
|
||||
<textarea matInput rows="3" [(ngModel)]="symbol.notes"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
36
src/app/components/editSymbol/editSymbol.component.ts
Normal file
36
src/app/components/editSymbol/editSymbol.component.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import {Component, Inject} from "@angular/core";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {MapSymbol} from "../../models/mapSymbol";
|
||||
import {MAT_BOTTOM_SHEET_DATA, MatBottomSheetRef} from "@angular/material/bottom-sheet";
|
||||
import {ColorPickerDialogComponent} from "../colorPickerDialog/colorPickerDialog.component";
|
||||
|
||||
@Component({
|
||||
selector: 'edit-symbol',
|
||||
templateUrl: 'editSymbol.component.html'
|
||||
})
|
||||
export class EditSymbolComponent {
|
||||
symbol: MapSymbol;
|
||||
mapItem;
|
||||
|
||||
constructor(private dialog: MatDialog, private ref: MatBottomSheetRef, @Inject(MAT_BOTTOM_SHEET_DATA) data) {
|
||||
this.symbol = Object.assign({color: '#ff4141'}, data.symbol);
|
||||
this.mapItem = data.item;
|
||||
|
||||
this.mapItem.enableEdit();
|
||||
this.ref.afterDismissed().subscribe(() => this.mapItem.disableEdit());
|
||||
}
|
||||
|
||||
close() {
|
||||
let latlng = this.mapItem.getLatLng();
|
||||
this.symbol.latlng = {lat: latlng.lat, lng: latlng.lng};
|
||||
if(this.mapItem.getRadius) this.symbol['radius'] = this.mapItem.getRadius();
|
||||
this.ref.dismiss(this.symbol);
|
||||
}
|
||||
|
||||
colorPicker() {
|
||||
this.dialog.open(ColorPickerDialogComponent, {data: this.symbol.color, hasBackdrop: false, panelClass: 'p-0'}).afterClosed()
|
||||
.subscribe(color => {
|
||||
this.symbol.color = color
|
||||
});
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
<div>
|
||||
<div class="row">
|
||||
<mat-form-field appearance="fill" class="col-12 col-md-6">
|
||||
<mat-label>Label</mat-label>
|
||||
<input matInput [(ngModel)]="marker.label">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-divider></mat-divider>
|
||||
<button mat-button class="float-right mt-2" (click)="close()">Close</button>
|
||||
</div>
|
@ -1,16 +0,0 @@
|
||||
import {Component, Inject} from "@angular/core";
|
||||
import {MatBottomSheetRef} from "@angular/material";
|
||||
import {MAT_BOTTOM_SHEET_DATA} from "@angular/material/bottom-sheet";
|
||||
|
||||
@Component({
|
||||
selector: 'calibrate',
|
||||
templateUrl: 'marker.component.html'
|
||||
})
|
||||
export class MarkerComponent {
|
||||
|
||||
constructor(private bottomSheetRef: MatBottomSheetRef, @Inject(MAT_BOTTOM_SHEET_DATA) public marker) { }
|
||||
|
||||
close() {
|
||||
this.bottomSheetRef.dismiss();
|
||||
}
|
||||
}
|
@ -4,19 +4,21 @@ export interface LatLng {
|
||||
}
|
||||
|
||||
export interface MapData {
|
||||
circles?: Circle[];
|
||||
circles?: {[key: string]: Circle};
|
||||
locations?: {[key: string]: Marker};
|
||||
markers?: Marker[];
|
||||
measurements?: Measurement[];
|
||||
polygons?: Polygon[];
|
||||
polylines?: Polyline[];
|
||||
rectangles?: Rectangle[];
|
||||
markers?: {[key: string]: Marker};
|
||||
measurements?: {[key: string]: Measurement};
|
||||
polygons?: {[key: string]: Polygon};
|
||||
polylines?: {[key: string]: Polyline};
|
||||
rectangles?: {[key: string]: Rectangle};
|
||||
}
|
||||
|
||||
export interface MapSymbol {
|
||||
deleted?: boolean;
|
||||
id?: string;
|
||||
symbol?: any;
|
||||
latlng?: LatLng | LatLng[];
|
||||
new?: boolean;
|
||||
noClick?: boolean;
|
||||
noDelete?: boolean;
|
||||
noDeleteTool?: boolean;
|
||||
noSelect?: boolean;
|
||||
@ -26,6 +28,7 @@ export interface MapSymbol {
|
||||
interactive?: boolean;
|
||||
rotationAngle?: number;
|
||||
rotationOrigin?: string;
|
||||
updated?: number;
|
||||
}
|
||||
|
||||
export interface Circle extends MapSymbol {
|
||||
|
@ -108,7 +108,7 @@ export class MapService {
|
||||
newCircle(c: Circle) {
|
||||
let circle = L.circle(c.latlng, Object.assign({color: '#ff4141'}, 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.noClick) 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;
|
||||
}
|
||||
@ -116,7 +116,7 @@ export class MapService {
|
||||
newMarker(m: Marker) {
|
||||
let marker = L.marker(m.latlng, Object.assign({color: '#ff4141'}, 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.noClick) 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;
|
||||
}
|
||||
@ -132,20 +132,20 @@ export class MapService {
|
||||
|
||||
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}));
|
||||
if(m.noClick) line.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: m, item: group}));
|
||||
return group;
|
||||
}
|
||||
|
||||
newPolygon(p: Polygon) {
|
||||
let polygon = new L.Polygon(p.latlng, Object.assign({color: '#ff4141'}, p)).addTo(this.map);
|
||||
polygon.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: p, item: polygon}));
|
||||
if(!p.noClick) polygon.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: p, item: polygon}));
|
||||
if(!p.noDelete) this.polygons.push(polygon);
|
||||
return polygon;
|
||||
}
|
||||
|
||||
newPolyline(p: Polyline) {
|
||||
let polyline = new L.Polyline(p.latlng, Object.assign({color: '#ff4141', weight: 10}, 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.noClick) polyline.on('click', e => this.click.next({latlng: {lat: e.latlng.lat, lng: e.latlng.lng}, symbol: p, item: polyline}));
|
||||
if(!p.noDelete) this.polylines.push(polyline);
|
||||
return polyline;
|
||||
}
|
||||
@ -153,7 +153,7 @@ export class MapService {
|
||||
newRectangle(r: Rectangle) {
|
||||
let rect = new L.Rectangle([r.latlng, r.latlng2], Object.assign({color: '#ff4141'}, 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.noClick) 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;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import {Injectable} from "@angular/core";
|
||||
import {AngularFirestore, AngularFirestoreDocument} from "@angular/fire/firestore";
|
||||
import {BehaviorSubject, combineLatest, Subscription} from "rxjs";
|
||||
import {Circle, MapData, MapSymbol, Marker, Measurement, Polygon, Polyline, Position, Rectangle} from "../models/mapSymbol";
|
||||
import * as _ from 'lodash';
|
||||
import {Md5} from 'ts-md5';
|
||||
import {filter, map} from "rxjs/operators";
|
||||
|
||||
export const LOCATION_COLLECTION = 'Users';
|
||||
@ -22,6 +22,7 @@ export class SyncService {
|
||||
private saveInterval: number;
|
||||
private username: string;
|
||||
|
||||
freeze = new BehaviorSubject<boolean>(false);
|
||||
mapData = new BehaviorSubject<MapData>({});
|
||||
status = new BehaviorSubject<string>(null);
|
||||
|
||||
@ -39,10 +40,13 @@ export class SyncService {
|
||||
}
|
||||
|
||||
private addMapSymbol(s: MapSymbol, key: string) {
|
||||
s.new = true;
|
||||
let map = this.mapData.value;
|
||||
if(!map[key]) map[key] = [];
|
||||
map[key].push(s);
|
||||
if(!map[key]) map[key] = {};
|
||||
do {
|
||||
s.updated = new Date().getTime();
|
||||
s.id = Md5.hashStr(s.updated.toString()).toString();
|
||||
} while (!!map[key][s.id]);
|
||||
map[key][s.id] = s;
|
||||
this.mapData.next(map);
|
||||
this.mapChanged = true;
|
||||
this.status.next('modified');
|
||||
@ -67,8 +71,8 @@ export class SyncService {
|
||||
addMyLocation(location: Position) {
|
||||
location.timestamp = new Date();
|
||||
let markForSave = this.location == null;
|
||||
if(!this.locationChanged) this.locationChanged = !_.isEqual(this.location, location);
|
||||
if(this.locationChanged) this.location = location;
|
||||
this.locationChanged = true;
|
||||
this.location = location;
|
||||
if(markForSave) return this.save(false, true);
|
||||
}
|
||||
|
||||
@ -86,9 +90,7 @@ export class SyncService {
|
||||
|
||||
delete(...symbols) {
|
||||
let map = this.mapData.value;
|
||||
Object.keys(map).filter(key => Array.isArray(map[key])).forEach(key => {
|
||||
symbols.forEach(s => map[key] = map[key].filter(ss => !_.isEqual(s, ss)))
|
||||
});
|
||||
Object.keys(map).forEach(key => symbols.filter(s => !!map[key][s.id]).forEach(s => map[key][s.id].deleted = true));
|
||||
this.mapData.next(map);
|
||||
this.mapChanged = true;
|
||||
this.status.next('modified');
|
||||
@ -105,15 +107,15 @@ export class SyncService {
|
||||
let aMinuteAgo = new Date();
|
||||
aMinuteAgo.setMinutes(aMinuteAgo.getMinutes() - 1);
|
||||
return ref.where('timestamp', '>=', aMinuteAgo);
|
||||
}).snapshotChanges())
|
||||
}).snapshotChanges(), this.freeze)
|
||||
.pipe(map(data => {
|
||||
let newMap = data[0];
|
||||
let oldMap = this.mapData.value;
|
||||
if(data[2]) return oldMap;
|
||||
let newMap = data[0] || {};
|
||||
let mergedMap = this.mergeMaps(newMap, oldMap);
|
||||
|
||||
let locations = data[1].map(doc => ({id: doc.payload.doc.id, data: <Marker>doc.payload.doc.data()}));
|
||||
locations.filter(l => l.id != username).forEach(l => {
|
||||
if(!mergedMap.locations) mergedMap.locations = {};
|
||||
mergedMap.locations[l.id] = l.data;
|
||||
});
|
||||
|
||||
@ -127,14 +129,20 @@ export class SyncService {
|
||||
}
|
||||
|
||||
mergeMaps(newMap: MapData, oldMap: MapData) {
|
||||
let map = Object.assign({}, newMap);
|
||||
Object.keys(oldMap).forEach(key => {
|
||||
if(Array.isArray(map[key])) {
|
||||
if(!map[key]) map[key] = [];
|
||||
oldMap[key].filter(s => !_.find(map[key], s) && s.new).forEach(s => map[key].push(s));
|
||||
}
|
||||
let map: MapData = {locations: {}};
|
||||
Object.keys(newMap).forEach(key => {
|
||||
if(!map[key]) map[key] = {};
|
||||
Object.keys(newMap[key]).filter(id => !newMap[key][id].deleted)
|
||||
.forEach(id => map[key][id] = newMap[key][id]);
|
||||
});
|
||||
|
||||
Object.keys(oldMap).filter(key => key != 'locations').forEach(key => {
|
||||
if(!map[key]) map[key] = {};
|
||||
Object.keys(oldMap[key]).filter(id => {
|
||||
let newS = map[key][id] || false;
|
||||
return newS && newS.updated > map[key][id].updated;
|
||||
}).forEach(id => map[key][id] = oldMap[key][id]);
|
||||
});
|
||||
if(!map.locations) map.locations = {};
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -153,7 +161,6 @@ export class SyncService {
|
||||
if(map && this.mapDoc && this.mapChanged) {
|
||||
this.status.next('saving');
|
||||
let map = this.mapData.value;
|
||||
Object.values(map).filter(val => Array.isArray(val)).forEach(val => val.filter(s => s.new).forEach(s => delete s.new));
|
||||
delete map.locations;
|
||||
promises.push(this.mapDoc.set(map));
|
||||
this.mapChanged = false;
|
||||
|
@ -2,7 +2,7 @@
|
||||
position: absolute;
|
||||
top: 15%;
|
||||
left: 50%;
|
||||
z-index: 500;
|
||||
z-index: 5000;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
bottom: 15%;
|
||||
left: 50%;
|
||||
width: 200px;
|
||||
z-index: 500;
|
||||
z-index: 5000;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
@ -19,5 +19,5 @@
|
||||
position: absolute;
|
||||
bottom: 2%;
|
||||
right: 2%;
|
||||
z-index: 500;
|
||||
z-index: 5000;
|
||||
}
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
.palette {
|
||||
position: fixed;
|
||||
z-index: 500;
|
||||
z-index: 5000;
|
||||
top: 60px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
.share {
|
||||
position: fixed;
|
||||
z-index: 500;
|
||||
z-index: 5000;
|
||||
top: 60px;
|
||||
right: 15px;
|
||||
}
|
||||
@ -19,14 +19,14 @@
|
||||
.info {
|
||||
background-color: #00000050;
|
||||
position: fixed;
|
||||
z-index: 500;
|
||||
z-index: 5000;
|
||||
bottom: 15px;
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
.gps {
|
||||
position: fixed;
|
||||
z-index: 500;
|
||||
z-index: 5000;
|
||||
bottom: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
@ -50,7 +50,7 @@
|
||||
::ng-deep .mat-toolbar {
|
||||
position: absolute;
|
||||
height: 45px !important;
|
||||
z-index: 500;
|
||||
z-index: 5000;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
|
||||
|
@ -12,9 +12,12 @@ 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";
|
||||
import {MapData, MapSymbol, Marker} from "../../models/mapSymbol";
|
||||
import {Adjectives} from "../../adjectives";
|
||||
import {Nouns} from "../../nounes";
|
||||
import {EditSymbolComponent} from "../../components/editSymbol/editSymbol.component";
|
||||
|
||||
declare const L;
|
||||
|
||||
@Component({
|
||||
selector: 'map',
|
||||
@ -95,28 +98,25 @@ export class MapComponent implements OnDestroy, OnInit {
|
||||
// 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(Object.assign(l, {icon: 'dot'})));
|
||||
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));
|
||||
if (map.circles) Object.values(map.circles).filter(c => !c.deleted).forEach(c => this.map.newCircle(c));
|
||||
if (map.locations) Object.values(map.locations).forEach(l => this.map.newMarker(Object.assign(l, {icon: 'dot', noDeleteTool: true})));
|
||||
if (map.markers) Object.values(map.markers).filter(m => !m.deleted).forEach(m => this.map.newMarker(m));
|
||||
if (map.measurements) Object.values(map.measurements).filter(m => !m.deleted).forEach(m => this.map.newMeasurement(m));
|
||||
if (map.polygons) Object.values(map.polygons).filter(p => !p.deleted).forEach(p => this.map.newPolygon(p));
|
||||
if (map.polylines) Object.values(map.polylines).filter(p => !p.deleted).forEach(p => this.map.newPolyline(p));
|
||||
if (map.rectangles) Object.values(map.rectangles).filter(r => !r.deleted).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);
|
||||
this.map.click.pipe(filter(e => !!e)).subscribe(e => {
|
||||
if(this.sub == null && e.symbol) {
|
||||
this.sub = this.bottomSheet.open(EditSymbolComponent, {data: e, disableClose: true, hasBackdrop: false}).afterDismissed().pipe(finalize(() => this.sub = null)).subscribe(symbol => {
|
||||
this.syncService.delete(e.symbol);
|
||||
if(e.item instanceof L.Circle) {
|
||||
this.syncService.addCircle(symbol);
|
||||
}
|
||||
});
|
||||
}*/
|
||||
}
|
||||
});
|
||||
|
||||
// Display location information & submit it
|
||||
@ -172,9 +172,12 @@ export class MapComponent implements OnDestroy, OnInit {
|
||||
startCalibrating = (menuItem?) => {
|
||||
this.calibration = this.bottomSheet.open(CalibrateComponent, {hasBackdrop: false, disableClose: true});
|
||||
this.sub = this.calibration.afterDismissed().pipe(finalize(() => {
|
||||
menuItem.enabled = false;
|
||||
})).subscribe(() => {
|
||||
this.calibration.dismiss();
|
||||
this.calibration = null;
|
||||
}), filter(menuItem => !!menuItem)).subscribe(() => menuItem.enabled = false);
|
||||
this.sub = null;
|
||||
});
|
||||
};
|
||||
|
||||
startCircle = menuItem => {
|
||||
@ -182,6 +185,7 @@ export class MapComponent implements OnDestroy, OnInit {
|
||||
let dimensions = await this.dialog.open(DimensionsDialogComponent, {data: ['Radius (m)'], panelClass: 'pb-0'}).afterClosed().toPromise();
|
||||
if(!dimensions) return;
|
||||
menuItem.enabled = false;
|
||||
this.sub = null;
|
||||
let circle = {latlng: e.latlng, radius: dimensions[0]};
|
||||
this.syncService.addCircle(circle);
|
||||
});
|
||||
@ -201,7 +205,7 @@ export class MapComponent implements OnDestroy, OnInit {
|
||||
this.showPalette = false;
|
||||
this.map.lock(true);
|
||||
})).subscribe(e => {
|
||||
let p = {latlng: [e.latlng], noDelete: true, color: this.drawColor, weight: 8};
|
||||
let p = {latlng: [e.latlng], noClick: true, 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(() => {
|
||||
@ -217,12 +221,13 @@ export class MapComponent implements OnDestroy, OnInit {
|
||||
startMarker = menuItem => {
|
||||
this.sub = this.map.click.pipe(skip(1), take(1)).subscribe(e => {
|
||||
menuItem.enabled = false;
|
||||
this.sub = null;
|
||||
let marker: Marker = {latlng: e.latlng};
|
||||
this.syncService.addMarker(marker);
|
||||
});
|
||||
};
|
||||
|
||||
startMeasuring = menuItem => {
|
||||
startMeasuring = () => {
|
||||
let lastPoint;
|
||||
this.sub = this.map.click.pipe(skip(1), finalize(() => this.map.delete(lastPoint))).subscribe(e => {
|
||||
if (lastPoint) {
|
||||
@ -253,6 +258,7 @@ export class MapComponent implements OnDestroy, OnInit {
|
||||
this.sub = this.map.click.pipe(skip(1), take(2), finalize(() => this.map.delete(lastPoint))).subscribe(e => {
|
||||
if (lastPoint) {
|
||||
menuItem.enabled = false;
|
||||
this.sub = null;
|
||||
let rect = {latlng: {lat: lastPoint.getLatLng().lat, lng: lastPoint.getLatLng().lng}, latlng2: e.latlng};
|
||||
this.syncService.addRectangle(rect);
|
||||
return this.map.delete(lastPoint);
|
||||
|
@ -14,6 +14,10 @@ body {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.curs-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.d-relative {
|
||||
position: relative;
|
||||
}
|
||||
@ -47,3 +51,22 @@ a[href^="https://maps.google.com/maps"]{display:none !important}
|
||||
background: none !important;
|
||||
|
||||
}
|
||||
|
||||
.cdk-overlay-container {
|
||||
z-index: 5500 !important;
|
||||
}
|
||||
|
||||
.leaflet-tooltip {
|
||||
background: rgba(0, 0, 0, 0.6) !important;
|
||||
border-color: rgba(0, 0, 0, 0.6) !important;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.leaflet-popup-content-wrapper {
|
||||
background: rgba(0, 0, 0, 0.6) !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.leaflet-popup-tip {
|
||||
background: rgba(0, 0, 0, 0.6) !important;
|
||||
}
|
||||
|
@ -7621,6 +7621,11 @@ try-require@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/try-require/-/try-require-1.2.1.tgz#34489a2cac0c09c1cc10ed91ba011594d4333be2"
|
||||
integrity sha1-NEiaLKwMCcHMEO2RugEVlNQzO+I=
|
||||
|
||||
ts-md5@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/ts-md5/-/ts-md5-1.2.5.tgz#4cb00ddf687251a2aba09922f95f766bf6486a15"
|
||||
integrity sha512-0E8UHsfEmK9CICH47YLVIN6/wtGJJ7/8XiAbUBszTHxeucglueTgPn86D8Ec3UG9tYWTICVY/EuUGQ+Xa2iSEA==
|
||||
|
||||
ts-node@~7.0.0:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf"
|
||||
|
Loading…
Reference in New Issue
Block a user