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,6 +830,7 @@ | ||
830 | <exclude>src/.browserslistrc</exclude> | 830 | <exclude>src/.browserslistrc</exclude> |
831 | <exclude>**/yarn.lock</exclude> | 831 | <exclude>**/yarn.lock</exclude> |
832 | <exclude>**/*.raw</exclude> | 832 | <exclude>**/*.raw</exclude> |
833 | + <exclude>**/*.patch</exclude> | ||
833 | <exclude>**/apache/cassandra/io/**</exclude> | 834 | <exclude>**/apache/cassandra/io/**</exclude> |
834 | <exclude>.run/**</exclude> | 835 | <exclude>.run/**</exclude> |
835 | </excludes> | 836 | </excludes> |
@@ -79,6 +79,7 @@ | @@ -79,6 +79,7 @@ | ||
79 | "src/app/modules/home/components/widget/lib/maps/markers.scss", | 79 | "src/app/modules/home/components/widget/lib/maps/markers.scss", |
80 | "node_modules/leaflet.markercluster/dist/MarkerCluster.css", | 80 | "node_modules/leaflet.markercluster/dist/MarkerCluster.css", |
81 | "node_modules/leaflet.markercluster/dist/MarkerCluster.Default.css", | 81 | "node_modules/leaflet.markercluster/dist/MarkerCluster.Default.css", |
82 | + "node_modules/@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css", | ||
82 | "node_modules/prismjs/themes/prism.css", | 83 | "node_modules/prismjs/themes/prism.css", |
83 | "node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css" | 84 | "node_modules/prismjs/plugins/line-numbers/prism-line-numbers.css" |
84 | ], | 85 | ], |
@@ -28,6 +28,7 @@ | @@ -28,6 +28,7 @@ | ||
28 | "@date-io/date-fns": "^2.10.11", | 28 | "@date-io/date-fns": "^2.10.11", |
29 | "@flowjs/flow.js": "^2.14.1", | 29 | "@flowjs/flow.js": "^2.14.1", |
30 | "@flowjs/ngx-flow": "~0.4.6", | 30 | "@flowjs/ngx-flow": "~0.4.6", |
31 | + "@geoman-io/leaflet-geoman-free": "^2.11.3", | ||
31 | "@juggle/resize-observer": "^3.3.1", | 32 | "@juggle/resize-observer": "^3.3.1", |
32 | "@mat-datetimepicker/core": "~6.0.2", | 33 | "@mat-datetimepicker/core": "~6.0.2", |
33 | "@material-ui/core": "^4.11.4", | 34 | "@material-ui/core": "^4.11.4", |
@@ -57,11 +58,10 @@ | @@ -57,11 +58,10 @@ | ||
57 | "jstree-bootstrap-theme": "^1.0.1", | 58 | "jstree-bootstrap-theme": "^1.0.1", |
58 | "jszip": "^3.6.0", | 59 | "jszip": "^3.6.0", |
59 | "leaflet": "^1.7.1", | 60 | "leaflet": "^1.7.1", |
60 | - "leaflet-editable": "^1.2.0", | ||
61 | "leaflet-polylinedecorator": "^1.6.0", | 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 | "material-design-icons": "^3.0.1", | 65 | "material-design-icons": "^3.0.1", |
66 | "messageformat": "^2.3.0", | 66 | "messageformat": "^2.3.0", |
67 | "moment": "^2.29.1", | 67 | "moment": "^2.29.1", |
@@ -113,10 +113,11 @@ | @@ -113,10 +113,11 @@ | ||
113 | "@types/jquery": "^3.5.2", | 113 | "@types/jquery": "^3.5.2", |
114 | "@types/js-beautify": "^1.13.1", | 114 | "@types/js-beautify": "^1.13.1", |
115 | "@types/jstree": "^3.3.40", | 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 | "@types/lodash": "^4.14.170", | 121 | "@types/lodash": "^4.14.170", |
121 | "@types/moment-timezone": "^0.5.30", | 122 | "@types/moment-timezone": "^0.5.30", |
122 | "@types/mousetrap": "1.6.3", | 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,23 +14,15 @@ | ||
14 | /// limitations under the License. | 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 | import tinycolor from 'tinycolor2'; | 18 | import tinycolor from 'tinycolor2'; |
27 | import 'leaflet-providers'; | 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 | import { | 23 | import { |
31 | defaultSettings, | 24 | defaultSettings, |
32 | FormattedData, | 25 | FormattedData, |
33 | - MapProviders, | ||
34 | MapSettings, | 26 | MapSettings, |
35 | MarkerSettings, | 27 | MarkerSettings, |
36 | PolygonSettings, | 28 | PolygonSettings, |
@@ -39,12 +31,10 @@ import { | @@ -39,12 +31,10 @@ import { | ||
39 | UnitedMapSettings | 31 | UnitedMapSettings |
40 | } from './map-models'; | 32 | } from './map-models'; |
41 | import { Marker } from './markers'; | 33 | import { Marker } from './markers'; |
42 | -import { Observable, of } from 'rxjs'; | 34 | +import { forkJoin, Observable, of } from 'rxjs'; |
43 | import { Polyline } from './polyline'; | 35 | import { Polyline } from './polyline'; |
44 | import { Polygon } from './polygon'; | 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 | import { | 38 | import { |
49 | checkLngLat, | 39 | checkLngLat, |
50 | createLoadingDiv, | 40 | createLoadingDiv, |
@@ -54,6 +44,15 @@ import { | @@ -54,6 +44,15 @@ import { | ||
54 | } from '@home/components/widget/lib/maps/common-maps-utils'; | 44 | } from '@home/components/widget/lib/maps/common-maps-utils'; |
55 | import { WidgetContext } from '@home/models/widget-component.models'; | 45 | import { WidgetContext } from '@home/models/widget-component.models'; |
56 | import { deepClone, isDefinedAndNotNull, isEmptyStr, isString } from '@core/utils'; | 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 | export default abstract class LeafletMap { | 57 | export default abstract class LeafletMap { |
59 | 58 | ||
@@ -78,20 +77,20 @@ export default abstract class LeafletMap { | @@ -78,20 +77,20 @@ export default abstract class LeafletMap { | ||
78 | drawRoutes: boolean; | 77 | drawRoutes: boolean; |
79 | showPolygon: boolean; | 78 | showPolygon: boolean; |
80 | updatePending = false; | 79 | updatePending = false; |
80 | + editPolygons = false; | ||
81 | + selectedEntity: FormattedData; | ||
81 | addMarkers: L.Marker[] = []; | 82 | addMarkers: L.Marker[] = []; |
82 | addPolygons: L.Polygon[] = []; | 83 | addPolygons: L.Polygon[] = []; |
83 | // tslint:disable-next-line:no-string-literal | 84 | // tslint:disable-next-line:no-string-literal |
84 | southWest = new L.LatLng(-Projection.SphericalMercator['MAX_LATITUDE'], -180); | 85 | southWest = new L.LatLng(-Projection.SphericalMercator['MAX_LATITUDE'], -180); |
85 | // tslint:disable-next-line:no-string-literal | 86 | // tslint:disable-next-line:no-string-literal |
86 | northEast = new L.LatLng(Projection.SphericalMercator['MAX_LATITUDE'], 180); | 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 | protected constructor(public ctx: WidgetContext, | 89 | protected constructor(public ctx: WidgetContext, |
92 | public $container: HTMLElement, | 90 | public $container: HTMLElement, |
93 | options: UnitedMapSettings) { | 91 | options: UnitedMapSettings) { |
94 | this.options = options; | 92 | this.options = options; |
93 | + this.editPolygons = options.showPolygon && options.editablePolygon; | ||
95 | } | 94 | } |
96 | 95 | ||
97 | public initSettings(options: MapSettings) { | 96 | public initSettings(options: MapSettings) { |
@@ -102,16 +101,28 @@ export default abstract class LeafletMap { | @@ -102,16 +101,28 @@ export default abstract class LeafletMap { | ||
102 | removeOutsideVisibleBounds, | 101 | removeOutsideVisibleBounds, |
103 | animate, | 102 | animate, |
104 | chunkedLoading, | 103 | chunkedLoading, |
104 | + spiderfyOnMaxZoom, | ||
105 | maxClusterRadius, | 105 | maxClusterRadius, |
106 | maxZoom }: MapSettings = options; | 106 | maxZoom }: MapSettings = options; |
107 | if (useClusterMarkers) { | 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 | const clusteringSettings: MarkerClusterGroupOptions = { | 112 | const clusteringSettings: MarkerClusterGroupOptions = { |
109 | - spiderfyOnMaxZoom: false, | 113 | + spiderfyOnMaxZoom, |
110 | zoomToBoundsOnClick: zoomOnClick, | 114 | zoomToBoundsOnClick: zoomOnClick, |
111 | showCoverageOnHover, | 115 | showCoverageOnHover, |
112 | removeOutsideVisibleBounds, | 116 | removeOutsideVisibleBounds, |
113 | animate, | 117 | animate, |
114 | - chunkedLoading | 118 | + chunkedLoading, |
119 | + pmIgnore: true, | ||
120 | + spiderLegPolylineOptions: { | ||
121 | + pmIgnore: true | ||
122 | + }, | ||
123 | + polygonOptions: { | ||
124 | + pmIgnore: true | ||
125 | + } | ||
115 | }; | 126 | }; |
116 | if (maxClusterRadius && maxClusterRadius > 0) { | 127 | if (maxClusterRadius && maxClusterRadius > 0) { |
117 | clusteringSettings.maxClusterRadius = Math.floor(maxClusterRadius); | 128 | clusteringSettings.maxClusterRadius = Math.floor(maxClusterRadius); |
@@ -119,183 +130,165 @@ export default abstract class LeafletMap { | @@ -119,183 +130,165 @@ export default abstract class LeafletMap { | ||
119 | if (maxZoom && maxZoom >= 0 && maxZoom < 19) { | 130 | if (maxZoom && maxZoom >= 0 && maxZoom < 19) { |
120 | clusteringSettings.disableClusteringAtZoom = Math.floor(maxZoom); | 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 | public setLoading(loading: boolean) { | 293 | public setLoading(loading: boolean) { |
301 | if (this.loading !== loading) { | 294 | if (this.loading !== loading) { |
@@ -337,11 +330,10 @@ export default abstract class LeafletMap { | @@ -337,11 +330,10 @@ export default abstract class LeafletMap { | ||
337 | if (this.options.disableScrollZooming) { | 330 | if (this.options.disableScrollZooming) { |
338 | this.map.scrollWheelZoom.disable(); | 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 | if (this.options.useClusterMarkers) { | 338 | if (this.options.useClusterMarkers) { |
347 | this.map.addLayer(this.markersCluster); | 339 | this.map.addLayer(this.markersCluster); |
@@ -352,12 +344,53 @@ export default abstract class LeafletMap { | @@ -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 | createLatLng(lat: number, lng: number): L.LatLng { | 396 | createLatLng(lat: number, lng: number): L.LatLng { |
@@ -441,7 +474,7 @@ export default abstract class LeafletMap { | @@ -441,7 +474,7 @@ export default abstract class LeafletMap { | ||
441 | } | 474 | } |
442 | 475 | ||
443 | convertToCustomFormat(position: L.LatLng, offset = 0): object { | 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 | return { | 479 | return { |
447 | [this.options.latKeyName]: position.lat, | 480 | [this.options.latKeyName]: position.lat, |
@@ -455,17 +488,18 @@ export default abstract class LeafletMap { | @@ -455,17 +488,18 @@ export default abstract class LeafletMap { | ||
455 | if (point.length) { | 488 | if (point.length) { |
456 | return this.convertToPolygonFormat(point); | 489 | return this.convertToPolygonFormat(point); |
457 | } else { | 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 | return { | 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,7 +518,15 @@ export default abstract class LeafletMap { | ||
484 | } | 518 | } |
485 | this.updateMarkers(formattedData, false); | 519 | this.updateMarkers(formattedData, false); |
486 | this.updateBoundsInternal(); | 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 | this.datasources = formattedData; | 530 | this.datasources = formattedData; |
489 | } | 531 | } |
490 | } else { | 532 | } else { |
@@ -577,10 +619,10 @@ export default abstract class LeafletMap { | @@ -577,10 +619,10 @@ export default abstract class LeafletMap { | ||
577 | } | 619 | } |
578 | 620 | ||
579 | dragMarker = (e, data = {} as FormattedData) => { | 621 | dragMarker = (e, data = {} as FormattedData) => { |
580 | - if (e.type !== 'dragend') { | 622 | + if (e === undefined) { |
581 | return; | 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 | private createMarker(key: string, data: FormattedData, dataSources: FormattedData[], settings: MarkerSettings, | 628 | private createMarker(key: string, data: FormattedData, dataSources: FormattedData[], settings: MarkerSettings, |
@@ -728,11 +770,15 @@ export default abstract class LeafletMap { | @@ -728,11 +770,15 @@ export default abstract class LeafletMap { | ||
728 | 770 | ||
729 | // Polygon | 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 | updatePolygons(polyData: FormattedData[], updateBounds = true) { | 777 | updatePolygons(polyData: FormattedData[], updateBounds = true) { |
732 | const keys: string[] = []; | 778 | const keys: string[] = []; |
733 | this.polygonsData = deepClone(polyData); | 779 | this.polygonsData = deepClone(polyData); |
734 | polyData.forEach((data: FormattedData) => { | 780 | polyData.forEach((data: FormattedData) => { |
735 | - if (data && isDefinedAndNotNull(data[this.options.polygonKeyName]) && !isEmptyStr(data[this.options.polygonKeyName])) { | 781 | + if (this.isValidPolygonPosition(data)) { |
736 | if (isString((data[this.options.polygonKeyName]))) { | 782 | if (isString((data[this.options.polygonKeyName]))) { |
737 | data[this.options.polygonKeyName] = JSON.parse(data[this.options.polygonKeyName]); | 783 | data[this.options.polygonKeyName] = JSON.parse(data[this.options.polygonKeyName]); |
738 | } | 784 | } |
@@ -758,15 +804,14 @@ export default abstract class LeafletMap { | @@ -758,15 +804,14 @@ export default abstract class LeafletMap { | ||
758 | } | 804 | } |
759 | 805 | ||
760 | dragPolygonVertex = (e?, data = {} as FormattedData) => { | 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 | return; | 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 | createPolygon(polyData: FormattedData, dataSources: FormattedData[], settings: PolygonSettings, updateBounds = true) { | 817 | createPolygon(polyData: FormattedData, dataSources: FormattedData[], settings: PolygonSettings, updateBounds = true) { |
@@ -57,6 +57,7 @@ export type MapSettings = { | @@ -57,6 +57,7 @@ export type MapSettings = { | ||
57 | showCoverageOnHover: boolean, | 57 | showCoverageOnHover: boolean, |
58 | animate: boolean, | 58 | animate: boolean, |
59 | maxClusterRadius: number, | 59 | maxClusterRadius: number, |
60 | + spiderfyOnMaxZoom: boolean, | ||
60 | chunkedLoading: boolean, | 61 | chunkedLoading: boolean, |
61 | removeOutsideVisibleBounds: boolean, | 62 | removeOutsideVisibleBounds: boolean, |
62 | useCustomProvider: boolean, | 63 | useCustomProvider: boolean, |
@@ -14,41 +14,23 @@ | @@ -14,41 +14,23 @@ | ||
14 | /// limitations under the License. | 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 | import LeafletMap from './leaflet-map'; | 18 | import LeafletMap from './leaflet-map'; |
25 | import { | 19 | import { |
26 | commonMapSettingsSchema, | 20 | commonMapSettingsSchema, |
27 | mapPolygonSchema, | 21 | mapPolygonSchema, |
28 | - mapProviderSchema, | ||
29 | markerClusteringSettingsSchema, | 22 | markerClusteringSettingsSchema, |
30 | markerClusteringSettingsSchemaLeaflet, | 23 | markerClusteringSettingsSchemaLeaflet, |
31 | routeMapSettingsSchema | 24 | routeMapSettingsSchema |
32 | } from './schemes'; | 25 | } from './schemes'; |
33 | import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface'; | 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 | import { WidgetContext } from '@app/modules/home/models/widget-component.models'; | 28 | import { WidgetContext } from '@app/modules/home/models/widget-component.models'; |
42 | import { getDefCenterPosition, getProviderSchema, parseFunction, parseWithTranslation } from './common-maps-utils'; | 29 | import { getDefCenterPosition, getProviderSchema, parseFunction, parseWithTranslation } from './common-maps-utils'; |
43 | import { Datasource, DatasourceData, JsonSettingsSchema, WidgetActionDescriptor } from '@shared/models/widget.models'; | 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 | import { TranslateService } from '@ngx-translate/core'; | 31 | import { TranslateService } from '@ngx-translate/core'; |
48 | import { UtilsService } from '@core/services/utils.service'; | 32 | import { UtilsService } from '@core/services/utils.service'; |
49 | import { EntityDataPageLink } from '@shared/models/query/query.models'; | 33 | import { EntityDataPageLink } from '@shared/models/query/query.models'; |
50 | -import { isDefined } from '@core/utils'; | ||
51 | -import { forkJoin, Observable, of } from 'rxjs'; | ||
52 | import { providerClass } from '@home/components/widget/lib/maps/providers'; | 34 | import { providerClass } from '@home/components/widget/lib/maps/providers'; |
53 | 35 | ||
54 | // @dynamic | 36 | // @dynamic |
@@ -81,8 +63,6 @@ export class MapWidgetController implements MapWidgetInterface { | @@ -81,8 +63,6 @@ export class MapWidgetController implements MapWidgetInterface { | ||
81 | } | 63 | } |
82 | parseWithTranslation.setTranslate(this.translate); | 64 | parseWithTranslation.setTranslate(this.translate); |
83 | this.map = new MapClass(this.ctx, $element, this.settings); | 65 | this.map = new MapClass(this.ctx, $element, this.settings); |
84 | - this.map.saveMarkerLocation = this.setMarkerLocation; | ||
85 | - this.map.savePolygonLocation = this.savePolygonLocation; | ||
86 | this.pageLink = { | 66 | this.pageLink = { |
87 | page: 0, | 67 | page: 0, |
88 | pageSize: this.settings.mapPageSize, | 68 | pageSize: this.settings.mapPageSize, |
@@ -178,112 +158,6 @@ export class MapWidgetController implements MapWidgetInterface { | @@ -178,112 +158,6 @@ export class MapWidgetController implements MapWidgetInterface { | ||
178 | }, entityName, null, entityLabel); | 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 | initSettings(settings: UnitedMapSettings, isEditMap?: boolean): UnitedMapSettings { | 161 | initSettings(settings: UnitedMapSettings, isEditMap?: boolean): UnitedMapSettings { |
288 | const functionParams = ['data', 'dsData', 'dsIndex']; | 162 | const functionParams = ['data', 'dsData', 'dsIndex']; |
289 | this.provider = settings.provider || this.mapProvider; | 163 | this.provider = settings.provider || this.mapProvider; |
@@ -42,9 +42,7 @@ export class Marker { | @@ -42,9 +42,7 @@ export class Marker { | ||
42 | constructor(private map: LeafletMap, private location: L.LatLng, public settings: MarkerSettings, | 42 | constructor(private map: LeafletMap, private location: L.LatLng, public settings: MarkerSettings, |
43 | data?: FormattedData, dataSources?, onDragendListener?) { | 43 | data?: FormattedData, dataSources?, onDragendListener?) { |
44 | this.setDataSources(data, dataSources); | 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 | this.markerOffset = [ | 47 | this.markerOffset = [ |
50 | isDefined(settings.markerOffsetX) ? settings.markerOffsetX : 0.5, | 48 | isDefined(settings.markerOffsetX) ? settings.markerOffsetX : 0.5, |
@@ -72,8 +70,8 @@ export class Marker { | @@ -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,19 +197,24 @@ export class Marker { | ||
199 | 197 | ||
200 | createColoredMarkerIcon(color: tinycolor.Instance): { size: number[], icon: Icon } { | 198 | createColoredMarkerIcon(color: tinycolor.Instance): { size: number[], icon: Icon } { |
201 | return { | 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 | removeMarker() { | 218 | removeMarker() { |
216 | /* this.map$.subscribe(map => | 219 | /* this.map$.subscribe(map => |
217 | this.leafletMarker.addTo(map))*/ | 220 | this.leafletMarker.addTo(map))*/ |
@@ -17,7 +17,6 @@ | @@ -17,7 +17,6 @@ | ||
17 | import L, { LatLngExpression, LeafletMouseEvent } from 'leaflet'; | 17 | import L, { LatLngExpression, LeafletMouseEvent } from 'leaflet'; |
18 | import { createTooltip } from './maps-utils'; | 18 | import { createTooltip } from './maps-utils'; |
19 | import { functionValueCalculator, parseWithTranslation, safeExecute } from './common-maps-utils'; | 19 | import { functionValueCalculator, parseWithTranslation, safeExecute } from './common-maps-utils'; |
20 | -import 'leaflet-editable/src/Leaflet.Editable'; | ||
21 | import { FormattedData, PolygonSettings } from './map-models'; | 20 | import { FormattedData, PolygonSettings } from './map-models'; |
22 | 21 | ||
23 | export class Polygon { | 22 | export class Polygon { |
@@ -37,14 +36,12 @@ export class Polygon { | @@ -37,14 +36,12 @@ export class Polygon { | ||
37 | color: settings.polygonStrokeColor, | 36 | color: settings.polygonStrokeColor, |
38 | weight: settings.polygonStrokeWeight, | 37 | weight: settings.polygonStrokeWeight, |
39 | fillOpacity: settings.polygonOpacity, | 38 | fillOpacity: settings.polygonOpacity, |
40 | - opacity: settings.polygonStrokeOpacity | 39 | + opacity: settings.polygonStrokeOpacity, |
40 | + pmIgnore: !settings.editablePolygon | ||
41 | }).addTo(this.map); | 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,13 +70,7 @@ export class Polygon { | ||
73 | updatePolygon(data: FormattedData, dataSources: FormattedData[], settings: PolygonSettings) { | 70 | updatePolygon(data: FormattedData, dataSources: FormattedData[], settings: PolygonSettings) { |
74 | this.data = data; | 71 | this.data = data; |
75 | this.dataSources = dataSources; | 72 | this.dataSources = dataSources; |
76 | - if (settings.editablePolygon) { | ||
77 | - this.leafletPoly.disableEdit(); | ||
78 | - } | ||
79 | this.leafletPoly.setLatLngs(data[this.settings.polygonKeyName]); | 73 | this.leafletPoly.setLatLngs(data[this.settings.polygonKeyName]); |
80 | - if (settings.editablePolygon) { | ||
81 | - this.leafletPoly.enableEdit(this.map); | ||
82 | - } | ||
83 | if (settings.showPolygonTooltip) { | 74 | if (settings.showPolygonTooltip) { |
84 | this.updateTooltip(this.data); | 75 | this.updateTooltip(this.data); |
85 | } | 76 | } |
@@ -14,7 +14,8 @@ | @@ -14,7 +14,8 @@ | ||
14 | /// limitations under the License. | 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 | import 'leaflet-polylinedecorator'; | 19 | import 'leaflet-polylinedecorator'; |
19 | 20 | ||
20 | import { FormattedData, PolylineSettings } from './map-models'; | 21 | import { FormattedData, PolylineSettings } from './map-models'; |
@@ -23,7 +24,7 @@ import { functionValueCalculator } from '@home/components/widget/lib/maps/common | @@ -23,7 +24,7 @@ import { functionValueCalculator } from '@home/components/widget/lib/maps/common | ||
23 | export class Polyline { | 24 | export class Polyline { |
24 | 25 | ||
25 | leafletPoly: L.Polyline; | 26 | leafletPoly: L.Polyline; |
26 | - polylineDecorator: L.PolylineDecorator; | 27 | + polylineDecorator: PolylineDecorator; |
27 | dataSources: FormattedData[]; | 28 | dataSources: FormattedData[]; |
28 | data: FormattedData; | 29 | data: FormattedData; |
29 | 30 | ||
@@ -36,7 +37,7 @@ export class Polyline { | @@ -36,7 +37,7 @@ export class Polyline { | ||
36 | ).addTo(this.map); | 37 | ).addTo(this.map); |
37 | 38 | ||
38 | if (settings.usePolylineDecorator) { | 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,7 +48,7 @@ export class Polyline { | ||
47 | offset: settings.decoratorOffset, | 48 | offset: settings.decoratorOffset, |
48 | endOffset: settings.endDecoratorOffset, | 49 | endOffset: settings.endDecoratorOffset, |
49 | repeat: settings.decoratorRepeat, | 50 | repeat: settings.decoratorRepeat, |
50 | - symbol: L.Symbol[settings.decoratorSymbol]({ | 51 | + symbol: Symbol[settings.decoratorSymbol]({ |
51 | pixelSize: settings.decoratorSymbolSize, | 52 | pixelSize: settings.decoratorSymbolSize, |
52 | polygon: false, | 53 | polygon: false, |
53 | pathOptions: { | 54 | pathOptions: { |
@@ -78,7 +79,8 @@ export class Polyline { | @@ -78,7 +79,8 @@ export class Polyline { | ||
78 | opacity: functionValueCalculator(settings.useStrokeOpacityFunction, settings.strokeOpacityFunction, | 79 | opacity: functionValueCalculator(settings.useStrokeOpacityFunction, settings.strokeOpacityFunction, |
79 | [this.data, this.dataSources, this.data.dsIndex], settings.strokeOpacity), | 80 | [this.data, this.dataSources, this.data.dsIndex], settings.strokeOpacity), |
80 | weight: functionValueCalculator(settings.useStrokeWeightFunction, settings.strokeWeightFunction, | 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,7 +38,6 @@ export class GoogleMap extends LeafletMap { | ||
38 | this.loadGoogle(() => { | 38 | this.loadGoogle(() => { |
39 | const map = L.map($container, { | 39 | const map = L.map($container, { |
40 | attributionControl: false, | 40 | attributionControl: false, |
41 | - editable: !!options.editablePolygon, | ||
42 | tap: L.Browser.safari && L.Browser.mobile | 41 | tap: L.Browser.safari && L.Browser.mobile |
43 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); | 42 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); |
44 | (L.gridLayer as any).googleMutant({ | 43 | (L.gridLayer as any).googleMutant({ |
@@ -23,7 +23,6 @@ export class HEREMap extends LeafletMap { | @@ -23,7 +23,6 @@ export class HEREMap extends LeafletMap { | ||
23 | constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) { | 23 | constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) { |
24 | super(ctx, $container, options); | 24 | super(ctx, $container, options); |
25 | const map = L.map($container, { | 25 | const map = L.map($container, { |
26 | - editable: !!options.editablePolygon, | ||
27 | tap: L.Browser.safari && L.Browser.mobile | 26 | tap: L.Browser.safari && L.Browser.mobile |
28 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); | 27 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); |
29 | const tileLayer = (L.tileLayer as any).provider(options.mapProviderHere || 'HERE.normalDay', options.credentials); | 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,7 +22,6 @@ import { filter, map, mergeMap } from 'rxjs/operators'; | ||
22 | import { | 22 | import { |
23 | aspectCache, | 23 | aspectCache, |
24 | calculateNewPointCoordinate, | 24 | calculateNewPointCoordinate, |
25 | - checkLngLat, | ||
26 | parseFunction | 25 | parseFunction |
27 | } from '@home/components/widget/lib/maps/common-maps-utils'; | 26 | } from '@home/components/widget/lib/maps/common-maps-utils'; |
28 | import { WidgetContext } from '@home/models/widget-component.models'; | 27 | import { WidgetContext } from '@home/models/widget-component.models'; |
@@ -221,7 +220,6 @@ export class ImageMap extends LeafletMap { | @@ -221,7 +220,6 @@ export class ImageMap extends LeafletMap { | ||
221 | zoom: 1, | 220 | zoom: 1, |
222 | crs: L.CRS.Simple, | 221 | crs: L.CRS.Simple, |
223 | attributionControl: false, | 222 | attributionControl: false, |
224 | - editable: !!this.options.editablePolygon, | ||
225 | tap: L.Browser.safari && L.Browser.mobile | 223 | tap: L.Browser.safari && L.Browser.mobile |
226 | }); | 224 | }); |
227 | this.updateBounds(updateImage); | 225 | this.updateBounds(updateImage); |
@@ -263,7 +261,13 @@ export class ImageMap extends LeafletMap { | @@ -263,7 +261,13 @@ export class ImageMap extends LeafletMap { | ||
263 | return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1); | 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 | const point = this.latLngToPoint(position); | 271 | const point = this.latLngToPoint(position); |
268 | const customX = calculateNewPointCoordinate(point.x, width); | 272 | const customX = calculateNewPointCoordinate(point.x, width); |
269 | const customY = calculateNewPointCoordinate(point.y, height); | 273 | const customY = calculateNewPointCoordinate(point.y, height); |
@@ -279,13 +283,9 @@ export class ImageMap extends LeafletMap { | @@ -279,13 +283,9 @@ export class ImageMap extends LeafletMap { | ||
279 | point.y = height; | 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 | return { | 286 | return { |
285 | [this.options.xPosKeyName]: customX, | 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,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 | return { | 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,7 +23,6 @@ export class OpenStreetMap extends LeafletMap { | ||
23 | constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) { | 23 | constructor(ctx: WidgetContext, $container, options: UnitedMapSettings) { |
24 | super(ctx, $container, options); | 24 | super(ctx, $container, options); |
25 | const map = L.map($container, { | 25 | const map = L.map($container, { |
26 | - editable: !!options.editablePolygon, | ||
27 | tap: L.Browser.safari && L.Browser.mobile | 26 | tap: L.Browser.safari && L.Browser.mobile |
28 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); | 27 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); |
29 | let tileLayer; | 28 | let tileLayer; |
@@ -25,7 +25,6 @@ export class TencentMap extends LeafletMap { | @@ -25,7 +25,6 @@ export class TencentMap extends LeafletMap { | ||
25 | super(ctx, $container, options); | 25 | super(ctx, $container, options); |
26 | const txUrl = 'http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0'; | 26 | const txUrl = 'http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0'; |
27 | const map = L.map($container, { | 27 | const map = L.map($container, { |
28 | - editable: !!options.editablePolygon, | ||
29 | tap: L.Browser.safari && L.Browser.mobile | 28 | tap: L.Browser.safari && L.Browser.mobile |
30 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); | 29 | }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel || DEFAULT_ZOOM_LEVEL); |
31 | const txLayer = L.tileLayer(txUrl, { | 30 | const txLayer = L.tileLayer(txUrl, { |
@@ -728,6 +728,11 @@ export const markerClusteringSettingsSchemaLeaflet = | @@ -728,6 +728,11 @@ export const markerClusteringSettingsSchemaLeaflet = | ||
728 | type: 'number', | 728 | type: 'number', |
729 | default: 80 | 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 | chunkedLoading: { | 736 | chunkedLoading: { |
732 | title: 'Use chunks for adding markers so that the page does not freeze', | 737 | title: 'Use chunks for adding markers so that the page does not freeze', |
733 | type: 'boolean', | 738 | type: 'boolean', |
@@ -747,6 +752,7 @@ export const markerClusteringSettingsSchemaLeaflet = | @@ -747,6 +752,7 @@ export const markerClusteringSettingsSchemaLeaflet = | ||
747 | 'showCoverageOnHover', | 752 | 'showCoverageOnHover', |
748 | 'animate', | 753 | 'animate', |
749 | 'maxClusterRadius', | 754 | 'maxClusterRadius', |
755 | + 'spiderfyOnMaxZoom', | ||
750 | 'chunkedLoading', | 756 | 'chunkedLoading', |
751 | 'removeOutsideVisibleBounds' | 757 | 'removeOutsideVisibleBounds' |
752 | ] | 758 | ] |
@@ -100,7 +100,10 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy | @@ -100,7 +100,10 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy | ||
100 | addGroupInfo(schema, 'Path Settings'); | 100 | addGroupInfo(schema, 'Path Settings'); |
101 | addToSchema(schema, addCondition(pointSchema, 'model.showPoints === true', ['showPoints'])); | 101 | addToSchema(schema, addCondition(pointSchema, 'model.showPoints === true', ['showPoints'])); |
102 | addGroupInfo(schema, 'Path Points Settings'); | 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 | addGroupInfo(schema, 'Polygon Settings'); | 107 | addGroupInfo(schema, 'Polygon Settings'); |
105 | return schema; | 108 | return schema; |
106 | } | 109 | } |
@@ -115,6 +118,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy | @@ -115,6 +118,7 @@ export class TripAnimationComponent implements OnInit, AfterViewInit, OnDestroy | ||
115 | rotationAngle: 0 | 118 | rotationAngle: 0 |
116 | }; | 119 | }; |
117 | this.settings = { ...settings, ...this.ctx.settings }; | 120 | this.settings = { ...settings, ...this.ctx.settings }; |
121 | + this.settings.editablePolygon = false; | ||
118 | this.useAnchors = this.settings.showPoints && this.settings.usePointAsAnchor; | 122 | this.useAnchors = this.settings.showPoints && this.settings.usePointAsAnchor; |
119 | this.settings.pointAsAnchorFunction = parseFunction(this.settings.pointAsAnchorFunction, ['data', 'dsData', 'dsIndex']); | 123 | this.settings.pointAsAnchorFunction = parseFunction(this.settings.pointAsAnchorFunction, ['data', 'dsData', 'dsIndex']); |
120 | this.settings.tooltipFunction = parseFunction(this.settings.tooltipFunction, ['data', 'dsData', 'dsIndex']); | 124 | this.settings.tooltipFunction = parseFunction(this.settings.tooltipFunction, ['data', 'dsData', 'dsIndex']); |
@@ -41,6 +41,7 @@ import { EdgesOverviewWidgetComponent } from '@home/components/widget/lib/edges- | @@ -41,6 +41,7 @@ import { EdgesOverviewWidgetComponent } from '@home/components/widget/lib/edges- | ||
41 | import { JsonInputWidgetComponent } from '@home/components/widget/lib/json-input-widget.component'; | 41 | import { JsonInputWidgetComponent } from '@home/components/widget/lib/json-input-widget.component'; |
42 | import { QrCodeWidgetComponent } from '@home/components/widget/lib/qrcode-widget.component'; | 42 | import { QrCodeWidgetComponent } from '@home/components/widget/lib/qrcode-widget.component'; |
43 | import { MarkdownWidgetComponent } from '@home/components/widget/lib/markdown-widget.component'; | 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 | @NgModule({ | 46 | @NgModule({ |
46 | declarations: | 47 | declarations: |
@@ -62,7 +63,8 @@ import { MarkdownWidgetComponent } from '@home/components/widget/lib/markdown-wi | @@ -62,7 +63,8 @@ import { MarkdownWidgetComponent } from '@home/components/widget/lib/markdown-wi | ||
62 | NavigationCardsWidgetComponent, | 63 | NavigationCardsWidgetComponent, |
63 | NavigationCardWidgetComponent, | 64 | NavigationCardWidgetComponent, |
64 | QrCodeWidgetComponent, | 65 | QrCodeWidgetComponent, |
65 | - MarkdownWidgetComponent | 66 | + MarkdownWidgetComponent, |
67 | + SelectEntityDialogComponent | ||
66 | ], | 68 | ], |
67 | imports: [ | 69 | imports: [ |
68 | CommonModule, | 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> |
ui-ngx/src/assets/add_polygon.svg
deleted
100644 → 0
@@ -3238,7 +3238,40 @@ | @@ -3238,7 +3238,40 @@ | ||
3238 | "update-timeseries": "Update timeseries", | 3238 | "update-timeseries": "Update timeseries", |
3239 | "value": "Value" | 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 | "icon": { | 3276 | "icon": { |
3244 | "icon": "Icon", | 3277 | "icon": "Icon", |
ui-ngx/src/assets/shadow.png
0 → 100644
712 Bytes
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | "compilerOptions": { | 3 | "compilerOptions": { |
4 | "outDir": "../out-tsc/app", | 4 | "outDir": "../out-tsc/app", |
5 | "types": ["node", "jquery", "flot", "tooltipster", "tinycolor2", "js-beautify", | 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 | "angularCompilerOptions": { | 8 | "angularCompilerOptions": { |
9 | "fullTemplateTypeCheck": true | 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,15 +17,13 @@ | ||
17 | import * as L from 'leaflet'; | 17 | import * as L from 'leaflet'; |
18 | 18 | ||
19 | declare module 'leaflet' { | 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,7 +20,8 @@ | ||
20 | "src/typings/jquery.flot.typings.d.ts", | 20 | "src/typings/jquery.flot.typings.d.ts", |
21 | "src/typings/jquery.jstree.typings.d.ts", | 21 | "src/typings/jquery.jstree.typings.d.ts", |
22 | "src/typings/split.js.typings.d.ts", | 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 | "paths": { | 26 | "paths": { |
26 | "@app/*": ["src/app/*"], | 27 | "@app/*": ["src/app/*"], |
@@ -1422,6 +1422,18 @@ | @@ -1422,6 +1422,18 @@ | ||
1422 | "@types/flowjs" "2.13.3" | 1422 | "@types/flowjs" "2.13.3" |
1423 | tslib "^1.9.0" | 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 | "@istanbuljs/schema@^0.1.2": | 1437 | "@istanbuljs/schema@^0.1.2": |
1426 | version "0.1.2" | 1438 | version "0.1.2" |
1427 | resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" | 1439 | resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" |
@@ -1688,6 +1700,167 @@ | @@ -1688,6 +1700,167 @@ | ||
1688 | resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" | 1700 | resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" |
1689 | integrity sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow== | 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 | "@types/canvas-gauges@^2.1.2": | 1864 | "@types/canvas-gauges@^2.1.2": |
1692 | version "2.1.2" | 1865 | version "2.1.2" |
1693 | resolved "https://registry.yarnpkg.com/@types/canvas-gauges/-/canvas-gauges-2.1.2.tgz#fb9ece324cb15ae137791ad21eb2db70e11a7210" | 1866 | resolved "https://registry.yarnpkg.com/@types/canvas-gauges/-/canvas-gauges-2.1.2.tgz#fb9ece324cb15ae137791ad21eb2db70e11a7210" |
@@ -1725,6 +1898,11 @@ | @@ -1725,6 +1898,11 @@ | ||
1725 | resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.7.tgz#c8fa532b60a0042219cdf173ca21a975ef0666ad" | 1898 | resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.7.tgz#c8fa532b60a0042219cdf173ca21a975ef0666ad" |
1726 | integrity sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ== | 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 | "@types/glob@^7.1.1": | 1906 | "@types/glob@^7.1.1": |
1729 | version "7.1.3" | 1907 | version "7.1.3" |
1730 | resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" | 1908 | resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" |
@@ -1791,34 +1969,48 @@ | @@ -1791,34 +1969,48 @@ | ||
1791 | dependencies: | 1969 | dependencies: |
1792 | "@types/jquery" "*" | 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 | version "1.2.1" | 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 | dependencies: | 1983 | dependencies: |
1799 | "@types/leaflet" "*" | 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 | dependencies: | 1990 | dependencies: |
1806 | "@types/leaflet" "*" | 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 | dependencies: | 1997 | dependencies: |
1813 | "@types/leaflet" "*" | 1998 | "@types/leaflet" "*" |
1814 | 1999 | ||
1815 | -"@types/leaflet@*", "@types/leaflet@1.5.17": | 2000 | +"@types/leaflet@*": |
1816 | version "1.5.17" | 2001 | version "1.5.17" |
1817 | resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.5.17.tgz#b2153dc12c344e6896a93ffc6b61ac79da251e5b" | 2002 | resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.5.17.tgz#b2153dc12c344e6896a93ffc6b61ac79da251e5b" |
1818 | integrity sha512-2XYq9k6kNjhNI7PaTz8Rdxcc8Vzwu97OaS9CtcrTxnTSxFUGwjlGjTDvhTLJU+JRSfZ4lBwGcl0SjZHALdVr6g== | 2003 | integrity sha512-2XYq9k6kNjhNI7PaTz8Rdxcc8Vzwu97OaS9CtcrTxnTSxFUGwjlGjTDvhTLJU+JRSfZ4lBwGcl0SjZHALdVr6g== |
1819 | dependencies: | 2004 | dependencies: |
1820 | "@types/geojson" "*" | 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 | "@types/lodash@^4.14.170": | 2014 | "@types/lodash@^4.14.170": |
1823 | version "4.14.170" | 2015 | version "4.14.170" |
1824 | resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6" | 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,6 +5050,17 @@ gensync@^1.0.0-beta.2: | ||
4858 | resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" | 5050 | resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" |
4859 | integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== | 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 | get-caller-file@^2.0.1, get-caller-file@^2.0.5: | 5064 | get-caller-file@^2.0.1, get-caller-file@^2.0.5: |
4862 | version "2.0.5" | 5065 | version "2.0.5" |
4863 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" | 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,11 +6427,6 @@ klona@^2.0.4: | ||
6224 | resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" | 6427 | resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" |
6225 | integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== | 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 | leaflet-polylinedecorator@^1.6.0: | 6430 | leaflet-polylinedecorator@^1.6.0: |
6233 | version "1.6.0" | 6431 | version "1.6.0" |
6234 | resolved "https://registry.yarnpkg.com/leaflet-polylinedecorator/-/leaflet-polylinedecorator-1.6.0.tgz#9ef79fd1b5302d67b72efe959a8ecd2553f27266" | 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,25 +6434,25 @@ leaflet-polylinedecorator@^1.6.0: | ||
6236 | dependencies: | 6434 | dependencies: |
6237 | leaflet-rotatedmarker "^0.2.0" | 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 | leaflet-rotatedmarker@^0.2.0: | 6442 | leaflet-rotatedmarker@^0.2.0: |
6245 | version "0.2.0" | 6443 | version "0.2.0" |
6246 | resolved "https://registry.yarnpkg.com/leaflet-rotatedmarker/-/leaflet-rotatedmarker-0.2.0.tgz#4467f49f98d1bfd56959bd9c6705203dd2601277" | 6444 | resolved "https://registry.yarnpkg.com/leaflet-rotatedmarker/-/leaflet-rotatedmarker-0.2.0.tgz#4467f49f98d1bfd56959bd9c6705203dd2601277" |
6247 | integrity sha1-RGf0n5jRv9VpWb2cZwUgPdJgEnc= | 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 | leaflet@^1.7.1: | 6457 | leaflet@^1.7.1: |
6260 | version "1.7.1" | 6458 | version "1.7.1" |
@@ -6365,7 +6563,7 @@ lodash.uniq@^4.5.0: | @@ -6365,7 +6563,7 @@ lodash.uniq@^4.5.0: | ||
6365 | resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" | 6563 | resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" |
6366 | integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= | 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 | version "4.17.21" | 6567 | version "4.17.21" |
6370 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" | 6568 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" |
6371 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== | 6569 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== |
@@ -7651,6 +7849,13 @@ pnp-webpack-plugin@1.6.4: | @@ -7651,6 +7849,13 @@ pnp-webpack-plugin@1.6.4: | ||
7651 | dependencies: | 7849 | dependencies: |
7652 | ts-pnp "^1.1.6" | 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 | popper.js@1.16.1-lts: | 7859 | popper.js@1.16.1-lts: |
7655 | version "1.16.1-lts" | 7860 | version "1.16.1-lts" |
7656 | resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05" | 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,6 +8396,11 @@ querystringify@^2.1.1: | ||
8191 | resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" | 8396 | resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" |
8192 | integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== | 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 | raf@^3.4.0, raf@^3.4.1: | 8404 | raf@^3.4.0, raf@^3.4.1: |
8195 | version "3.4.1" | 8405 | version "3.4.1" |
8196 | resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" | 8406 | resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" |
@@ -8243,6 +8453,13 @@ raw-loader@4.0.2: | @@ -8243,6 +8453,13 @@ raw-loader@4.0.2: | ||
8243 | loader-utils "^2.0.0" | 8453 | loader-utils "^2.0.0" |
8244 | schema-utils "^3.0.0" | 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 | rc-align@^4.0.0: | 8463 | rc-align@^4.0.0: |
8247 | version "4.0.8" | 8464 | version "4.0.8" |
8248 | resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-4.0.8.tgz#276c3f5dfadf0de4bb95392cb81568c9e947a668" | 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,6 +9515,11 @@ speed-measure-webpack-plugin@1.4.2: | ||
9298 | dependencies: | 9515 | dependencies: |
9299 | chalk "^4.1.0" | 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 | split-string@^3.0.1, split-string@^3.0.2: | 9523 | split-string@^3.0.1, split-string@^3.0.2: |
9302 | version "3.1.0" | 9524 | version "3.1.0" |
9303 | resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" | 9525 | resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" |