umap-project 3.2.0__py3-none-any.whl → 3.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of umap-project might be problematic. Click here for more details.
- umap/__init__.py +1 -1
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +42 -38
- umap/locale/en/LC_MESSAGES/django.mo +0 -0
- umap/locale/en/LC_MESSAGES/django.po +15 -15
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +39 -35
- umap/locale/nl/LC_MESSAGES/django.mo +0 -0
- umap/locale/nl/LC_MESSAGES/django.po +31 -27
- umap/settings/base.py +2 -0
- umap/static/umap/css/contextmenu.css +58 -2
- umap/static/umap/css/form.css +175 -45
- umap/static/umap/css/icon.css +20 -0
- umap/static/umap/img/16-white.svg +21 -40
- umap/static/umap/img/16.svg +1 -1
- umap/static/umap/img/24-white.svg +9 -9
- umap/static/umap/img/24.svg +23 -10
- umap/static/umap/img/source/16-white.svg +23 -41
- umap/static/umap/img/source/16.svg +1 -1
- umap/static/umap/img/source/24-white.svg +11 -11
- umap/static/umap/img/source/24.svg +25 -12
- umap/static/umap/js/modules/caption.js +8 -0
- umap/static/umap/js/modules/data/features.js +318 -174
- umap/static/umap/js/modules/data/layer.js +27 -20
- umap/static/umap/js/modules/form/builder.js +11 -7
- umap/static/umap/js/modules/form/fields.js +10 -7
- umap/static/umap/js/modules/formatter.js +42 -20
- umap/static/umap/js/modules/importer.js +6 -1
- umap/static/umap/js/modules/importers/opendata.js +125 -37
- umap/static/umap/js/modules/importers/openrouteservice.js +140 -0
- umap/static/umap/js/modules/managers.js +12 -4
- umap/static/umap/js/modules/printer.js +107 -0
- umap/static/umap/js/modules/rendering/controls.js +78 -2
- umap/static/umap/js/modules/rendering/icon.js +113 -82
- umap/static/umap/js/modules/rendering/layers/cluster.js +220 -64
- umap/static/umap/js/modules/rendering/map.js +5 -1
- umap/static/umap/js/modules/rendering/template.js +71 -1
- umap/static/umap/js/modules/rendering/ui.js +101 -34
- umap/static/umap/js/modules/schema.js +24 -0
- umap/static/umap/js/modules/share.js +19 -12
- umap/static/umap/js/modules/ui/bar.js +6 -1
- umap/static/umap/js/modules/ui/base.js +24 -9
- umap/static/umap/js/modules/ui/contextmenu.js +17 -7
- umap/static/umap/js/modules/ui/dialog.js +7 -4
- umap/static/umap/js/modules/umap.js +68 -62
- umap/static/umap/js/umap.controls.js +22 -57
- umap/static/umap/locale/am_ET.js +39 -4
- umap/static/umap/locale/am_ET.json +39 -4
- umap/static/umap/locale/ar.js +39 -4
- umap/static/umap/locale/ar.json +39 -4
- umap/static/umap/locale/ast.js +39 -4
- umap/static/umap/locale/ast.json +39 -4
- umap/static/umap/locale/bg.js +39 -4
- umap/static/umap/locale/bg.json +39 -4
- umap/static/umap/locale/br.js +39 -4
- umap/static/umap/locale/br.json +39 -4
- umap/static/umap/locale/ca.js +39 -4
- umap/static/umap/locale/ca.json +39 -4
- umap/static/umap/locale/cs_CZ.js +39 -4
- umap/static/umap/locale/cs_CZ.json +39 -4
- umap/static/umap/locale/da.js +47 -12
- umap/static/umap/locale/da.json +47 -12
- umap/static/umap/locale/de.js +39 -4
- umap/static/umap/locale/de.json +39 -4
- umap/static/umap/locale/el.js +81 -46
- umap/static/umap/locale/el.json +81 -46
- umap/static/umap/locale/en.js +38 -4
- umap/static/umap/locale/en.json +38 -4
- umap/static/umap/locale/en_US.json +39 -4
- umap/static/umap/locale/es.js +47 -12
- umap/static/umap/locale/es.json +47 -12
- umap/static/umap/locale/et.js +39 -4
- umap/static/umap/locale/et.json +39 -4
- umap/static/umap/locale/eu.js +80 -45
- umap/static/umap/locale/eu.json +80 -45
- umap/static/umap/locale/fa_IR.js +39 -4
- umap/static/umap/locale/fa_IR.json +39 -4
- umap/static/umap/locale/fi.js +39 -4
- umap/static/umap/locale/fi.json +39 -4
- umap/static/umap/locale/fr.js +39 -4
- umap/static/umap/locale/fr.json +39 -4
- umap/static/umap/locale/gl.js +39 -4
- umap/static/umap/locale/gl.json +39 -4
- umap/static/umap/locale/he.js +39 -4
- umap/static/umap/locale/he.json +39 -4
- umap/static/umap/locale/hr.js +39 -4
- umap/static/umap/locale/hr.json +39 -4
- umap/static/umap/locale/hu.js +55 -20
- umap/static/umap/locale/hu.json +55 -20
- umap/static/umap/locale/id.js +39 -4
- umap/static/umap/locale/id.json +39 -4
- umap/static/umap/locale/is.js +39 -4
- umap/static/umap/locale/is.json +39 -4
- umap/static/umap/locale/it.js +39 -4
- umap/static/umap/locale/it.json +39 -4
- umap/static/umap/locale/ja.js +39 -4
- umap/static/umap/locale/ja.json +39 -4
- umap/static/umap/locale/ko.js +39 -4
- umap/static/umap/locale/ko.json +39 -4
- umap/static/umap/locale/lt.js +39 -4
- umap/static/umap/locale/lt.json +39 -4
- umap/static/umap/locale/ms.js +52 -17
- umap/static/umap/locale/ms.json +52 -17
- umap/static/umap/locale/nl.js +58 -23
- umap/static/umap/locale/nl.json +58 -23
- umap/static/umap/locale/no.js +39 -4
- umap/static/umap/locale/no.json +39 -4
- umap/static/umap/locale/pl.js +39 -4
- umap/static/umap/locale/pl.json +39 -4
- umap/static/umap/locale/pl_PL.json +39 -4
- umap/static/umap/locale/pt.js +39 -4
- umap/static/umap/locale/pt.json +39 -4
- umap/static/umap/locale/pt_BR.js +39 -4
- umap/static/umap/locale/pt_BR.json +39 -4
- umap/static/umap/locale/pt_PT.js +39 -4
- umap/static/umap/locale/pt_PT.json +39 -4
- umap/static/umap/locale/ro.js +39 -4
- umap/static/umap/locale/ro.json +39 -4
- umap/static/umap/locale/ru.js +39 -4
- umap/static/umap/locale/ru.json +39 -4
- umap/static/umap/locale/sk_SK.js +39 -4
- umap/static/umap/locale/sk_SK.json +39 -4
- umap/static/umap/locale/sl.js +39 -4
- umap/static/umap/locale/sl.json +39 -4
- umap/static/umap/locale/sr.js +39 -4
- umap/static/umap/locale/sr.json +39 -4
- umap/static/umap/locale/sv.js +39 -4
- umap/static/umap/locale/sv.json +39 -4
- umap/static/umap/locale/th_TH.js +39 -4
- umap/static/umap/locale/th_TH.json +39 -4
- umap/static/umap/locale/tr.js +39 -4
- umap/static/umap/locale/tr.json +39 -4
- umap/static/umap/locale/uk_UA.js +39 -4
- umap/static/umap/locale/uk_UA.json +39 -4
- umap/static/umap/locale/vi.js +39 -4
- umap/static/umap/locale/vi.json +39 -4
- umap/static/umap/locale/vi_VN.json +39 -4
- umap/static/umap/locale/zh.js +39 -4
- umap/static/umap/locale/zh.json +39 -4
- umap/static/umap/locale/zh_CN.json +39 -4
- umap/static/umap/locale/zh_TW.Big5.json +39 -4
- umap/static/umap/locale/zh_TW.js +98 -63
- umap/static/umap/locale/zh_TW.json +98 -63
- umap/static/umap/map.css +90 -41
- umap/static/umap/vars.css +1 -0
- umap/static/umap/vendors/editable/Leaflet.Editable.js +3 -1
- umap/static/umap/vendors/openrouteservice/ors-js-client.js +521 -0
- umap/static/umap/vendors/openrouteservice/ors-js-client.js.map +1 -0
- umap/static/umap/vendors/simple-elevation-chart/elevation.js +63 -0
- umap/static/umap/vendors/simple-elevation-chart/elevation.svg +8 -0
- umap/static/umap/vendors/snapdom/snapdom.min.mjs +3 -0
- umap/storage/staticfiles.py +12 -0
- umap/templates/umap/css.html +0 -4
- umap/templates/umap/js.html +1 -3
- umap/tests/integration/test_basics.py +2 -0
- umap/tests/integration/test_conditional_rules.py +17 -17
- umap/tests/integration/test_datalayer.py +1 -1
- umap/tests/integration/test_draw_polygon.py +3 -5
- umap/tests/integration/test_draw_polyline.py +4 -6
- umap/tests/integration/test_draw_route.py +178 -0
- umap/tests/integration/test_edit_map.py +1 -1
- umap/tests/integration/test_edit_marker.py +7 -7
- umap/tests/integration/test_edit_polygon.py +2 -2
- umap/tests/integration/test_export_map.py +74 -10
- umap/tests/integration/test_map_preview.py +1 -1
- umap/tests/integration/test_share.py +1 -1
- umap/tests/integration/test_tableeditor.py +4 -4
- umap/tests/integration/test_websocket_sync.py +4 -4
- umap/utils.py +5 -1
- umap/views.py +2 -0
- {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/METADATA +9 -9
- {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/RECORD +175 -171
- umap/static/umap/vendors/markercluster/MarkerCluster.Default.css +0 -60
- umap/static/umap/vendors/markercluster/MarkerCluster.css +0 -14
- umap/static/umap/vendors/markercluster/leaflet.markercluster.js +0 -2
- umap/static/umap/vendors/markercluster/leaflet.markercluster.js.map +0 -1
- {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/WHEEL +0 -0
- {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/entry_points.txt +0 -0
- {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,11 +7,17 @@ import {
|
|
|
7
7
|
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
8
8
|
import { MutatingForm } from '../form/builder.js'
|
|
9
9
|
import { translate } from '../i18n.js'
|
|
10
|
+
import {
|
|
11
|
+
PREFERENCES as ORS_PREFERENCES,
|
|
12
|
+
PROFILES as ORS_PROFILES,
|
|
13
|
+
Importer as OpenRouteService,
|
|
14
|
+
} from '../importers/openrouteservice.js'
|
|
10
15
|
import loadPopup from '../rendering/popup.js'
|
|
11
16
|
import {
|
|
12
17
|
LeafletMarker,
|
|
13
18
|
LeafletPolygon,
|
|
14
19
|
LeafletPolyline,
|
|
20
|
+
LeafletRoute,
|
|
15
21
|
MaskPolygon,
|
|
16
22
|
} from '../rendering/ui.js'
|
|
17
23
|
import { SCHEMA } from '../schema.js'
|
|
@@ -88,6 +94,14 @@ class Feature {
|
|
|
88
94
|
return [...this.datalayer.fields, ...this._umap.fields]
|
|
89
95
|
}
|
|
90
96
|
|
|
97
|
+
setter(key, value) {
|
|
98
|
+
if (key === 'datalayer') {
|
|
99
|
+
this.changeDataLayer(value)
|
|
100
|
+
} else {
|
|
101
|
+
Utils.setObjectValue(this, key, value)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
91
105
|
isOnScreen(bounds) {
|
|
92
106
|
return this.ui?.isOnScreen(bounds)
|
|
93
107
|
}
|
|
@@ -209,6 +223,8 @@ class Feature {
|
|
|
209
223
|
edit(event) {
|
|
210
224
|
if (!this._umap.editEnabled || this.isReadOnly()) return
|
|
211
225
|
if (this._umap.editedFeature === this && !event?.force) return
|
|
226
|
+
// If this feature is active (popup open), let's close it.
|
|
227
|
+
this.deactivate()
|
|
212
228
|
const container = DomUtil.create('div', 'umap-feature-container')
|
|
213
229
|
DomUtil.createTitle(
|
|
214
230
|
container,
|
|
@@ -244,21 +260,29 @@ class Feature {
|
|
|
244
260
|
})
|
|
245
261
|
form.appendChild(button)
|
|
246
262
|
this.appendEditFieldsets(container)
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
263
|
+
const [details, { fieldset }] = Utils.loadTemplateWithRefs(`
|
|
264
|
+
<details>
|
|
265
|
+
<summary>${translate('Advanced actions')}</summary>
|
|
266
|
+
<fieldset class="button-bar by2" data-ref=fieldset></fieldset>
|
|
267
|
+
</details>
|
|
268
|
+
`)
|
|
269
|
+
container.appendChild(details)
|
|
270
|
+
this.getAdvancedEditActions(fieldset)
|
|
271
|
+
const onPanelLoaded = this._umap.editPanel.open({ content: container })
|
|
272
|
+
onPanelLoaded.then(() => {
|
|
254
273
|
builder.form.querySelector('input')?.focus()
|
|
255
274
|
})
|
|
256
275
|
this._umap.editedFeature = this
|
|
257
276
|
if (!this.ui.isOnScreen(this._umap._leafletMap.getBounds())) this.zoomTo(event)
|
|
277
|
+
return onPanelLoaded
|
|
258
278
|
}
|
|
259
279
|
|
|
260
280
|
toggleEditing() {
|
|
261
|
-
this.
|
|
281
|
+
if (this._umap.editedFeature === this) {
|
|
282
|
+
this._umap.editPanel.close()
|
|
283
|
+
} else {
|
|
284
|
+
this.edit()
|
|
285
|
+
}
|
|
262
286
|
}
|
|
263
287
|
|
|
264
288
|
getAdvancedEditActions(container) {
|
|
@@ -407,7 +431,6 @@ class Feature {
|
|
|
407
431
|
if (this.datalayer) {
|
|
408
432
|
this.datalayer.removeFeature(this)
|
|
409
433
|
}
|
|
410
|
-
|
|
411
434
|
datalayer.addFeature(this)
|
|
412
435
|
this.sync.upsert(this.toGeoJSON())
|
|
413
436
|
this.redraw()
|
|
@@ -496,21 +519,6 @@ class Feature {
|
|
|
496
519
|
})
|
|
497
520
|
}
|
|
498
521
|
|
|
499
|
-
getInplaceEditMenu() {
|
|
500
|
-
return [
|
|
501
|
-
{
|
|
502
|
-
action: () => this.toggleEditing(),
|
|
503
|
-
title: translate('Toggle edit mode (⇧+Click)'),
|
|
504
|
-
icon: 'icon-edit',
|
|
505
|
-
},
|
|
506
|
-
{
|
|
507
|
-
action: () => this.del(),
|
|
508
|
-
title: translate('Delete this feature'),
|
|
509
|
-
icon: 'icon-delete',
|
|
510
|
-
},
|
|
511
|
-
]
|
|
512
|
-
}
|
|
513
|
-
|
|
514
522
|
isFiltered() {
|
|
515
523
|
const filterKeys = this.datalayer.getFilterKeys()
|
|
516
524
|
const filter = this._umap.browser.options.filter
|
|
@@ -613,9 +621,14 @@ class Feature {
|
|
|
613
621
|
}
|
|
614
622
|
}
|
|
615
623
|
|
|
616
|
-
|
|
624
|
+
getContextMenu(event) {
|
|
617
625
|
const permalink = this.getPermalink()
|
|
618
|
-
|
|
626
|
+
const items = []
|
|
627
|
+
if (this._umap.editEnabled && !this.isReadOnly()) {
|
|
628
|
+
items.push({
|
|
629
|
+
items: this.getEditContextMenu(event),
|
|
630
|
+
})
|
|
631
|
+
}
|
|
619
632
|
if (permalink) {
|
|
620
633
|
items.push({
|
|
621
634
|
label: translate('Permalink'),
|
|
@@ -637,32 +650,43 @@ class Feature {
|
|
|
637
650
|
this._umap.tooltip.open({ content: L._('✅ Copied!') })
|
|
638
651
|
},
|
|
639
652
|
})
|
|
640
|
-
if (this._umap.editEnabled && !this.isReadOnly()) {
|
|
641
|
-
items = items.concat(this.getContextMenuEditItems(event))
|
|
642
|
-
}
|
|
643
653
|
return items
|
|
644
654
|
}
|
|
645
655
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
}
|
|
656
|
+
getDrawingTools(event) {
|
|
657
|
+
return [
|
|
658
|
+
{
|
|
659
|
+
title: translate('Toggle edit mode (⇧+Click)'),
|
|
660
|
+
action: () => this.toggleEditing(),
|
|
661
|
+
icon: 'icon-edit',
|
|
662
|
+
},
|
|
663
|
+
]
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
getEditContextMenu(event) {
|
|
667
|
+
const items = []
|
|
668
|
+
const vertexClicked = event.vertex
|
|
669
|
+
if (vertexClicked) {
|
|
670
|
+
items.push(...this.getVertexTools(event))
|
|
671
|
+
} else {
|
|
672
|
+
items.push(...this.getDrawingTools(event))
|
|
653
673
|
}
|
|
654
|
-
items
|
|
674
|
+
items.push(
|
|
675
|
+
'-',
|
|
655
676
|
{
|
|
656
|
-
|
|
677
|
+
title: this._umap.help.displayLabel('EDIT_FEATURE_LAYER', false),
|
|
678
|
+
icon: 'icon-layers',
|
|
657
679
|
action: () => this.datalayer.edit(),
|
|
658
680
|
},
|
|
659
681
|
{
|
|
660
|
-
|
|
661
|
-
|
|
682
|
+
title: translate('Clone this feature'),
|
|
683
|
+
icon: 'icon-copy',
|
|
684
|
+
action: () => this.clone(),
|
|
662
685
|
},
|
|
663
686
|
{
|
|
664
|
-
|
|
665
|
-
|
|
687
|
+
title: translate('Delete this feature'),
|
|
688
|
+
icon: 'icon-delete',
|
|
689
|
+
action: () => this.del(),
|
|
666
690
|
}
|
|
667
691
|
)
|
|
668
692
|
return items
|
|
@@ -677,7 +701,10 @@ class Feature {
|
|
|
677
701
|
}
|
|
678
702
|
|
|
679
703
|
deactivate() {
|
|
680
|
-
if (this._umap.activeFeature === this)
|
|
704
|
+
if (this._umap.activeFeature === this) {
|
|
705
|
+
this._umap.activeFeature = undefined
|
|
706
|
+
this.ui.closePopup()
|
|
707
|
+
}
|
|
681
708
|
}
|
|
682
709
|
}
|
|
683
710
|
|
|
@@ -722,6 +749,7 @@ export class Point extends Feature {
|
|
|
722
749
|
return [
|
|
723
750
|
'properties._umap_options.color',
|
|
724
751
|
'properties._umap_options.iconClass',
|
|
752
|
+
'properties._umap_options.iconSize',
|
|
725
753
|
'properties._umap_options.iconUrl',
|
|
726
754
|
'properties._umap_options.iconOpacity',
|
|
727
755
|
]
|
|
@@ -754,12 +782,12 @@ export class Point extends Feature {
|
|
|
754
782
|
}
|
|
755
783
|
|
|
756
784
|
zoomTo(event) {
|
|
757
|
-
if (this.datalayer.isClustered() &&
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
super.zoomTo(event)
|
|
785
|
+
if (this.datalayer.isClustered() && this.ui._cluster) {
|
|
786
|
+
this.ui._cluster.zoomToCoverage().then(() => {
|
|
787
|
+
this.ui._cluster.spiderfy()
|
|
788
|
+
})
|
|
762
789
|
}
|
|
790
|
+
super.zoomTo(event)
|
|
763
791
|
}
|
|
764
792
|
}
|
|
765
793
|
|
|
@@ -778,8 +806,9 @@ class Path extends Feature {
|
|
|
778
806
|
|
|
779
807
|
edit(event) {
|
|
780
808
|
if (this._umap.editEnabled) {
|
|
781
|
-
super.edit(event)
|
|
809
|
+
const promise = super.edit(event)
|
|
782
810
|
if (!this.ui.editEnabled()) this.ui.makeGeometryEditable()
|
|
811
|
+
return promise
|
|
783
812
|
}
|
|
784
813
|
}
|
|
785
814
|
|
|
@@ -837,33 +866,6 @@ class Path extends Feature {
|
|
|
837
866
|
return other
|
|
838
867
|
}
|
|
839
868
|
|
|
840
|
-
getInplaceEditMenu(event) {
|
|
841
|
-
const items = super.getInplaceEditMenu()
|
|
842
|
-
if (this.isMulti()) {
|
|
843
|
-
items.push({
|
|
844
|
-
action: () => this.ui.enableEdit().deleteShapeAt(event.latlng),
|
|
845
|
-
title: translate('Delete this shape'),
|
|
846
|
-
icon: 'icon-delete-shape',
|
|
847
|
-
})
|
|
848
|
-
items.push({
|
|
849
|
-
action: () => this.ui.isolateShape(event.latlng),
|
|
850
|
-
title: translate('Extract shape to separate feature'),
|
|
851
|
-
icon: 'icon-extract-shape',
|
|
852
|
-
})
|
|
853
|
-
}
|
|
854
|
-
return items
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
getInplaceEditVertexMenu(event) {
|
|
858
|
-
return [
|
|
859
|
-
{
|
|
860
|
-
action: () => event.vertex.delete(),
|
|
861
|
-
title: translate('Delete this vertex (Alt+Click)'),
|
|
862
|
-
icon: 'icon-delete-vertex',
|
|
863
|
-
},
|
|
864
|
-
]
|
|
865
|
-
}
|
|
866
|
-
|
|
867
869
|
zoomTo({ easing, callback }) {
|
|
868
870
|
// Use bounds instead of centroid for paths.
|
|
869
871
|
easing = easing || this._umap.getProperty('easing')
|
|
@@ -878,62 +880,55 @@ class Path extends Feature {
|
|
|
878
880
|
if (callback) callback.call(this)
|
|
879
881
|
}
|
|
880
882
|
|
|
881
|
-
|
|
882
|
-
const items = super.
|
|
883
|
+
getContextMenu(event) {
|
|
884
|
+
const items = super.getContextMenu(event)
|
|
883
885
|
items.push({
|
|
884
886
|
label: translate('Display measure'),
|
|
885
887
|
action: () => Alert.info(this.ui.getMeasure()),
|
|
886
888
|
})
|
|
887
|
-
if (this._umap.editEnabled && !this.isReadOnly() && this.isMulti()) {
|
|
888
|
-
items.push(...this.getContextMenuMultiItems(event))
|
|
889
|
-
}
|
|
890
889
|
return items
|
|
891
890
|
}
|
|
892
891
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
'-',
|
|
892
|
+
getVertexTools(event) {
|
|
893
|
+
return [
|
|
896
894
|
{
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
},
|
|
895
|
+
action: () => event.vertex.delete(),
|
|
896
|
+
title: translate('Delete this vertex (Alt+Click)'),
|
|
897
|
+
icon: 'icon-delete-vertex',
|
|
901
898
|
},
|
|
902
899
|
]
|
|
903
|
-
const shape = this.ui.shapeAt(event.latlng)
|
|
904
|
-
if (this.ui._latlngs.indexOf(shape) > 0) {
|
|
905
|
-
items.push({
|
|
906
|
-
label: translate('Make main shape'),
|
|
907
|
-
action: () => {
|
|
908
|
-
this.ui.enableEdit().deleteShape(shape)
|
|
909
|
-
this.ui.editor.prependShape(shape)
|
|
910
|
-
},
|
|
911
|
-
})
|
|
912
|
-
}
|
|
913
|
-
return items
|
|
914
900
|
}
|
|
915
901
|
|
|
916
|
-
|
|
917
|
-
const items = super.
|
|
902
|
+
getDrawingTools(event) {
|
|
903
|
+
const items = super.getDrawingTools(event)
|
|
904
|
+
if (this.isMulti()) {
|
|
905
|
+
items.push(
|
|
906
|
+
{
|
|
907
|
+
title: translate('Extract shape to separate feature'),
|
|
908
|
+
icon: 'icon-extract-shape',
|
|
909
|
+
action: () => {
|
|
910
|
+
this.ui.isolateShape(event.latlng)
|
|
911
|
+
},
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
title: translate('Delete this shape'),
|
|
915
|
+
icon: 'icon-delete-shape',
|
|
916
|
+
action: () => this.ui.enableEdit().deleteShapeAt(event.latlng),
|
|
917
|
+
}
|
|
918
|
+
)
|
|
919
|
+
}
|
|
918
920
|
if (
|
|
919
921
|
this._umap?.editedFeature !== this &&
|
|
920
922
|
this.isSameClass(this._umap.editedFeature)
|
|
921
923
|
) {
|
|
922
924
|
items.push({
|
|
923
|
-
|
|
925
|
+
title: translate('Transfer shape to edited feature'),
|
|
926
|
+
icon: 'icon-transfer-shape',
|
|
924
927
|
action: () => {
|
|
925
928
|
this.transferShape(event.latlng, this._umap.editedFeature)
|
|
926
929
|
},
|
|
927
930
|
})
|
|
928
931
|
}
|
|
929
|
-
if (this.isMulti()) {
|
|
930
|
-
items.push({
|
|
931
|
-
label: translate('Extract shape to separate feature'),
|
|
932
|
-
action: () => {
|
|
933
|
-
this.ui.isolateShape(event.latlng)
|
|
934
|
-
},
|
|
935
|
-
})
|
|
936
|
-
}
|
|
937
932
|
return items
|
|
938
933
|
}
|
|
939
934
|
}
|
|
@@ -965,13 +960,63 @@ export class LineString extends Path {
|
|
|
965
960
|
}
|
|
966
961
|
|
|
967
962
|
getUIClass() {
|
|
968
|
-
|
|
963
|
+
const klass = super.getUIClass()
|
|
964
|
+
if (klass) return klass
|
|
965
|
+
if (this.isRoute()) {
|
|
966
|
+
return LeafletRoute
|
|
967
|
+
}
|
|
968
|
+
return LeafletPolyline
|
|
969
969
|
}
|
|
970
970
|
|
|
971
971
|
isSameClass(other) {
|
|
972
972
|
return other instanceof LineString
|
|
973
973
|
}
|
|
974
974
|
|
|
975
|
+
cancelRoute() {
|
|
976
|
+
const oldRoute = Utils.CopyJSON(this.properties._umap_options.route)
|
|
977
|
+
this.properties._umap_options.route.active = false
|
|
978
|
+
this.redraw()
|
|
979
|
+
this.edit()
|
|
980
|
+
this.sync.update('properties._umap_options.route', null, oldRoute)
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
restoreRoute() {
|
|
984
|
+
const oldRoute = Utils.CopyJSON(this.properties._umap_options.route)
|
|
985
|
+
this._ensureRoute()
|
|
986
|
+
delete this.properties._umap_options.route.active
|
|
987
|
+
this.redraw()
|
|
988
|
+
this.sync.update(
|
|
989
|
+
'properties._umap_options.route',
|
|
990
|
+
this.properties._umap_options.route,
|
|
991
|
+
oldRoute
|
|
992
|
+
)
|
|
993
|
+
this.edit().then((panel) => {
|
|
994
|
+
panel.scrollTo('details#edit-route')
|
|
995
|
+
})
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
toRoute() {
|
|
999
|
+
this._ensureRoute()
|
|
1000
|
+
this.properties._umap_options.route.coordinates = Utils.CopyJSON(this.coordinates)
|
|
1001
|
+
this.redraw()
|
|
1002
|
+
this.sync.update(
|
|
1003
|
+
'properties._umap_options.route',
|
|
1004
|
+
this.properties._umap_options.route,
|
|
1005
|
+
null
|
|
1006
|
+
)
|
|
1007
|
+
this.edit().then((panel) => {
|
|
1008
|
+
panel.scrollTo('details#edit-route')
|
|
1009
|
+
})
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
askForRouteSettings() {
|
|
1013
|
+
const container = Utils.loadTemplate(
|
|
1014
|
+
`<div><h3>${translate('Route settings')}</h3></div>`
|
|
1015
|
+
)
|
|
1016
|
+
container.appendChild(this.routeForm())
|
|
1017
|
+
return this._umap.dialog.open({ template: container })
|
|
1018
|
+
}
|
|
1019
|
+
|
|
975
1020
|
toPolygon() {
|
|
976
1021
|
const geojson = this.toGeoJSON()
|
|
977
1022
|
geojson.geometry.type = 'Polygon'
|
|
@@ -986,15 +1031,51 @@ export class LineString extends Path {
|
|
|
986
1031
|
this.del()
|
|
987
1032
|
}
|
|
988
1033
|
|
|
1034
|
+
isRoute() {
|
|
1035
|
+
return (
|
|
1036
|
+
!!this.properties._umap_options.route &&
|
|
1037
|
+
this.properties._umap_options.route.active !== false
|
|
1038
|
+
)
|
|
1039
|
+
}
|
|
1040
|
+
|
|
989
1041
|
getAdvancedEditActions(container) {
|
|
990
1042
|
super.getAdvancedEditActions(container)
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1043
|
+
const button = Utils.loadTemplate(`
|
|
1044
|
+
<button class="button" type="button"><i class="icon icon-24 icon-polygon"></i>${translate('Transform to polygon')}</button>
|
|
1045
|
+
`)
|
|
1046
|
+
container.appendChild(button)
|
|
1047
|
+
button.addEventListener('click', () => this.toPolygon())
|
|
1048
|
+
if (this.isRoute()) {
|
|
1049
|
+
const button = Utils.loadTemplate(`
|
|
1050
|
+
<button class="button" type="button"><i class="icon icon-24 icon-polyline"></i>${translate('Transform to regular line')}</button>
|
|
1051
|
+
`)
|
|
1052
|
+
container.appendChild(button)
|
|
1053
|
+
button.addEventListener('click', () => this.cancelRoute())
|
|
1054
|
+
} else if (!this.isMulti() && this.coordinates.length < 10) {
|
|
1055
|
+
const button = Utils.loadTemplate(`
|
|
1056
|
+
<button class="button" type="button"><i class="icon icon-24 icon-route"></i>${translate('Transform to route')}</button>
|
|
1057
|
+
`)
|
|
1058
|
+
container.appendChild(button)
|
|
1059
|
+
button.addEventListener('click', () =>
|
|
1060
|
+
this.askForRouteSettings().then(() => {
|
|
1061
|
+
this.toRoute()
|
|
1062
|
+
this.computeRoute()
|
|
1063
|
+
})
|
|
1064
|
+
)
|
|
1065
|
+
} else if (this.properties._umap_options.route?.coordinates) {
|
|
1066
|
+
const button = Utils.loadTemplate(`
|
|
1067
|
+
<button class="button" type="button"><i class="icon icon-24 icon-route"></i>${translate('Restore route')}</button>
|
|
1068
|
+
`)
|
|
1069
|
+
container.appendChild(button)
|
|
1070
|
+
button.addEventListener('click', () => this.restoreRoute())
|
|
1071
|
+
}
|
|
1072
|
+
if (this._umap.properties.ORSAPIKey) {
|
|
1073
|
+
const button = Utils.loadTemplate(`
|
|
1074
|
+
<button class="button" type="button"><i class="icon icon-24 icon-mountain"></i>${translate('Compute elevations')}</button>
|
|
1075
|
+
`)
|
|
1076
|
+
container.appendChild(button)
|
|
1077
|
+
button.addEventListener('click', () => this.computeElevation())
|
|
1078
|
+
}
|
|
998
1079
|
}
|
|
999
1080
|
|
|
1000
1081
|
_mergeShapes(from, to) {
|
|
@@ -1046,38 +1127,40 @@ export class LineString extends Path {
|
|
|
1046
1127
|
return !LineUtil.isFlat(this.coordinates) && this.coordinates.length > 1
|
|
1047
1128
|
}
|
|
1048
1129
|
|
|
1049
|
-
|
|
1050
|
-
const items = super.
|
|
1051
|
-
const
|
|
1052
|
-
if (
|
|
1130
|
+
getVertexTools(event) {
|
|
1131
|
+
const items = super.getVertexTools(event)
|
|
1132
|
+
const index = event.vertex.getIndex()
|
|
1133
|
+
if (index !== 0 && index !== event.vertex.getLastIndex()) {
|
|
1053
1134
|
items.push({
|
|
1054
|
-
|
|
1055
|
-
|
|
1135
|
+
title: translate('Split line'),
|
|
1136
|
+
icon: 'icon-split-line',
|
|
1137
|
+
action: () => event.vertex.split(),
|
|
1138
|
+
})
|
|
1139
|
+
} else if (index === 0 || index === event.vertex.getLastIndex()) {
|
|
1140
|
+
items.push({
|
|
1141
|
+
title: this._umap.help.displayLabel('CONTINUE_LINE', false),
|
|
1142
|
+
icon: 'icon-continue-line',
|
|
1143
|
+
action: () => event.vertex.continue(),
|
|
1056
1144
|
})
|
|
1057
|
-
}
|
|
1058
|
-
if (vertexClicked) {
|
|
1059
|
-
const index = event.vertex.getIndex()
|
|
1060
|
-
if (index !== 0 && index !== event.vertex.getLastIndex()) {
|
|
1061
|
-
items.push({
|
|
1062
|
-
label: translate('Split line'),
|
|
1063
|
-
action: () => event.vertex.split(),
|
|
1064
|
-
})
|
|
1065
|
-
} else if (index === 0 || index === event.vertex.getLastIndex()) {
|
|
1066
|
-
items.push({
|
|
1067
|
-
label: this._umap.help.displayLabel('CONTINUE_LINE'),
|
|
1068
|
-
action: () => event.vertex.continue(),
|
|
1069
|
-
})
|
|
1070
|
-
}
|
|
1071
1145
|
}
|
|
1072
1146
|
return items
|
|
1073
1147
|
}
|
|
1074
1148
|
|
|
1075
|
-
|
|
1076
|
-
const items = super.
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1149
|
+
getDrawingTools(event) {
|
|
1150
|
+
const items = super.getDrawingTools(event)
|
|
1151
|
+
if (this.isMulti()) {
|
|
1152
|
+
items.push({
|
|
1153
|
+
title: translate('Merge lines'),
|
|
1154
|
+
icon: 'icon-merge',
|
|
1155
|
+
action: () => this.mergeShapes(),
|
|
1156
|
+
})
|
|
1157
|
+
} else {
|
|
1158
|
+
items.push({
|
|
1159
|
+
title: translate('Transform to polygon'),
|
|
1160
|
+
icon: 'icon-polygon',
|
|
1161
|
+
action: () => this.toPolygon(),
|
|
1162
|
+
})
|
|
1163
|
+
}
|
|
1081
1164
|
return items
|
|
1082
1165
|
}
|
|
1083
1166
|
|
|
@@ -1086,23 +1169,64 @@ export class LineString extends Path {
|
|
|
1086
1169
|
return Object.assign({ gain, loss }, super.extendedProperties())
|
|
1087
1170
|
}
|
|
1088
1171
|
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
if (index === 0 || index === event.vertex.getLastIndex()) {
|
|
1093
|
-
items.push({
|
|
1094
|
-
action: () => event.vertex.continue(),
|
|
1095
|
-
title: translate('Continue line'),
|
|
1096
|
-
icon: 'icon-continue-line',
|
|
1097
|
-
})
|
|
1098
|
-
} else {
|
|
1099
|
-
items.push({
|
|
1100
|
-
action: () => event.vertex.split(),
|
|
1101
|
-
title: translate('Split line'),
|
|
1102
|
-
icon: 'icon-split-line',
|
|
1103
|
-
})
|
|
1172
|
+
_ensureRoute() {
|
|
1173
|
+
if (!this.properties._umap_options.route) {
|
|
1174
|
+
this.properties._umap_options.route = {}
|
|
1104
1175
|
}
|
|
1105
|
-
|
|
1176
|
+
this.properties._umap_options.route.profile ??= ORS_PROFILES[0][0]
|
|
1177
|
+
this.properties._umap_options.route.preference ??= ORS_PREFERENCES[0][0]
|
|
1178
|
+
this.properties._umap_options.route.elevation ??= false
|
|
1179
|
+
this.properties._umap_options.route.coordinates ??= []
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
routeForm() {
|
|
1183
|
+
this._ensureRoute()
|
|
1184
|
+
const metadatas = [
|
|
1185
|
+
[
|
|
1186
|
+
'profile',
|
|
1187
|
+
{
|
|
1188
|
+
handler: 'Select',
|
|
1189
|
+
selectOptions: ORS_PROFILES,
|
|
1190
|
+
label: translate('Profile'),
|
|
1191
|
+
},
|
|
1192
|
+
],
|
|
1193
|
+
[
|
|
1194
|
+
'elevation',
|
|
1195
|
+
{
|
|
1196
|
+
handler: 'Switch',
|
|
1197
|
+
label: translate('Compute elevations'),
|
|
1198
|
+
},
|
|
1199
|
+
],
|
|
1200
|
+
[
|
|
1201
|
+
'preference',
|
|
1202
|
+
{
|
|
1203
|
+
handler: 'Select',
|
|
1204
|
+
selectOptions: ORS_PREFERENCES,
|
|
1205
|
+
label: translate('Route preference'),
|
|
1206
|
+
},
|
|
1207
|
+
],
|
|
1208
|
+
]
|
|
1209
|
+
const form = new MutatingForm(this.properties._umap_options.route, metadatas, {
|
|
1210
|
+
umap: this._umap,
|
|
1211
|
+
})
|
|
1212
|
+
return form.build()
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
_editRoute(container) {
|
|
1216
|
+
const template = `
|
|
1217
|
+
<details id="edit-route">
|
|
1218
|
+
<summary>${translate('Route settings')}</summary>
|
|
1219
|
+
<fieldset data-ref=fieldset></fieldset>
|
|
1220
|
+
</details>
|
|
1221
|
+
`
|
|
1222
|
+
const [details, { fieldset }] = Utils.loadTemplateWithRefs(template)
|
|
1223
|
+
container.appendChild(details)
|
|
1224
|
+
fieldset.appendChild(this.routeForm())
|
|
1225
|
+
const button = Utils.loadTemplate(
|
|
1226
|
+
`<button data-ref=button type="button">${translate('Compute route')}</button>`
|
|
1227
|
+
)
|
|
1228
|
+
fieldset.appendChild(button)
|
|
1229
|
+
button.addEventListener('click', async () => this.computeRoute())
|
|
1106
1230
|
}
|
|
1107
1231
|
|
|
1108
1232
|
addExtraEditFieldset(container) {
|
|
@@ -1120,6 +1244,34 @@ export class LineString extends Path {
|
|
|
1120
1244
|
})
|
|
1121
1245
|
const fieldset = DomUtil.createFieldset(container, translate('Line decoration'))
|
|
1122
1246
|
fieldset.appendChild(builder.build())
|
|
1247
|
+
if (this._umap.properties.ORSAPIKey && this.isRoute()) {
|
|
1248
|
+
this._editRoute(container)
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
async computeElevation() {
|
|
1253
|
+
if (!this._umap.properties.ORSAPIKey) return
|
|
1254
|
+
const importer = new OpenRouteService(this._umap)
|
|
1255
|
+
const geometry = await importer.elevation(this.geometry)
|
|
1256
|
+
if (geometry?.type) {
|
|
1257
|
+
const oldGeometry = Utils.CopyJSON(this._geometry)
|
|
1258
|
+
this.geometry = geometry
|
|
1259
|
+
this.ui.resetTooltip()
|
|
1260
|
+
this.sync.update('geometry', this.geometry, oldGeometry)
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
async computeRoute() {
|
|
1265
|
+
if (!this._umap.properties.ORSAPIKey) return
|
|
1266
|
+
const importer = new OpenRouteService(this._umap)
|
|
1267
|
+
await importer.directions(this.properties._umap_options.route).then((geometry) => {
|
|
1268
|
+
if (geometry?.type) {
|
|
1269
|
+
const oldGeometry = Utils.CopyJSON(this._geometry)
|
|
1270
|
+
this.geometry = geometry
|
|
1271
|
+
this.ui.resetTooltip()
|
|
1272
|
+
this.sync.update('geometry', this.geometry, oldGeometry)
|
|
1273
|
+
}
|
|
1274
|
+
})
|
|
1123
1275
|
}
|
|
1124
1276
|
}
|
|
1125
1277
|
|
|
@@ -1226,29 +1378,21 @@ export class Polygon extends Path {
|
|
|
1226
1378
|
)
|
|
1227
1379
|
}
|
|
1228
1380
|
|
|
1229
|
-
|
|
1230
|
-
const items = super.
|
|
1231
|
-
items.push({
|
|
1232
|
-
action: () => this.ui.startHole(event),
|
|
1233
|
-
title: translate('Start a hole here'),
|
|
1234
|
-
icon: 'icon-hole',
|
|
1235
|
-
})
|
|
1236
|
-
return items
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
getContextMenuEditItems(event) {
|
|
1240
|
-
const items = super.getContextMenuEditItems(event)
|
|
1381
|
+
getDrawingTools(event) {
|
|
1382
|
+
const items = super.getDrawingTools(event)
|
|
1241
1383
|
const shape = this.ui.shapeAt(event.latlng)
|
|
1242
1384
|
// No multi and no holes.
|
|
1243
1385
|
if (shape && !this.isMulti() && (LineUtil.isFlat(shape) || shape.length === 1)) {
|
|
1244
1386
|
items.push({
|
|
1245
|
-
|
|
1387
|
+
title: translate('Transform to lines'),
|
|
1388
|
+
icon: 'icon-polyline',
|
|
1246
1389
|
action: () => this.toLineString(),
|
|
1247
1390
|
})
|
|
1248
1391
|
}
|
|
1249
1392
|
items.push({
|
|
1250
|
-
|
|
1393
|
+
title: translate('Start a hole here'),
|
|
1251
1394
|
action: () => this.ui.startHole(event),
|
|
1395
|
+
icon: 'icon-hole',
|
|
1252
1396
|
})
|
|
1253
1397
|
return items
|
|
1254
1398
|
}
|