umap-project 2.7.0__py3-none-any.whl → 2.7.0b0__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/es/LC_MESSAGES/django.mo +0 -0
- umap/locale/es/LC_MESSAGES/django.po +128 -134
- umap/settings/base.py +1 -1
- umap/static/umap/css/contextmenu.css +1 -1
- umap/static/umap/css/importers.css +0 -4
- umap/static/umap/img/16.svg +184 -1
- umap/static/umap/img/24-white.svg +0 -1
- umap/static/umap/img/24.svg +0 -1
- umap/static/umap/img/source/16.svg +200 -753
- umap/static/umap/img/source/24-white.svg +2 -3
- umap/static/umap/img/source/24.svg +2 -3
- umap/static/umap/js/modules/browser.js +0 -47
- umap/static/umap/js/modules/caption.js +4 -10
- umap/static/umap/js/modules/data/layer.js +14 -26
- umap/static/umap/js/modules/importer.js +0 -3
- umap/static/umap/js/modules/importers/communesfr.js +2 -2
- umap/static/umap/js/modules/rendering/layers/classified.js +0 -2
- umap/static/umap/js/modules/rendering/ui.js +6 -28
- umap/static/umap/js/modules/share.js +3 -1
- umap/static/umap/js/modules/slideshow.js +1 -1
- umap/static/umap/js/modules/sync/engine.js +8 -14
- umap/static/umap/js/modules/sync/hlc.js +3 -3
- umap/static/umap/js/modules/sync/updaters.js +2 -14
- umap/static/umap/js/modules/tableeditor.js +1 -1
- umap/static/umap/js/modules/ui/contextmenu.js +2 -18
- umap/static/umap/js/modules/utils.js +4 -24
- umap/static/umap/js/umap.controls.js +10 -31
- umap/static/umap/js/umap.core.js +1 -1
- umap/static/umap/js/umap.js +23 -31
- umap/static/umap/locale/ca.js +4 -8
- umap/static/umap/locale/ca.json +4 -8
- umap/static/umap/locale/en.js +1 -5
- umap/static/umap/locale/en.json +1 -5
- umap/static/umap/locale/es.js +319 -330
- umap/static/umap/locale/es.json +319 -330
- umap/static/umap/locale/fr.js +1 -5
- umap/static/umap/locale/fr.json +1 -5
- umap/static/umap/map.css +7 -37
- umap/static/umap/unittests/hlc.js +3 -10
- umap/static/umap/unittests/utils.js +0 -24
- umap/static/umap/vars.css +1 -2
- umap/static/umap/vendors/colorbrewer/colorbrewer.js +317 -309
- umap/static/umap/vendors/dompurify/purify.es.js +16 -15
- umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js +2 -2
- umap/static/umap/vendors/locatecontrol/L.Control.Locate.min.js.map +1 -1
- umap/static/umap/vendors/simple-statistics/simple-statistics.min.js +1 -1
- umap/static/umap/vendors/simple-statistics/simple-statistics.min.js.map +1 -1
- umap/templates/umap/css.html +2 -0
- umap/templates/umap/js.html +1 -0
- umap/templates/umap/map_detail.html +2 -2
- umap/tests/fixtures/test_upload_data.csv +2 -2
- umap/tests/integration/test_browser.py +7 -69
- umap/tests/integration/test_caption.py +3 -3
- umap/tests/integration/test_datalayer.py +5 -1
- umap/tests/integration/test_edit_datalayer.py +2 -1
- umap/tests/integration/test_edit_map.py +1 -1
- umap/tests/integration/test_edit_marker.py +1 -1
- umap/tests/integration/test_facets_browser.py +3 -3
- umap/tests/integration/test_import.py +4 -0
- umap/tests/integration/test_map.py +4 -0
- umap/tests/integration/test_view_marker.py +0 -63
- umap/tests/test_map_views.py +0 -19
- {umap_project-2.7.0.dist-info → umap_project-2.7.0b0.dist-info}/METADATA +10 -14
- {umap_project-2.7.0.dist-info → umap_project-2.7.0b0.dist-info}/RECORD +69 -72
- umap/asgi.py +0 -15
- umap/static/umap/img/importers/cadastrefr.svg +0 -23
- umap/static/umap/js/modules/importers/cadastrefr.js +0 -62
- {umap_project-2.7.0.dist-info → umap_project-2.7.0b0.dist-info}/WHEEL +0 -0
- {umap_project-2.7.0.dist-info → umap_project-2.7.0b0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.7.0.dist-info → umap_project-2.7.0b0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
2
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
3
|
|
|
4
|
-
<svg width="252" height="252" viewBox="0 0 66.674992 66.674992" version="1.1" id="svg2876" inkscape:version="1.
|
|
5
|
-
<sodipodi:namedview id="namedview2878" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="
|
|
4
|
+
<svg width="252" height="252" viewBox="0 0 66.674992 66.674992" version="1.1" id="svg2876" inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)" sodipodi:docname="24-white.svg" inkscape:export-filename="../24-white.svg" inkscape:export-xdpi="7.52" inkscape:export-ydpi="7.52" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
|
5
|
+
<sodipodi:namedview id="namedview2878" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="2.6753614" inkscape:cx="107.64901" inkscape:cy="85.409023" inkscape:window-width="960" inkscape:window-height="1011" inkscape:window-x="20" inkscape:window-y="20" inkscape:window-maximized="0" inkscape:current-layer="layer1">
|
|
6
6
|
<inkscape:grid type="xygrid" id="grid2997" empspacing="6" originx="0" originy="0" spacingy="0.2645833" spacingx="0.2645833" units="px" visible="true" />
|
|
7
7
|
<inkscape:grid id="grid1" units="px" originx="0" originy="0" spacingx="9.5249989" spacingy="9.5249989" empcolor="#3f3fff" empopacity="0.25098039" color="#3f3fff" opacity="0.1254902" empspacing="1" dotted="false" gridanglex="30" gridanglez="30" visible="true" />
|
|
8
8
|
</sodipodi:namedview>
|
|
@@ -74,6 +74,5 @@
|
|
|
74
74
|
<g id="info" transform="matrix(0.33072916,0,0,0.33072916,-11.906249,-256.10415)" style="stroke-width:0.8">
|
|
75
75
|
<path id="path3762" style="fill:#f2f2f2;fill-opacity:1;stroke:#999999;stroke-width:0.2;stroke-dasharray:none;stroke-opacity:1" d="m 107.99999,838.36217 a 8,8 0 0 0 -7.999998,8 8,8 0 0 0 7.999998,8 8,8 0 0 0 8,-8 8,8 0 0 0 -8,-8 z m 0,2.5 a 1.5,1.5 0 0 1 1.5,1.5 1.5,1.5 0 0 1 -1.5,1.5 1.5,1.5 0 0 1 -1.5,-1.5 1.5,1.5 0 0 1 1.5,-1.5 z m -1,4.5 h 2 v 6 h -2 z" />
|
|
76
76
|
</g>
|
|
77
|
-
<path d="m 5.6444435,59.43432 v 1.034991 h 1.0541546 z m 1.1759257,1.612262 h -1.1759257 c -0.3247228,0 -0.5879626,-0.258453 -0.5879626,-0.577271 v -1.154545 h -2.3518514 v 5.195451 h 4.1157397 z m -4.1157397,-2.309089 h 3.0615854 l 1.6421175,1.612259 v 4.160465 c 0,0.318822 -0.2632403,0.577275 -0.5879632,0.577275 h -4.1157397 c -0.3247231,0 -0.5879631,-0.258453 -0.5879631,-0.577275 v -5.195451 c 0,-0.31882 0.26324,-0.577273 0.5879631,-0.577273 z m 1.7638882,3.92135 v -1.323625 h 0.5879632 v 1.323625 l 0.3800861,-0.373177 0.415753,0.408196 -1.0898206,1.070004 -1.0898208,-1.070004 0.4157526,-0.408196 z" fill-rule="evenodd" id="downloadfile" style="fill:#f2f2f2;fill-opacity:1;stroke-width:0.06614583;stroke:#999999;stroke-opacity:0.50980395;stroke-dasharray:none" />
|
|
78
77
|
</g>
|
|
79
78
|
</svg>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
2
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
3
3
|
|
|
4
|
-
<svg width="252" height="252" viewBox="0 0 66.674999 66.674999" version="1.1" id="svg6237" inkscape:version="1.
|
|
5
|
-
<sodipodi:namedview id="namedview6239" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="3.1596124" inkscape:cx="
|
|
4
|
+
<svg width="252" height="252" viewBox="0 0 66.674999 66.674999" version="1.1" id="svg6237" inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)" sodipodi:docname="24.svg" inkscape:export-filename="../24.svg" inkscape:export-xdpi="7.52" inkscape:export-ydpi="7.52" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
|
5
|
+
<sodipodi:namedview id="namedview6239" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" showgrid="true" showguides="true" inkscape:zoom="3.1596124" inkscape:cx="117.10297" inkscape:cy="106.50041" inkscape:window-width="960" inkscape:window-height="1011" inkscape:window-x="20" inkscape:window-y="20" inkscape:window-maximized="0" inkscape:current-layer="layer1">
|
|
6
6
|
<inkscape:grid type="xygrid" id="grid6358" empspacing="6" originx="0" originy="0" spacingy="0.26458333" spacingx="0.26458333" units="px" visible="true" />
|
|
7
7
|
<inkscape:grid id="grid1" units="px" originx="0" originy="0" spacingx="9.5249999" spacingy="9.5249999" empcolor="#3f3fff" empopacity="0.25098039" color="#ff0000" opacity="0.83529412" empspacing="0" dotted="false" gridanglex="30" gridanglez="30" visible="true" />
|
|
8
8
|
</sodipodi:namedview>
|
|
@@ -98,6 +98,5 @@
|
|
|
98
98
|
<g id="info" transform="matrix(0.33072916,0,0,0.33072916,-11.90625,-256.10415)" style="fill:#4d4d4d;fill-opacity:1;stroke-width:0.8">
|
|
99
99
|
<path id="path3762" style="fill:#4d4d4d;fill-opacity:1;stroke:none;stroke-width:0.8" d="m 108,838.36217 a 8,8 0 0 0 -8,8 8,8 0 0 0 8,8 8,8 0 0 0 8,-8 8,8 0 0 0 -8,-8 z m 0,2.5 a 1.5,1.5 0 0 1 1.5,1.5 1.5,1.5 0 0 1 -1.5,1.5 1.5,1.5 0 0 1 -1.5,-1.5 1.5,1.5 0 0 1 1.5,-1.5 z m -1,4.5 h 2 v 6 h -2 z" />
|
|
100
100
|
</g>
|
|
101
|
-
<path d="m 5.6444435,59.43432 v 1.034991 h 1.0541546 z m 1.1759257,1.612262 h -1.1759257 c -0.3247228,0 -0.5879626,-0.258453 -0.5879626,-0.577271 v -1.154545 h -2.3518514 v 5.195451 h 4.1157397 z m -4.1157397,-2.309089 h 3.0615854 l 1.6421175,1.612259 v 4.160465 c 0,0.318822 -0.2632403,0.577275 -0.5879632,0.577275 h -4.1157397 c -0.3247231,0 -0.5879631,-0.258453 -0.5879631,-0.577275 v -5.195451 c 0,-0.31882 0.26324,-0.577273 0.5879631,-0.577273 z m 1.7638882,3.92135 v -1.323625 h 0.5879632 v 1.323625 l 0.3800861,-0.373177 0.415753,0.408196 -1.0898206,1.070004 -1.0898208,-1.070004 0.4157526,-0.408196 z" fill-rule="evenodd" id="downloadfile" style="fill:#464646;fill-opacity:1;stroke-width:0.192424" />
|
|
102
101
|
</g>
|
|
103
102
|
</svg>
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { DomEvent, DomUtil, stamp } from '../../vendors/leaflet/leaflet-src.esm.js'
|
|
2
2
|
import { translate } from './i18n.js'
|
|
3
3
|
import * as Icon from './rendering/icon.js'
|
|
4
|
-
import * as Utils from './utils.js'
|
|
5
|
-
import { EXPORT_FORMATS } from './formatter.js'
|
|
6
|
-
import ContextMenu from './ui/contextmenu.js'
|
|
7
4
|
|
|
8
5
|
export default class Browser {
|
|
9
6
|
constructor(map) {
|
|
@@ -101,7 +98,6 @@ export default class Browser {
|
|
|
101
98
|
datalayer.eachFeature((feature) => this.addFeature(feature, container))
|
|
102
99
|
|
|
103
100
|
const total = datalayer.count()
|
|
104
|
-
if (!total) return
|
|
105
101
|
const current = container.querySelectorAll('li').length
|
|
106
102
|
const count = total === current ? total : `${current}/${total}`
|
|
107
103
|
const counter = DomUtil.create('span', 'datalayer-counter', headline)
|
|
@@ -168,7 +164,6 @@ export default class Browser {
|
|
|
168
164
|
})
|
|
169
165
|
this.filtersTitle = container.querySelector('summary')
|
|
170
166
|
this.toggleBadge()
|
|
171
|
-
this.addMainToolbox(container)
|
|
172
167
|
this.dataContainer = DomUtil.create('div', '', container)
|
|
173
168
|
|
|
174
169
|
let fields = [
|
|
@@ -220,48 +215,6 @@ export default class Browser {
|
|
|
220
215
|
}
|
|
221
216
|
}
|
|
222
217
|
|
|
223
|
-
addMainToolbox(container) {
|
|
224
|
-
const [toolbox, { toggle, fitBounds, download }] = Utils.loadTemplateWithRefs(`
|
|
225
|
-
<div class="main-toolbox">
|
|
226
|
-
<i class="icon icon-16 icon-eye" title="${translate('show/hide all layers')}" data-ref="toggle"></i>
|
|
227
|
-
<i class="icon icon-16 icon-zoom" title="${translate('zoom to data extent')}" data-ref="fitBounds"></i>
|
|
228
|
-
<i class="icon icon-16 icon-download" title="${translate('download visible data')}" data-ref="download"></i>
|
|
229
|
-
</div>
|
|
230
|
-
`)
|
|
231
|
-
container.appendChild(toolbox)
|
|
232
|
-
toggle.addEventListener('click', () => this.toggleLayers())
|
|
233
|
-
fitBounds.addEventListener('click', () => this.map.fitDataBounds())
|
|
234
|
-
download.addEventListener('click', () => this.downloadVisible(download))
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
downloadVisible(element) {
|
|
238
|
-
const menu = new ContextMenu({ fixed: true })
|
|
239
|
-
const items = []
|
|
240
|
-
for (const format of Object.keys(EXPORT_FORMATS)) {
|
|
241
|
-
items.push({
|
|
242
|
-
label: format,
|
|
243
|
-
action: () => this.map.share.download(format),
|
|
244
|
-
})
|
|
245
|
-
}
|
|
246
|
-
menu.openBelow(element, items)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
toggleLayers() {
|
|
250
|
-
// If at least one layer is shown, hide it
|
|
251
|
-
// otherwise show all
|
|
252
|
-
let allHidden = true
|
|
253
|
-
this.map.eachBrowsableDataLayer((datalayer) => {
|
|
254
|
-
if (datalayer.isVisible()) allHidden = false
|
|
255
|
-
})
|
|
256
|
-
this.map.eachBrowsableDataLayer((datalayer) => {
|
|
257
|
-
if (allHidden) {
|
|
258
|
-
datalayer.show()
|
|
259
|
-
} else {
|
|
260
|
-
if (datalayer.isVisible()) datalayer.hide()
|
|
261
|
-
}
|
|
262
|
-
})
|
|
263
|
-
}
|
|
264
|
-
|
|
265
218
|
static backButton(map) {
|
|
266
219
|
const button = DomUtil.createButtonIcon(
|
|
267
220
|
DomUtil.create('li', '', undefined),
|
|
@@ -40,21 +40,15 @@ export default class Caption {
|
|
|
40
40
|
)
|
|
41
41
|
const creditsContainer = DomUtil.create('div', 'credits-container', container)
|
|
42
42
|
this.addCredits(creditsContainer)
|
|
43
|
-
this.map.panel.open({ content: container })
|
|
44
|
-
// Create the legend when the panel is actually on the DOM
|
|
45
|
-
this.map.eachDataLayerReverse((datalayer) => datalayer.renderLegend())
|
|
46
|
-
})
|
|
43
|
+
this.map.panel.open({ content: container })
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
addDataLayer(datalayer, container) {
|
|
50
47
|
if (!datalayer.options.inCaption) return
|
|
51
|
-
const p = DomUtil.create(
|
|
52
|
-
|
|
53
|
-
`caption-item ${datalayer.cssId}`,
|
|
54
|
-
container
|
|
55
|
-
)
|
|
56
|
-
const legend = DomUtil.create('span', 'datalayer-legend', p)
|
|
48
|
+
const p = DomUtil.create('p', 'datalayer-legend', container)
|
|
49
|
+
const legend = DomUtil.create('span', '', p)
|
|
57
50
|
const headline = DomUtil.create('strong', '', p)
|
|
51
|
+
datalayer.renderLegend(legend)
|
|
58
52
|
if (datalayer.options.description) {
|
|
59
53
|
DomUtil.element({
|
|
60
54
|
tagName: 'span',
|
|
@@ -115,10 +115,6 @@ export class DataLayer {
|
|
|
115
115
|
return this._isDeleted
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
get cssId() {
|
|
119
|
-
return `datalayer-${stamp(this)}`
|
|
120
|
-
}
|
|
121
|
-
|
|
122
118
|
getSyncMetadata() {
|
|
123
119
|
return {
|
|
124
120
|
subject: 'datalayer',
|
|
@@ -239,7 +235,6 @@ export class DataLayer {
|
|
|
239
235
|
}
|
|
240
236
|
|
|
241
237
|
dataChanged() {
|
|
242
|
-
if (!this.hasDataLoaded()) return
|
|
243
238
|
this.map.onDataLayersChanged()
|
|
244
239
|
this.layer.dataChanged()
|
|
245
240
|
}
|
|
@@ -247,13 +242,8 @@ export class DataLayer {
|
|
|
247
242
|
fromGeoJSON(geojson, sync = true) {
|
|
248
243
|
this.addData(geojson, sync)
|
|
249
244
|
this._geojson = geojson
|
|
250
|
-
this.onDataLoaded()
|
|
251
|
-
this.dataChanged()
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
onDataLoaded() {
|
|
255
245
|
this._dataloaded = true
|
|
256
|
-
this.
|
|
246
|
+
this.dataChanged()
|
|
257
247
|
}
|
|
258
248
|
|
|
259
249
|
async fromUmapGeoJSON(geojson) {
|
|
@@ -394,7 +384,7 @@ export class DataLayer {
|
|
|
394
384
|
this.indexProperties(feature)
|
|
395
385
|
this.map.features_index[feature.getSlug()] = feature
|
|
396
386
|
this.showFeature(feature)
|
|
397
|
-
this.dataChanged()
|
|
387
|
+
if (this.hasDataLoaded()) this.dataChanged()
|
|
398
388
|
}
|
|
399
389
|
|
|
400
390
|
removeFeature(feature, sync) {
|
|
@@ -405,7 +395,7 @@ export class DataLayer {
|
|
|
405
395
|
feature.disconnectFromDataLayer(this)
|
|
406
396
|
this._index.splice(this._index.indexOf(id), 1)
|
|
407
397
|
delete this._features[id]
|
|
408
|
-
if (this.isVisible()) this.dataChanged()
|
|
398
|
+
if (this.hasDataLoaded() && this.isVisible()) this.dataChanged()
|
|
409
399
|
}
|
|
410
400
|
|
|
411
401
|
indexProperties(feature) {
|
|
@@ -812,12 +802,13 @@ export class DataLayer {
|
|
|
812
802
|
this
|
|
813
803
|
)
|
|
814
804
|
if (this.umap_id) {
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
805
|
+
const download = DomUtil.createLink(
|
|
806
|
+
'button umap-download',
|
|
807
|
+
advancedButtons,
|
|
808
|
+
translate('Download'),
|
|
809
|
+
this._dataUrl(),
|
|
810
|
+
'_blank'
|
|
811
|
+
)
|
|
821
812
|
}
|
|
822
813
|
const backButton = DomUtil.createButtonIcon(
|
|
823
814
|
undefined,
|
|
@@ -1129,13 +1120,10 @@ export class DataLayer {
|
|
|
1129
1120
|
return 'displayName'
|
|
1130
1121
|
}
|
|
1131
1122
|
|
|
1132
|
-
renderLegend() {
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
const color = DomUtil.create('span', 'datalayer-color', container)
|
|
1137
|
-
color.style.backgroundColor = this.getColor()
|
|
1138
|
-
}
|
|
1123
|
+
renderLegend(container) {
|
|
1124
|
+
if (this.layer.renderLegend) return this.layer.renderLegend(container)
|
|
1125
|
+
const color = DomUtil.create('span', 'datalayer-color', container)
|
|
1126
|
+
color.style.backgroundColor = this.getColor()
|
|
1139
1127
|
}
|
|
1140
1128
|
|
|
1141
1129
|
renderToolbox(container) {
|
|
@@ -69,9 +69,6 @@ export default class Importer {
|
|
|
69
69
|
case 'communesfr':
|
|
70
70
|
import('./importers/communesfr.js').then(register)
|
|
71
71
|
break
|
|
72
|
-
case 'cadastrefr':
|
|
73
|
-
import('./importers/cadastrefr.js').then(register)
|
|
74
|
-
break
|
|
75
72
|
case 'overpass':
|
|
76
73
|
import('./importers/overpass.js').then(register)
|
|
77
74
|
break
|
|
@@ -2,7 +2,7 @@ import { DomUtil } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
|
2
2
|
import { BaseAjax, SingleMixin } from '../autocomplete.js'
|
|
3
3
|
import * as Util from '../utils.js'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
class Autocomplete extends SingleMixin(BaseAjax) {
|
|
6
6
|
createResult(item) {
|
|
7
7
|
return super.createResult({
|
|
8
8
|
value: item.code,
|
|
@@ -46,7 +46,7 @@ export class Importer {
|
|
|
46
46
|
importer.dialog.close()
|
|
47
47
|
},
|
|
48
48
|
}
|
|
49
|
-
this.autocomplete = new
|
|
49
|
+
this.autocomplete = new Autocomplete(container, options)
|
|
50
50
|
|
|
51
51
|
importer.dialog.open({
|
|
52
52
|
template: container,
|
|
@@ -3,7 +3,6 @@ import { translate } from '../../i18n.js'
|
|
|
3
3
|
import { LayerMixin } from './base.js'
|
|
4
4
|
import * as Utils from '../../utils.js'
|
|
5
5
|
import { CircleMarker } from '../ui.js'
|
|
6
|
-
import colorbrewer from '../../../../vendors/colorbrewer/colorbrewer.js'
|
|
7
6
|
|
|
8
7
|
// Layer where each feature color is relative to the others,
|
|
9
8
|
// so we need all features before behing able to set one
|
|
@@ -75,7 +74,6 @@ const ClassifiedMixin = {
|
|
|
75
74
|
},
|
|
76
75
|
|
|
77
76
|
renderLegend: function (container) {
|
|
78
|
-
if (!this.datalayer.hasDataLoaded()) return
|
|
79
77
|
const parent = DomUtil.create('ul', '', container)
|
|
80
78
|
const items = this.getLegendItems()
|
|
81
79
|
for (const [color, label] of items) {
|
|
@@ -36,12 +36,6 @@ const FeatureMixin = {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
|
|
39
|
-
_removeIcon: function () {
|
|
40
|
-
// It may not be in the DOM, and Leaflet does not deal with this
|
|
41
|
-
// situation
|
|
42
|
-
if (this._icon) Marker.prototype._removeIcon.call(this)
|
|
43
|
-
},
|
|
44
|
-
|
|
45
39
|
addInteractions: function () {
|
|
46
40
|
this.on('contextmenu editable:vertex:contextmenu', this.onContextMenu)
|
|
47
41
|
this.on('click', this.onClick)
|
|
@@ -92,10 +86,12 @@ const FeatureMixin = {
|
|
|
92
86
|
|
|
93
87
|
onContextMenu: function (event) {
|
|
94
88
|
DomEvent.stop(event)
|
|
95
|
-
const items = this.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
89
|
+
const items = this._map.getContextMenuItems(event)
|
|
90
|
+
items.push('-', ...this.feature.getContextMenuItems(event))
|
|
91
|
+
this._map.contextmenu.open(
|
|
92
|
+
[event.originalEvent.clientX, event.originalEvent.clientY],
|
|
93
|
+
items
|
|
94
|
+
)
|
|
99
95
|
},
|
|
100
96
|
|
|
101
97
|
onCommit: function () {
|
|
@@ -167,12 +163,6 @@ export const LeafletMarker = Marker.extend({
|
|
|
167
163
|
return this.setLatLng(latlng)
|
|
168
164
|
},
|
|
169
165
|
|
|
170
|
-
getEvents: function () {
|
|
171
|
-
const events = Marker.prototype.getEvents.call(this)
|
|
172
|
-
events.moveend = this.onMoveEnd
|
|
173
|
-
return events
|
|
174
|
-
},
|
|
175
|
-
|
|
176
166
|
addInteractions() {
|
|
177
167
|
PointMixin.addInteractions.call(this)
|
|
178
168
|
this._popupHandlersAdded = true // prevent Leaflet from binding event on bindPopup
|
|
@@ -180,19 +170,7 @@ export const LeafletMarker = Marker.extend({
|
|
|
180
170
|
this.on('popupclose', this.resetHighlight)
|
|
181
171
|
},
|
|
182
172
|
|
|
183
|
-
onMoveEnd: function () {
|
|
184
|
-
this._initIcon()
|
|
185
|
-
this.update()
|
|
186
|
-
},
|
|
187
|
-
|
|
188
173
|
_initIcon: function () {
|
|
189
|
-
if (!this._map.getBounds().contains(this.getCenter())) {
|
|
190
|
-
if (this._icon) this._removeIcon()
|
|
191
|
-
if (this._tooltip && this.isTooltipOpen()) {
|
|
192
|
-
this.unbindTooltip()
|
|
193
|
-
}
|
|
194
|
-
return
|
|
195
|
-
}
|
|
196
174
|
this.options.icon = this.getIcon()
|
|
197
175
|
Marker.prototype._initIcon.call(this)
|
|
198
176
|
// Allow to run code when icon is actually part of the DOM
|
|
@@ -142,7 +142,9 @@ export default class Share {
|
|
|
142
142
|
async format(mode) {
|
|
143
143
|
const type = EXPORT_FORMATS[mode]
|
|
144
144
|
const content = await type.formatter(this.map)
|
|
145
|
-
|
|
145
|
+
let name = this.map.options.name || 'data'
|
|
146
|
+
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
|
|
147
|
+
const filename = name + type.ext
|
|
146
148
|
return { content, filetype: type.filetype, filename }
|
|
147
149
|
}
|
|
148
150
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as Utils from '../utils.js'
|
|
2
|
-
import { HybridLogicalClock } from './hlc.js'
|
|
3
1
|
import { DataLayerUpdater, FeatureUpdater, MapUpdater } from './updaters.js'
|
|
4
2
|
import { WebSocketTransport } from './websocket.js'
|
|
3
|
+
import { HybridLogicalClock } from './hlc.js'
|
|
4
|
+
import * as Utils from '../utils.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The syncEngine exposes an API to sync messages between peers over the network.
|
|
@@ -81,7 +81,7 @@ export class SyncEngine {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
_send(inputMessage) {
|
|
84
|
-
|
|
84
|
+
let message = this._operations.addLocal(inputMessage)
|
|
85
85
|
|
|
86
86
|
if (this.offline) return
|
|
87
87
|
if (this.transport) {
|
|
@@ -101,11 +101,6 @@ export class SyncEngine {
|
|
|
101
101
|
updater.applyMessage(operation)
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
getNumberOfConnectedPeers() {
|
|
105
|
-
if (this.peers) return this.peers.length
|
|
106
|
-
return 0
|
|
107
|
-
}
|
|
108
|
-
|
|
109
104
|
/**
|
|
110
105
|
* This is called by the transport layer on new messages,
|
|
111
106
|
* and dispatches the different "on*" methods.
|
|
@@ -151,10 +146,10 @@ export class SyncEngine {
|
|
|
151
146
|
onJoinResponse({ uuid, peers }) {
|
|
152
147
|
debug('received join response', { uuid, peers })
|
|
153
148
|
this.uuid = uuid
|
|
154
|
-
this.
|
|
149
|
+
this.peers = peers
|
|
155
150
|
|
|
156
151
|
// Get one peer at random
|
|
157
|
-
|
|
152
|
+
let randomPeer = this._getRandomPeer()
|
|
158
153
|
|
|
159
154
|
if (randomPeer) {
|
|
160
155
|
// Retrieve the operations which happened before join.
|
|
@@ -173,7 +168,6 @@ export class SyncEngine {
|
|
|
173
168
|
onListPeersResponse({ peers }) {
|
|
174
169
|
debug('received peerinfo', { peers })
|
|
175
170
|
this.peers = peers
|
|
176
|
-
this.updaters.map.update({ key: 'numberOfConnectedPeers' })
|
|
177
171
|
}
|
|
178
172
|
|
|
179
173
|
/**
|
|
@@ -254,7 +248,7 @@ export class SyncEngine {
|
|
|
254
248
|
* @returns {string|bool} the selected peer uuid, or False if none was found.
|
|
255
249
|
*/
|
|
256
250
|
_getRandomPeer() {
|
|
257
|
-
|
|
251
|
+
let otherPeers = this.peers.filter((p) => p !== this.uuid)
|
|
258
252
|
if (otherPeers.length > 0) {
|
|
259
253
|
const random = Math.floor(Math.random() * otherPeers.length)
|
|
260
254
|
return otherPeers[random]
|
|
@@ -308,7 +302,7 @@ export class Operations {
|
|
|
308
302
|
* @returns {*} clock-aware message
|
|
309
303
|
*/
|
|
310
304
|
addLocal(inputMessage) {
|
|
311
|
-
|
|
305
|
+
let message = { ...inputMessage, hlc: this._hlc.tick() }
|
|
312
306
|
this._operations.push(message)
|
|
313
307
|
return message
|
|
314
308
|
}
|
|
@@ -348,7 +342,7 @@ export class Operations {
|
|
|
348
342
|
*/
|
|
349
343
|
storeRemoteOperations(remoteOperations) {
|
|
350
344
|
// get the highest date from the passed operations
|
|
351
|
-
|
|
345
|
+
let greatestHLC = remoteOperations
|
|
352
346
|
.map((op) => op.hlc)
|
|
353
347
|
.reduce((max, current) => (current > max ? current : max))
|
|
354
348
|
|
|
@@ -30,12 +30,12 @@ export class HybridLogicalClock {
|
|
|
30
30
|
* @returns object
|
|
31
31
|
*/
|
|
32
32
|
parse(raw) {
|
|
33
|
-
|
|
33
|
+
let tokens = raw.split(':')
|
|
34
34
|
|
|
35
35
|
if (tokens.length !== 3) {
|
|
36
36
|
throw new SyntaxError(`Unable to parse ${raw}`)
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
let [walltime, rawNN, id] = tokens
|
|
39
39
|
|
|
40
40
|
let nn = Number.parseInt(rawNN)
|
|
41
41
|
if (Number.isNaN(nn)) {
|
|
@@ -92,7 +92,7 @@ export class HybridLogicalClock {
|
|
|
92
92
|
if (now > local.walltime && now > remote.walltime) {
|
|
93
93
|
nextValue = { ...local, walltime: now }
|
|
94
94
|
} else if (local.walltime == remote.walltime) {
|
|
95
|
-
|
|
95
|
+
let nn = Math.max(local.nn, remote.nn) + 1
|
|
96
96
|
nextValue = { ...local, nn: nn }
|
|
97
97
|
} else if (remote.walltime > local.walltime) {
|
|
98
98
|
nextValue = { ...remote, id: local.id, nn: remote.nn + 1 }
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { fieldInSchema } from '../utils.js'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Updaters are classes able to convert messages
|
|
5
3
|
* received from other peers (or from the server) to changes on the map.
|
|
@@ -44,10 +42,7 @@ class BaseUpdater {
|
|
|
44
42
|
|
|
45
43
|
export class MapUpdater extends BaseUpdater {
|
|
46
44
|
update({ key, value }) {
|
|
47
|
-
|
|
48
|
-
this.updateObjectValue(this.map, key, value)
|
|
49
|
-
}
|
|
50
|
-
|
|
45
|
+
this.updateObjectValue(this.map, key, value)
|
|
51
46
|
this.map.render([key])
|
|
52
47
|
}
|
|
53
48
|
}
|
|
@@ -61,14 +56,7 @@ export class DataLayerUpdater extends BaseUpdater {
|
|
|
61
56
|
|
|
62
57
|
update({ key, metadata, value }) {
|
|
63
58
|
const datalayer = this.getDataLayerFromID(metadata.id)
|
|
64
|
-
|
|
65
|
-
this.updateObjectValue(datalayer, key, value)
|
|
66
|
-
} else {
|
|
67
|
-
console.debug(
|
|
68
|
-
'Not applying update for datalayer because key is not in the schema',
|
|
69
|
-
key
|
|
70
|
-
)
|
|
71
|
-
}
|
|
59
|
+
this.updateObjectValue(datalayer, key, value)
|
|
72
60
|
datalayer.render([key])
|
|
73
61
|
}
|
|
74
62
|
}
|
|
@@ -15,18 +15,7 @@ export default class ContextMenu extends Positioned {
|
|
|
15
15
|
})
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
open(
|
|
19
|
-
const left = event.clientX
|
|
20
|
-
const top = event.clientY
|
|
21
|
-
this.openAt([left, top], items)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
openBelow(element, items) {
|
|
25
|
-
const coords = this.getPosition(element)
|
|
26
|
-
this.openAt([coords.left, coords.bottom], items)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
openAt([left, top], items) {
|
|
18
|
+
open([left, top], items) {
|
|
30
19
|
this.container.innerHTML = ''
|
|
31
20
|
for (const item of items) {
|
|
32
21
|
if (item === '-') {
|
|
@@ -47,12 +36,7 @@ export default class ContextMenu extends Positioned {
|
|
|
47
36
|
this.container.appendChild(li)
|
|
48
37
|
}
|
|
49
38
|
}
|
|
50
|
-
|
|
51
|
-
// "focusout" element on link click, preventing to trigger the click action
|
|
52
|
-
const parent = document
|
|
53
|
-
.elementFromPoint(left, top)
|
|
54
|
-
.closest('.leaflet-container').parentNode
|
|
55
|
-
parent.appendChild(this.container)
|
|
39
|
+
document.body.appendChild(this.container)
|
|
56
40
|
if (this.options.fixed) {
|
|
57
41
|
this.setPosition({ left, top })
|
|
58
42
|
} else {
|
|
@@ -35,7 +35,7 @@ export function checkId(string) {
|
|
|
35
35
|
* @returns Array[string]
|
|
36
36
|
*/
|
|
37
37
|
export function getImpactsFromSchema(fields, schema) {
|
|
38
|
-
|
|
38
|
+
schema = schema || U.SCHEMA
|
|
39
39
|
const impacted = fields
|
|
40
40
|
.map((field) => {
|
|
41
41
|
// remove the option prefix for fields
|
|
@@ -46,30 +46,14 @@ export function getImpactsFromSchema(fields, schema) {
|
|
|
46
46
|
.reduce((acc, field) => {
|
|
47
47
|
// retrieve the "impacts" field from the schema
|
|
48
48
|
// and merge them together using sets
|
|
49
|
-
const impacts =
|
|
50
|
-
|
|
51
|
-
acc.add(impact)
|
|
52
|
-
}
|
|
49
|
+
const impacts = schema[field]?.impacts || []
|
|
50
|
+
impacts.forEach((impact) => acc.add(impact))
|
|
53
51
|
return acc
|
|
54
52
|
}, new Set())
|
|
55
53
|
|
|
56
54
|
return Array.from(impacted)
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
/**
|
|
60
|
-
* Check if a field exists in the schema.
|
|
61
|
-
*
|
|
62
|
-
* @param {string} field
|
|
63
|
-
* @param {object} schema
|
|
64
|
-
* @returns {boolean}
|
|
65
|
-
*/
|
|
66
|
-
export function fieldInSchema(field, schema) {
|
|
67
|
-
const current_schema = schema || U.SCHEMA
|
|
68
|
-
if (typeof field !== 'string') return false
|
|
69
|
-
const field_name = field.replace('options.', '').split('.')[0]
|
|
70
|
-
return current_schema[field_name] !== undefined
|
|
71
|
-
}
|
|
72
|
-
|
|
73
57
|
/**
|
|
74
58
|
* Import DOM purify, and initialize it.
|
|
75
59
|
*
|
|
@@ -423,10 +407,6 @@ export class WithTemplate {
|
|
|
423
407
|
}
|
|
424
408
|
}
|
|
425
409
|
|
|
426
|
-
export function deepEqual(object1, object2)
|
|
410
|
+
export function deepEqual(object1, object2){
|
|
427
411
|
return JSON.stringify(object1) === JSON.stringify(object2)
|
|
428
412
|
}
|
|
429
|
-
|
|
430
|
-
export function slugify(str) {
|
|
431
|
-
return (str || 'data').replace(/[^a-z0-9]/gi, '_').toLowerCase()
|
|
432
|
-
}
|
|
@@ -453,13 +453,17 @@ U.PermanentCreditsControl = L.Control.extend({
|
|
|
453
453
|
},
|
|
454
454
|
|
|
455
455
|
onAdd: function () {
|
|
456
|
-
|
|
456
|
+
const paragraphContainer = L.DomUtil.create(
|
|
457
457
|
'div',
|
|
458
|
-
'umap-permanent-credits-container
|
|
458
|
+
'umap-permanent-credits-container'
|
|
459
459
|
)
|
|
460
|
+
const creditsParagraph = L.DomUtil.create('p', '', paragraphContainer)
|
|
461
|
+
|
|
462
|
+
this.paragraphContainer = paragraphContainer
|
|
460
463
|
this.setCredits()
|
|
461
464
|
this.setBackground()
|
|
462
|
-
|
|
465
|
+
|
|
466
|
+
return paragraphContainer
|
|
463
467
|
},
|
|
464
468
|
|
|
465
469
|
setCredits: function () {
|
|
@@ -657,36 +661,11 @@ const ControlsMixin = {
|
|
|
657
661
|
})
|
|
658
662
|
}
|
|
659
663
|
button.addEventListener('click', () => {
|
|
660
|
-
|
|
664
|
+
const x = button.offsetLeft
|
|
665
|
+
const y = button.offsetTop + button.offsetHeight
|
|
666
|
+
menu.open([x, y], actions)
|
|
661
667
|
})
|
|
662
668
|
}
|
|
663
|
-
|
|
664
|
-
const connectedPeers = this.sync.getNumberOfConnectedPeers()
|
|
665
|
-
if (connectedPeers !== 0) {
|
|
666
|
-
const connectedPeersCount = L.DomUtil.createButton(
|
|
667
|
-
'leaflet-control-connected-peers',
|
|
668
|
-
rightContainer,
|
|
669
|
-
'',
|
|
670
|
-
)
|
|
671
|
-
L.DomEvent.on(connectedPeersCount, 'mouseover', () => {
|
|
672
|
-
this.tooltip.open({
|
|
673
|
-
content: L._('{connectedPeers} peer(s) currently connected to this map', {
|
|
674
|
-
connectedPeers: connectedPeers,
|
|
675
|
-
}),
|
|
676
|
-
anchor: connectedPeersCount,
|
|
677
|
-
position: 'bottom',
|
|
678
|
-
delay: 500,
|
|
679
|
-
duration: 5000,
|
|
680
|
-
})
|
|
681
|
-
})
|
|
682
|
-
|
|
683
|
-
const updateConnectedPeersCount = () => {
|
|
684
|
-
connectedPeersCount.innerHTML =
|
|
685
|
-
'<span>' + this.sync.getNumberOfConnectedPeers() + '</span>'
|
|
686
|
-
}
|
|
687
|
-
updateConnectedPeersCount()
|
|
688
|
-
}
|
|
689
|
-
|
|
690
669
|
this.help.getStartedLink(rightContainer)
|
|
691
670
|
const controlEditCancel = L.DomUtil.createButton(
|
|
692
671
|
'leaflet-control-edit-cancel',
|