umap-project 2.6.3__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/admin.py +64 -1
- umap/context_processors.py +1 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- umap/locale/cs_CZ/LC_MESSAGES/django.po +96 -92
- umap/locale/de/LC_MESSAGES/django.mo +0 -0
- umap/locale/de/LC_MESSAGES/django.po +19 -18
- umap/locale/en/LC_MESSAGES/django.po +47 -43
- umap/locale/fr/LC_MESSAGES/django.mo +0 -0
- umap/locale/fr/LC_MESSAGES/django.po +51 -47
- umap/locale/pt/LC_MESSAGES/django.mo +0 -0
- umap/locale/pt/LC_MESSAGES/django.po +64 -60
- umap/management/commands/clean_tilelayer.py +152 -0
- umap/management/commands/purge_purgatory.py +28 -0
- umap/models.py +27 -2
- umap/settings/base.py +2 -0
- umap/static/umap/base.css +4 -4
- umap/static/umap/css/contextmenu.css +5 -0
- umap/static/umap/css/icon.css +7 -2
- umap/static/umap/img/16-white.svg +9 -2
- umap/static/umap/img/16.svg +3 -0
- umap/static/umap/img/source/16-white.svg +10 -3
- umap/static/umap/img/source/16.svg +4 -1
- umap/static/umap/js/modules/autocomplete.js +7 -3
- umap/static/umap/js/modules/browser.js +7 -1
- umap/static/umap/js/modules/caption.js +6 -1
- umap/static/umap/js/modules/data/features.js +176 -2
- umap/static/umap/js/modules/data/layer.js +31 -26
- umap/static/umap/js/modules/formatter.js +3 -2
- umap/static/umap/js/modules/global.js +2 -0
- umap/static/umap/js/modules/importers/communesfr.js +13 -1
- umap/static/umap/js/modules/permissions.js +123 -93
- umap/static/umap/js/modules/rendering/ui.js +37 -212
- umap/static/umap/js/modules/sync/engine.js +365 -14
- umap/static/umap/js/modules/sync/hlc.js +106 -0
- umap/static/umap/js/modules/sync/updaters.js +4 -4
- umap/static/umap/js/modules/sync/websocket.js +1 -1
- umap/static/umap/js/modules/ui/base.js +2 -2
- umap/static/umap/js/modules/ui/contextmenu.js +34 -17
- umap/static/umap/js/modules/urls.js +5 -1
- umap/static/umap/js/modules/utils.js +5 -1
- umap/static/umap/js/umap.controls.js +47 -47
- umap/static/umap/js/umap.core.js +3 -3
- umap/static/umap/js/umap.forms.js +3 -1
- umap/static/umap/js/umap.js +95 -112
- umap/static/umap/locale/br.js +13 -4
- umap/static/umap/locale/br.json +13 -4
- umap/static/umap/locale/ca.js +21 -12
- umap/static/umap/locale/ca.json +21 -12
- umap/static/umap/locale/cs_CZ.js +87 -78
- umap/static/umap/locale/cs_CZ.json +87 -78
- umap/static/umap/locale/de.js +17 -8
- umap/static/umap/locale/de.json +17 -8
- umap/static/umap/locale/en.js +9 -2
- umap/static/umap/locale/en.json +9 -2
- umap/static/umap/locale/eu.js +10 -3
- umap/static/umap/locale/eu.json +10 -3
- umap/static/umap/locale/fa_IR.js +11 -4
- umap/static/umap/locale/fa_IR.json +11 -4
- umap/static/umap/locale/fr.js +11 -4
- umap/static/umap/locale/fr.json +11 -4
- umap/static/umap/locale/hu.js +10 -3
- umap/static/umap/locale/hu.json +10 -3
- umap/static/umap/locale/pt.js +17 -8
- umap/static/umap/locale/pt.json +17 -8
- umap/static/umap/locale/pt_PT.js +13 -4
- umap/static/umap/locale/pt_PT.json +13 -4
- umap/static/umap/locale/zh_TW.js +13 -4
- umap/static/umap/locale/zh_TW.json +13 -4
- umap/static/umap/map.css +7 -22
- umap/static/umap/unittests/hlc.js +158 -0
- umap/static/umap/unittests/sync.js +321 -15
- umap/static/umap/unittests/utils.js +23 -0
- umap/static/umap/vendors/georsstogeojson/GeoRSSToGeoJSON.js +111 -80
- umap/templates/umap/dashboard_menu.html +4 -2
- umap/templates/umap/js.html +0 -4
- umap/tests/integration/test_anonymous_owned_map.py +1 -0
- umap/tests/integration/test_basics.py +1 -1
- umap/tests/integration/test_circles_layer.py +12 -0
- umap/tests/integration/test_datalayer.py +5 -0
- umap/tests/integration/test_draw_polygon.py +17 -9
- umap/tests/integration/test_draw_polyline.py +12 -8
- umap/tests/integration/test_edit_datalayer.py +4 -6
- umap/tests/integration/test_edit_map.py +1 -1
- umap/tests/integration/test_import.py +5 -0
- umap/tests/integration/test_map.py +5 -0
- umap/tests/integration/test_owned_map.py +1 -1
- umap/tests/integration/test_view_polygon.py +12 -12
- umap/tests/integration/test_websocket_sync.py +65 -3
- umap/tests/test_clean_tilelayer.py +83 -0
- umap/tests/test_datalayer.py +24 -0
- umap/tests/test_map_views.py +1 -0
- umap/tests/test_purge_purgatory.py +25 -0
- umap/tests/test_websocket_server.py +22 -0
- umap/urls.py +5 -1
- umap/views.py +6 -3
- umap/websocket_server.py +130 -27
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/METADATA +9 -9
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/RECORD +102 -97
- umap/static/umap/vendors/contextmenu/leaflet.contextmenu.min.css +0 -1
- umap/static/umap/vendors/contextmenu/leaflet.contextmenu.min.js +0 -7
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/WHEEL +0 -0
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/entry_points.txt +0 -0
- {umap_project-2.6.3.dist-info → umap_project-2.7.0b0.dist-info}/licenses/LICENSE +0 -0
|
@@ -42,101 +42,129 @@ export class MapPermissions {
|
|
|
42
42
|
return !this.map.options.permissions.owner
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
return this.map
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
edit() {
|
|
50
|
-
if (this.map.options.editMode !== 'advanced') return
|
|
51
|
-
if (!this.map.options.umap_id) {
|
|
52
|
-
return Alert.info(translate('Please save the map first'))
|
|
53
|
-
}
|
|
54
|
-
const container = DomUtil.create('div', 'permissions-panel')
|
|
45
|
+
_editAnonymous(container) {
|
|
55
46
|
const fields = []
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
if (this.isOwner()) {
|
|
48
|
+
fields.push([
|
|
49
|
+
'options.edit_status',
|
|
50
|
+
{
|
|
51
|
+
handler: 'IntSelect',
|
|
52
|
+
label: translate('Who can edit'),
|
|
53
|
+
selectOptions: this.map.options.edit_statuses,
|
|
54
|
+
},
|
|
55
|
+
])
|
|
56
|
+
const builder = new U.FormBuilder(this, fields)
|
|
57
|
+
const form = builder.build()
|
|
58
|
+
container.appendChild(form)
|
|
59
|
+
|
|
58
60
|
if (this.options.anonymous_edit_url) {
|
|
59
|
-
|
|
61
|
+
DomUtil.createCopiableInput(
|
|
62
|
+
container,
|
|
63
|
+
translate('Secret edit link:'),
|
|
60
64
|
this.options.anonymous_edit_url
|
|
61
|
-
|
|
62
|
-
DomUtil.element({
|
|
63
|
-
tagName: 'p',
|
|
64
|
-
className: 'help-text',
|
|
65
|
-
innerHTML: helpText,
|
|
66
|
-
parent: container,
|
|
67
|
-
})
|
|
68
|
-
fields.push([
|
|
69
|
-
'options.edit_status',
|
|
70
|
-
{
|
|
71
|
-
handler: 'IntSelect',
|
|
72
|
-
label: translate('Who can edit'),
|
|
73
|
-
selectOptions: this.map.options.edit_statuses,
|
|
74
|
-
helpText: helpText,
|
|
75
|
-
},
|
|
76
|
-
])
|
|
65
|
+
)
|
|
77
66
|
}
|
|
78
|
-
|
|
79
|
-
if (this.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
67
|
+
|
|
68
|
+
if (this.map.options.user?.id) {
|
|
69
|
+
// We have a user, and this user has come through here, so they can edit the map, so let's allow to own the map.
|
|
70
|
+
// Note: real check is made on the back office anyway.
|
|
71
|
+
const advancedActions = DomUtil.createFieldset(
|
|
72
|
+
container,
|
|
73
|
+
translate('Advanced actions')
|
|
74
|
+
)
|
|
75
|
+
const advancedButtons = DomUtil.create('div', 'button-bar', advancedActions)
|
|
76
|
+
DomUtil.createButton(
|
|
77
|
+
'button',
|
|
78
|
+
advancedButtons,
|
|
79
|
+
translate('Attach the map to my account'),
|
|
80
|
+
this.attach,
|
|
81
|
+
this
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
_editWithOwner(container) {
|
|
88
|
+
const topFields = []
|
|
89
|
+
const collaboratorsFields = []
|
|
90
|
+
const fieldset = Utils.loadTemplate(
|
|
91
|
+
`<fieldset class="separator"><legend>${translate('Map')}</legend></fieldset>`
|
|
92
|
+
)
|
|
93
|
+
container.appendChild(fieldset)
|
|
94
|
+
if (this.isOwner()) {
|
|
95
|
+
topFields.push([
|
|
96
|
+
'options.edit_status',
|
|
97
|
+
{
|
|
98
|
+
handler: 'IntSelect',
|
|
99
|
+
label: translate('Who can edit'),
|
|
100
|
+
selectOptions: this.map.options.edit_statuses,
|
|
101
|
+
},
|
|
102
|
+
])
|
|
103
|
+
topFields.push([
|
|
104
|
+
'options.share_status',
|
|
105
|
+
{
|
|
106
|
+
handler: 'IntSelect',
|
|
107
|
+
label: translate('Who can view'),
|
|
108
|
+
selectOptions: this.map.options.share_statuses,
|
|
109
|
+
},
|
|
110
|
+
])
|
|
111
|
+
collaboratorsFields.push([
|
|
112
|
+
'options.owner',
|
|
113
|
+
{ handler: 'ManageOwner', label: translate("Map's owner") },
|
|
114
|
+
])
|
|
115
|
+
if (this.map.options.user?.teams?.length) {
|
|
116
|
+
collaboratorsFields.push([
|
|
117
|
+
'options.team',
|
|
90
118
|
{
|
|
91
|
-
handler: '
|
|
92
|
-
label: translate('
|
|
93
|
-
|
|
119
|
+
handler: 'ManageTeam',
|
|
120
|
+
label: translate('Attach map to a team'),
|
|
121
|
+
teams: this.map.options.user.teams,
|
|
94
122
|
},
|
|
95
123
|
])
|
|
96
|
-
fields.push([
|
|
97
|
-
'options.owner',
|
|
98
|
-
{ handler: 'ManageOwner', label: translate("Map's owner") },
|
|
99
|
-
])
|
|
100
|
-
if (this.map.options.user?.teams?.length) {
|
|
101
|
-
fields.push([
|
|
102
|
-
'options.team',
|
|
103
|
-
{
|
|
104
|
-
handler: 'ManageTeam',
|
|
105
|
-
label: translate('Attach map to a team'),
|
|
106
|
-
teams: this.map.options.user.teams,
|
|
107
|
-
},
|
|
108
|
-
])
|
|
109
|
-
}
|
|
110
124
|
}
|
|
111
|
-
fields.push([
|
|
112
|
-
'options.editors',
|
|
113
|
-
{ handler: 'ManageEditors', label: translate("Map's editors") },
|
|
114
|
-
])
|
|
115
125
|
}
|
|
126
|
+
collaboratorsFields.push([
|
|
127
|
+
'options.editors',
|
|
128
|
+
{ handler: 'ManageEditors', label: translate("Map's editors") },
|
|
129
|
+
])
|
|
116
130
|
|
|
117
|
-
const builder = new U.FormBuilder(this,
|
|
131
|
+
const builder = new U.FormBuilder(this, topFields)
|
|
118
132
|
const form = builder.build()
|
|
119
133
|
container.appendChild(form)
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const advancedActions = DomUtil.createFieldset(
|
|
124
|
-
container,
|
|
125
|
-
translate('Advanced actions')
|
|
134
|
+
if (collaboratorsFields.length) {
|
|
135
|
+
const fieldset = Utils.loadTemplate(
|
|
136
|
+
`<fieldset class="separator"><legend>${translate('Manage collaborators')}</legend></fieldset>`
|
|
126
137
|
)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
138
|
+
container.appendChild(fieldset)
|
|
139
|
+
const builder = new U.FormBuilder(this, collaboratorsFields)
|
|
140
|
+
const form = builder.build()
|
|
141
|
+
container.appendChild(form)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
_editDatalayers(container) {
|
|
146
|
+
if (this.map.hasLayers()) {
|
|
147
|
+
const fieldset = Utils.loadTemplate(
|
|
148
|
+
`<fieldset class="separator"><legend>${translate('Datalayers')}</legend></fieldset>`
|
|
134
149
|
)
|
|
150
|
+
container.appendChild(fieldset)
|
|
151
|
+
this.map.eachDataLayer((datalayer) => {
|
|
152
|
+
datalayer.permissions.edit(fieldset)
|
|
153
|
+
})
|
|
135
154
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
edit() {
|
|
158
|
+
if (this.map.options.editMode !== 'advanced') return
|
|
159
|
+
if (!this.map.options.umap_id) {
|
|
160
|
+
Alert.info(translate('Please save the map first'))
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
const container = DomUtil.create('div', 'permissions-panel')
|
|
164
|
+
DomUtil.createTitle(container, translate('Update permissions'), 'icon-key')
|
|
165
|
+
if (this.isAnonymousMap()) this._editAnonymous(container)
|
|
166
|
+
else this._editWithOwner(container)
|
|
167
|
+
this._editDatalayers(container)
|
|
140
168
|
this.map.editPanel.open({ content: container, className: 'dark' })
|
|
141
169
|
}
|
|
142
170
|
|
|
@@ -150,15 +178,16 @@ export class MapPermissions {
|
|
|
150
178
|
}
|
|
151
179
|
|
|
152
180
|
async save() {
|
|
153
|
-
if (!this.isDirty) return
|
|
181
|
+
if (!this.isDirty) return
|
|
154
182
|
const formData = new FormData()
|
|
155
183
|
if (!this.isAnonymousMap() && this.options.editors) {
|
|
156
184
|
const editors = this.options.editors.map((u) => u.id)
|
|
157
185
|
for (let i = 0; i < this.options.editors.length; i++)
|
|
158
186
|
formData.append('editors', this.options.editors[i].id)
|
|
159
187
|
}
|
|
160
|
-
if (this.isOwner() || this.isAnonymousMap())
|
|
188
|
+
if (this.isOwner() || this.isAnonymousMap()) {
|
|
161
189
|
formData.append('edit_status', this.options.edit_status)
|
|
190
|
+
}
|
|
162
191
|
if (this.isOwner()) {
|
|
163
192
|
formData.append('owner', this.options.owner?.id)
|
|
164
193
|
formData.append('team', this.options.team?.id || '')
|
|
@@ -172,7 +201,6 @@ export class MapPermissions {
|
|
|
172
201
|
if (!error) {
|
|
173
202
|
this.commit()
|
|
174
203
|
this.isDirty = false
|
|
175
|
-
this.map.continueSaving()
|
|
176
204
|
this.map.fire('postsync')
|
|
177
205
|
}
|
|
178
206
|
}
|
|
@@ -197,9 +225,11 @@ export class MapPermissions {
|
|
|
197
225
|
}
|
|
198
226
|
|
|
199
227
|
getShareStatusDisplay() {
|
|
200
|
-
|
|
201
|
-
this.options.
|
|
202
|
-
|
|
228
|
+
if (this.map.options.share_statuses) {
|
|
229
|
+
return Object.fromEntries(this.map.options.share_statuses)[
|
|
230
|
+
this.options.share_status
|
|
231
|
+
]
|
|
232
|
+
}
|
|
203
233
|
}
|
|
204
234
|
}
|
|
205
235
|
|
|
@@ -225,7 +255,7 @@ export class DataLayerPermissions {
|
|
|
225
255
|
return this._isDirty
|
|
226
256
|
}
|
|
227
257
|
|
|
228
|
-
|
|
258
|
+
get map() {
|
|
229
259
|
return this.datalayer.map
|
|
230
260
|
}
|
|
231
261
|
|
|
@@ -238,7 +268,7 @@ export class DataLayerPermissions {
|
|
|
238
268
|
label: translate('Who can edit "{layer}"', {
|
|
239
269
|
layer: this.datalayer.getName(),
|
|
240
270
|
}),
|
|
241
|
-
selectOptions: this.
|
|
271
|
+
selectOptions: this.map.options.datalayer_edit_statuses,
|
|
242
272
|
},
|
|
243
273
|
],
|
|
244
274
|
]
|
|
@@ -250,16 +280,17 @@ export class DataLayerPermissions {
|
|
|
250
280
|
}
|
|
251
281
|
|
|
252
282
|
getUrl() {
|
|
253
|
-
return
|
|
254
|
-
map_id: this.
|
|
283
|
+
return this.map.urls.get('datalayer_permissions', {
|
|
284
|
+
map_id: this.map.options.umap_id,
|
|
255
285
|
pk: this.datalayer.umap_id,
|
|
256
286
|
})
|
|
257
287
|
}
|
|
288
|
+
|
|
258
289
|
async save() {
|
|
259
|
-
if (!this.isDirty) return
|
|
290
|
+
if (!this.isDirty) return
|
|
260
291
|
const formData = new FormData()
|
|
261
292
|
formData.append('edit_status', this.options.edit_status)
|
|
262
|
-
const [data, response, error] = await this.
|
|
293
|
+
const [data, response, error] = await this.map.server.post(
|
|
263
294
|
this.getUrl(),
|
|
264
295
|
{},
|
|
265
296
|
formData
|
|
@@ -267,7 +298,6 @@ export class DataLayerPermissions {
|
|
|
267
298
|
if (!error) {
|
|
268
299
|
this.commit()
|
|
269
300
|
this.isDirty = false
|
|
270
|
-
this.datalayer.map.continueSaving()
|
|
271
301
|
}
|
|
272
302
|
}
|
|
273
303
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
latLng,
|
|
10
10
|
LatLng,
|
|
11
11
|
LatLngBounds,
|
|
12
|
+
DomEvent,
|
|
12
13
|
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
|
13
14
|
import { translate } from '../i18n.js'
|
|
14
15
|
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
|
@@ -36,7 +37,7 @@ const FeatureMixin = {
|
|
|
36
37
|
},
|
|
37
38
|
|
|
38
39
|
addInteractions: function () {
|
|
39
|
-
this.on('contextmenu editable:vertex:contextmenu', this.
|
|
40
|
+
this.on('contextmenu editable:vertex:contextmenu', this.onContextMenu)
|
|
40
41
|
this.on('click', this.onClick)
|
|
41
42
|
},
|
|
42
43
|
|
|
@@ -61,7 +62,7 @@ const FeatureMixin = {
|
|
|
61
62
|
}).addTo(this._map, this.feature, event.latlng)
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
+
DomEvent.stop(event)
|
|
65
66
|
},
|
|
66
67
|
|
|
67
68
|
resetTooltip: function () {
|
|
@@ -83,67 +84,14 @@ const FeatureMixin = {
|
|
|
83
84
|
}
|
|
84
85
|
},
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
this._map.contextmenu.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
getContextMenuItems: function (event) {
|
|
94
|
-
const permalink = this.feature.getPermalink()
|
|
95
|
-
let items = []
|
|
96
|
-
if (permalink) {
|
|
97
|
-
items.push({
|
|
98
|
-
text: translate('Permalink'),
|
|
99
|
-
callback: () => {
|
|
100
|
-
window.open(permalink)
|
|
101
|
-
},
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
items.push({
|
|
105
|
-
text: translate('Copy as GeoJSON'),
|
|
106
|
-
callback: () => {
|
|
107
|
-
L.Util.copyToClipboard(JSON.stringify(this.feature.toGeoJSON()))
|
|
108
|
-
this._map.tooltip.open({ content: L._('✅ Copied!') })
|
|
109
|
-
},
|
|
110
|
-
})
|
|
111
|
-
if (this._map.editEnabled && !this.feature.isReadOnly()) {
|
|
112
|
-
items = items.concat(this.getContextMenuEditItems(event))
|
|
113
|
-
}
|
|
114
|
-
return items
|
|
115
|
-
},
|
|
116
|
-
|
|
117
|
-
getContextMenuEditItems: function () {
|
|
118
|
-
let items = ['-']
|
|
119
|
-
if (this._map.editedFeature !== this) {
|
|
120
|
-
items.push({
|
|
121
|
-
text: `${translate('Edit this feature')} (⇧+Click)`,
|
|
122
|
-
callback: this.feature.edit,
|
|
123
|
-
context: this.feature,
|
|
124
|
-
iconCls: 'umap-edit',
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
items = items.concat(
|
|
128
|
-
{
|
|
129
|
-
text: this._map.help.displayLabel('EDIT_FEATURE_LAYER'),
|
|
130
|
-
callback: this.feature.datalayer.edit,
|
|
131
|
-
context: this.feature.datalayer,
|
|
132
|
-
iconCls: 'umap-edit',
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
text: translate('Delete this feature'),
|
|
136
|
-
callback: this.feature.confirmDelete,
|
|
137
|
-
context: this.feature,
|
|
138
|
-
iconCls: 'umap-delete',
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
text: translate('Clone this feature'),
|
|
142
|
-
callback: this.feature.clone,
|
|
143
|
-
context: this.feature,
|
|
144
|
-
}
|
|
87
|
+
onContextMenu: function (event) {
|
|
88
|
+
DomEvent.stop(event)
|
|
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
|
|
145
94
|
)
|
|
146
|
-
return items
|
|
147
95
|
},
|
|
148
96
|
|
|
149
97
|
onCommit: function () {
|
|
@@ -158,27 +106,6 @@ const PointMixin = {
|
|
|
158
106
|
isOnScreen: function (bounds) {
|
|
159
107
|
return bounds.contains(this.getCenter())
|
|
160
108
|
},
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export const LeafletMarker = Marker.extend({
|
|
164
|
-
parentClass: Marker,
|
|
165
|
-
includes: [FeatureMixin, PointMixin],
|
|
166
|
-
|
|
167
|
-
initialize: function (feature, latlng) {
|
|
168
|
-
FeatureMixin.initialize.call(this, feature, latlng)
|
|
169
|
-
this.setIcon(this.getIcon())
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
getClass: () => LeafletMarker,
|
|
173
|
-
|
|
174
|
-
// Make API consistent with path
|
|
175
|
-
getLatLngs: function () {
|
|
176
|
-
return this.getLatLng()
|
|
177
|
-
},
|
|
178
|
-
|
|
179
|
-
setLatLngs: function (latlng) {
|
|
180
|
-
return this.setLatLng(latlng)
|
|
181
|
-
},
|
|
182
109
|
|
|
183
110
|
addInteractions() {
|
|
184
111
|
FeatureMixin.addInteractions.call(this)
|
|
@@ -190,9 +117,6 @@ export const LeafletMarker = Marker.extend({
|
|
|
190
117
|
this.on('editable:drawing:commit', this.onCommit)
|
|
191
118
|
if (!this.feature.isReadOnly()) this.on('mouseover', this._enableDragging)
|
|
192
119
|
this.on('mouseout', this._onMouseOut)
|
|
193
|
-
this._popupHandlersAdded = true // prevent Leaflet from binding event on bindPopup
|
|
194
|
-
this.on('popupopen', this.highlight)
|
|
195
|
-
this.on('popupclose', this.resetHighlight)
|
|
196
120
|
},
|
|
197
121
|
|
|
198
122
|
_onMouseOut: function () {
|
|
@@ -222,6 +146,29 @@ export const LeafletMarker = Marker.extend({
|
|
|
222
146
|
this.disableEdit()
|
|
223
147
|
}
|
|
224
148
|
},
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const LeafletMarker = Marker.extend({
|
|
152
|
+
parentClass: Marker,
|
|
153
|
+
includes: [FeatureMixin, PointMixin],
|
|
154
|
+
|
|
155
|
+
initialize: function (feature, latlng) {
|
|
156
|
+
FeatureMixin.initialize.call(this, feature, latlng)
|
|
157
|
+
this.setIcon(this.getIcon())
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
getClass: () => LeafletMarker,
|
|
161
|
+
|
|
162
|
+
setLatLngs: function (latlng) {
|
|
163
|
+
return this.setLatLng(latlng)
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
addInteractions() {
|
|
167
|
+
PointMixin.addInteractions.call(this)
|
|
168
|
+
this._popupHandlersAdded = true // prevent Leaflet from binding event on bindPopup
|
|
169
|
+
this.on('popupopen', this.highlight)
|
|
170
|
+
this.on('popupclose', this.resetHighlight)
|
|
171
|
+
},
|
|
225
172
|
|
|
226
173
|
_initIcon: function () {
|
|
227
174
|
this.options.icon = this.getIcon()
|
|
@@ -344,6 +291,10 @@ const PathMixin = {
|
|
|
344
291
|
}
|
|
345
292
|
options.pointerEvents = options.interactive ? 'visiblePainted' : 'stroke'
|
|
346
293
|
this.parentClass.prototype.setStyle.call(this, options)
|
|
294
|
+
// TODO remove me when this gets merged and released:
|
|
295
|
+
// https://github.com/Leaflet/Leaflet/pull/9475
|
|
296
|
+
|
|
297
|
+
this._path.classList.toggle('leaflet-interactive', options.interactive)
|
|
347
298
|
},
|
|
348
299
|
|
|
349
300
|
_redraw: function () {
|
|
@@ -360,65 +311,6 @@ const PathMixin = {
|
|
|
360
311
|
}).addTo(this._map, this, event.latlng, event.vertex)
|
|
361
312
|
},
|
|
362
313
|
|
|
363
|
-
getContextMenuItems: function (event) {
|
|
364
|
-
let items = FeatureMixin.getContextMenuItems.call(this, event)
|
|
365
|
-
items.push({
|
|
366
|
-
text: translate('Display measure'),
|
|
367
|
-
callback: () => Alert.info(this.getMeasure()),
|
|
368
|
-
})
|
|
369
|
-
if (this._map.editEnabled && !this.feature.isReadOnly() && this.feature.isMulti()) {
|
|
370
|
-
items = items.concat(this.getContextMenuMultiItems(event))
|
|
371
|
-
}
|
|
372
|
-
return items
|
|
373
|
-
},
|
|
374
|
-
|
|
375
|
-
getContextMenuMultiItems: function (event) {
|
|
376
|
-
const items = [
|
|
377
|
-
'-',
|
|
378
|
-
{
|
|
379
|
-
text: translate('Remove shape from the multi'),
|
|
380
|
-
callback: () => {
|
|
381
|
-
this.enableEdit().deleteShapeAt(event.latlng)
|
|
382
|
-
},
|
|
383
|
-
},
|
|
384
|
-
]
|
|
385
|
-
const shape = this.shapeAt(event.latlng)
|
|
386
|
-
if (this._latlngs.indexOf(shape) > 0) {
|
|
387
|
-
items.push({
|
|
388
|
-
text: translate('Make main shape'),
|
|
389
|
-
callback: () => {
|
|
390
|
-
this.enableEdit().deleteShape(shape)
|
|
391
|
-
this.editor.prependShape(shape)
|
|
392
|
-
},
|
|
393
|
-
})
|
|
394
|
-
}
|
|
395
|
-
return items
|
|
396
|
-
},
|
|
397
|
-
|
|
398
|
-
getContextMenuEditItems: function (event) {
|
|
399
|
-
const items = FeatureMixin.getContextMenuEditItems.call(this, event)
|
|
400
|
-
if (
|
|
401
|
-
this._map?.editedFeature !== this.feature &&
|
|
402
|
-
this.feature.isSameClass(this._map.editedFeature)
|
|
403
|
-
) {
|
|
404
|
-
items.push({
|
|
405
|
-
text: translate('Transfer shape to edited feature'),
|
|
406
|
-
callback: () => {
|
|
407
|
-
this.feature.transferShape(event.latlng, this._map.editedFeature)
|
|
408
|
-
},
|
|
409
|
-
})
|
|
410
|
-
}
|
|
411
|
-
if (this.feature.isMulti()) {
|
|
412
|
-
items.push({
|
|
413
|
-
text: translate('Extract shape to separate feature'),
|
|
414
|
-
callback: () => {
|
|
415
|
-
this.isolateShape(event.latlng)
|
|
416
|
-
},
|
|
417
|
-
})
|
|
418
|
-
}
|
|
419
|
-
return items
|
|
420
|
-
},
|
|
421
|
-
|
|
422
314
|
isolateShape: function (atLatLng) {
|
|
423
315
|
if (!this.feature.isMulti()) return
|
|
424
316
|
const shape = this.enableEdit().deleteShapeAt(atLatLng)
|
|
@@ -463,46 +355,6 @@ export const LeafletPolyline = Polyline.extend({
|
|
|
463
355
|
return actions
|
|
464
356
|
},
|
|
465
357
|
|
|
466
|
-
getContextMenuEditItems: function (event) {
|
|
467
|
-
const items = PathMixin.getContextMenuEditItems.call(this, event)
|
|
468
|
-
const vertexClicked = event.vertex
|
|
469
|
-
let index
|
|
470
|
-
if (!this.feature.isMulti()) {
|
|
471
|
-
items.push({
|
|
472
|
-
text: translate('Transform to polygon'),
|
|
473
|
-
callback: this.feature.toPolygon,
|
|
474
|
-
context: this.feature,
|
|
475
|
-
})
|
|
476
|
-
}
|
|
477
|
-
if (vertexClicked) {
|
|
478
|
-
index = event.vertex.getIndex()
|
|
479
|
-
if (index !== 0 && index !== event.vertex.getLastIndex()) {
|
|
480
|
-
items.push({
|
|
481
|
-
text: translate('Split line'),
|
|
482
|
-
callback: event.vertex.split,
|
|
483
|
-
context: event.vertex,
|
|
484
|
-
})
|
|
485
|
-
} else if (index === 0 || index === event.vertex.getLastIndex()) {
|
|
486
|
-
items.push({
|
|
487
|
-
text: this._map.help.displayLabel('CONTINUE_LINE'),
|
|
488
|
-
callback: event.vertex.continue,
|
|
489
|
-
context: event.vertex.continue,
|
|
490
|
-
})
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
return items
|
|
494
|
-
},
|
|
495
|
-
|
|
496
|
-
getContextMenuMultiItems: function (event) {
|
|
497
|
-
const items = PathMixin.getContextMenuMultiItems.call(this, event)
|
|
498
|
-
items.push({
|
|
499
|
-
text: translate('Merge lines'),
|
|
500
|
-
callback: this.feature.mergeShapes,
|
|
501
|
-
context: this.feature,
|
|
502
|
-
})
|
|
503
|
-
return items
|
|
504
|
-
},
|
|
505
|
-
|
|
506
358
|
getMeasure: function (shape) {
|
|
507
359
|
// FIXME: compute from data in feature (with TurfJS)
|
|
508
360
|
const length = L.GeoUtil.lineLength(this._map, shape || this._defaultShape())
|
|
@@ -516,29 +368,6 @@ export const LeafletPolygon = Polygon.extend({
|
|
|
516
368
|
|
|
517
369
|
getClass: () => LeafletPolygon,
|
|
518
370
|
|
|
519
|
-
getContextMenuEditItems: function (event) {
|
|
520
|
-
const items = PathMixin.getContextMenuEditItems.call(this, event)
|
|
521
|
-
const shape = this.shapeAt(event.latlng)
|
|
522
|
-
// No multi and no holes.
|
|
523
|
-
if (
|
|
524
|
-
shape &&
|
|
525
|
-
!this.feature.isMulti() &&
|
|
526
|
-
(LineUtil.isFlat(shape) || shape.length === 1)
|
|
527
|
-
) {
|
|
528
|
-
items.push({
|
|
529
|
-
text: translate('Transform to lines'),
|
|
530
|
-
callback: this.feature.toLineString,
|
|
531
|
-
context: this.feature,
|
|
532
|
-
})
|
|
533
|
-
}
|
|
534
|
-
items.push({
|
|
535
|
-
text: translate('Start a hole here'),
|
|
536
|
-
callback: this.startHole,
|
|
537
|
-
context: this,
|
|
538
|
-
})
|
|
539
|
-
return items
|
|
540
|
-
},
|
|
541
|
-
|
|
542
371
|
startHole: function (event) {
|
|
543
372
|
this.enableEdit().newHole(event.latlng)
|
|
544
373
|
},
|
|
@@ -603,8 +432,4 @@ export const CircleMarker = BaseCircleMarker.extend({
|
|
|
603
432
|
getCenter: function () {
|
|
604
433
|
return this._latlng
|
|
605
434
|
},
|
|
606
|
-
// FIXME when Leaflet.Editable knows about CircleMarker
|
|
607
|
-
editEnabled: () => false,
|
|
608
|
-
enableEdit: () => {}, // No-op
|
|
609
|
-
disableEdit: () => {}, // No-op
|
|
610
435
|
})
|