diff --git a/package.json b/package.json
index 620261c..0660616 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"leaflet-polylinedecorator": "^1.6.0",
"leaflet-rotatedmarker": "^0.2.0",
"ng-click-outside": "^5.0.0",
+ "ngx-color-picker": "^8.1.0",
"rxjs": "~6.4.0",
"tslib": "^1.9.0",
"web-animations-js": "^2.3.2",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 7e65816..d01bde6 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -19,12 +19,17 @@ import {PaletteComponent} from "./components/palette/palette.component";
import {MarkerComponent} from "./components/marker/marker.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";
@NgModule({
declarations: [
AnimatedBackgroundComponent,
AppComponent,
CalibrateComponent,
+ CircleComponent,
+ ColorPickerDialogComponent,
HomeComponent,
MapComponent,
MarkerComponent,
@@ -39,13 +44,14 @@ import {ClickOutsideModule} from "ng-click-outside";
BrowserAnimationsModule,
BrowserModule,
ClickOutsideModule,
+ ColorPickerModule,
FormsModule,
MaterialModule,
ServiceWorkerModule.register('ngsw-worker.js', {enabled: environment.production}),
MatInputModule,
],
providers: [],
- entryComponents: [CalibrateComponent, MarkerComponent, PermissionsComponent],
+ entryComponents: [CalibrateComponent, CircleComponent, ColorPickerDialogComponent, MarkerComponent, PermissionsComponent],
bootstrap: [AppComponent]
})
export class AppModule {
diff --git a/src/app/components/circle/circle.component.html b/src/app/components/circle/circle.component.html
new file mode 100644
index 0000000..ab338c5
--- /dev/null
+++ b/src/app/components/circle/circle.component.html
@@ -0,0 +1,17 @@
+
+
+
+
+ Notes
+
+
+
+
+
+
diff --git a/src/app/components/circle/circle.component.ts b/src/app/components/circle/circle.component.ts
new file mode 100644
index 0000000..cbfc6a7
--- /dev/null
+++ b/src/app/components/circle/circle.component.ts
@@ -0,0 +1,37 @@
+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
+ });
+ }
+}
diff --git a/src/app/components/colorPickerDialog/colorPickerDialog.component.html b/src/app/components/colorPickerDialog/colorPickerDialog.component.html
new file mode 100644
index 0000000..f66427d
--- /dev/null
+++ b/src/app/components/colorPickerDialog/colorPickerDialog.component.html
@@ -0,0 +1,7 @@
+
diff --git a/src/app/components/colorPickerDialog/colorPickerDialog.component.ts b/src/app/components/colorPickerDialog/colorPickerDialog.component.ts
new file mode 100644
index 0000000..8f5fe99
--- /dev/null
+++ b/src/app/components/colorPickerDialog/colorPickerDialog.component.ts
@@ -0,0 +1,14 @@
+import {Component, Inject} from "@angular/core";
+import {MAT_DIALOG_DATA} from "@angular/material/dialog";
+
+@Component({
+ selector: '',
+ templateUrl: `./colorPickerDialog.component.html`
+})
+export class ColorPickerDialogComponent {
+ readonly originalColor: string;
+
+ constructor(@Inject(MAT_DIALOG_DATA) public color) {
+ this.originalColor = color;
+ }
+}
diff --git a/src/app/components/marker/marker.component.html b/src/app/components/marker/marker.component.html
index 34f4858..c54814d 100644
--- a/src/app/components/marker/marker.component.html
+++ b/src/app/components/marker/marker.component.html
@@ -5,4 +5,6 @@
+
+
diff --git a/src/app/components/marker/marker.component.ts b/src/app/components/marker/marker.component.ts
index 8d42f6e..f1ca28d 100644
--- a/src/app/components/marker/marker.component.ts
+++ b/src/app/components/marker/marker.component.ts
@@ -9,4 +9,8 @@ import {MAT_BOTTOM_SHEET_DATA} from "@angular/material/bottom-sheet";
export class MarkerComponent {
constructor(private bottomSheetRef: MatBottomSheetRef, @Inject(MAT_BOTTOM_SHEET_DATA) public marker) { }
+
+ close() {
+ this.bottomSheetRef.dismiss();
+ }
}
diff --git a/src/app/models/drawing.ts b/src/app/models/drawing.ts
deleted file mode 100644
index 3ed5a75..0000000
--- a/src/app/models/drawing.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {LatLng} from "./latlng";
-
-export interface Drawing {
- color: string;
- path: LatLng[];
-}
diff --git a/src/app/models/latlng.ts b/src/app/models/latlng.ts
deleted file mode 100644
index 818e6bf..0000000
--- a/src/app/models/latlng.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export interface LatLng {
- lat: number;
- lng: number;
-}
diff --git a/src/app/models/map.ts b/src/app/models/map.ts
index 210d09a..912d1c8 100644
--- a/src/app/models/map.ts
+++ b/src/app/models/map.ts
@@ -1,12 +1,2 @@
-import {Marker} from "./marker";
-import {Drawing} from "./drawing";
-import {User} from "./user";
-import {Message} from "./message";
-
export interface Map {
- drawings: Drawing[];
- markers: Marker[];
- messages: Message[];
- name: string;
- users: User[];
}
diff --git a/src/app/models/mapSymbol.ts b/src/app/models/mapSymbol.ts
new file mode 100644
index 0000000..ee66cf2
--- /dev/null
+++ b/src/app/models/mapSymbol.ts
@@ -0,0 +1,46 @@
+export interface LatLng {
+ lat: number;
+ lng: number;
+}
+
+export interface MapSymbol {
+ symbol?: any;
+ latlng?: LatLng | LatLng[];
+ noDelete?: boolean;
+ noSelect?: boolean;
+ label?: string;
+ color?: string;
+ notes?: string;
+ interactive?: boolean;
+ rotationAngle?: number;
+ rotationOrigin?: string;
+}
+
+export interface Circle extends MapSymbol {
+ latlng: LatLng;
+ radius?: number;
+}
+
+export interface Square extends MapSymbol {
+ latlng: LatLng;
+ latlng2: LatLng;
+}
+
+export interface Polyline extends MapSymbol {
+ latlng: LatLng[];
+}
+
+export interface Marker extends MapSymbol {
+ latlng: LatLng;
+ icon?: any;
+}
+
+export interface Polygon extends MapSymbol {
+ latlng: LatLng[];
+}
+
+export interface Measurement extends MapSymbol {
+ latlng: LatLng;
+ latlng2: LatLng;
+ weight?: number;
+}
diff --git a/src/app/models/marker.ts b/src/app/models/marker.ts
deleted file mode 100644
index 98e2f5b..0000000
--- a/src/app/models/marker.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import {LatLng} from "./latlng";
-
-export interface Marker {
- latLng: LatLng;
- name: string;
- color: string;
- notes: string;
- icon: string;
-}
diff --git a/src/app/models/measurement.ts b/src/app/models/measurement.ts
deleted file mode 100644
index e008bdf..0000000
--- a/src/app/models/measurement.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {LatLng} from "./latlng";
-
-export interface Measurement {
- start: LatLng;
- end: LatLng;
-}
diff --git a/src/app/models/message.ts b/src/app/models/message.ts
deleted file mode 100644
index 540119d..0000000
--- a/src/app/models/message.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {User} from "./user";
-
-export interface Message {
- from: User;
- text: string;
-}
diff --git a/src/app/models/user.ts b/src/app/models/user.ts
deleted file mode 100644
index 8d3b5a9..0000000
--- a/src/app/models/user.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import {LatLng} from "./latlng";
-
-export interface User {
- name: string;
- icon: string;
- latLng: LatLng;
-}
diff --git a/src/app/services/map.service.ts b/src/app/services/map.service.ts
index 9d0b9a0..7b7e880 100644
--- a/src/app/services/map.service.ts
+++ b/src/app/services/map.service.ts
@@ -1,7 +1,7 @@
import {BehaviorSubject} from "rxjs";
import {distanceInM} from "../utils";
import {environment} from "../../environments/environment";
-import {LatLng} from "../models/latlng";
+import {Circle, LatLng, Marker, Measurement} from "../models/mapSymbol";
declare const L;
@@ -39,6 +39,8 @@ export class MapService {
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({event: e}));
this.setMapLayer();
+
+ this.map.on('editable:drag', e => console.log(e));
}
centerOn(latlng: LatLng, zoom=14) {
@@ -115,34 +117,36 @@ export class MapService {
if(this.weatherLayer) this.weatherLayer.layer.addTo(this.map);
}
- newCircle(latlng: LatLng, radius?: number, opts: any={}) {
- if(!radius) radius = 100_000 / this.map.getZoom();
- opts.radius = radius;
- let circle = L.circle(latlng, opts).addTo(this.map);
+ newCircle(c: Circle) {
+ if(!c.radius) c.radius = 10000;
+ if(!c.color) c.color = '#ff4141';
+ let circle = L.circle(c.latlng, c).addTo(this.map);
+ circle.symbol = c;
circle.on('click', e => this.click.next({event: e, symbol: circle}));
return circle;
}
- newMarker(latlng: LatLng, opts: any={}) {
- if(!opts.icon) opts.icon = MARKER;
- let marker = L.marker(latlng, opts).addTo(this.map);
- if(opts.label) marker.bindTooltip(opts.label, {permanent: true, direction: 'bottom'});
- this.markers.push(marker);
+ newMarker(m: Marker) {
+ if(!m.icon) m.icon = MARKER;
+ let marker = L.marker(m.latlng, m).addTo(this.map);
+ if(m.label) marker.bindTooltip(m.label, {permanent: true, direction: 'bottom'});
+ marker.symbol = m;
marker.on('click', e => this.click.next({event: e, symbol: marker}));
return marker;
}
- newMeasurement(latlng1: LatLng, latlng2: LatLng) {
- let line = L.polyline([latlng1, latlng2], {color: '#ff4141', weight: 10});
+ newMeasurement(m: Measurement) {
+ if(!m.color) m.color = '#ff4141';
+ if(!m.weight) m.weight = 8;
+ let line = L.polyline([m.latlng, m.latlng2], m);
let decoration = L.polylineDecorator(line, {patterns: [
- {offset: '100%', repeat: 0, symbol: L.Symbol.arrowHead({pixelSize: 15, polygon: false, headAngle: 180, pathOptions: {color: '#ff4141', weight: 10, stroke: true}})},
- {offset: '-100%', repeat: 0, symbol: L.Symbol.arrowHead({pixelSize: 15, polygon: false, headAngle: 180, pathOptions: {color: '#ff4141', weight: 10, stroke: true}})}
+ {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})}
]});
- this.measurements.push({line: line, decoration: decoration});
- let distance = distanceInM(latlng1.lat, latlng1.lng, latlng2.lat, latlng2.lng);
- let group = L.layerGroup([line, decoration]);
+ let group = L.layerGroup([line, decoration]).addTo(this.map);
+ group.symbol = m;
line.on('click', e => this.click.next({event: e, symbol: group}));
- group.addTo(this.map);
+ let distance = distanceInM(m.latlng.lat, m.latlng.lng, m.latlng2.lat, m.latlng2.lng);
line.bindPopup(`${distance > 1000 ? Math.round(distance / 100) / 10 : Math.round(distance)} ${distance > 1000 ? 'k' : ''}m`, {autoClose: false, closeOnClick: false}).openPopup();
return group;
}
diff --git a/src/app/views/map/map.component.ts b/src/app/views/map/map.component.ts
index 46f6117..19d3ed7 100644
--- a/src/app/views/map/map.component.ts
+++ b/src/app/views/map/map.component.ts
@@ -11,6 +11,7 @@ import {MarkerComponent} from "../../components/marker/marker.component";
import {MatBottomSheetRef} from "@angular/material/bottom-sheet";
import {copyToClipboard} from "../../utils";
import {ActivatedRoute} from "@angular/router";
+import {CircleComponent} from "../../components/circle/circle.component";
declare const L;
@@ -70,17 +71,30 @@ export class MapComponent implements OnInit {
this.map = new MapService('map');
// Handle click actions
- this.map.click.pipe(filter(e => !!e)).subscribe(e => {
- if(!!e.symbol && this.menu[6].enabled) return this.map.delete(e.symbol);
- if(e.symbol instanceof L.Marker) this.bottomSheet.open(MarkerComponent, {data: e.symbol});
+ 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;
+ /*this.bottomSheet.open(MarkerComponent, {data: e.symbol, hasBackdrop: false, disableClose: true});*/
+ } else if(e.symbol instanceof L.Circle) {
+ if(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.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({lat: pos.latitude, lng: pos.longitude}, {noDelete: true, icon: ARROW, rotationAngle: pos.heading, rotationOrigin: 'center'});
- this.positionMarker.circle = this.map.newCircle({lat: pos.latitude, lng: pos.longitude}, 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', radius: pos.accuracy, interactive: false});
this.position = pos;
});
@@ -95,14 +109,14 @@ export class MapComponent implements OnInit {
addCircle() {
this.map.click.pipe(skip(1), take(1), filter(() => this.menu[2].enabled)).subscribe(e => {
this.menu[2].enabled = false;
- this.map.newCircle(e.event.latlng);
+ this.map.newCircle({latlng: e.event.latlng});
});
}
addMarker() {
this.map.click.pipe(skip(1), take(1), filter(() => this.menu[0].enabled)).subscribe(e => {
this.menu[0].enabled = false;
- this.map.newMarker(e.event.latlng);
+ this.map.newMarker({latlng: e.event.latlng});
});
}
@@ -147,10 +161,10 @@ export class MapComponent implements OnInit {
startMeasuring() {
this.measuringSubscription = this.map.click.pipe(skip(1)).subscribe(e => {
if(this.lastMeasuringPoint) {
- this.map.newMeasurement(this.lastMeasuringPoint.getLatLng(), e.event.latlng);
+ this.map.newMeasurement({latlng: this.lastMeasuringPoint.getLatLng(), latlng2: e.event.latlng});
this.map.delete(this.lastMeasuringPoint);
}
- this.lastMeasuringPoint = this.map.newMarker(e.event.latlng, {icon: MEASURE});
+ this.lastMeasuringPoint = this.map.newMarker({latlng: e.event.latlng, icon: MEASURE});
})
}
diff --git a/src/styles.scss b/src/styles.scss
index a4f51f6..528e254 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -16,3 +16,18 @@ body {
font-family: Roboto, "Helvetica Neue", sans-serif;
background-color: black;
}
+
+.d-relative {
+ position: relative;
+}
+
+.overflow-hidden {
+ overflow: hidden;
+}
+
+.cdk-overlay-pane.p-0 {
+ .mat-dialog-container {
+ padding: 0;
+ overflow: hidden;
+ }
+}