Commit 715eefa6d0b1cf035a770166179e3081504c4adb
Committed by
GitHub
Merge pull request #5616 from vvlladd28/improvement/map-widgets/marker-placement
[3.3.3] UI: Improvement add/edit location marker/polygon in maps widgets
Showing
29 changed files
with
758 additions
and
445 deletions
... | ... | @@ -830,6 +830,7 @@ |
830 | 830 | <exclude>src/.browserslistrc</exclude> |
831 | 831 | <exclude>**/yarn.lock</exclude> |
832 | 832 | <exclude>**/*.raw</exclude> |
833 | + <exclude>**/*.patch</exclude> | |
833 | 834 | <exclude>**/apache/cassandra/io/**</exclude> |
834 | 835 | <exclude>.run/**</exclude> |
835 | 836 | </excludes> | ... | ... |
... | ... | @@ -79,6 +79,7 @@ |
79 | 79 | "src/app/modules/home/components/widget/lib/maps/markers.scss", |
80 | 80 | "node_modules/leaflet.markercluster/dist/MarkerCluster.css", |
81 | 81 | "node_modules/leaflet.markercluster/dist/MarkerCluster.Default.css", |
82 | + "node_modules/@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css", | |
82 | 83 | "node_modules/prismjs/themes/prism.css", |
83 | 84 | "node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css" |
84 | 85 | ], | ... | ... |
... | ... | @@ -28,6 +28,7 @@ |
28 | 28 | "@date-io/date-fns": "^2.10.11", |
29 | 29 | "@flowjs/flow.js": "^2.14.1", |
30 | 30 | "@flowjs/ngx-flow": "~0.4.6", |
31 | + "@geoman-io/leaflet-geoman-free": "^2.11.3", | |
31 | 32 | "@juggle/resize-observer": "^3.3.1", |
32 | 33 | "@mat-datetimepicker/core": "~6.0.2", |
33 | 34 | "@material-ui/core": "^4.11.4", |
... | ... | @@ -57,11 +58,10 @@ |
57 | 58 | "jstree-bootstrap-theme": "^1.0.1", |
58 | 59 | "jszip": "^3.6.0", |
59 | 60 | "leaflet": "^1.7.1", |
60 | - "leaflet-editable": "^1.2.0", | |
61 | 61 | "leaflet-polylinedecorator": "^1.6.0", |
62 | - "leaflet-providers": "^1.12.0", | |
63 | - "leaflet.gridlayer.googlemutant": "0.10.2", | |
64 | - "leaflet.markercluster": "^1.5.0", | |
62 | + "leaflet-providers": "^1.13.0", | |
63 | + "leaflet.gridlayer.googlemutant": "^0.13.4", | |
64 | + "leaflet.markercluster": "^1.5.3", | |
65 | 65 | "material-design-icons": "^3.0.1", |
66 | 66 | "messageformat": "^2.3.0", |
67 | 67 | "moment": "^2.29.1", |
... | ... | @@ -113,10 +113,11 @@ |
113 | 113 | "@types/jquery": "^3.5.2", |
114 | 114 | "@types/js-beautify": "^1.13.1", |
115 | 115 | "@types/jstree": "^3.3.40", |
116 | - "@types/leaflet": "1.5.17", | |
117 | - "@types/leaflet-editable": "^1.2.1", | |
118 | - "@types/leaflet-polylinedecorator": "^1.6.0", | |
119 | - "@types/leaflet.markercluster": "^1.4.4", | |
116 | + "@types/leaflet": "^1.7.6", | |
117 | + "@types/leaflet-polylinedecorator": "^1.6.1", | |
118 | + "@types/leaflet-providers": "^1.2.1", | |
119 | + "@types/leaflet.gridlayer.googlemutant": "^0.4.6", | |
120 | + "@types/leaflet.markercluster": "^1.4.6", | |
120 | 121 | "@types/lodash": "^4.14.170", |
121 | 122 | "@types/moment-timezone": "^0.5.30", |
122 | 123 | "@types/mousetrap": "1.6.3", | ... | ... |
ui-ngx/src/app/modules/home/components/widget/lib/maps/dialogs/select-entity-dialog.component.html
0 → 100644
1 | +<!-- | |
2 | + | |
3 | + Copyright © 2016-2021 The Thingsboard Authors | |
4 | + | |
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | + you may not use this file except in compliance with the License. | |
7 | + You may obtain a copy of the License at | |
8 | + | |
9 | + http://www.apache.org/licenses/LICENSE-2.0 | |
10 | + | |
11 | + Unless required by applicable law or agreed to in writing, software | |
12 | + distributed under the License is distributed on an "AS IS" BASIS, | |
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | + See the License for the specific language governing permissions and | |
15 | + limitations under the License. | |
16 | + | |
17 | +--> | |
18 | +<form #addEntityForm="ngForm" [formGroup]="selectEntityFormGroup" (ngSubmit)="save()"> | |
19 | + <mat-toolbar fxLayout="row" color="primary"> | |
20 | + <h2 translate>widgets.maps.select-entity</h2> | |
21 | + <span fxFlex></span> | |
22 | + <button mat-icon-button [matDialogClose]="null" type="button"> | |
23 | + <mat-icon class="material-icons">close</mat-icon> | |
24 | + </button> | |
25 | + </mat-toolbar> | |
26 | + <mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async"> | |
27 | + </mat-progress-bar> | |
28 | + <div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div> | |
29 | + <div mat-dialog-content> | |
30 | + <mat-form-field class="mat-block" style="min-width: 280px"> | |
31 | + <mat-label translate>entity.entity</mat-label> | |
32 | + <mat-select formControlName="entity"> | |
33 | + <mat-option *ngFor="let entity of data.entities" [value]="entity"> | |
34 | + {{ entity.entityName }} | |
35 | + </mat-option> | |
36 | + </mat-select> | |
37 | + </mat-form-field> | |
38 | + <div class="tb-hint" translate>widgets.maps.select-entity-hint</div> | |
39 | + </div> | |
40 | + <div mat-dialog-actions fxLayout="row" fxLayoutAlign="end center"> | |
41 | + <button mat-button color="primary" | |
42 | + type="button" | |
43 | + [disabled]="(isLoading$ | async)" | |
44 | + [matDialogClose]="null" | |
45 | + cdkFocusInitial> | |
46 | + {{ 'action.cancel' | translate }} | |
47 | + </button> | |
48 | + <button mat-raised-button color="primary" | |
49 | + type="submit" | |
50 | + [disabled]="(isLoading$ | async) || addEntityForm.invalid || !addEntityForm.dirty"> | |
51 | + {{ 'action.add' | translate }} | |
52 | + </button> | |
53 | + </div> | |
54 | +</form> | ... | ... |
ui-ngx/src/app/modules/home/components/widget/lib/maps/dialogs/select-entity-dialog.component.scss
0 → 100644
1 | +/** | |
2 | + * Copyright © 2016-2021 The Thingsboard Authors | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | +:host { | |
17 | + .tb-hint { | |
18 | + margin-top: -1.25em; | |
19 | + max-width: fit-content; | |
20 | + } | |
21 | +} | ... | ... |
ui-ngx/src/app/modules/home/components/widget/lib/maps/dialogs/select-entity-dialog.component.ts
0 → 100644
1 | +/// | |
2 | +/// Copyright © 2016-2021 The Thingsboard Authors | |
3 | +/// | |
4 | +/// Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | +/// you may not use this file except in compliance with the License. | |
6 | +/// You may obtain a copy of the License at | |
7 | +/// | |
8 | +/// http://www.apache.org/licenses/LICENSE-2.0 | |
9 | +/// | |
10 | +/// Unless required by applicable law or agreed to in writing, software | |
11 | +/// distributed under the License is distributed on an "AS IS" BASIS, | |
12 | +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | +/// See the License for the specific language governing permissions and | |
14 | +/// limitations under the License. | |
15 | +/// | |
16 | + | |
17 | +import { Component, Inject } from '@angular/core'; | |
18 | +import { DialogComponent } from '@shared/components/dialog.component'; | |
19 | +import { Store } from '@ngrx/store'; | |
20 | +import { AppState } from '@core/core.state'; | |
21 | +import { Router } from '@angular/router'; | |
22 | +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; | |
23 | +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; | |
24 | +import { FormattedData } from '@home/components/widget/lib/maps/map-models'; | |
25 | + | |
26 | +export interface SelectEntityDialogData { | |
27 | + entities: FormattedData[]; | |
28 | +} | |
29 | + | |
30 | +@Component({ | |
31 | + selector: 'tb-select-entity-dialog', | |
32 | + templateUrl: './select-entity-dialog.component.html', | |
33 | + styleUrls: ['./select-entity-dialog.component.scss'] | |
34 | +}) | |
35 | +export class SelectEntityDialogComponent extends DialogComponent<SelectEntityDialogComponent, FormattedData> { | |
36 | + | |
37 | + selectEntityFormGroup: FormGroup; | |
38 | + | |
39 | + constructor(protected store: Store<AppState>, | |
40 | + protected router: Router, | |
41 | + @Inject(MAT_DIALOG_DATA) public data: SelectEntityDialogData, | |
42 | + public dialogRef: MatDialogRef<SelectEntityDialogComponent, FormattedData>, | |
43 | + public fb: FormBuilder) { | |
44 | + super(store, router, dialogRef); | |
45 | + | |
46 | + this.selectEntityFormGroup = this.fb.group( | |
47 | + { | |
48 | + entity: ['', Validators.required] | |
49 | + } | |
50 | + ); | |
51 | + } | |
52 | + | |
53 | + save(): void { | |
54 | + this.dialogRef.close(this.selectEntityFormGroup.value.entity); | |
55 | + } | |
56 | +} | ... | ... |
... | ... | @@ -14,23 +14,15 @@ |
14 | 14 | /// limitations under the License. |
15 | 15 | /// |
16 | 16 | |
17 | -import L, { | |
18 | - FeatureGroup, | |
19 | - Icon, | |
20 | - LatLngBounds, | |
21 | - LatLngTuple, | |
22 | - markerClusterGroup, | |
23 | - MarkerClusterGroup, | |
24 | - MarkerClusterGroupOptions, Projection | |
25 | -} from 'leaflet'; | |
17 | +import L, { FeatureGroup, Icon, LatLngBounds, LatLngTuple, Projection } from 'leaflet'; | |
26 | 18 | import tinycolor from 'tinycolor2'; |
27 | 19 | import 'leaflet-providers'; |
28 | -import 'leaflet.markercluster/dist/leaflet.markercluster'; | |
20 | +import { MarkerClusterGroup, MarkerClusterGroupOptions } from 'leaflet.markercluster/dist/leaflet.markercluster'; | |
21 | +import '@geoman-io/leaflet-geoman-free'; | |
29 | 22 | |
30 | 23 | import { |
31 | 24 | defaultSettings, |
32 | 25 | FormattedData, |
33 | - MapProviders, | |
34 | 26 | MapSettings, |
35 | 27 | MarkerSettings, |
36 | 28 | PolygonSettings, |
... | ... | @@ -39,12 +31,10 @@ import { |
39 | 31 | UnitedMapSettings |
40 | 32 | } from './map-models'; |
41 | 33 | import { Marker } from './markers'; |
42 | -import { Observable, of } from 'rxjs'; | |
34 | +import { forkJoin, Observable, of } from 'rxjs'; | |
43 | 35 | import { Polyline } from './polyline'; |
44 | 36 | import { Polygon } from './polygon'; |
45 | -import { | |
46 | - createTooltip, | |
47 | -} from '@home/components/widget/lib/maps/maps-utils'; | |
37 | +import { createTooltip } from '@home/components/widget/lib/maps/maps-utils'; | |
48 | 38 | import { |
49 | 39 | checkLngLat, |
50 | 40 | createLoadingDiv, |
... | ... | @@ -54,6 +44,15 @@ import { |
54 | 44 | } from '@home/components/widget/lib/maps/common-maps-utils'; |
55 | 45 | import { WidgetContext } from '@home/models/widget-component.models'; |
56 | 46 | import { deepClone, isDefinedAndNotNull, isEmptyStr, isString } from '@core/utils'; |
47 | +import { TranslateService } from '@ngx-translate/core'; | |
48 | +import { | |
49 | + SelectEntityDialogComponent, | |
50 | + SelectEntityDialogData | |
51 | +} from '@home/components/widget/lib/maps/dialogs/select-entity-dialog.component'; | |
52 | +import { MatDialog } from '@angular/material/dialog'; | |
53 | +import { AttributeService } from '@core/http/attribute.service'; | |
54 | +import { EntityId } from '@shared/models/id/entity-id'; | |
55 | +import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models'; | |
57 | 56 | |
58 | 57 | export default abstract class LeafletMap { |
59 | 58 | |
... | ... | @@ -78,20 +77,20 @@ export default abstract class LeafletMap { |
78 | 77 | drawRoutes: boolean; |
79 | 78 | showPolygon: boolean; |
80 | 79 | updatePending = false; |
80 | + editPolygons = false; | |
81 | + selectedEntity: FormattedData; | |
81 | 82 | addMarkers: L.Marker[] = []; |
82 | 83 | addPolygons: L.Polygon[] = []; |
83 | 84 | // tslint:disable-next-line:no-string-literal |
84 | 85 | southWest = new L.LatLng(-Projection.SphericalMercator['MAX_LATITUDE'], -180); |
85 | 86 | // tslint:disable-next-line:no-string-literal |
86 | 87 | northEast = new L.LatLng(Projection.SphericalMercator['MAX_LATITUDE'], 180); |
87 | - mousePositionOnMap: L.LatLng; | |
88 | - addMarker: L.Control; | |
89 | - addPolygon: L.Control; | |
90 | 88 | |
91 | 89 | protected constructor(public ctx: WidgetContext, |
92 | 90 | public $container: HTMLElement, |
93 | 91 | options: UnitedMapSettings) { |
94 | 92 | this.options = options; |
93 | + this.editPolygons = options.showPolygon && options.editablePolygon; | |
95 | 94 | } |
96 | 95 | |
97 | 96 | public initSettings(options: MapSettings) { |
... | ... | @@ -102,16 +101,28 @@ export default abstract class LeafletMap { |
102 | 101 | removeOutsideVisibleBounds, |
103 | 102 | animate, |
104 | 103 | chunkedLoading, |
104 | + spiderfyOnMaxZoom, | |
105 | 105 | maxClusterRadius, |
106 | 106 | maxZoom }: MapSettings = options; |
107 | 107 | if (useClusterMarkers) { |
108 | + // disabled marker cluster icon | |
109 | + (L as any).MarkerCluster = (L as any).MarkerCluster.extend({ | |
110 | + options: { pmIgnore: true, ...L.Icon.prototype.options } | |
111 | + }); | |
108 | 112 | const clusteringSettings: MarkerClusterGroupOptions = { |
109 | - spiderfyOnMaxZoom: false, | |
113 | + spiderfyOnMaxZoom, | |
110 | 114 | zoomToBoundsOnClick: zoomOnClick, |
111 | 115 | showCoverageOnHover, |
112 | 116 | removeOutsideVisibleBounds, |
113 | 117 | animate, |
114 | - chunkedLoading | |
118 | + chunkedLoading, | |
119 | + pmIgnore: true, | |
120 | + spiderLegPolylineOptions: { | |
121 | + pmIgnore: true | |
122 | + }, | |
123 | + polygonOptions: { | |
124 | + pmIgnore: true | |
125 | + } | |
115 | 126 | }; |
116 | 127 | if (maxClusterRadius && maxClusterRadius > 0) { |
117 | 128 | clusteringSettings.maxClusterRadius = Math.floor(maxClusterRadius); |
... | ... | @@ -119,183 +130,165 @@ export default abstract class LeafletMap { |
119 | 130 | if (maxZoom && maxZoom >= 0 && maxZoom < 19) { |
120 | 131 | clusteringSettings.disableClusteringAtZoom = Math.floor(maxZoom); |
121 | 132 | } |
122 | - this.markersCluster = markerClusterGroup(clusteringSettings); | |
133 | + this.markersCluster = new MarkerClusterGroup(clusteringSettings); | |
123 | 134 | } |
124 | 135 | } |
125 | 136 | |
126 | - addMarkerControl() { | |
127 | - if (this.options.draggableMarker) { | |
128 | - this.map.on('mousemove', (e: L.LeafletMouseEvent) => { | |
129 | - this.mousePositionOnMap = e.latlng; | |
130 | - }); | |
131 | - const dragListener = (e: L.DragEndEvent) => { | |
132 | - if (e.type === 'dragend' && this.mousePositionOnMap) { | |
133 | - const icon = L.icon({ | |
134 | - iconRetinaUrl: 'marker-icon-2x.png', | |
135 | - iconUrl: 'marker-icon.png', | |
136 | - shadowUrl: 'marker-shadow.png', | |
137 | - iconSize: [25, 41], | |
138 | - iconAnchor: [12, 41], | |
139 | - popupAnchor: [1, -34], | |
140 | - tooltipAnchor: [16, -28], | |
141 | - shadowSize: [41, 41] | |
142 | - }); | |
143 | - const customLatLng = this.convertToCustomFormat(this.mousePositionOnMap); | |
144 | - this.mousePositionOnMap.lat = customLatLng[this.options.latKeyName]; | |
145 | - this.mousePositionOnMap.lng = customLatLng[this.options.lngKeyName]; | |
146 | - | |
147 | - const newMarker = L.marker(this.mousePositionOnMap, { icon }).addTo(this.map); | |
148 | - this.addMarkers.push(newMarker); | |
149 | - const datasourcesList = document.createElement('div'); | |
150 | - const header = document.createElement('p'); | |
151 | - header.appendChild(document.createTextNode('Select entity:')); | |
152 | - header.setAttribute('style', 'font-size: 14px; margin: 8px 0'); | |
153 | - datasourcesList.appendChild(header); | |
154 | - this.datasources.forEach(ds => { | |
155 | - const dsItem = document.createElement('p'); | |
156 | - dsItem.appendChild(document.createTextNode(ds.entityName)); | |
157 | - dsItem.setAttribute('style', 'font-size: 14px; margin: 8px 0; cursor: pointer'); | |
158 | - dsItem.onclick = () => { | |
159 | - const updatedEnttity = { ...ds, ...customLatLng }; | |
160 | - this.saveMarkerLocation(updatedEnttity).subscribe(() => { | |
161 | - this.map.removeLayer(newMarker); | |
162 | - const markerIndex = this.addMarkers.indexOf(newMarker); | |
163 | - if (markerIndex > -1) { | |
164 | - this.addMarkers.splice(markerIndex, 1); | |
165 | - } | |
166 | - this.deleteMarker(ds.entityName); | |
167 | - this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options); | |
168 | - }); | |
169 | - }; | |
170 | - datasourcesList.appendChild(dsItem); | |
171 | - }); | |
172 | - datasourcesList.appendChild(document.createElement('br')); | |
173 | - const deleteBtn = document.createElement('a'); | |
174 | - deleteBtn.appendChild(document.createTextNode('Discard changes')); | |
175 | - deleteBtn.onclick = () => { | |
176 | - this.map.removeLayer(newMarker); | |
177 | - const markerIndex = this.addMarkers.indexOf(newMarker); | |
178 | - if (markerIndex > -1) { | |
179 | - this.addMarkers.splice(markerIndex, 1); | |
180 | - } | |
181 | - }; | |
182 | - datasourcesList.appendChild(deleteBtn); | |
183 | - const popup = L.popup(); | |
184 | - popup.setContent(datasourcesList); | |
185 | - newMarker.bindPopup(popup).openPopup(); | |
186 | - } | |
187 | - this.addMarker.setPosition('topright'); | |
188 | - }; | |
189 | - const addMarker = L.Control.extend({ | |
190 | - onAdd() { | |
191 | - const img = L.DomUtil.create('img') as any; | |
192 | - img.src = `assets/add_location.svg`; | |
193 | - img.style.width = '32px'; | |
194 | - img.style.height = '32px'; | |
195 | - img.title = 'Drag and drop to add marker'; | |
196 | - img.onclick = this.dragMarker; | |
197 | - img.draggable = true; | |
198 | - const draggableImg = new L.Draggable(img); | |
199 | - draggableImg.enable(); | |
200 | - draggableImg.on('dragend', dragListener); | |
201 | - return img; | |
202 | - }, | |
203 | - onRemove() { | |
204 | - }, | |
205 | - dragMarker: this.dragMarker | |
206 | - } as any); | |
207 | - const addMarkerControl = (opts) => { | |
208 | - return new addMarker(opts); | |
209 | - }; | |
210 | - this.addMarker = addMarkerControl({ position: 'topright' }).addTo(this.map); | |
137 | + private selectEntityWithoutLocationDialog(shapes: L.PM.SUPPORTED_SHAPES): Observable<FormattedData> { | |
138 | + let entities; | |
139 | + switch (shapes) { | |
140 | + case 'Polygon': | |
141 | + case 'Rectangle': | |
142 | + entities = this.datasources.filter(pData => !this.isValidPolygonPosition(pData)); | |
143 | + break; | |
144 | + case 'Marker': | |
145 | + entities = this.datasources.filter(mData => !this.convertPosition(mData)); | |
146 | + break; | |
147 | + default: | |
148 | + return of(null); | |
149 | + } | |
150 | + if (entities.length === 1) { | |
151 | + return of(entities[0]); | |
152 | + } | |
153 | + const dialog = this.ctx.$injector.get(MatDialog); | |
154 | + return dialog.open<SelectEntityDialogComponent, SelectEntityDialogData, FormattedData>(SelectEntityDialogComponent, | |
155 | + { | |
156 | + disableClose: true, | |
157 | + panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], | |
158 | + data: { | |
159 | + entities | |
160 | + } | |
161 | + }).afterClosed(); | |
162 | + } | |
163 | + | |
164 | + private selectEntityWithoutLocation(type: string) { | |
165 | + this.selectEntityWithoutLocationDialog(type.substring(2)).subscribe((data) => { | |
166 | + if (data !== null) { | |
167 | + this.selectedEntity = data; | |
168 | + this.toggleDrawMode(type); | |
169 | + } else { | |
170 | + this.map.pm.Toolbar.toggleButton(type, false); | |
211 | 171 | } |
172 | + }); | |
173 | + } | |
174 | + | |
175 | + private toggleDrawMode(type: string) { | |
176 | + this.map.pm.Draw[type].toggle(); | |
212 | 177 | } |
213 | 178 | |
214 | - addPolygonControl() { | |
215 | - if (this.options.showPolygon && this.options.editablePolygon) { | |
216 | - this.map.on('mousemove', (e: L.LeafletMouseEvent) => { | |
217 | - this.mousePositionOnMap = e.latlng; | |
179 | + addEditControl() { | |
180 | + // Customize edit marker | |
181 | + if (this.options.draggableMarker) { | |
182 | + const actions = [{ | |
183 | + text: L.PM.Utils.getTranslation('actions.cancel'), | |
184 | + onClick: () => this.toggleDrawMode('tbMarker') | |
185 | + }]; | |
186 | + | |
187 | + this.map.pm.Toolbar.copyDrawControl('Marker', { | |
188 | + name: 'tbMarker', | |
189 | + afterClick: () => this.selectEntityWithoutLocation('tbMarker'), | |
190 | + disabled: true, | |
191 | + actions | |
192 | + }); | |
193 | + } | |
194 | + | |
195 | + // Customize edit polygon | |
196 | + if (this.editPolygons) { | |
197 | + const rectangleActions = [ | |
198 | + { | |
199 | + text: L.PM.Utils.getTranslation('actions.cancel'), | |
200 | + onClick: () => this.toggleDrawMode('tbRectangle') | |
201 | + } | |
202 | + ]; | |
203 | + | |
204 | + const polygonActions = [ | |
205 | + 'finish' as const, | |
206 | + 'removeLastVertex' as const, | |
207 | + { | |
208 | + text: L.PM.Utils.getTranslation('actions.cancel'), | |
209 | + onClick: () => this.toggleDrawMode('tbPolygon') | |
210 | + } | |
211 | + ]; | |
212 | + | |
213 | + this.map.pm.Toolbar.copyDrawControl('Rectangle', { | |
214 | + name: 'tbRectangle', | |
215 | + afterClick: () => this.selectEntityWithoutLocation('tbRectangle'), | |
216 | + disabled: true, | |
217 | + actions: rectangleActions | |
218 | + }); | |
219 | + | |
220 | + this.map.pm.Toolbar.copyDrawControl('Polygon', { | |
221 | + name: 'tbPolygon', | |
222 | + afterClick: () => this.selectEntityWithoutLocation('tbPolygon'), | |
223 | + disabled: true, | |
224 | + actions: polygonActions | |
225 | + }); | |
226 | + } | |
227 | + | |
228 | + const translateService = this.ctx.$injector.get(TranslateService); | |
229 | + this.map.pm.setLang('en', translateService.instant('widgets.maps'), 'en'); | |
230 | + this.map.pm.addControls({ | |
231 | + position: 'topleft', | |
232 | + drawMarker: false, | |
233 | + drawCircle: false, | |
234 | + drawCircleMarker: false, | |
235 | + drawRectangle: false, | |
236 | + drawPolyline: false, | |
237 | + drawPolygon: false, | |
238 | + editMode: this.editPolygons, | |
239 | + cutPolygon: this.editPolygons, | |
240 | + rotateMode: this.editPolygons | |
218 | 241 | }); |
219 | 242 | |
220 | - const dragListener = (e: L.DragEndEvent) => { | |
221 | - if (e.type === 'dragend') { | |
222 | - const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01; | |
223 | - | |
224 | - const convert = this.convertToCustomFormat(this.mousePositionOnMap, polygonOffset); | |
225 | - this.mousePositionOnMap.lat = convert[this.options.latKeyName]; | |
226 | - this.mousePositionOnMap.lng = convert[this.options.lngKeyName]; | |
227 | - | |
228 | - const latlng1 = this.mousePositionOnMap; | |
229 | - const latlng2 = L.latLng(this.mousePositionOnMap.lat, this.mousePositionOnMap.lng + polygonOffset); | |
230 | - const latlng3 = L.latLng(this.mousePositionOnMap.lat - polygonOffset, this.mousePositionOnMap.lng); | |
231 | - const polygonPoints = [latlng1, latlng2, latlng3]; | |
232 | - | |
233 | - const newPolygon = L.polygon(polygonPoints).addTo(this.map); | |
234 | - this.addPolygons.push(newPolygon); | |
235 | - const datasourcesList = document.createElement('div'); | |
236 | - const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(polygonPoints)}; | |
237 | - const header = document.createElement('p'); | |
238 | - header.appendChild(document.createTextNode('Select entity:')); | |
239 | - header.setAttribute('style', 'font-size: 14px; margin: 8px 0'); | |
240 | - datasourcesList.appendChild(header); | |
241 | - this.datasources.forEach(ds => { | |
242 | - const dsItem = document.createElement('p'); | |
243 | - dsItem.appendChild(document.createTextNode(ds.entityName)); | |
244 | - dsItem.setAttribute('style', 'font-size: 14px; margin: 8px 0; cursor: pointer'); | |
245 | - dsItem.onclick = () => { | |
246 | - const updatedEnttity = { ...ds, ...customLatLng }; | |
247 | - this.savePolygonLocation(updatedEnttity).subscribe(() => { | |
248 | - this.map.removeLayer(newPolygon); | |
249 | - const polygonIndex = this.addPolygons.indexOf(newPolygon); | |
250 | - if (polygonIndex > -1) { | |
251 | - this.addPolygons.splice(polygonIndex, 1); | |
252 | - } | |
253 | - this.deletePolygon(ds.entityName); | |
254 | - }); | |
255 | - }; | |
256 | - datasourcesList.appendChild(dsItem); | |
243 | + this.map.on('pm:create', (e) => { | |
244 | + if (e.shape === 'tbMarker') { | |
245 | + // @ts-ignore | |
246 | + this.saveLocation(this.selectedEntity, this.convertToCustomFormat(e.layer.getLatLng())).subscribe(() => { | |
247 | + }); | |
248 | + } else if (e.shape === 'tbRectangle' || e.shape === 'tbPolygon') { | |
249 | + // @ts-ignore | |
250 | + this.saveLocation(this.selectedEntity, this.convertPolygonToCustomFormat(e.layer.getLatLngs()[0])).subscribe(() => { | |
257 | 251 | }); |
258 | - datasourcesList.appendChild(document.createElement('br')); | |
259 | - const deleteBtn = document.createElement('a'); | |
260 | - deleteBtn.appendChild(document.createTextNode('Discard changes')); | |
261 | - deleteBtn.onclick = () => { | |
262 | - this.map.removeLayer(newPolygon); | |
263 | - const polygonIndex = this.addPolygons.indexOf(newPolygon); | |
264 | - if (polygonIndex > -1) { | |
265 | - this.addPolygons.splice(polygonIndex, 1); | |
266 | - } | |
267 | - }; | |
268 | - datasourcesList.appendChild(deleteBtn); | |
269 | - const popup = L.popup(); | |
270 | - popup.setContent(datasourcesList); | |
271 | - newPolygon.bindPopup(popup).openPopup(); | |
272 | 252 | } |
273 | - this.addPolygon.setPosition('topright'); | |
274 | - }; | |
275 | - const addPolygon = L.Control.extend({ | |
276 | - onAdd() { | |
277 | - const img = L.DomUtil.create('img') as any; | |
278 | - img.src = `assets/add_polygon.svg`; | |
279 | - img.style.width = '32px'; | |
280 | - img.style.height = '32px'; | |
281 | - img.title = 'Drag and drop to add Polygon'; | |
282 | - img.onclick = this.dragPolygonVertex; | |
283 | - img.draggable = true; | |
284 | - const draggableImg = new L.Draggable(img); | |
285 | - draggableImg.enable(); | |
286 | - draggableImg.on('dragend', dragListener); | |
287 | - return img; | |
288 | - }, | |
289 | - onRemove() { | |
290 | - }, | |
291 | - dragPolygonVertex: this.dragPolygonVertex | |
292 | - } as any); | |
293 | - const addPolygonControl = (opts) => { | |
294 | - return new addPolygon(opts); | |
295 | - }; | |
296 | - this.addPolygon = addPolygonControl({ position: 'topright' }).addTo(this.map); | |
253 | + // @ts-ignore | |
254 | + e.layer._pmTempLayer = true; | |
255 | + e.layer.remove(); | |
256 | + }); | |
257 | + | |
258 | + this.map.on('pm:cut', (e) => { | |
259 | + // @ts-ignore | |
260 | + e.originalLayer.setLatLngs(e.layer.getLatLngs()); | |
261 | + e.originalLayer.addTo(this.map); | |
262 | + // @ts-ignore | |
263 | + e.originalLayer._pmTempLayer = false; | |
264 | + const iterator = this.polygons.values(); | |
265 | + let result = iterator.next(); | |
266 | + while (!result.done && e.originalLayer !== result.value.leafletPoly) { | |
267 | + result = iterator.next(); | |
268 | + } | |
269 | + // @ts-ignore | |
270 | + e.layer._pmTempLayer = true; | |
271 | + e.layer.remove(); | |
272 | + }); | |
273 | + | |
274 | + this.map.on('pm:remove', (e) => { | |
275 | + if (e.shape === 'Marker') { | |
276 | + const iterator = this.markers.values(); | |
277 | + let result = iterator.next(); | |
278 | + while (!result.done && e.layer !== result.value.leafletMarker) { | |
279 | + result = iterator.next(); | |
280 | + } | |
281 | + this.saveLocation(result.value.data, this.convertToCustomFormat(null)).subscribe(() => {}); | |
282 | + } else if (e.shape === 'Polygon') { | |
283 | + const iterator = this.polygons.values(); | |
284 | + let result = iterator.next(); | |
285 | + while (!result.done && e.layer !== result.value.leafletPoly) { | |
286 | + result = iterator.next(); | |
287 | + } | |
288 | + this.saveLocation(result.value.data, this.convertPolygonToCustomFormat(null)).subscribe(() => {}); | |
289 | + } | |
290 | + }); | |
297 | 291 | } |
298 | - } | |
299 | 292 | |
300 | 293 | public setLoading(loading: boolean) { |
301 | 294 | if (this.loading !== loading) { |
... | ... | @@ -337,11 +330,10 @@ export default abstract class LeafletMap { |
337 | 330 | if (this.options.disableScrollZooming) { |
338 | 331 | this.map.scrollWheelZoom.disable(); |
339 | 332 | } |
340 | - if (this.options.draggableMarker) { | |
341 | - this.addMarkerControl(); | |
342 | - } | |
343 | - if (this.options.editablePolygon) { | |
344 | - this.addPolygonControl(); | |
333 | + if (this.options.draggableMarker || this.editPolygons) { | |
334 | + this.addEditControl(); | |
335 | + } else { | |
336 | + this.map.pm.disableDraw(); | |
345 | 337 | } |
346 | 338 | if (this.options.useClusterMarkers) { |
347 | 339 | this.map.addLayer(this.markersCluster); |
... | ... | @@ -352,12 +344,53 @@ export default abstract class LeafletMap { |
352 | 344 | } |
353 | 345 | } |
354 | 346 | |
355 | - public saveMarkerLocation(datasource: FormattedData, lat?: number, lng?: number): Observable<any> { | |
356 | - return of(null); | |
357 | - } | |
347 | + private saveLocation(e: FormattedData, values: {[key: string]: any}): Observable<any> { | |
348 | + const attributeService = this.ctx.$injector.get(AttributeService); | |
349 | + const attributes = []; | |
350 | + const timeseries = []; | |
351 | + | |
352 | + const entityId: EntityId = { | |
353 | + entityType: e.$datasource.entityType, | |
354 | + id: e.$datasource.entityId | |
355 | + }; | |
358 | 356 | |
359 | - public savePolygonLocation(datasource: FormattedData, coordinates?: Array<[number, number]>): Observable<any> { | |
360 | - return of(null); | |
357 | + for (const dataKeyName of Object.keys(values)) { | |
358 | + for (const key of e.$datasource.dataKeys) { | |
359 | + if (dataKeyName === key.name) { | |
360 | + const value = { | |
361 | + key: key.name, | |
362 | + value: values[dataKeyName] | |
363 | + }; | |
364 | + if (key.type === DataKeyType.attribute) { | |
365 | + attributes.push(value); | |
366 | + } else if (key.type === DataKeyType.timeseries) { | |
367 | + timeseries.push(value); | |
368 | + } | |
369 | + break; | |
370 | + } | |
371 | + } | |
372 | + } | |
373 | + | |
374 | + const observables: Observable<any>[] = []; | |
375 | + if (timeseries.length) { | |
376 | + observables.push(attributeService.saveEntityTimeseries( | |
377 | + entityId, | |
378 | + LatestTelemetry.LATEST_TELEMETRY, | |
379 | + timeseries | |
380 | + )); | |
381 | + } | |
382 | + if (attributes.length) { | |
383 | + observables.push(attributeService.saveEntityAttributes( | |
384 | + entityId, | |
385 | + AttributeScope.SERVER_SCOPE, | |
386 | + attributes | |
387 | + )); | |
388 | + } | |
389 | + if (observables.length) { | |
390 | + return forkJoin(observables); | |
391 | + } else { | |
392 | + return of(null); | |
393 | + } | |
361 | 394 | } |
362 | 395 | |
363 | 396 | createLatLng(lat: number, lng: number): L.LatLng { |
... | ... | @@ -441,7 +474,7 @@ export default abstract class LeafletMap { |
441 | 474 | } |
442 | 475 | |
443 | 476 | convertToCustomFormat(position: L.LatLng, offset = 0): object { |
444 | - position = checkLngLat(position, this.southWest, this.northEast, offset); | |
477 | + position = position ? checkLngLat(position, this.southWest, this.northEast, offset) : {lat: null, lng: null} as L.LatLng; | |
445 | 478 | |
446 | 479 | return { |
447 | 480 | [this.options.latKeyName]: position.lat, |
... | ... | @@ -455,17 +488,18 @@ export default abstract class LeafletMap { |
455 | 488 | if (point.length) { |
456 | 489 | return this.convertToPolygonFormat(point); |
457 | 490 | } else { |
458 | - return [point.lat, point.lng]; | |
491 | + const convertPoint = checkLngLat(point, this.southWest, this.northEast); | |
492 | + return [convertPoint.lat, convertPoint.lng]; | |
459 | 493 | } |
460 | 494 | }); |
461 | - } else { | |
462 | - return []; | |
463 | 495 | } |
496 | + return []; | |
464 | 497 | } |
465 | 498 | |
466 | - convertPolygonToCustomFormat(expression: any[][]): object { | |
499 | + convertPolygonToCustomFormat(expression: any[][]): {[key: string]: any} { | |
500 | + const coordinate = expression ? this.convertToPolygonFormat(expression) : null; | |
467 | 501 | return { |
468 | - [this.options.polygonKeyName] : this.convertToPolygonFormat(expression) | |
502 | + [this.options.polygonKeyName]: coordinate | |
469 | 503 | }; |
470 | 504 | } |
471 | 505 | |
... | ... | @@ -484,7 +518,15 @@ export default abstract class LeafletMap { |
484 | 518 | } |
485 | 519 | this.updateMarkers(formattedData, false); |
486 | 520 | this.updateBoundsInternal(); |
487 | - if (this.options.draggableMarker || this.options.editablePolygon) { | |
521 | + if (this.options.draggableMarker) { | |
522 | + const foundEntityWithoutLocation = formattedData.some(mData => !this.convertPosition(mData)); | |
523 | + this.map.pm.Toolbar.setButtonDisabled('tbMarker', !foundEntityWithoutLocation); | |
524 | + this.datasources = formattedData; | |
525 | + } | |
526 | + if (this.editPolygons) { | |
527 | + const foundEntityWithoutPolygon = formattedData.some(pData => !this.isValidPolygonPosition(pData)); | |
528 | + this.map.pm.Toolbar.setButtonDisabled('tbPolygon', !foundEntityWithoutPolygon); | |
529 | + this.map.pm.Toolbar.setButtonDisabled('tbRectangle', !foundEntityWithoutPolygon); | |
488 | 530 | this.datasources = formattedData; |
489 | 531 | } |
490 | 532 | } else { |
... | ... | @@ -577,10 +619,10 @@ export default abstract class LeafletMap { |
577 | 619 | } |
578 | 620 | |
579 | 621 | dragMarker = (e, data = {} as FormattedData) => { |
580 | - if (e.type !== 'dragend') { | |
622 | + if (e === undefined) { | |
581 | 623 | return; |
582 | 624 | } |
583 | - this.saveMarkerLocation({ ...data, ...this.convertToCustomFormat(e.target._latlng) }).subscribe(); | |
625 | + this.saveLocation(data, this.convertToCustomFormat(e.target._latlng)).subscribe(); | |
584 | 626 | } |
585 | 627 | |
586 | 628 | private createMarker(key: string, data: FormattedData, dataSources: FormattedData[], settings: MarkerSettings, |
... | ... | @@ -728,11 +770,15 @@ export default abstract class LeafletMap { |
728 | 770 | |
729 | 771 | // Polygon |
730 | 772 | |
773 | + isValidPolygonPosition(data: FormattedData): boolean { | |
774 | + return data && isDefinedAndNotNull(data[this.options.polygonKeyName]) && !isEmptyStr(data[this.options.polygonKeyName]); | |
775 | + } | |
776 | + | |
731 | 777 | updatePolygons(polyData: FormattedData[], updateBounds = true) { |
732 | 778 | const keys: string[] = []; |
733 | 779 | this.polygonsData = deepClone(polyData); |
734 | 780 | polyData.forEach((data: FormattedData) => { |
735 | - if (data && isDefinedAndNotNull(data[this.options.polygonKeyName]) && !isEmptyStr(data[this.options.polygonKeyName])) { | |
781 | + if (this.isValidPolygonPosition(data)) { | |
736 | 782 | if (isString((data[this.options.polygonKeyName]))) { |
737 | 783 | data[this.options.polygonKeyName] = JSON.parse(data[this.options.polygonKeyName]); |
738 | 784 | } |
... | ... | @@ -758,15 +804,14 @@ export default abstract class LeafletMap { |
758 | 804 | } |
759 | 805 | |
760 | 806 | dragPolygonVertex = (e?, data = {} as FormattedData) => { |
761 | - if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) { | |
807 | + if (e === undefined) { | |
762 | 808 | return; |
763 | 809 | } |
764 | - if (this.options.provider !== MapProviders.image) { | |
765 | - for (const key of Object.keys(e.layer._latlngs[0])) { | |
766 | - e.layer._latlngs[0][key] = checkLngLat(e.layer._latlngs[0][key], this.southWest, this.northEast); | |
767 | - } | |
810 | + let coordinates = e.layer.getLatLngs(); | |
811 | + if (coordinates.length === 1) { | |
812 | + coordinates = coordinates[0]; | |
768 | 813 | } |
769 | - this.savePolygonLocation({ ...data, ...this.convertPolygonToCustomFormat(e.layer._latlngs) }).subscribe(); | |
814 | + this.saveLocation(data, this.convertPolygonToCustomFormat(coordinates)).subscribe(() => {}); | |
770 | 815 | } |
771 | 816 | |
772 | 817 | createPolygon(polyData: FormattedData, dataSources: FormattedData[], settings: PolygonSettings, updateBounds = true) { | ... | ... |
... | ... | @@ -14,41 +14,23 @@ |
14 | 14 | /// limitations under the License. |
15 | 15 | /// |
16 | 16 | |
17 | -import { | |
18 | - defaultSettings, | |
19 | - FormattedData, | |
20 | - hereProviders, | |
21 | - MapProviders, | |
22 | - UnitedMapSettings | |
23 | -} from './map-models'; | |
17 | +import { defaultSettings, hereProviders, MapProviders, UnitedMapSettings } from './map-models'; | |
24 | 18 | import LeafletMap from './leaflet-map'; |
25 | 19 | import { |
26 | 20 | commonMapSettingsSchema, |
27 | 21 | mapPolygonSchema, |
28 | - mapProviderSchema, | |
29 | 22 | markerClusteringSettingsSchema, |
30 | 23 | markerClusteringSettingsSchemaLeaflet, |
31 | 24 | routeMapSettingsSchema |
32 | 25 | } from './schemes'; |
33 | 26 | import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface'; |
34 | -import { | |
35 | - addCondition, | |
36 | - addGroupInfo, | |
37 | - addToSchema, | |
38 | - initSchema, | |
39 | - mergeSchemes | |
40 | -} from '@core/schema-utils'; | |
27 | +import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils'; | |
41 | 28 | import { WidgetContext } from '@app/modules/home/models/widget-component.models'; |
42 | 29 | import { getDefCenterPosition, getProviderSchema, parseFunction, parseWithTranslation } from './common-maps-utils'; |
43 | 30 | import { Datasource, DatasourceData, JsonSettingsSchema, WidgetActionDescriptor } from '@shared/models/widget.models'; |
44 | -import { EntityId } from '@shared/models/id/entity-id'; | |
45 | -import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models'; | |
46 | -import { AttributeService } from '@core/http/attribute.service'; | |
47 | 31 | import { TranslateService } from '@ngx-translate/core'; |
48 | 32 | import { UtilsService } from '@core/services/utils.service'; |
49 | 33 | import { EntityDataPageLink } from '@shared/models/query/query.models'; |
50 | -import { isDefined } from '@core/utils'; | |
51 | -import { forkJoin, Observable, of } from 'rxjs'; | |
52 | 34 | import { providerClass } from '@home/components/widget/lib/maps/providers'; |
53 | 35 | |
54 | 36 | // @dynamic |
... | ... | @@ -81,8 +63,6 @@ export class MapWidgetController implements MapWidgetInterface { |
81 | 63 | } |
82 | 64 | parseWithTranslation.setTranslate(this.translate); |
83 | 65 | this.map = new MapClass(this.ctx, $element, this.settings); |
84 | - this.map.saveMarkerLocation = this.setMarkerLocation; | |
85 | - this.map.savePolygonLocation = this.savePolygonLocation; | |
86 | 66 | this.pageLink = { |
87 | 67 | page: 0, |
88 | 68 | pageSize: this.settings.mapPageSize, |
... | ... | @@ -178,112 +158,6 @@ export class MapWidgetController implements MapWidgetInterface { |
178 | 158 | }, entityName, null, entityLabel); |
179 | 159 | } |
180 | 160 | |
181 | - setMarkerLocation = (e: FormattedData, lat?: number, lng?: number) => { | |
182 | - const attributeService = this.ctx.$injector.get(AttributeService); | |
183 | - | |
184 | - const entityId: EntityId = { | |
185 | - entityType: e.$datasource.entityType, | |
186 | - id: e.$datasource.entityId | |
187 | - }; | |
188 | - const attributes = []; | |
189 | - const timeseries = []; | |
190 | - | |
191 | - const latProperties = [this.settings.latKeyName, this.settings.xPosKeyName]; | |
192 | - const lngProperties = [this.settings.lngKeyName, this.settings.yPosKeyName]; | |
193 | - e.$datasource.dataKeys.forEach(key => { | |
194 | - let value; | |
195 | - if (latProperties.includes(key.name)) { | |
196 | - value = { | |
197 | - key: key.name, | |
198 | - value: isDefined(lat) ? lat : e[key.name] | |
199 | - }; | |
200 | - } else if (lngProperties.includes(key.name)) { | |
201 | - value = { | |
202 | - key: key.name, | |
203 | - value: isDefined(lng) ? lng : e[key.name] | |
204 | - }; | |
205 | - } | |
206 | - if (value) { | |
207 | - if (key.type === DataKeyType.attribute) { | |
208 | - attributes.push(value); | |
209 | - } | |
210 | - if (key.type === DataKeyType.timeseries) { | |
211 | - timeseries.push(value); | |
212 | - } | |
213 | - } | |
214 | - }); | |
215 | - const observables: Observable<any>[] = []; | |
216 | - if (timeseries.length) { | |
217 | - observables.push(attributeService.saveEntityTimeseries( | |
218 | - entityId, | |
219 | - LatestTelemetry.LATEST_TELEMETRY, | |
220 | - timeseries | |
221 | - )); | |
222 | - } | |
223 | - if (attributes.length) { | |
224 | - observables.push(attributeService.saveEntityAttributes( | |
225 | - entityId, | |
226 | - AttributeScope.SERVER_SCOPE, | |
227 | - attributes | |
228 | - )); | |
229 | - } | |
230 | - if (observables.length) { | |
231 | - return forkJoin(observables); | |
232 | - } else { | |
233 | - return of(null); | |
234 | - } | |
235 | - } | |
236 | - | |
237 | - savePolygonLocation = (e: FormattedData, coordinates?: Array<any>) => { | |
238 | - const attributeService = this.ctx.$injector.get(AttributeService); | |
239 | - | |
240 | - const entityId: EntityId = { | |
241 | - entityType: e.$datasource.entityType, | |
242 | - id: e.$datasource.entityId | |
243 | - }; | |
244 | - const attributes = []; | |
245 | - const timeseries = []; | |
246 | - | |
247 | - const coordinatesProperties = this.settings.polygonKeyName; | |
248 | - e.$datasource.dataKeys.forEach(key => { | |
249 | - let value; | |
250 | - if (coordinatesProperties === key.name) { | |
251 | - value = { | |
252 | - key: key.name, | |
253 | - value: isDefined(coordinates) ? coordinates : e[key.name] | |
254 | - }; | |
255 | - } | |
256 | - if (value) { | |
257 | - if (key.type === DataKeyType.attribute) { | |
258 | - attributes.push(value); | |
259 | - } | |
260 | - if (key.type === DataKeyType.timeseries) { | |
261 | - timeseries.push(value); | |
262 | - } | |
263 | - } | |
264 | - }); | |
265 | - const observables: Observable<any>[] = []; | |
266 | - if (timeseries.length) { | |
267 | - observables.push(attributeService.saveEntityTimeseries( | |
268 | - entityId, | |
269 | - LatestTelemetry.LATEST_TELEMETRY, | |
270 | - timeseries | |
271 | - )); | |
272 | - } | |
273 | - if (attributes.length) { | |
274 | - observables.push(attributeService.saveEntityAttributes( | |
275 | - entityId, | |
276 | - AttributeScope.SERVER_SCOPE, | |
277 | - attributes | |
278 | - )); | |
279 | - } | |
280 | - if (observables.length) { | |
281 | - return forkJoin(observables); | |
282 | - } else { | |
283 | - return of(null); | |
284 | - } | |
285 | - } | |
286 | - | |
287 | 161 | initSettings(settings: UnitedMapSettings, isEditMap?: boolean): UnitedMapSettings { |
288 | 162 | const functionParams = ['data', 'dsData', 'dsIndex']; |
289 | 163 | this.provider = settings.provider || this.mapProvider; | ... | ... |
... | ... | @@ -42,9 +42,7 @@ export class Marker { |
42 | 42 | constructor(private map: LeafletMap, private location: L.LatLng, public settings: MarkerSettings, |
43 | 43 | data?: FormattedData, dataSources?, onDragendListener?) { |
44 | 44 | this.setDataSources(data, dataSources); |
45 | - this.leafletMarker = L.marker(location, { | |
46 | - draggable: settings.draggableMarker | |
47 | - }); | |
45 | + this.leafletMarker = L.marker(location, {pmIgnore: !settings.draggableMarker}); | |
48 | 46 | |
49 | 47 | this.markerOffset = [ |
50 | 48 | isDefined(settings.markerOffsetX) ? settings.markerOffsetX : 0.5, |
... | ... | @@ -72,8 +70,8 @@ export class Marker { |
72 | 70 | }); |
73 | 71 | } |
74 | 72 | |
75 | - if (onDragendListener) { | |
76 | - this.leafletMarker.on('dragend', (e) => onDragendListener(e, this.data)); | |
73 | + if (settings.draggableMarker && onDragendListener) { | |
74 | + this.leafletMarker.on('pm:dragend', (e) => onDragendListener(e, this.data)); | |
77 | 75 | } |
78 | 76 | } |
79 | 77 | |
... | ... | @@ -199,19 +197,24 @@ export class Marker { |
199 | 197 | |
200 | 198 | createColoredMarkerIcon(color: tinycolor.Instance): { size: number[], icon: Icon } { |
201 | 199 | return { |
202 | - size: [21, 34], | |
203 | - icon: L.icon({ | |
204 | - iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + color.toHex(), | |
205 | - iconSize: [21, 34], | |
206 | - iconAnchor: [21 * this.markerOffset[0], 34 * this.markerOffset[1]], | |
207 | - popupAnchor: [0, -34], | |
208 | - shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow', | |
209 | - shadowSize: [40, 37], | |
210 | - shadowAnchor: [12, 35] | |
200 | + size: [21, 34], | |
201 | + icon: L.icon({ | |
202 | + iconUrl: this.createColorIconURI(color), | |
203 | + iconSize: [21, 34], | |
204 | + iconAnchor: [21 * this.markerOffset[0], 34 * this.markerOffset[1]], | |
205 | + popupAnchor: [0, -34], | |
206 | + shadowUrl: 'assets/shadow.png', | |
207 | + shadowSize: [40, 37], | |
208 | + shadowAnchor: [12, 35] | |
211 | 209 | }) |
212 | 210 | }; |
213 | 211 | } |
214 | 212 | |
213 | + createColorIconURI(color: tinycolor.Instance): string { | |
214 | + const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="-191.35 -351.18 1083.58 1730.46"><path fill-rule="evenodd" clip-rule="evenodd" fill="#${color.toHex()}" stroke="#000" stroke-width="37" stroke-miterlimit="10" d="M351.833 1360.78c-38.766-190.3-107.116-348.665-189.903-495.44C100.523 756.469 29.386 655.978-36.434 550.404c-21.972-35.244-40.934-72.477-62.047-109.054-42.216-73.137-76.444-157.935-74.269-267.932 2.125-107.473 33.208-193.685 78.03-264.173C-21-206.69 102.481-301.745 268.164-326.724c135.466-20.425 262.475 14.082 352.543 66.747 73.6 43.038 130.596 100.528 173.92 168.28 45.22 70.716 76.36 154.26 78.971 263.233 1.337 55.83-7.805 107.532-20.684 150.417-13.034 43.41-33.996 79.695-52.646 118.455-36.406 75.659-82.049 144.981-127.855 214.345-136.437 206.606-264.496 417.31-320.58 706.028z"/><circle fill-rule="evenodd" clip-rule="evenodd" cx="352.891" cy="225.779" r="183.332"/></svg>`; | |
215 | + return 'data:image/svg+xml;base64,' + btoa(svg); | |
216 | + } | |
217 | + | |
215 | 218 | removeMarker() { |
216 | 219 | /* this.map$.subscribe(map => |
217 | 220 | this.leafletMarker.addTo(map))*/ | ... | ... |
... | ... | @@ -17,7 +17,6 @@ |
17 | 17 | import L, { LatLngExpression, LeafletMouseEvent } from 'leaflet'; |
18 | 18 | import { createTooltip } from './maps-utils'; |
19 | 19 | import { functionValueCalculator, parseWithTranslation, safeExecute } from './common-maps-utils'; |
20 | -import 'leaflet-editable/src/Leaflet.Editable'; | |
21 | 20 | import { FormattedData, PolygonSettings } from './map-models'; |
22 | 21 | |
23 | 22 | export class Polygon { |
... | ... | @@ -37,14 +36,12 @@ export class Polygon { |
37 | 36 | color: settings.polygonStrokeColor, |
38 | 37 | weight: settings.polygonStrokeWeight, |
39 | 38 | fillOpacity: settings.polygonOpacity, |
40 | - opacity: settings.polygonStrokeOpacity | |
39 | + opacity: settings.polygonStrokeOpacity, | |
40 | + pmIgnore: !settings.editablePolygon | |
41 | 41 | }).addTo(this.map); |
42 | - if (settings.editablePolygon) { | |
43 | - this.leafletPoly.enableEdit(this.map); | |
44 | - if (onDragendListener) { | |
45 | - this.leafletPoly.on('editable:vertex:dragend', e => onDragendListener(e, this.data)); | |
46 | - this.leafletPoly.on('editable:vertex:deleted', e => onDragendListener(e, this.data)); | |
47 | - } | |
42 | + | |
43 | + if (settings.editablePolygon && onDragendListener) { | |
44 | + this.leafletPoly.on('pm:edit', (e) => onDragendListener(e, this.data)); | |
48 | 45 | } |
49 | 46 | |
50 | 47 | |
... | ... | @@ -73,13 +70,7 @@ export class Polygon { |
73 | 70 | updatePolygon(data: FormattedData, dataSources: FormattedData[], settings: PolygonSettings) { |
74 | 71 | this.data = data; |
75 | 72 | this.dataSources = dataSources; |
76 | - if (settings.editablePolygon) { | |
77 | - this.leafletPoly.disableEdit(); | |
78 | - } | |
79 | 73 | this.leafletPoly.setLatLngs(data[this.settings.polygonKeyName]); |
80 | - if (settings.editablePolygon) { | |
81 | - this.leafletPoly.enableEdit(this.map); | |
82 | - } | |
83 | 74 | if (settings.showPolygonTooltip) { |
84 | 75 | this.updateTooltip(this.data); |
85 | 76 | } | ... | ... |
... | ... | @@ -14,7 +14,8 @@ |
14 | 14 | /// limitations under the License. |
15 | 15 | /// |
16 | 16 | |
17 | -import L, { PolylineDecoratorOptions } from 'leaflet'; | |
17 | +// @ts-ignore | |
18 | +import L, { PolylineDecorator, PolylineDecoratorOptions, Symbol } from 'leaflet'; | |
18 | 19 | import 'leaflet-polylinedecorator'; |
19 | 20 | |
20 | 21 | import { FormattedData, PolylineSettings } from './map-models'; |
... | ... | @@ -23,7 +24,7 @@ import { functionValueCalculator } from '@home/components/widget/lib/maps/common |
23 | 24 | export class Polyline { |
24 | 25 | |
25 | 26 | leafletPoly: L.Polyline; |
26 | - polylineDecorator: L.PolylineDecorator; | |
27 | + polylineDecorator: PolylineDecorator; | |
27 | 28 | dataSources: FormattedData[]; |
28 | 29 | data: FormattedData; |
29 | 30 | |
... | ... | @@ -36,7 +37,7 @@ export class Polyline { |
36 | 37 | ).addTo(this.map); |
37 | 38 | |
38 | 39 | if (settings.usePolylineDecorator) { |
39 | - this.polylineDecorator = L.polylineDecorator(this.leafletPoly, this.getDecoratorSettings(settings)).addTo(this.map); | |
40 | + this.polylineDecorator = new PolylineDecorator(this.leafletPoly, this.getDecoratorSettings(settings)).addTo(this.map); | |
40 | 41 | } |
41 | 42 | } |
42 | 43 | |
... | ... | @@ -47,7 +48,7 @@ export class Polyline { |
47 | 48 | offset: settings.decoratorOffset, |
48 | 49 | endOffset: settings.endDecoratorOffset, |
49 | 50 | repeat: settings.decoratorRepeat, |
50 | - symbol: L.Symbol[settings.decoratorSymbol]({ | |
51 | + symbol: Symbol[settings.decoratorSymbol]({ | |
51 | 52 | pixelSize: settings.decoratorSymbolSize, |
52 | 53 | polygon: false, |
53 | 54 | pathOptions: { |
... | ... | @@ -78,7 +79,8 @@ export class Polyline { |
78 | 79 | opacity: functionValueCalculator(settings.useStrokeOpacityFunction, settings.strokeOpacityFunction, |
79 | 80 | [this.data, this.dataSources, this.data.dsIndex], settings.strokeOpacity), |
80 | 81 | weight: functionValueCalculator(settings.useStrokeWeightFunction, settings.strokeWeightFunction, |
81 | - [this.data, this.dataSources, this.data.dsIndex], settings.strokeWeight) | |
82 | + [this.data, this.dataSources, this.data.dsIndex], settings.strokeWeight), | |
83 | + pmIgnore: true | |
82 | 84 | }; |
83 | 85 | } |
84 | 86 | ... | ... |
... | ... | @@ -38,7 +38,6 @@ export class GoogleMap extends LeafletMap { |
38 | 38 | this.loadGoogle(() => { |
39 | 39 | const map = L.map($container, { |
40 | 40 | attributionControl: false, |
41 | - editable: !!options.editablePolygon, | |
42 | 41 | tap: L.Browser.safari && L.Browser.mobile |
43 | 42 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); |
44 | 43 | (L.gridLayer as any).googleMutant({ | ... | ... |
... | ... | @@ -23,7 +23,6 @@ export class HEREMap extends LeafletMap { |
23 | 23 | constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) { |
24 | 24 | super(ctx, $container, options); |
25 | 25 | const map = L.map($container, { |
26 | - editable: !!options.editablePolygon, | |
27 | 26 | tap: L.Browser.safari && L.Browser.mobile |
28 | 27 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); |
29 | 28 | const tileLayer = (L.tileLayer as any).provider(options.mapProviderHere || 'HERE.normalDay', options.credentials); | ... | ... |
... | ... | @@ -22,7 +22,6 @@ import { filter, map, mergeMap } from 'rxjs/operators'; |
22 | 22 | import { |
23 | 23 | aspectCache, |
24 | 24 | calculateNewPointCoordinate, |
25 | - checkLngLat, | |
26 | 25 | parseFunction |
27 | 26 | } from '@home/components/widget/lib/maps/common-maps-utils'; |
28 | 27 | import { WidgetContext } from '@home/models/widget-component.models'; |
... | ... | @@ -221,7 +220,6 @@ export class ImageMap extends LeafletMap { |
221 | 220 | zoom: 1, |
222 | 221 | crs: L.CRS.Simple, |
223 | 222 | attributionControl: false, |
224 | - editable: !!this.options.editablePolygon, | |
225 | 223 | tap: L.Browser.safari && L.Browser.mobile |
226 | 224 | }); |
227 | 225 | this.updateBounds(updateImage); |
... | ... | @@ -263,7 +261,13 @@ export class ImageMap extends LeafletMap { |
263 | 261 | return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1); |
264 | 262 | } |
265 | 263 | |
266 | - convertToCustomFormat(position: L.LatLng, offset = 0, width = this.width, height = this.height): object { | |
264 | + convertToCustomFormat(position: L.LatLng, offset = 0, width = this.width, height = this.height): {[key: string]: any} { | |
265 | + if (!position) { | |
266 | + return { | |
267 | + [this.options.xPosKeyName]: null, | |
268 | + [this.options.yPosKeyName]: null | |
269 | + }; | |
270 | + } | |
267 | 271 | const point = this.latLngToPoint(position); |
268 | 272 | const customX = calculateNewPointCoordinate(point.x, width); |
269 | 273 | const customY = calculateNewPointCoordinate(point.y, height); |
... | ... | @@ -279,13 +283,9 @@ export class ImageMap extends LeafletMap { |
279 | 283 | point.y = height; |
280 | 284 | } |
281 | 285 | |
282 | - const customLatLng = checkLngLat(this.pointToLatLng(point.x, point.y), this.southWest, this.northEast, offset); | |
283 | - | |
284 | 286 | return { |
285 | 287 | [this.options.xPosKeyName]: customX, |
286 | - [this.options.yPosKeyName]: customY, | |
287 | - [this.options.latKeyName]: customLatLng.lat, | |
288 | - [this.options.lngKeyName]: customLatLng.lng | |
288 | + [this.options.yPosKeyName]: customY | |
289 | 289 | }; |
290 | 290 | } |
291 | 291 | |
... | ... | @@ -304,9 +304,10 @@ export class ImageMap extends LeafletMap { |
304 | 304 | } |
305 | 305 | } |
306 | 306 | |
307 | - convertPolygonToCustomFormat(expression: any[][]): object { | |
307 | + convertPolygonToCustomFormat(expression: any[][]): {[key: string]: any} { | |
308 | + const coordinate = expression ? this.convertToPolygonFormat(expression) : null; | |
308 | 309 | return { |
309 | - [this.options.polygonKeyName] : this.convertToPolygonFormat(expression) | |
310 | + [this.options.polygonKeyName]: coordinate | |
310 | 311 | }; |
311 | 312 | } |
312 | 313 | } | ... | ... |
... | ... | @@ -23,7 +23,6 @@ export class OpenStreetMap extends LeafletMap { |
23 | 23 | constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) { |
24 | 24 | super(ctx, $container, options); |
25 | 25 | const map = L.map($container, { |
26 | - editable: !!options.editablePolygon, | |
27 | 26 | tap: L.Browser.safari && L.Browser.mobile |
28 | 27 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); |
29 | 28 | let tileLayer; | ... | ... |
... | ... | @@ -25,7 +25,6 @@ export class TencentMap extends LeafletMap { |
25 | 25 | super(ctx, $container, options); |
26 | 26 | const txUrl = 'http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0'; |
27 | 27 | const map = L.map($container, { |
28 | - editable: !!options.editablePolygon, | |
29 | 28 | tap: L.Browser.safari && L.Browser.mobile |
30 | 29 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); |
31 | 30 | const txLayer = L.tileLayer(txUrl, { | ... | ... |
... | ... | @@ -728,6 +728,11 @@ export const markerClusteringSettingsSchemaLeaflet = |
728 | 728 | type: 'number', |
729 | 729 | default: 80 |
730 | 730 | }, |
731 | + spiderfyOnMaxZoom: { | |
732 | + title: 'Spiderfy at the max zoom level (to see all cluster markers)', | |
733 | + type: 'boolean', | |
734 | + default: false | |
735 | + }, | |
731 | 736 | chunkedLoading: { |
732 | 737 | title: 'Use chunks for adding markers so that the page does not freeze', |
733 | 738 | type: 'boolean', |
... | ... | @@ -747,6 +752,7 @@ export const markerClusteringSettingsSchemaLeaflet = |
747 | 752 | 'showCoverageOnHover', |
748 | 753 | 'animate', |
749 | 754 | 'maxClusterRadius', |
755 | + 'spiderfyOnMaxZoom', | |
750 | 756 | 'chunkedLoading', |
751 | 757 | 'removeOutsideVisibleBounds' |
752 | 758 | ] | ... | ... |
... | ... | @@ -100,7 +100,10 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
100 | 100 | addGroupInfo(schema, 'Path Settings'); |
101 | 101 | addToSchema(schema, addCondition(pointSchema, 'model.showPoints === true', ['showPoints'])); |
102 | 102 | addGroupInfo(schema, 'Path Points Settings'); |
103 | - addToSchema(schema, addCondition(mapPolygonSchema, 'model.showPolygon === true', ['showPolygon'])); | |
103 | + const mapPolygonSchemaWithoutEdit = mapPolygonSchema; | |
104 | + delete mapPolygonSchemaWithoutEdit.schema.properties.editablePolygon; | |
105 | + mapPolygonSchemaWithoutEdit.form.splice(mapPolygonSchemaWithoutEdit.form.indexOf('editablePolygon'), 1); | |
106 | + addToSchema(schema, addCondition(mapPolygonSchemaWithoutEdit, 'model.showPolygon === true', ['showPolygon'])); | |
104 | 107 | addGroupInfo(schema, 'Polygon Settings'); |
105 | 108 | return schema; |
106 | 109 | } |
... | ... | @@ -115,6 +118,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy |
115 | 118 | rotationAngle: 0 |
116 | 119 | }; |
117 | 120 | this.settings = { ...settings, ...this.ctx.settings }; |
121 | + this.settings.editablePolygon = false; | |
118 | 122 | this.useAnchors = this.settings.showPoints && this.settings.usePointAsAnchor; |
119 | 123 | this.settings.pointAsAnchorFunction = parseFunction(this.settings.pointAsAnchorFunction, ['data', 'dsData', 'dsIndex']); |
120 | 124 | this.settings.tooltipFunction = parseFunction(this.settings.tooltipFunction, ['data', 'dsData', 'dsIndex']); | ... | ... |
... | ... | @@ -41,6 +41,7 @@ import { EdgesOverviewWidgetComponent } from '@home/components/widget/lib/edges- |
41 | 41 | import { JsonInputWidgetComponent } from '@home/components/widget/lib/json-input-widget.component'; |
42 | 42 | import { QrCodeWidgetComponent } from '@home/components/widget/lib/qrcode-widget.component'; |
43 | 43 | import { MarkdownWidgetComponent } from '@home/components/widget/lib/markdown-widget.component'; |
44 | +import { SelectEntityDialogComponent } from './lib/maps/dialogs/select-entity-dialog.component'; | |
44 | 45 | |
45 | 46 | @NgModule({ |
46 | 47 | declarations: |
... | ... | @@ -62,7 +63,8 @@ import { MarkdownWidgetComponent } from '@home/components/widget/lib/markdown-wi |
62 | 63 | NavigationCardsWidgetComponent, |
63 | 64 | NavigationCardWidgetComponent, |
64 | 65 | QrCodeWidgetComponent, |
65 | - MarkdownWidgetComponent | |
66 | + MarkdownWidgetComponent, | |
67 | + SelectEntityDialogComponent | |
66 | 68 | ], |
67 | 69 | imports: [ |
68 | 70 | CommonModule, | ... | ... |
ui-ngx/src/assets/add_location.svg
deleted
100644 → 0
1 | -<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path d="M24 4c-7.72 0-14 6.28-14 14 0 10.5 14 26 14 26s14-15.5 14-26c0-7.72-6.28-14-14-14zm8 16h-6v6h-4v-6h-6v-4h6v-6h4v6h6v4z"/></svg> | |
\ No newline at end of file |
ui-ngx/src/assets/add_polygon.svg
deleted
100644 → 0
... | ... | @@ -3238,7 +3238,40 @@ |
3238 | 3238 | "update-timeseries": "Update timeseries", |
3239 | 3239 | "value": "Value" |
3240 | 3240 | }, |
3241 | - "invalid-qr-code-text": "Invalid input text for QR code. Input should have a string type" | |
3241 | + "invalid-qr-code-text": "Invalid input text for QR code. Input should have a string type", | |
3242 | + "maps": { | |
3243 | + "select-entity": "Select entity", | |
3244 | + "select-entity-hint": "Hint: after selection click at the map to set position", | |
3245 | + "tooltips": { | |
3246 | + "placeMarker": "Click to place marker", | |
3247 | + "firstVertex": "Click to place first point", | |
3248 | + "continueLine": "Click to continue drawing", | |
3249 | + "finishLine": "Click any existing marker to finish", | |
3250 | + "finishPoly": "Click first marker to finish and save", | |
3251 | + "finishRect": "Click to finish and save", | |
3252 | + "startCircle": "Click to place circle center", | |
3253 | + "finishCircle": "Click to finish circle", | |
3254 | + "placeCircleMarker": "Click to place circle marker" | |
3255 | + }, | |
3256 | + "actions": { | |
3257 | + "finish": "Finish", | |
3258 | + "cancel": "Cancel", | |
3259 | + "removeLastVertex": "Remove last point" | |
3260 | + }, | |
3261 | + "buttonTitles": { | |
3262 | + "drawMarkerButton": "Create marker", | |
3263 | + "drawPolyButton": "Create polygon", | |
3264 | + "drawLineButton": "Create Polyline", | |
3265 | + "drawCircleButton": "Create Circle", | |
3266 | + "drawRectButton": "Create rectangle", | |
3267 | + "editButton": "Edit mode", | |
3268 | + "dragButton": "Drag-drop mode", | |
3269 | + "cutButton": "Cut polygon area", | |
3270 | + "deleteButton": "Remove", | |
3271 | + "drawCircleMarkerButton": "Create circle marker", | |
3272 | + "rotateButton": "Rotate polygon" | |
3273 | + } | |
3274 | + } | |
3242 | 3275 | }, |
3243 | 3276 | "icon": { |
3244 | 3277 | "icon": "Icon", | ... | ... |
ui-ngx/src/assets/shadow.png
0 → 100644
712 Bytes
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | "compilerOptions": { |
4 | 4 | "outDir": "../out-tsc/app", |
5 | 5 | "types": ["node", "jquery", "flot", "tooltipster", "tinycolor2", "js-beautify", |
6 | - "react", "react-dom", "jstree", "raphael", "canvas-gauges", "leaflet", "leaflet.markercluster", "leaflet-editable"] | |
6 | + "react", "react-dom", "jstree", "raphael", "canvas-gauges"] | |
7 | 7 | }, |
8 | 8 | "angularCompilerOptions": { |
9 | 9 | "fullTemplateTypeCheck": true | ... | ... |
ui-ngx/src/typings/leaflet-geoman-extend.d.ts
renamed from
ui-ngx/src/typings/add-marker.d.ts
... | ... | @@ -17,15 +17,13 @@ |
17 | 17 | import * as L from 'leaflet'; |
18 | 18 | |
19 | 19 | declare module 'leaflet' { |
20 | - | |
21 | - namespace Control { | |
22 | - class AddMarker extends L.Control { } | |
23 | - class AddPolygon extends L.Control { } | |
24 | - } | |
25 | - | |
26 | - namespace control { | |
27 | - function addMarker(options): Control.AddMarker; | |
28 | - function addPolygon(options): Control.AddPolygon; | |
20 | + namespace PM { | |
21 | + interface PMMapToolbar { | |
22 | + toggleButton( | |
23 | + name: string, | |
24 | + status: boolean, | |
25 | + disableOthers?: boolean | |
26 | + ): void; | |
29 | 27 | } |
30 | - | |
28 | + } | |
31 | 29 | } | ... | ... |
... | ... | @@ -20,7 +20,8 @@ |
20 | 20 | "src/typings/jquery.flot.typings.d.ts", |
21 | 21 | "src/typings/jquery.jstree.typings.d.ts", |
22 | 22 | "src/typings/split.js.typings.d.ts", |
23 | - "src/typings/add-marker.d.ts" | |
23 | + "node_modules/@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.d.ts", | |
24 | + "src/typings/leaflet-geoman-extend.d.ts" | |
24 | 25 | ], |
25 | 26 | "paths": { |
26 | 27 | "@app/*": ["src/app/*"], | ... | ... |
... | ... | @@ -1422,6 +1422,18 @@ |
1422 | 1422 | "@types/flowjs" "2.13.3" |
1423 | 1423 | tslib "^1.9.0" |
1424 | 1424 | |
1425 | +"@geoman-io/leaflet-geoman-free@^2.11.3": | |
1426 | + version "2.11.3" | |
1427 | + resolved "https://registry.yarnpkg.com/@geoman-io/leaflet-geoman-free/-/leaflet-geoman-free-2.11.3.tgz#480164ab76c2b2a885003e0c111284f3c3160a36" | |
1428 | + integrity sha512-LsiurEgKEHBcTnAVl8h7EfS5V/doCuxePzPE9SnfrhtJBN7IzP6UwkEo35Agwko+BnIuw/o2bE4F7irvKwQzjw== | |
1429 | + dependencies: | |
1430 | + "@turf/boolean-contains" "6.3.0" | |
1431 | + "@turf/kinks" "6.3.0" | |
1432 | + "@turf/line-intersect" "6.3.0" | |
1433 | + "@turf/line-split" "6.3.0" | |
1434 | + lodash "4.17.21" | |
1435 | + polygon-clipping "0.15.3" | |
1436 | + | |
1425 | 1437 | "@istanbuljs/schema@^0.1.2": |
1426 | 1438 | version "0.1.2" |
1427 | 1439 | resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" |
... | ... | @@ -1688,6 +1700,167 @@ |
1688 | 1700 | resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" |
1689 | 1701 | integrity sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow== |
1690 | 1702 | |
1703 | +"@turf/bbox@*", "@turf/bbox@^6.3.0": | |
1704 | + version "6.5.0" | |
1705 | + resolved "https://registry.yarnpkg.com/@turf/bbox/-/bbox-6.5.0.tgz#bec30a744019eae420dac9ea46fb75caa44d8dc5" | |
1706 | + integrity sha512-RBbLaao5hXTYyyg577iuMtDB8ehxMlUqHEJiMs8jT1GHkFhr6sYre3lmLsPeYEi/ZKj5TP5tt7fkzNdJ4GIVyw== | |
1707 | + dependencies: | |
1708 | + "@turf/helpers" "^6.5.0" | |
1709 | + "@turf/meta" "^6.5.0" | |
1710 | + | |
1711 | +"@turf/bearing@^6.5.0": | |
1712 | + version "6.5.0" | |
1713 | + resolved "https://registry.yarnpkg.com/@turf/bearing/-/bearing-6.5.0.tgz#462a053c6c644434bdb636b39f8f43fb0cd857b0" | |
1714 | + integrity sha512-dxINYhIEMzgDOztyMZc20I7ssYVNEpSv04VbMo5YPQsqa80KO3TFvbuCahMsCAW5z8Tncc8dwBlEFrmRjJG33A== | |
1715 | + dependencies: | |
1716 | + "@turf/helpers" "^6.5.0" | |
1717 | + "@turf/invariant" "^6.5.0" | |
1718 | + | |
1719 | +"@turf/boolean-contains@6.3.0": | |
1720 | + version "6.3.0" | |
1721 | + resolved "https://registry.yarnpkg.com/@turf/boolean-contains/-/boolean-contains-6.3.0.tgz#fe4fc359e408c8c3c89e7fb159c9d31fde48779a" | |
1722 | + integrity sha512-1MW7B5G5tIu1lnAv3pXyFzl75wfBYnbA2GhwHDb4okIXMhloy/r5uIqAZHo0fOXykKVJS/gIfA/MioKIftoTug== | |
1723 | + dependencies: | |
1724 | + "@turf/bbox" "^6.3.0" | |
1725 | + "@turf/boolean-point-in-polygon" "^6.3.0" | |
1726 | + "@turf/boolean-point-on-line" "^6.3.0" | |
1727 | + "@turf/helpers" "^6.3.0" | |
1728 | + "@turf/invariant" "^6.3.0" | |
1729 | + | |
1730 | +"@turf/boolean-point-in-polygon@^6.3.0": | |
1731 | + version "6.5.0" | |
1732 | + resolved "https://registry.yarnpkg.com/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-6.5.0.tgz#6d2e9c89de4cd2e4365004c1e51490b7795a63cf" | |
1733 | + integrity sha512-DtSuVFB26SI+hj0SjrvXowGTUCHlgevPAIsukssW6BG5MlNSBQAo70wpICBNJL6RjukXg8d2eXaAWuD/CqL00A== | |
1734 | + dependencies: | |
1735 | + "@turf/helpers" "^6.5.0" | |
1736 | + "@turf/invariant" "^6.5.0" | |
1737 | + | |
1738 | +"@turf/boolean-point-on-line@^6.3.0": | |
1739 | + version "6.5.0" | |
1740 | + resolved "https://registry.yarnpkg.com/@turf/boolean-point-on-line/-/boolean-point-on-line-6.5.0.tgz#a8efa7bad88760676f395afb9980746bc5b376e9" | |
1741 | + integrity sha512-A1BbuQ0LceLHvq7F/P7w3QvfpmZqbmViIUPHdNLvZimFNLo4e6IQunmzbe+8aSStH9QRZm3VOflyvNeXvvpZEQ== | |
1742 | + dependencies: | |
1743 | + "@turf/helpers" "^6.5.0" | |
1744 | + "@turf/invariant" "^6.5.0" | |
1745 | + | |
1746 | +"@turf/destination@^6.5.0": | |
1747 | + version "6.5.0" | |
1748 | + resolved "https://registry.yarnpkg.com/@turf/destination/-/destination-6.5.0.tgz#30a84702f9677d076130e0440d3223ae503fdae1" | |
1749 | + integrity sha512-4cnWQlNC8d1tItOz9B4pmJdWpXqS0vEvv65bI/Pj/genJnsL7evI0/Xw42RvEGROS481MPiU80xzvwxEvhQiMQ== | |
1750 | + dependencies: | |
1751 | + "@turf/helpers" "^6.5.0" | |
1752 | + "@turf/invariant" "^6.5.0" | |
1753 | + | |
1754 | +"@turf/distance@^6.5.0": | |
1755 | + version "6.5.0" | |
1756 | + resolved "https://registry.yarnpkg.com/@turf/distance/-/distance-6.5.0.tgz#21f04d5f86e864d54e2abde16f35c15b4f36149a" | |
1757 | + integrity sha512-xzykSLfoURec5qvQJcfifw/1mJa+5UwByZZ5TZ8iaqjGYN0vomhV9aiSLeYdUGtYRESZ+DYC/OzY+4RclZYgMg== | |
1758 | + dependencies: | |
1759 | + "@turf/helpers" "^6.5.0" | |
1760 | + "@turf/invariant" "^6.5.0" | |
1761 | + | |
1762 | +"@turf/helpers@6.x", "@turf/helpers@^6.3.0", "@turf/helpers@^6.5.0": | |
1763 | + version "6.5.0" | |
1764 | + resolved "https://registry.yarnpkg.com/@turf/helpers/-/helpers-6.5.0.tgz#f79af094bd6b8ce7ed2bd3e089a8493ee6cae82e" | |
1765 | + integrity sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw== | |
1766 | + | |
1767 | +"@turf/invariant@^6.3.0", "@turf/invariant@^6.5.0": | |
1768 | + version "6.5.0" | |
1769 | + resolved "https://registry.yarnpkg.com/@turf/invariant/-/invariant-6.5.0.tgz#970afc988023e39c7ccab2341bd06979ddc7463f" | |
1770 | + integrity sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg== | |
1771 | + dependencies: | |
1772 | + "@turf/helpers" "^6.5.0" | |
1773 | + | |
1774 | +"@turf/kinks@6.3.0": | |
1775 | + version "6.3.0" | |
1776 | + resolved "https://registry.yarnpkg.com/@turf/kinks/-/kinks-6.3.0.tgz#a16b4ccc5a5aae139d43e36271e0a0494fdb4bf7" | |
1777 | + integrity sha512-BLWvbl2/fa4SeJzVMbleT6Vo1cmzwmzRfxL2xxMei2jmf6JSvqDoMJFwIHGXrLZXvhOCb1b2C+MhBfhtc7kYkQ== | |
1778 | + dependencies: | |
1779 | + "@turf/helpers" "^6.3.0" | |
1780 | + | |
1781 | +"@turf/line-intersect@6.3.0": | |
1782 | + version "6.3.0" | |
1783 | + resolved "https://registry.yarnpkg.com/@turf/line-intersect/-/line-intersect-6.3.0.tgz#726a50edc66bb7b5e798b052b103fb0da4d1c4f4" | |
1784 | + integrity sha512-3naxR7XpkPd2vst3Mw6DFry4C9m3o0/f2n/xu5UAyxb88Ie4m2k+1eqkhzMMx/0L+E6iThWpLx7DASM6q6o9ow== | |
1785 | + dependencies: | |
1786 | + "@turf/helpers" "^6.3.0" | |
1787 | + "@turf/invariant" "^6.3.0" | |
1788 | + "@turf/line-segment" "^6.3.0" | |
1789 | + "@turf/meta" "^6.3.0" | |
1790 | + geojson-rbush "3.x" | |
1791 | + | |
1792 | +"@turf/line-intersect@^6.3.0", "@turf/line-intersect@^6.5.0": | |
1793 | + version "6.5.0" | |
1794 | + resolved "https://registry.yarnpkg.com/@turf/line-intersect/-/line-intersect-6.5.0.tgz#dea48348b30c093715d2195d2dd7524aee4cf020" | |
1795 | + integrity sha512-CS6R1tZvVQD390G9Ea4pmpM6mJGPWoL82jD46y0q1KSor9s6HupMIo1kY4Ny+AEYQl9jd21V3Scz20eldpbTVA== | |
1796 | + dependencies: | |
1797 | + "@turf/helpers" "^6.5.0" | |
1798 | + "@turf/invariant" "^6.5.0" | |
1799 | + "@turf/line-segment" "^6.5.0" | |
1800 | + "@turf/meta" "^6.5.0" | |
1801 | + geojson-rbush "3.x" | |
1802 | + | |
1803 | +"@turf/line-segment@^6.3.0", "@turf/line-segment@^6.5.0": | |
1804 | + version "6.5.0" | |
1805 | + resolved "https://registry.yarnpkg.com/@turf/line-segment/-/line-segment-6.5.0.tgz#ee73f3ffcb7c956203b64ed966d96af380a4dd65" | |
1806 | + integrity sha512-jI625Ho4jSuJESNq66Mmi290ZJ5pPZiQZruPVpmHkUw257Pew0alMmb6YrqYNnLUuiVVONxAAKXUVeeUGtycfw== | |
1807 | + dependencies: | |
1808 | + "@turf/helpers" "^6.5.0" | |
1809 | + "@turf/invariant" "^6.5.0" | |
1810 | + "@turf/meta" "^6.5.0" | |
1811 | + | |
1812 | +"@turf/line-split@6.3.0": | |
1813 | + version "6.3.0" | |
1814 | + resolved "https://registry.yarnpkg.com/@turf/line-split/-/line-split-6.3.0.tgz#ee218f66cd65ce84eafc4956c24083663f6082ea" | |
1815 | + integrity sha512-Q0nUJ0vczy11piyEz0FaKScFwSQtb1HJ2RPEMCw1coUJhTCB02KBWQLImhYqwsD3uLg+H/fxaJ1Gva6EPWoDNQ== | |
1816 | + dependencies: | |
1817 | + "@turf/bbox" "^6.3.0" | |
1818 | + "@turf/helpers" "^6.3.0" | |
1819 | + "@turf/invariant" "^6.3.0" | |
1820 | + "@turf/line-intersect" "^6.3.0" | |
1821 | + "@turf/line-segment" "^6.3.0" | |
1822 | + "@turf/meta" "^6.3.0" | |
1823 | + "@turf/nearest-point-on-line" "^6.3.0" | |
1824 | + "@turf/square" "^6.3.0" | |
1825 | + "@turf/truncate" "^6.3.0" | |
1826 | + geojson-rbush "3.x" | |
1827 | + | |
1828 | +"@turf/meta@6.x", "@turf/meta@^6.3.0", "@turf/meta@^6.5.0": | |
1829 | + version "6.5.0" | |
1830 | + resolved "https://registry.yarnpkg.com/@turf/meta/-/meta-6.5.0.tgz#b725c3653c9f432133eaa04d3421f7e51e0418ca" | |
1831 | + integrity sha512-RrArvtsV0vdsCBegoBtOalgdSOfkBrTJ07VkpiCnq/491W67hnMWmDu7e6Ztw0C3WldRYTXkg3SumfdzZxLBHA== | |
1832 | + dependencies: | |
1833 | + "@turf/helpers" "^6.5.0" | |
1834 | + | |
1835 | +"@turf/nearest-point-on-line@^6.3.0": | |
1836 | + version "6.5.0" | |
1837 | + resolved "https://registry.yarnpkg.com/@turf/nearest-point-on-line/-/nearest-point-on-line-6.5.0.tgz#8e1cd2cdc0b5acaf4c8d8b3b33bb008d3cb99e7b" | |
1838 | + integrity sha512-WthrvddddvmymnC+Vf7BrkHGbDOUu6Z3/6bFYUGv1kxw8tiZ6n83/VG6kHz4poHOfS0RaNflzXSkmCi64fLBlg== | |
1839 | + dependencies: | |
1840 | + "@turf/bearing" "^6.5.0" | |
1841 | + "@turf/destination" "^6.5.0" | |
1842 | + "@turf/distance" "^6.5.0" | |
1843 | + "@turf/helpers" "^6.5.0" | |
1844 | + "@turf/invariant" "^6.5.0" | |
1845 | + "@turf/line-intersect" "^6.5.0" | |
1846 | + "@turf/meta" "^6.5.0" | |
1847 | + | |
1848 | +"@turf/square@^6.3.0": | |
1849 | + version "6.5.0" | |
1850 | + resolved "https://registry.yarnpkg.com/@turf/square/-/square-6.5.0.tgz#ab43eef99d39c36157ab5b80416bbeba1f6b2122" | |
1851 | + integrity sha512-BM2UyWDmiuHCadVhHXKIx5CQQbNCpOxB6S/aCNOCLbhCeypKX5Q0Aosc5YcmCJgkwO5BERCC6Ee7NMbNB2vHmQ== | |
1852 | + dependencies: | |
1853 | + "@turf/distance" "^6.5.0" | |
1854 | + "@turf/helpers" "^6.5.0" | |
1855 | + | |
1856 | +"@turf/truncate@^6.3.0": | |
1857 | + version "6.5.0" | |
1858 | + resolved "https://registry.yarnpkg.com/@turf/truncate/-/truncate-6.5.0.tgz#c3a16cad959f1be1c5156157d5555c64b19185d8" | |
1859 | + integrity sha512-pFxg71pLk+eJj134Z9yUoRhIi8vqnnKvCYwdT4x/DQl/19RVdq1tV3yqOT3gcTQNfniteylL5qV1uTBDV5sgrg== | |
1860 | + dependencies: | |
1861 | + "@turf/helpers" "^6.5.0" | |
1862 | + "@turf/meta" "^6.5.0" | |
1863 | + | |
1691 | 1864 | "@types/canvas-gauges@^2.1.2": |
1692 | 1865 | version "2.1.2" |
1693 | 1866 | resolved "https://registry.yarnpkg.com/@types/canvas-gauges/-/canvas-gauges-2.1.2.tgz#fb9ece324cb15ae137791ad21eb2db70e11a7210" |
... | ... | @@ -1725,6 +1898,11 @@ |
1725 | 1898 | resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.7.tgz#c8fa532b60a0042219cdf173ca21a975ef0666ad" |
1726 | 1899 | integrity sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ== |
1727 | 1900 | |
1901 | +"@types/geojson@7946.0.8": | |
1902 | + version "7946.0.8" | |
1903 | + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" | |
1904 | + integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== | |
1905 | + | |
1728 | 1906 | "@types/glob@^7.1.1": |
1729 | 1907 | version "7.1.3" |
1730 | 1908 | resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" |
... | ... | @@ -1791,34 +1969,48 @@ |
1791 | 1969 | dependencies: |
1792 | 1970 | "@types/jquery" "*" |
1793 | 1971 | |
1794 | -"@types/leaflet-editable@^1.2.1": | |
1972 | +"@types/leaflet-polylinedecorator@^1.6.1": | |
1973 | + version "1.6.1" | |
1974 | + resolved "https://registry.yarnpkg.com/@types/leaflet-polylinedecorator/-/leaflet-polylinedecorator-1.6.1.tgz#b6522f9dae52146bf73da249e4bedfbab200c6e4" | |
1975 | + integrity sha512-9etweJ2U4SWqcV/AR3i0NdWJByeMn6+zMUNlO6jVbpL8UI6qrMKybu8v9/s6UR4oXvsV4lZT6vzAsNAAMq5Ssg== | |
1976 | + dependencies: | |
1977 | + "@types/leaflet" "*" | |
1978 | + | |
1979 | +"@types/leaflet-providers@^1.2.1": | |
1795 | 1980 | version "1.2.1" |
1796 | - resolved "https://registry.yarnpkg.com/@types/leaflet-editable/-/leaflet-editable-1.2.1.tgz#12f1bd1d9af7beafbac256216062e97fe2ee4d55" | |
1797 | - integrity sha512-7Oms1HgulWiclkI0s1XLmr1yRylNoJX8sVUfAv9+28JzwWbKbLcQ6//vhFEOmoMlBQyL5veogKpUUb5qeF+Qyg== | |
1981 | + resolved "https://registry.yarnpkg.com/@types/leaflet-providers/-/leaflet-providers-1.2.1.tgz#620669b828959740a2d8572e0c0288a2382d3564" | |
1982 | + integrity sha512-uNyuXiNV2q3fmgNjQji2P6RjQISmL40bbOL91/3OAwiE3XhkLKPmSAtAcfe11MAIz45iEjdFZJWppq9QyfnPIw== | |
1798 | 1983 | dependencies: |
1799 | 1984 | "@types/leaflet" "*" |
1800 | 1985 | |
1801 | -"@types/leaflet-polylinedecorator@^1.6.0": | |
1802 | - version "1.6.0" | |
1803 | - resolved "https://registry.yarnpkg.com/@types/leaflet-polylinedecorator/-/leaflet-polylinedecorator-1.6.0.tgz#1572131ffedb3154c6e18e682d2fb700e203af19" | |
1804 | - integrity sha512-Z2BXZDjKEqHclwrAmhYdF1RwyFfa/NFxsoF79sitzaj5D/4YWHp/zDRcUZar5cQFKRgK66AYEIF7nKVuMzUGdw== | |
1986 | +"@types/leaflet.gridlayer.googlemutant@^0.4.6": | |
1987 | + version "0.4.6" | |
1988 | + resolved "https://registry.yarnpkg.com/@types/leaflet.gridlayer.googlemutant/-/leaflet.gridlayer.googlemutant-0.4.6.tgz#86d3ba9d432dec29b4796e37d815c233680e7fcb" | |
1989 | + integrity sha512-L0J7NadcZp5bcKQrv4DVlsEbQ90xLsOKScckAMnxoghh/wogk0GVkauYOYHBKeKDkx9qkMRzTf8oO+fKeYD7oQ== | |
1805 | 1990 | dependencies: |
1806 | 1991 | "@types/leaflet" "*" |
1807 | 1992 | |
1808 | -"@types/leaflet.markercluster@^1.4.4": | |
1809 | - version "1.4.4" | |
1810 | - resolved "https://registry.yarnpkg.com/@types/leaflet.markercluster/-/leaflet.markercluster-1.4.4.tgz#4b4772c86182923e920061a0c25cb3e53543ad35" | |
1811 | - integrity sha512-BQAilNWlBpYl4+PrsJXLOh4vyv7KfWi5kh3Fclg5y4gEeNeXKqhS6y1zzBB4+wcTuVUnMWfm2G0MfqA4yA5A5A== | |
1993 | +"@types/leaflet.markercluster@^1.4.6": | |
1994 | + version "1.4.6" | |
1995 | + resolved "https://registry.yarnpkg.com/@types/leaflet.markercluster/-/leaflet.markercluster-1.4.6.tgz#1159460b374ba5e329cb678d0e427f99dca75be5" | |
1996 | + integrity sha512-MD+bUDzxHznY0zOlSBUAMNQUGB2+xpJPKrR2MNEoBAAKa3QTKJJySBtCqWyGLvYNNO+Cdyc2c64aF2IFwe4fcQ== | |
1812 | 1997 | dependencies: |
1813 | 1998 | "@types/leaflet" "*" |
1814 | 1999 | |
1815 | -"@types/leaflet@*", "@types/leaflet@1.5.17": | |
2000 | +"@types/leaflet@*": | |
1816 | 2001 | version "1.5.17" |
1817 | 2002 | resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.5.17.tgz#b2153dc12c344e6896a93ffc6b61ac79da251e5b" |
1818 | 2003 | integrity sha512-2XYq9k6kNjhNI7PaTz8Rdxcc8Vzwu97OaS9CtcrTxnTSxFUGwjlGjTDvhTLJU+JRSfZ4lBwGcl0SjZHALdVr6g== |
1819 | 2004 | dependencies: |
1820 | 2005 | "@types/geojson" "*" |
1821 | 2006 | |
2007 | +"@types/leaflet@^1.7.6": | |
2008 | + version "1.7.6" | |
2009 | + resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.6.tgz#6580f4babb648972c5af3abc3d66866753fa9311" | |
2010 | + integrity sha512-Emkz3V08QnlelSbpT46OEAx+TBZYTOX2r1yM7W+hWg5+djHtQ1GbEXBDRLaqQDOYcDI51Ss0ayoqoKD4CtLUDA== | |
2011 | + dependencies: | |
2012 | + "@types/geojson" "*" | |
2013 | + | |
1822 | 2014 | "@types/lodash@^4.14.170": |
1823 | 2015 | version "4.14.170" |
1824 | 2016 | resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6" |
... | ... | @@ -4858,6 +5050,17 @@ gensync@^1.0.0-beta.2: |
4858 | 5050 | resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" |
4859 | 5051 | integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== |
4860 | 5052 | |
5053 | +geojson-rbush@3.x: | |
5054 | + version "3.2.0" | |
5055 | + resolved "https://registry.yarnpkg.com/geojson-rbush/-/geojson-rbush-3.2.0.tgz#8b543cf0d56f99b78faf1da52bb66acad6dfc290" | |
5056 | + integrity sha512-oVltQTXolxvsz1sZnutlSuLDEcQAKYC/uXt9zDzJJ6bu0W+baTI8LZBaTup5afzibEH4N3jlq2p+a152wlBJ7w== | |
5057 | + dependencies: | |
5058 | + "@turf/bbox" "*" | |
5059 | + "@turf/helpers" "6.x" | |
5060 | + "@turf/meta" "6.x" | |
5061 | + "@types/geojson" "7946.0.8" | |
5062 | + rbush "^3.0.1" | |
5063 | + | |
4861 | 5064 | get-caller-file@^2.0.1, get-caller-file@^2.0.5: |
4862 | 5065 | version "2.0.5" |
4863 | 5066 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" |
... | ... | @@ -6224,11 +6427,6 @@ klona@^2.0.4: |
6224 | 6427 | resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" |
6225 | 6428 | integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== |
6226 | 6429 | |
6227 | -leaflet-editable@^1.2.0: | |
6228 | - version "1.2.0" | |
6229 | - resolved "https://registry.yarnpkg.com/leaflet-editable/-/leaflet-editable-1.2.0.tgz#a3a01001764ba58ea923381ee6a1c814708a0b84" | |
6230 | - integrity sha512-wG11JwpL8zqIbypTop6xCRGagMuWw68ihYu4uqrqc5Ep0wnEJeyob7NB2Rt5t74Oih4rwJ3OfwaGbzdowOGfYQ== | |
6231 | - | |
6232 | 6430 | leaflet-polylinedecorator@^1.6.0: |
6233 | 6431 | version "1.6.0" |
6234 | 6432 | resolved "https://registry.yarnpkg.com/leaflet-polylinedecorator/-/leaflet-polylinedecorator-1.6.0.tgz#9ef79fd1b5302d67b72efe959a8ecd2553f27266" |
... | ... | @@ -6236,25 +6434,25 @@ leaflet-polylinedecorator@^1.6.0: |
6236 | 6434 | dependencies: |
6237 | 6435 | leaflet-rotatedmarker "^0.2.0" |
6238 | 6436 | |
6239 | -leaflet-providers@^1.12.0: | |
6240 | - version "1.12.0" | |
6241 | - resolved "https://registry.yarnpkg.com/leaflet-providers/-/leaflet-providers-1.12.0.tgz#bf407f580d9564480e2346bc1e6412ef696624cf" | |
6242 | - integrity sha512-pU/mR4B+NbayBGCg5/88dmRq7t1EGiNPhsVGV3yqHuDn594vIwus4CiPVW0RtiKJNKg8Vf1pILAbFl0i+yk+lQ== | |
6437 | +leaflet-providers@^1.13.0: | |
6438 | + version "1.13.0" | |
6439 | + resolved "https://registry.yarnpkg.com/leaflet-providers/-/leaflet-providers-1.13.0.tgz#10c843a23d5823a65096d40ad53f27029e13434b" | |
6440 | + integrity sha512-f/sN5wdgBbVA2jcCYzScIfYNxKdn2wBJP9bu+5cRX9Xj6g8Bt1G9Sr8WgJAt/ckIFIc3LVVxCBNFpSCfTuUElg== | |
6243 | 6441 | |
6244 | 6442 | leaflet-rotatedmarker@^0.2.0: |
6245 | 6443 | version "0.2.0" |
6246 | 6444 | resolved "https://registry.yarnpkg.com/leaflet-rotatedmarker/-/leaflet-rotatedmarker-0.2.0.tgz#4467f49f98d1bfd56959bd9c6705203dd2601277" |
6247 | 6445 | integrity sha1-RGf0n5jRv9VpWb2cZwUgPdJgEnc= |
6248 | 6446 | |
6249 | -leaflet.gridlayer.googlemutant@0.10.2: | |
6250 | - version "0.10.2" | |
6251 | - resolved "https://registry.yarnpkg.com/leaflet.gridlayer.googlemutant/-/leaflet.gridlayer.googlemutant-0.10.2.tgz#3c5351db4230beac1b1ea1f774d9288cfb0b6283" | |
6252 | - integrity sha512-r3le0W8izKmF2aeCCYp6P+dLQvPadV/vpJkres0ltDHiWac6qt3fQPNWjQl+8WCsCmcGTb1y5bmHOx0Yj6HA7g== | |
6447 | +leaflet.gridlayer.googlemutant@0.13.4: | |
6448 | + version "0.13.4" | |
6449 | + resolved "https://registry.yarnpkg.com/leaflet.gridlayer.googlemutant/-/leaflet.gridlayer.googlemutant-0.13.4.tgz#0add37d240c70c999e1f1d341208e6fea2372c40" | |
6450 | + integrity sha512-oC6xUSFJ9HP4WIupXakgiYckdBHuHQeSaxTXsVlcvcpfsuYoJ/HFIrz1bmK4Qr/qKO4fY1MDM6AoewU7Bph8ZQ== | |
6253 | 6451 | |
6254 | -leaflet.markercluster@^1.5.0: | |
6255 | - version "1.5.0" | |
6256 | - resolved "https://registry.yarnpkg.com/leaflet.markercluster/-/leaflet.markercluster-1.5.0.tgz#54db42485da32fc3d92c7ae22d0d7982879e0b67" | |
6257 | - integrity sha512-Fvf/cq4o806mJL50n+fZW9+QALDDLPvt7vuAjlD2vfnxx3srMDs2vWINJze4nKYJYRY45OC6tM/669C3pLwMCA== | |
6452 | +leaflet.markercluster@^1.5.3: | |
6453 | + version "1.5.3" | |
6454 | + resolved "https://registry.yarnpkg.com/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz#9cdb52a4eab92671832e1ef9899669e80efc4056" | |
6455 | + integrity sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA== | |
6258 | 6456 | |
6259 | 6457 | leaflet@^1.7.1: |
6260 | 6458 | version "1.7.1" |
... | ... | @@ -6365,7 +6563,7 @@ lodash.uniq@^4.5.0: |
6365 | 6563 | resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" |
6366 | 6564 | integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= |
6367 | 6565 | |
6368 | -lodash@^4.0.1, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@~4.17.21: | |
6566 | +lodash@4.17.21, lodash@^4.0.1, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@~4.17.21: | |
6369 | 6567 | version "4.17.21" |
6370 | 6568 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" |
6371 | 6569 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== |
... | ... | @@ -7651,6 +7849,13 @@ pnp-webpack-plugin@1.6.4: |
7651 | 7849 | dependencies: |
7652 | 7850 | ts-pnp "^1.1.6" |
7653 | 7851 | |
7852 | +polygon-clipping@0.15.3: | |
7853 | + version "0.15.3" | |
7854 | + resolved "https://registry.yarnpkg.com/polygon-clipping/-/polygon-clipping-0.15.3.tgz#0215840438470ba2e9e6593625e4ea5c1087b4b7" | |
7855 | + integrity sha512-ho0Xx5DLkgxRx/+n4O74XyJ67DcyN3Tu9bGYKsnTukGAW6ssnuak6Mwcyb1wHy9MZc9xsUWqIoiazkZB5weECg== | |
7856 | + dependencies: | |
7857 | + splaytree "^3.1.0" | |
7858 | + | |
7654 | 7859 | popper.js@1.16.1-lts: |
7655 | 7860 | version "1.16.1-lts" |
7656 | 7861 | resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05" |
... | ... | @@ -8191,6 +8396,11 @@ querystringify@^2.1.1: |
8191 | 8396 | resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" |
8192 | 8397 | integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== |
8193 | 8398 | |
8399 | +quickselect@^2.0.0: | |
8400 | + version "2.0.0" | |
8401 | + resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" | |
8402 | + integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== | |
8403 | + | |
8194 | 8404 | raf@^3.4.0, raf@^3.4.1: |
8195 | 8405 | version "3.4.1" |
8196 | 8406 | resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" |
... | ... | @@ -8243,6 +8453,13 @@ raw-loader@4.0.2: |
8243 | 8453 | loader-utils "^2.0.0" |
8244 | 8454 | schema-utils "^3.0.0" |
8245 | 8455 | |
8456 | +rbush@^3.0.1: | |
8457 | + version "3.0.1" | |
8458 | + resolved "https://registry.yarnpkg.com/rbush/-/rbush-3.0.1.tgz#5fafa8a79b3b9afdfe5008403a720cc1de882ecf" | |
8459 | + integrity sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w== | |
8460 | + dependencies: | |
8461 | + quickselect "^2.0.0" | |
8462 | + | |
8246 | 8463 | rc-align@^4.0.0: |
8247 | 8464 | version "4.0.8" |
8248 | 8465 | resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-4.0.8.tgz#276c3f5dfadf0de4bb95392cb81568c9e947a668" |
... | ... | @@ -9298,6 +9515,11 @@ speed-measure-webpack-plugin@1.4.2: |
9298 | 9515 | dependencies: |
9299 | 9516 | chalk "^4.1.0" |
9300 | 9517 | |
9518 | +splaytree@^3.1.0: | |
9519 | + version "3.1.0" | |
9520 | + resolved "https://registry.yarnpkg.com/splaytree/-/splaytree-3.1.0.tgz#17d4a0108a6da3627579690b7b847241e18ddec8" | |
9521 | + integrity sha512-gvUGR7xnOy0fLKTCxDeUZYgU/I1Tdf8M/lM1Qrf8L2TIOR5ipZjGk02uYcdv0o2x7WjVRgpm3iS2clLyuVAt0Q== | |
9522 | + | |
9301 | 9523 | split-string@^3.0.1, split-string@^3.0.2: |
9302 | 9524 | version "3.1.0" |
9303 | 9525 | resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" | ... | ... |