umap-project 3.4.0b3__py3-none-any.whl → 3.6.0__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.
- umap/__init__.py +1 -1
- umap/locale/br/LC_MESSAGES/django.mo +0 -0
- umap/locale/br/LC_MESSAGES/django.po +71 -57
- umap/locale/da/LC_MESSAGES/django.mo +0 -0
- umap/locale/da/LC_MESSAGES/django.po +18 -14
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +20 -16
- umap/locale/en/LC_MESSAGES/django.po +18 -14
- umap/locale/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +20 -16
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +18 -14
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +20 -16
- umap/locale/pl/LC_MESSAGES/django.mo +0 -0
- umap/locale/pl/LC_MESSAGES/django.po +101 -95
- umap/locale/zh_TW/LC_MESSAGES/django.mo +0 -0
- umap/locale/zh_TW/LC_MESSAGES/django.po +20 -16
- umap/management/commands/clean_tilelayer.py +0 -1
- umap/management/commands/search_maps.py +95 -0
- umap/settings/__init__.py +9 -1
- umap/settings/base.py +7 -6
- umap/static/umap/content.css +0 -3
- umap/static/umap/css/bar.css +9 -6
- umap/static/umap/css/form.css +25 -9
- umap/static/umap/css/icon.css +8 -0
- umap/static/umap/css/popup.css +1 -0
- umap/static/umap/img/16-white.svg +5 -2
- umap/static/umap/img/16.svg +1 -1
- umap/static/umap/img/source/16-white.svg +7 -4
- umap/static/umap/img/source/16.svg +1 -1
- umap/static/umap/js/components/copiable.js +47 -0
- umap/static/umap/js/modules/autocomplete.js +32 -67
- umap/static/umap/js/modules/browser.js +31 -14
- umap/static/umap/js/modules/data/features.js +34 -36
- umap/static/umap/js/modules/data/fields.js +199 -23
- umap/static/umap/js/modules/data/layer.js +85 -96
- umap/static/umap/js/modules/domutils.js +25 -1
- umap/static/umap/js/modules/filters.js +24 -50
- umap/static/umap/js/modules/form/builder.js +17 -16
- umap/static/umap/js/modules/form/fields.js +20 -20
- umap/static/umap/js/modules/formatter.js +9 -1
- umap/static/umap/js/modules/help.js +12 -13
- umap/static/umap/js/modules/importer.js +17 -26
- umap/static/umap/js/modules/importers/banfr.js +0 -1
- umap/static/umap/js/modules/importers/cadastrefr.js +19 -19
- umap/static/umap/js/modules/importers/communesfr.js +7 -8
- umap/static/umap/js/modules/importers/datasets.js +14 -14
- umap/static/umap/js/modules/importers/geodatamine.js +20 -22
- umap/static/umap/js/modules/importers/opendata.js +10 -0
- umap/static/umap/js/modules/importers/overpass.js +19 -18
- umap/static/umap/js/modules/managers.js +1 -1
- umap/static/umap/js/modules/permissions.js +15 -5
- umap/static/umap/js/modules/rendering/controls.js +203 -10
- umap/static/umap/js/modules/rendering/icon.js +5 -9
- umap/static/umap/js/modules/rendering/layers/base.js +1 -1
- umap/static/umap/js/modules/rendering/layers/classified.js +16 -11
- umap/static/umap/js/modules/rendering/layers/heat.js +1 -0
- umap/static/umap/js/modules/rendering/map.js +67 -57
- umap/static/umap/js/modules/rendering/popup.js +6 -3
- umap/static/umap/js/modules/rendering/template.js +40 -40
- umap/static/umap/js/modules/rendering/ui.js +1 -2
- umap/static/umap/js/modules/rules.js +34 -41
- umap/static/umap/js/modules/schema.js +0 -7
- umap/static/umap/js/modules/share.js +36 -69
- umap/static/umap/js/modules/slideshow.js +3 -3
- umap/static/umap/js/modules/tableeditor.js +0 -1
- umap/static/umap/js/modules/ui/bar.js +53 -33
- umap/static/umap/js/modules/ui/hash.js +36 -0
- umap/static/umap/js/modules/ui/loader.js +26 -0
- umap/static/umap/js/modules/ui/panel.js +33 -21
- umap/static/umap/js/modules/ui/tooltip.js +1 -1
- umap/static/umap/js/modules/umap.js +81 -80
- umap/static/umap/js/modules/utils.js +13 -3
- umap/static/umap/js/umap.controls.js +16 -179
- umap/static/umap/locale/am_ET.js +7 -8
- umap/static/umap/locale/am_ET.json +7 -8
- umap/static/umap/locale/ar.js +7 -8
- umap/static/umap/locale/ar.json +7 -8
- umap/static/umap/locale/ast.js +7 -8
- umap/static/umap/locale/ast.json +7 -8
- umap/static/umap/locale/bg.js +7 -8
- umap/static/umap/locale/bg.json +7 -8
- umap/static/umap/locale/br.js +44 -36
- umap/static/umap/locale/br.json +44 -36
- umap/static/umap/locale/ca.js +7 -8
- umap/static/umap/locale/ca.json +7 -8
- umap/static/umap/locale/cs_CZ.js +7 -8
- umap/static/umap/locale/cs_CZ.json +7 -8
- umap/static/umap/locale/da.js +8 -9
- umap/static/umap/locale/da.json +8 -9
- umap/static/umap/locale/de.js +62 -63
- umap/static/umap/locale/de.json +62 -63
- umap/static/umap/locale/el.js +7 -8
- umap/static/umap/locale/el.json +7 -8
- umap/static/umap/locale/en.js +7 -8
- umap/static/umap/locale/en.json +7 -8
- umap/static/umap/locale/en_US.json +7 -8
- umap/static/umap/locale/es.js +19 -20
- umap/static/umap/locale/es.json +19 -20
- umap/static/umap/locale/et.js +7 -8
- umap/static/umap/locale/et.json +7 -8
- umap/static/umap/locale/eu.js +23 -24
- umap/static/umap/locale/eu.json +23 -24
- umap/static/umap/locale/fa_IR.js +7 -8
- umap/static/umap/locale/fa_IR.json +7 -8
- umap/static/umap/locale/fi.js +7 -8
- umap/static/umap/locale/fi.json +7 -8
- umap/static/umap/locale/fr.js +11 -12
- umap/static/umap/locale/fr.json +11 -12
- umap/static/umap/locale/gl.js +147 -148
- umap/static/umap/locale/gl.json +147 -148
- umap/static/umap/locale/he.js +7 -8
- umap/static/umap/locale/he.json +7 -8
- umap/static/umap/locale/hr.js +7 -8
- umap/static/umap/locale/hr.json +7 -8
- umap/static/umap/locale/hu.js +8 -9
- umap/static/umap/locale/hu.json +8 -9
- umap/static/umap/locale/id.js +7 -8
- umap/static/umap/locale/id.json +7 -8
- umap/static/umap/locale/is.js +7 -8
- umap/static/umap/locale/is.json +7 -8
- umap/static/umap/locale/it.js +7 -8
- umap/static/umap/locale/it.json +7 -8
- umap/static/umap/locale/ja.js +7 -8
- umap/static/umap/locale/ja.json +7 -8
- umap/static/umap/locale/ko.js +7 -8
- umap/static/umap/locale/ko.json +7 -8
- umap/static/umap/locale/lt.js +7 -8
- umap/static/umap/locale/lt.json +7 -8
- umap/static/umap/locale/ms.js +7 -8
- umap/static/umap/locale/ms.json +7 -8
- umap/static/umap/locale/nl.js +7 -8
- umap/static/umap/locale/nl.json +7 -8
- umap/static/umap/locale/no.js +7 -8
- umap/static/umap/locale/no.json +7 -8
- umap/static/umap/locale/pl.js +53 -54
- umap/static/umap/locale/pl.json +53 -54
- umap/static/umap/locale/pl_PL.json +7 -8
- umap/static/umap/locale/pt.js +7 -8
- umap/static/umap/locale/pt.json +7 -8
- umap/static/umap/locale/pt_BR.js +7 -8
- umap/static/umap/locale/pt_BR.json +7 -8
- umap/static/umap/locale/pt_PT.js +7 -8
- umap/static/umap/locale/pt_PT.json +7 -8
- umap/static/umap/locale/ro.js +7 -8
- umap/static/umap/locale/ro.json +7 -8
- umap/static/umap/locale/ru.js +7 -8
- umap/static/umap/locale/ru.json +7 -8
- umap/static/umap/locale/sk_SK.js +7 -8
- umap/static/umap/locale/sk_SK.json +7 -8
- umap/static/umap/locale/sl.js +7 -8
- umap/static/umap/locale/sl.json +7 -8
- umap/static/umap/locale/sr.js +7 -8
- umap/static/umap/locale/sr.json +7 -8
- umap/static/umap/locale/sv.js +7 -8
- umap/static/umap/locale/sv.json +7 -8
- umap/static/umap/locale/th_TH.js +7 -8
- umap/static/umap/locale/th_TH.json +7 -8
- umap/static/umap/locale/tr.js +7 -8
- umap/static/umap/locale/tr.json +7 -8
- umap/static/umap/locale/uk_UA.js +7 -8
- umap/static/umap/locale/uk_UA.json +7 -8
- umap/static/umap/locale/vi.js +7 -8
- umap/static/umap/locale/vi.json +7 -8
- umap/static/umap/locale/vi_VN.json +7 -8
- umap/static/umap/locale/zh.js +7 -8
- umap/static/umap/locale/zh.json +7 -8
- umap/static/umap/locale/zh_CN.json +7 -8
- umap/static/umap/locale/zh_TW.Big5.json +7 -8
- umap/static/umap/locale/zh_TW.js +20 -21
- umap/static/umap/locale/zh_TW.json +20 -21
- umap/static/umap/map.css +6 -21
- umap/static/umap/unittests/utils.js +7 -7
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.esm.js +942 -0
- umap/static/umap/vendors/photon/leaflet.photon.esm.js +472 -0
- umap/sync/app.py +4 -1
- umap/templates/umap/content_footer.html +1 -0
- umap/templates/umap/css.html +0 -4
- umap/templates/umap/js.html +1 -8
- umap/templates/umap/team_form.html +2 -1
- umap/tests/integration/conftest.py +3 -2
- umap/tests/integration/test_anonymous_owned_map.py +1 -1
- umap/tests/integration/test_conditional_rules.py +106 -51
- umap/tests/integration/test_draw_polygon.py +4 -0
- umap/tests/integration/test_draw_polyline.py +11 -0
- umap/tests/integration/test_edit_datalayer.py +1 -1
- umap/tests/integration/test_edit_map.py +2 -0
- umap/tests/integration/test_fields.py +19 -0
- umap/tests/integration/test_filters.py +24 -0
- umap/tests/integration/test_iframe.py +1 -1
- umap/tests/integration/test_import.py +26 -0
- umap/tests/integration/test_map.py +3 -3
- umap/tests/integration/test_optimistic_merge.py +7 -1
- umap/tests/integration/test_owned_map.py +2 -2
- umap/tests/integration/test_popup.py +31 -0
- umap/tests/integration/test_remote_data.py +5 -5
- umap/tests/integration/test_search.py +41 -0
- umap/tests/integration/test_share.py +2 -2
- umap/tests/integration/test_team.py +1 -1
- umap/tests/integration/test_websocket_sync.py +6 -1
- umap/tests/test_search_maps_command.py +44 -0
- umap/tests/test_utils.py +4 -1
- umap/utils.py +10 -3
- umap/views.py +17 -4
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/METADATA +29 -23
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/RECORD +210 -214
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/WHEEL +1 -1
- umap/static/umap/js/umap.core.js +0 -93
- umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.css +0 -46
- umap/static/umap/vendors/editinosm/Leaflet.EditInOSM.js +0 -240
- umap/static/umap/vendors/editinosm/edit-in-osm.png +0 -0
- umap/static/umap/vendors/hash/leaflet-hash.js +0 -162
- umap/static/umap/vendors/loading/Control.Loading.css +0 -26
- umap/static/umap/vendors/loading/Control.Loading.js +0 -351
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.css +0 -1
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.css.map +0 -1
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js +0 -4
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js.map +0 -1
- umap/static/umap/vendors/photon/leaflet.photon.js +0 -487
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/entry_points.txt +0 -0
- {umap_project-3.4.0b3.dist-info → umap_project-3.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DomUtil,
|
|
3
|
-
Util as LeafletUtil,
|
|
4
|
-
latLngBounds,
|
|
5
|
-
} from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
6
1
|
import {
|
|
7
2
|
uMapAlert as Alert,
|
|
8
3
|
uMapAlertCreation as AlertCreation,
|
|
@@ -36,6 +31,8 @@ import * as Utils from './utils.js'
|
|
|
36
31
|
import * as DOMUtils from './domutils.js'
|
|
37
32
|
import { DataLayerManager } from './managers.js'
|
|
38
33
|
import { Importer as OpenRouteService } from './importers/openrouteservice.js'
|
|
34
|
+
import Loader from './ui/loader.js'
|
|
35
|
+
import Hash from './ui/hash.js'
|
|
39
36
|
|
|
40
37
|
export default class Umap {
|
|
41
38
|
constructor(element, geojson) {
|
|
@@ -115,6 +112,10 @@ export default class Umap {
|
|
|
115
112
|
this.properties.homeControl = false
|
|
116
113
|
}
|
|
117
114
|
|
|
115
|
+
this.loader = new Loader(this._leafletMap._container)
|
|
116
|
+
if (this.properties.hash) {
|
|
117
|
+
this.hash = new Hash()
|
|
118
|
+
}
|
|
118
119
|
this._leafletMap.setup()
|
|
119
120
|
|
|
120
121
|
this.panel = new Panel(this, this._leafletMap)
|
|
@@ -261,15 +262,6 @@ export default class Umap {
|
|
|
261
262
|
return window.self !== window.top
|
|
262
263
|
}
|
|
263
264
|
|
|
264
|
-
get fieldKeys() {
|
|
265
|
-
return Array.from(
|
|
266
|
-
new Set([
|
|
267
|
-
...this.fields.keys(),
|
|
268
|
-
...this.datalayers.active().reduce((acc, dl) => acc.concat(dl.fieldKeys), []),
|
|
269
|
-
])
|
|
270
|
-
)
|
|
271
|
-
}
|
|
272
|
-
|
|
273
265
|
setPropertiesFromQueryString() {
|
|
274
266
|
const asBoolean = (key) => {
|
|
275
267
|
const value = this.searchParams.get(key)
|
|
@@ -681,7 +673,7 @@ export default class Umap {
|
|
|
681
673
|
const parent = this._leafletMap.getPane('overlayPane')
|
|
682
674
|
const datalayers = Object.values(this.datalayers)
|
|
683
675
|
.filter((datalayer) => !datalayer._isDeleted)
|
|
684
|
-
.sort((datalayer1, datalayer2) => datalayer1.rank
|
|
676
|
+
.sort((datalayer1, datalayer2) => datalayer1.rank - datalayer2.rank)
|
|
685
677
|
for (const datalayer of datalayers) {
|
|
686
678
|
const child = parent.querySelector(`[data-id="${datalayer.id}"]`)
|
|
687
679
|
parent.appendChild(child)
|
|
@@ -773,14 +765,19 @@ export default class Umap {
|
|
|
773
765
|
editCaption() {
|
|
774
766
|
if (!this.editEnabled) return
|
|
775
767
|
if (this.properties.editMode !== 'advanced') return
|
|
776
|
-
const container =
|
|
768
|
+
const container = DOMUtils.loadTemplate(`
|
|
769
|
+
<div>
|
|
770
|
+
<h3>
|
|
771
|
+
<i class="icon icon-16 icon-info"></i>
|
|
772
|
+
${translate('Edit map details')}
|
|
773
|
+
</h3>
|
|
774
|
+
</div>
|
|
775
|
+
`)
|
|
777
776
|
const metadataFields = [
|
|
778
777
|
'properties.name',
|
|
779
778
|
'properties.description',
|
|
780
779
|
'properties.is_template',
|
|
781
780
|
]
|
|
782
|
-
|
|
783
|
-
DomUtil.createTitle(container, translate('Edit map details'), 'icon-info')
|
|
784
781
|
const builder = new MutatingForm(this, metadataFields, {
|
|
785
782
|
className: 'map-metadata',
|
|
786
783
|
umap: this,
|
|
@@ -788,13 +785,13 @@ export default class Umap {
|
|
|
788
785
|
const form = builder.build()
|
|
789
786
|
container.appendChild(form)
|
|
790
787
|
|
|
791
|
-
const tags =
|
|
788
|
+
const tags = DOMUtils.createFieldset(container, translate('Tags'))
|
|
792
789
|
const tagsFields = ['properties.tags']
|
|
793
790
|
const tagsBuilder = new MutatingForm(this, tagsFields, {
|
|
794
791
|
umap: this,
|
|
795
792
|
})
|
|
796
793
|
tags.appendChild(tagsBuilder.build())
|
|
797
|
-
const credits =
|
|
794
|
+
const credits = DOMUtils.createFieldset(container, translate('Credits'))
|
|
798
795
|
const creditsFields = [
|
|
799
796
|
'properties.licence',
|
|
800
797
|
'properties.shortCredit',
|
|
@@ -810,7 +807,11 @@ export default class Umap {
|
|
|
810
807
|
editCenter() {
|
|
811
808
|
if (!this.editEnabled) return
|
|
812
809
|
if (this.properties.editMode !== 'advanced') return
|
|
813
|
-
const container =
|
|
810
|
+
const container = DOMUtils.loadTemplate(`
|
|
811
|
+
<div>
|
|
812
|
+
<h3><i class="icon icon-16 icon-zoom"></i>${translate('Edit map default view')}</h3>
|
|
813
|
+
</div>
|
|
814
|
+
`)
|
|
814
815
|
const metadataFields = [
|
|
815
816
|
['properties.zoom', { handler: 'IntInput', label: translate('Default zoom') }],
|
|
816
817
|
[
|
|
@@ -824,13 +825,12 @@ export default class Umap {
|
|
|
824
825
|
'properties.defaultView',
|
|
825
826
|
]
|
|
826
827
|
|
|
827
|
-
DomUtil.createTitle(container, translate('Edit map default view'), 'icon-zoom')
|
|
828
828
|
const builder = new MutatingForm(this, metadataFields, {
|
|
829
829
|
className: 'map-metadata',
|
|
830
830
|
umap: this,
|
|
831
831
|
})
|
|
832
832
|
const form = builder.build()
|
|
833
|
-
const button =
|
|
833
|
+
const button = DOMUtils.loadTemplate(
|
|
834
834
|
`<button type="button">${translate('Use current center and zoom')}</button>`
|
|
835
835
|
)
|
|
836
836
|
button.addEventListener('click', () => {
|
|
@@ -859,7 +859,7 @@ export default class Umap {
|
|
|
859
859
|
'properties.layerSwitcher',
|
|
860
860
|
])
|
|
861
861
|
const builder = new MutatingForm(this, UIFields, { umap: this })
|
|
862
|
-
const controlsOptions =
|
|
862
|
+
const controlsOptions = DOMUtils.createFieldset(
|
|
863
863
|
container,
|
|
864
864
|
translate('User interface options')
|
|
865
865
|
)
|
|
@@ -883,7 +883,7 @@ export default class Umap {
|
|
|
883
883
|
]
|
|
884
884
|
|
|
885
885
|
const builder = new MutatingForm(this, shapeOptions, { umap: this })
|
|
886
|
-
const defaultShapeProperties =
|
|
886
|
+
const defaultShapeProperties = DOMUtils.createFieldset(
|
|
887
887
|
container,
|
|
888
888
|
translate('Default shape properties')
|
|
889
889
|
)
|
|
@@ -901,7 +901,7 @@ export default class Umap {
|
|
|
901
901
|
]
|
|
902
902
|
|
|
903
903
|
const builder = new MutatingForm(this, shapeOptions, { umap: this })
|
|
904
|
-
const defaultShapeProperties =
|
|
904
|
+
const defaultShapeProperties = DOMUtils.createFieldset(
|
|
905
905
|
container,
|
|
906
906
|
translate('Default properties')
|
|
907
907
|
)
|
|
@@ -919,7 +919,7 @@ export default class Umap {
|
|
|
919
919
|
'properties.outlinkTarget',
|
|
920
920
|
]
|
|
921
921
|
const builder = new MutatingForm(this, popupFields, { umap: this })
|
|
922
|
-
const popupFieldset =
|
|
922
|
+
const popupFieldset = DOMUtils.createFieldset(
|
|
923
923
|
container,
|
|
924
924
|
translate('Default interaction options')
|
|
925
925
|
)
|
|
@@ -971,7 +971,7 @@ export default class Umap {
|
|
|
971
971
|
{ handler: 'Switch', label: translate('TMS format') },
|
|
972
972
|
],
|
|
973
973
|
]
|
|
974
|
-
const customTilelayer =
|
|
974
|
+
const customTilelayer = DOMUtils.createFieldset(
|
|
975
975
|
container,
|
|
976
976
|
translate('Custom background')
|
|
977
977
|
)
|
|
@@ -1022,7 +1022,7 @@ export default class Umap {
|
|
|
1022
1022
|
],
|
|
1023
1023
|
['properties.overlay.tms', { handler: 'Switch', label: translate('TMS format') }],
|
|
1024
1024
|
]
|
|
1025
|
-
const overlay =
|
|
1025
|
+
const overlay = DOMUtils.createFieldset(container, translate('Custom overlay'))
|
|
1026
1026
|
const builder = new MutatingForm(this, overlayFields, { umap: this })
|
|
1027
1027
|
overlay.appendChild(builder.build())
|
|
1028
1028
|
}
|
|
@@ -1031,7 +1031,7 @@ export default class Umap {
|
|
|
1031
1031
|
if (!Utils.isObject(this.properties.limitBounds)) {
|
|
1032
1032
|
this.properties.limitBounds = {}
|
|
1033
1033
|
}
|
|
1034
|
-
const limitBounds =
|
|
1034
|
+
const limitBounds = DOMUtils.createFieldset(container, translate('Limit bounds'))
|
|
1035
1035
|
const boundsFields = [
|
|
1036
1036
|
[
|
|
1037
1037
|
'properties.limitBounds.south',
|
|
@@ -1052,28 +1052,29 @@ export default class Umap {
|
|
|
1052
1052
|
]
|
|
1053
1053
|
const boundsBuilder = new MutatingForm(this, boundsFields, { umap: this })
|
|
1054
1054
|
limitBounds.appendChild(boundsBuilder.build())
|
|
1055
|
-
const boundsButtons
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1055
|
+
const [boundsButtons, { current, empty }] = DOMUtils.loadTemplateWithRefs(`
|
|
1056
|
+
<div class="button-bar half">
|
|
1057
|
+
<button type="button" data-ref="current">${translate('Use current bounds')}</button>
|
|
1058
|
+
<button type="button" data-ref="empty">${translate('Empty')}</button>
|
|
1059
|
+
</div>
|
|
1060
|
+
`)
|
|
1061
|
+
limitBounds.appendChild(boundsButtons)
|
|
1062
|
+
current.addEventListener('click', () => {
|
|
1063
|
+
const bounds = this._leafletMap.getBounds()
|
|
1064
|
+
const oldLimitBounds = { ...this.properties.limitBounds }
|
|
1065
|
+
this.properties.limitBounds.south = bounds.getSouth().toFixed(6)
|
|
1066
|
+
this.properties.limitBounds.west = bounds.getWest().toFixed(6)
|
|
1067
|
+
this.properties.limitBounds.north = bounds.getNorth().toFixed(6)
|
|
1068
|
+
this.properties.limitBounds.east = bounds.getEast().toFixed(6)
|
|
1069
|
+
boundsBuilder.fetchAll()
|
|
1070
|
+
this.sync.update(
|
|
1071
|
+
'properties.limitBounds',
|
|
1072
|
+
this.properties.limitBounds,
|
|
1073
|
+
oldLimitBounds
|
|
1074
|
+
)
|
|
1075
|
+
this._leafletMap.handleLimitBounds()
|
|
1076
|
+
})
|
|
1077
|
+
empty.addEventListener('click', () => {
|
|
1077
1078
|
const oldLimitBounds = { ...this.properties.limitBounds }
|
|
1078
1079
|
this.properties.limitBounds.south = null
|
|
1079
1080
|
this.properties.limitBounds.west = null
|
|
@@ -1090,7 +1091,7 @@ export default class Umap {
|
|
|
1090
1091
|
}
|
|
1091
1092
|
|
|
1092
1093
|
_editSlideshow(container) {
|
|
1093
|
-
const slideshow =
|
|
1094
|
+
const slideshow = DOMUtils.createFieldset(container, translate('Slideshow'))
|
|
1094
1095
|
const slideshowFields = [
|
|
1095
1096
|
[
|
|
1096
1097
|
'properties.slideshow.active',
|
|
@@ -1123,7 +1124,10 @@ export default class Umap {
|
|
|
1123
1124
|
}
|
|
1124
1125
|
|
|
1125
1126
|
_editSync(container) {
|
|
1126
|
-
const sync =
|
|
1127
|
+
const sync = DOMUtils.createFieldset(
|
|
1128
|
+
container,
|
|
1129
|
+
translate('Real-time collaboration')
|
|
1130
|
+
)
|
|
1127
1131
|
const builder = new MutatingForm(this, ['properties.syncEnabled'], {
|
|
1128
1132
|
umap: this,
|
|
1129
1133
|
})
|
|
@@ -1131,7 +1135,7 @@ export default class Umap {
|
|
|
1131
1135
|
}
|
|
1132
1136
|
|
|
1133
1137
|
_advancedActions(container) {
|
|
1134
|
-
const advancedActions =
|
|
1138
|
+
const advancedActions = DOMUtils.createFieldset(
|
|
1135
1139
|
container,
|
|
1136
1140
|
translate('Advanced actions')
|
|
1137
1141
|
)
|
|
@@ -1155,7 +1159,7 @@ export default class Umap {
|
|
|
1155
1159
|
</div>
|
|
1156
1160
|
`
|
|
1157
1161
|
const [bar, { del, clear, empty, clone, download }] =
|
|
1158
|
-
|
|
1162
|
+
DOMUtils.loadTemplateWithRefs(tpl)
|
|
1159
1163
|
advancedActions.appendChild(bar)
|
|
1160
1164
|
if (this.permissions.isOwner()) {
|
|
1161
1165
|
del.hidden = false
|
|
@@ -1172,12 +1176,11 @@ export default class Umap {
|
|
|
1172
1176
|
edit() {
|
|
1173
1177
|
if (!this.editEnabled) return
|
|
1174
1178
|
if (this.properties.editMode !== 'advanced') return
|
|
1175
|
-
const container =
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
)
|
|
1179
|
+
const container = DOMUtils.loadTemplate(`
|
|
1180
|
+
<div>
|
|
1181
|
+
<h3><i class="icon icon-16 icon-settings"></i>${translate('Map advanced properties')}</h3>
|
|
1182
|
+
</div>
|
|
1183
|
+
`)
|
|
1181
1184
|
this._editControls(container)
|
|
1182
1185
|
this._editShapeProperties(container)
|
|
1183
1186
|
this._editDefaultKeys(container)
|
|
@@ -1609,9 +1612,11 @@ export default class Umap {
|
|
|
1609
1612
|
else if (finalIndex > initialIndex) movedLayer.insertBefore(targetLayer)
|
|
1610
1613
|
else movedLayer.insertAfter(targetLayer)
|
|
1611
1614
|
this.sync.startBatch()
|
|
1612
|
-
this.datalayers.reverse().map((datalayer) => {
|
|
1615
|
+
this.datalayers.reverse().map(async (datalayer) => {
|
|
1613
1616
|
const rank = datalayer.getDOMOrder()
|
|
1614
1617
|
if (rank >= minIndex && rank <= maxIndex) {
|
|
1618
|
+
// TODO allow to save only metadata instead of force loading data
|
|
1619
|
+
if (!datalayer.isLoaded()) await datalayer.fetchData()
|
|
1615
1620
|
const oldRank = datalayer.rank
|
|
1616
1621
|
datalayer.rank = rank
|
|
1617
1622
|
datalayer.sync.update('options.rank', rank, oldRank)
|
|
@@ -1623,14 +1628,13 @@ export default class Umap {
|
|
|
1623
1628
|
}
|
|
1624
1629
|
const orderable = new Orderable(ul, onReorder)
|
|
1625
1630
|
|
|
1626
|
-
const bar =
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
)
|
|
1631
|
+
const [bar, { button }] = DOMUtils.loadTemplateWithRefs(`
|
|
1632
|
+
<div class="button-bar">
|
|
1633
|
+
<button type="button" class="show-on-edit block add-datalayer" data-ref="button">${translate('Add a layer')}</button>
|
|
1634
|
+
</div>
|
|
1635
|
+
`)
|
|
1636
|
+
button.addEventListener('click', () => this.newDataLayer())
|
|
1637
|
+
container.appendChild(bar)
|
|
1634
1638
|
|
|
1635
1639
|
this.editPanel.open({ content: container, highlight: 'layers' })
|
|
1636
1640
|
}
|
|
@@ -1738,6 +1742,7 @@ export default class Umap {
|
|
|
1738
1742
|
const fields = Object.keys(importedData.properties).map(
|
|
1739
1743
|
(field) => `properties.${field}`
|
|
1740
1744
|
)
|
|
1745
|
+
this.fields.pull()
|
|
1741
1746
|
this.filters.load()
|
|
1742
1747
|
this.render(fields)
|
|
1743
1748
|
this._leafletMap._setDefaultCenter()
|
|
@@ -1790,16 +1795,12 @@ export default class Umap {
|
|
|
1790
1795
|
await this.server.post(sendLink, {}, formData)
|
|
1791
1796
|
}
|
|
1792
1797
|
|
|
1793
|
-
getLayersBounds() {
|
|
1794
|
-
const bounds = new latLngBounds()
|
|
1795
|
-
this.datalayers.browsable().map((d) => {
|
|
1796
|
-
if (d.isVisible()) bounds.extend(d.layer.getBounds())
|
|
1797
|
-
})
|
|
1798
|
-
return bounds
|
|
1799
|
-
}
|
|
1800
|
-
|
|
1801
1798
|
fitDataBounds() {
|
|
1802
|
-
const
|
|
1799
|
+
const layers = this.datalayers
|
|
1800
|
+
.browsable()
|
|
1801
|
+
.filter((d) => d.isVisible())
|
|
1802
|
+
.map((d) => d.layer)
|
|
1803
|
+
const bounds = this._leafletMap.getLayersBounds(layers)
|
|
1803
1804
|
if (!this.hasData() || !bounds.isValid()) return false
|
|
1804
1805
|
this._leafletMap.fitBounds(bounds)
|
|
1805
1806
|
}
|
|
@@ -177,15 +177,15 @@ export function toHTML(r, options) {
|
|
|
177
177
|
// iframe
|
|
178
178
|
r = r.replace(
|
|
179
179
|
/{{{(https?[^|{]*)}}}/g,
|
|
180
|
-
'<div><iframe
|
|
180
|
+
'<div><iframe allowfullscreen src="$1" style="width: 100%; height: 300px; border: 0;"></iframe></div>'
|
|
181
181
|
)
|
|
182
182
|
r = r.replace(
|
|
183
183
|
/{{{(https?[^|{]*)\|(\d*)(px)?}}}/g,
|
|
184
|
-
'<div><iframe
|
|
184
|
+
'<div><iframe allowfullscreen src="$1" style="width: 100%; height: $2px; border: 0;"></iframe></div>'
|
|
185
185
|
)
|
|
186
186
|
r = r.replace(
|
|
187
187
|
/{{{(https?[^|{]*)\|(\d*)(px)?\*(\d*)(px)?}}}/g,
|
|
188
|
-
'<div><iframe
|
|
188
|
+
'<div><iframe allowfullscreen src="$1" style="width: $4px; height: $2px; border: 0;"></iframe></div>'
|
|
189
189
|
)
|
|
190
190
|
|
|
191
191
|
// images
|
|
@@ -681,3 +681,13 @@ export const COLORS = [
|
|
|
681
681
|
'Ivory',
|
|
682
682
|
'White',
|
|
683
683
|
]
|
|
684
|
+
|
|
685
|
+
export const LatLngIsValid = (latlng) => {
|
|
686
|
+
const [lat, lng] = Array.isArray(latlng) ? latlng : [latlng.lat, latlng.lng]
|
|
687
|
+
return (
|
|
688
|
+
Number.isFinite(lat) &&
|
|
689
|
+
Math.abs(lat) <= 90 &&
|
|
690
|
+
Number.isFinite(lng) &&
|
|
691
|
+
Math.abs(lng) <= 180
|
|
692
|
+
)
|
|
693
|
+
}
|
|
@@ -45,171 +45,17 @@ U.TileLayerControl = L.Control.IconLayers.extend({
|
|
|
45
45
|
const lastRow = this._container.querySelector(
|
|
46
46
|
'.leaflet-iconLayers-layersRow:last-child'
|
|
47
47
|
)
|
|
48
|
-
const button =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
})
|
|
55
|
-
L.DomEvent.on(button, 'click', () =>
|
|
48
|
+
const button = document.createElement('button')
|
|
49
|
+
button.className =
|
|
50
|
+
'leaflet-iconLayers-layerCell leaflet-iconLayers-layerCell-plus button'
|
|
51
|
+
button.textContent = '+'
|
|
52
|
+
lastRow.appendChild(button)
|
|
53
|
+
button.addEventListener('click', () =>
|
|
56
54
|
this.map._controls.tilelayersChooser.openSwitcher()
|
|
57
55
|
)
|
|
58
56
|
},
|
|
59
57
|
})
|
|
60
58
|
|
|
61
|
-
/*
|
|
62
|
-
* Take control over L.Control.Locate to be able to
|
|
63
|
-
* call start() before adding the control (and thus the button) to the map.
|
|
64
|
-
*/
|
|
65
|
-
U.Locate = L.Control.Locate.extend({
|
|
66
|
-
initialize: function (map, options) {
|
|
67
|
-
// When calling start(), it will try to add a location marker
|
|
68
|
-
// on the layer, which is normally added in the addTo/onAdd method
|
|
69
|
-
this._layer = this.options.layer = new L.LayerGroup()
|
|
70
|
-
// When calling start(), it will call _activate(), which then adds
|
|
71
|
-
// location related event listeners on the map
|
|
72
|
-
this.map = map
|
|
73
|
-
L.Control.Locate.prototype.initialize.call(this, options)
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
onAdd: function (map) {
|
|
77
|
-
const active = this._active
|
|
78
|
-
const container = L.Control.Locate.prototype.onAdd.call(this, map)
|
|
79
|
-
this._active = active
|
|
80
|
-
return container
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
_activate: function () {
|
|
84
|
-
this._map = this.map
|
|
85
|
-
L.Control.Locate.prototype._activate.call(this)
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
remove: function () {
|
|
89
|
-
// Prevent to call remove if the control is not really added to the map
|
|
90
|
-
// This occurs because we do create the control and call its activate
|
|
91
|
-
// method before adding the control button itself to the map, in the
|
|
92
|
-
// case where the map defaultView is set to "location"
|
|
93
|
-
if (!this._container || !this._container.parentNode) return
|
|
94
|
-
return L.Control.Locate.prototype.remove.call(this)
|
|
95
|
-
},
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
U.Search = L.PhotonSearch.extend({
|
|
99
|
-
initialize: function (map, input, layer, options) {
|
|
100
|
-
this.options.placeholder = L._('Type a place name or coordinates')
|
|
101
|
-
this.options.location_bias_scale = 0.5
|
|
102
|
-
L.PhotonSearch.prototype.initialize.call(this, map, input, options)
|
|
103
|
-
this.options.url = map.options.urls.search
|
|
104
|
-
if (map.options.maxBounds) this.options.bbox = map.options.maxBounds.toBBoxString()
|
|
105
|
-
this.reverse = new L.PhotonReverse({
|
|
106
|
-
handleResults: (geojson) => {
|
|
107
|
-
this.handleResultsWithReverse(geojson)
|
|
108
|
-
},
|
|
109
|
-
})
|
|
110
|
-
this.layer = layer
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
handleResultsWithReverse: function (geojson) {
|
|
114
|
-
const latlng = this.reverse.latlng
|
|
115
|
-
geojson.features.unshift({
|
|
116
|
-
type: 'Feature',
|
|
117
|
-
geometry: { type: 'Point', coordinates: [latlng.lng, latlng.lat] },
|
|
118
|
-
properties: {
|
|
119
|
-
name: L._('Go to "{coords}"', { coords: `${latlng.lat} ${latlng.lng}` }),
|
|
120
|
-
},
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
this.handleResults(geojson)
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
search: function () {
|
|
127
|
-
this.layer.clearLayers()
|
|
128
|
-
const pattern = /^(?<lat>[-+]?\d{1,2}[.,]\d+)\s*[ ,]\s*(?<lng>[-+]?\d{1,3}[.,]\d+)$/
|
|
129
|
-
if (pattern.test(this.input.value)) {
|
|
130
|
-
this.hide()
|
|
131
|
-
const { lat, lng } = pattern.exec(this.input.value).groups
|
|
132
|
-
const latlng = L.latLng(lat, lng)
|
|
133
|
-
if (latlng.isValid()) {
|
|
134
|
-
this.reverse.doReverse(latlng)
|
|
135
|
-
} else {
|
|
136
|
-
U.Alert.error(L._('Invalid latitude or longitude'))
|
|
137
|
-
}
|
|
138
|
-
return
|
|
139
|
-
}
|
|
140
|
-
// Only numbers, abort.
|
|
141
|
-
if (/^[\d .,]*$/.test(this.input.value)) return
|
|
142
|
-
// Do normal search
|
|
143
|
-
this.options.includePosition = this.map.getZoom() > 10
|
|
144
|
-
L.PhotonSearch.prototype.search.call(this)
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
onBlur: function (e) {
|
|
148
|
-
// Overrided because we don't want to hide the results on blur.
|
|
149
|
-
this.fire('blur')
|
|
150
|
-
},
|
|
151
|
-
|
|
152
|
-
formatResult: function (feature, el) {
|
|
153
|
-
const [tools, { point, geom }] = U.Utils.loadTemplateWithRefs(`
|
|
154
|
-
<span class="search-result-tools">
|
|
155
|
-
<button type="button" title="${L._('Add this geometry to my map')}" data-ref=geom><i class="icon icon-16 icon-polygon-plus"></i></button>
|
|
156
|
-
<button type="button" title="${L._('Add this place to my map')}" data-ref=point><i class="icon icon-16 icon-marker-plus"></i></button>
|
|
157
|
-
</span>
|
|
158
|
-
`)
|
|
159
|
-
geom.hidden = !['R', 'W'].includes(feature.properties.osm_type)
|
|
160
|
-
point.addEventListener('mousedown', (event) => {
|
|
161
|
-
event.stopPropagation()
|
|
162
|
-
const datalayer = this.map._umap.defaultEditDataLayer()
|
|
163
|
-
const marker = datalayer.makeFeature(feature)
|
|
164
|
-
marker.edit()
|
|
165
|
-
})
|
|
166
|
-
geom.addEventListener('mousedown', async (event) => {
|
|
167
|
-
event.stopPropagation()
|
|
168
|
-
const osm_id = feature.properties.osm_id
|
|
169
|
-
const types = {
|
|
170
|
-
R: 'relation',
|
|
171
|
-
W: 'way',
|
|
172
|
-
N: 'node',
|
|
173
|
-
}
|
|
174
|
-
const osm_type = types[feature.properties.osm_type]
|
|
175
|
-
if (!osm_type || !osm_id) return
|
|
176
|
-
const importer = this.map._umap.importer
|
|
177
|
-
importer.build()
|
|
178
|
-
importer.format = 'osm'
|
|
179
|
-
importer.url = `https://www.openstreetmap.org/api/0.6/${osm_type}/${osm_id}/full`
|
|
180
|
-
importer.submit()
|
|
181
|
-
})
|
|
182
|
-
el.appendChild(tools)
|
|
183
|
-
this._formatResult(feature, el)
|
|
184
|
-
const path = this.map._umap.getStaticPathFor('target.svg')
|
|
185
|
-
const icon = L.icon({
|
|
186
|
-
iconUrl: path,
|
|
187
|
-
iconSize: [24, 24],
|
|
188
|
-
iconAnchor: [12, 12],
|
|
189
|
-
})
|
|
190
|
-
const coords = feature.geometry.coordinates
|
|
191
|
-
const target = L.marker([coords[1], coords[0]], { icon })
|
|
192
|
-
el.addEventListener('mouseover', (event) => {
|
|
193
|
-
target.addTo(this.layer)
|
|
194
|
-
})
|
|
195
|
-
el.addEventListener('mouseout', (event) => {
|
|
196
|
-
target.removeFrom(this.layer)
|
|
197
|
-
})
|
|
198
|
-
},
|
|
199
|
-
|
|
200
|
-
setChoice: function (choice) {
|
|
201
|
-
choice = choice || this.RESULTS[this.CURRENT]
|
|
202
|
-
if (choice) {
|
|
203
|
-
const feature = choice.feature
|
|
204
|
-
const zoom = Math.max(this.map.getZoom(), 14) // Never unzoom.
|
|
205
|
-
this.map.setView(
|
|
206
|
-
[feature.geometry.coordinates[1], feature.geometry.coordinates[0]],
|
|
207
|
-
zoom
|
|
208
|
-
)
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
})
|
|
212
|
-
|
|
213
59
|
L.Control.MiniMap.include({
|
|
214
60
|
initialize: function (layer, options) {
|
|
215
61
|
L.Util.setOptions(this, options)
|
|
@@ -228,23 +74,6 @@ L.Control.MiniMap.include({
|
|
|
228
74
|
_cloneLayer: (layer) => new L.TileLayer(layer._url, L.Util.extend({}, layer.options)),
|
|
229
75
|
})
|
|
230
76
|
|
|
231
|
-
L.Control.Loading.include({
|
|
232
|
-
onAdd: function (map) {
|
|
233
|
-
this._container = L.DomUtil.create('div', 'umap-loader', map._controlContainer)
|
|
234
|
-
map.on('baselayerchange', this._layerAdd, this)
|
|
235
|
-
this._addMapListeners(map)
|
|
236
|
-
this._map = map
|
|
237
|
-
},
|
|
238
|
-
|
|
239
|
-
_showIndicator: function () {
|
|
240
|
-
this._map._container.classList.add('umap-loading')
|
|
241
|
-
},
|
|
242
|
-
|
|
243
|
-
_hideIndicator: function () {
|
|
244
|
-
this._map._container.classList.remove('umap-loading')
|
|
245
|
-
},
|
|
246
|
-
})
|
|
247
|
-
|
|
248
77
|
U.Editable = L.Editable.extend({
|
|
249
78
|
initialize: function (umap, options) {
|
|
250
79
|
this._umap = umap
|
|
@@ -252,9 +81,10 @@ U.Editable = L.Editable.extend({
|
|
|
252
81
|
this.on('editable:drawing:click editable:drawing:move', this.drawingTooltip)
|
|
253
82
|
// Layer for items added by users
|
|
254
83
|
this.on('editable:drawing:cancel', (event) => {
|
|
255
|
-
|
|
84
|
+
this.resetButtons()
|
|
256
85
|
})
|
|
257
86
|
this.on('editable:drawing:commit', function (event) {
|
|
87
|
+
this.resetButtons()
|
|
258
88
|
if (this._umap.editedFeature !== event.layer) {
|
|
259
89
|
const promise = event.layer.feature.edit(event)
|
|
260
90
|
if (event.layer.feature.isRoute?.()) {
|
|
@@ -278,6 +108,13 @@ U.Editable = L.Editable.extend({
|
|
|
278
108
|
this.on('editable:vertex:rawclick', this.onVertexRawClick)
|
|
279
109
|
},
|
|
280
110
|
|
|
111
|
+
resetButtons: () => {
|
|
112
|
+
const buttons = document.querySelectorAll('.umap-edit-bar .drawing-tool')
|
|
113
|
+
for (const button of buttons) {
|
|
114
|
+
button.classList.remove('on')
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
|
|
281
118
|
startRoute: function (latlng) {
|
|
282
119
|
const feature = this.createLineString()
|
|
283
120
|
feature.askForRouteSettings().then(async () => {
|
|
@@ -402,7 +239,7 @@ U.Editable = L.Editable.extend({
|
|
|
402
239
|
// (eg. line has only one drawn point)
|
|
403
240
|
// So let's check if the layer has no more shape
|
|
404
241
|
event.layer.feature.pullGeometry(false)
|
|
405
|
-
if (!event.layer.feature.hasGeom()) {
|
|
242
|
+
if (!event.layer.feature.hasGeom() || event.layer instanceof U.LeafletMarker) {
|
|
406
243
|
event.layer.feature.del()
|
|
407
244
|
} else {
|
|
408
245
|
event.layer.feature.onCommit()
|