umap-project 2.4.1__py3-none-any.whl → 2.5.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.
Files changed (199) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/el/LC_MESSAGES/django.po +145 -90
  4. umap/locale/en/LC_MESSAGES/django.po +13 -13
  5. umap/locale/eu/LC_MESSAGES/django.mo +0 -0
  6. umap/locale/eu/LC_MESSAGES/django.po +145 -89
  7. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  8. umap/locale/hu/LC_MESSAGES/django.po +100 -50
  9. umap/static/umap/base.css +5 -2
  10. umap/static/umap/content.css +2 -2
  11. umap/static/umap/css/contextmenu.css +11 -0
  12. umap/static/umap/css/dialog.css +25 -4
  13. umap/static/umap/css/importers.css +2 -0
  14. umap/static/umap/css/panel.css +6 -4
  15. umap/static/umap/css/slideshow.css +69 -0
  16. umap/static/umap/css/tableeditor.css +69 -0
  17. umap/static/umap/css/tooltip.css +3 -3
  18. umap/static/umap/img/16-white.svg +4 -0
  19. umap/static/umap/img/source/16-white.svg +5 -1
  20. umap/static/umap/js/components/alerts/alert.css +11 -11
  21. umap/static/umap/js/components/alerts/alert.js +1 -1
  22. umap/static/umap/js/modules/autocomplete.js +27 -5
  23. umap/static/umap/js/modules/browser.js +20 -14
  24. umap/static/umap/js/modules/caption.js +4 -4
  25. umap/static/umap/js/modules/dompurify.js +2 -3
  26. umap/static/umap/js/modules/facets.js +53 -17
  27. umap/static/umap/js/modules/formatter.js +153 -0
  28. umap/static/umap/js/modules/global.js +25 -16
  29. umap/static/umap/js/modules/help.js +26 -26
  30. umap/static/umap/js/modules/importer.js +10 -10
  31. umap/static/umap/js/modules/importers/communesfr.js +3 -1
  32. umap/static/umap/js/modules/importers/datasets.js +8 -6
  33. umap/static/umap/js/modules/importers/geodatamine.js +14 -14
  34. umap/static/umap/js/modules/importers/overpass.js +19 -15
  35. umap/static/umap/js/modules/orderable.js +2 -2
  36. umap/static/umap/js/modules/request.js +1 -1
  37. umap/static/umap/js/modules/rules.js +26 -11
  38. umap/static/umap/js/modules/schema.js +16 -12
  39. umap/static/umap/js/{umap.share.js → modules/share.js} +58 -103
  40. umap/static/umap/js/modules/slideshow.js +141 -0
  41. umap/static/umap/js/modules/sync/engine.js +3 -3
  42. umap/static/umap/js/modules/sync/updaters.js +10 -11
  43. umap/static/umap/js/modules/sync/websocket.js +1 -1
  44. umap/static/umap/js/modules/tableeditor.js +329 -0
  45. umap/static/umap/js/modules/ui/base.js +93 -0
  46. umap/static/umap/js/modules/ui/contextmenu.js +50 -0
  47. umap/static/umap/js/modules/ui/dialog.js +169 -31
  48. umap/static/umap/js/modules/ui/panel.js +7 -5
  49. umap/static/umap/js/modules/ui/tooltip.js +7 -77
  50. umap/static/umap/js/modules/urls.js +1 -2
  51. umap/static/umap/js/modules/utils.js +36 -16
  52. umap/static/umap/js/umap.controls.js +27 -29
  53. umap/static/umap/js/umap.core.js +19 -15
  54. umap/static/umap/js/umap.datalayer.permissions.js +15 -18
  55. umap/static/umap/js/umap.features.js +113 -131
  56. umap/static/umap/js/umap.forms.js +203 -228
  57. umap/static/umap/js/umap.icon.js +17 -22
  58. umap/static/umap/js/umap.js +117 -107
  59. umap/static/umap/js/umap.layer.js +374 -324
  60. umap/static/umap/js/umap.permissions.js +7 -10
  61. umap/static/umap/js/umap.popup.js +20 -20
  62. umap/static/umap/locale/am_ET.js +22 -5
  63. umap/static/umap/locale/am_ET.json +22 -5
  64. umap/static/umap/locale/ar.js +22 -5
  65. umap/static/umap/locale/ar.json +22 -5
  66. umap/static/umap/locale/ast.js +22 -5
  67. umap/static/umap/locale/ast.json +22 -5
  68. umap/static/umap/locale/bg.js +22 -5
  69. umap/static/umap/locale/bg.json +22 -5
  70. umap/static/umap/locale/br.js +22 -5
  71. umap/static/umap/locale/br.json +22 -5
  72. umap/static/umap/locale/ca.js +56 -39
  73. umap/static/umap/locale/ca.json +56 -39
  74. umap/static/umap/locale/cs_CZ.js +22 -5
  75. umap/static/umap/locale/cs_CZ.json +22 -5
  76. umap/static/umap/locale/da.js +22 -5
  77. umap/static/umap/locale/da.json +22 -5
  78. umap/static/umap/locale/de.js +22 -5
  79. umap/static/umap/locale/de.json +22 -5
  80. umap/static/umap/locale/el.js +27 -10
  81. umap/static/umap/locale/el.json +27 -10
  82. umap/static/umap/locale/en.js +22 -6
  83. umap/static/umap/locale/en.json +22 -6
  84. umap/static/umap/locale/en_US.json +22 -5
  85. umap/static/umap/locale/es.js +22 -6
  86. umap/static/umap/locale/es.json +22 -6
  87. umap/static/umap/locale/et.js +22 -5
  88. umap/static/umap/locale/et.json +22 -5
  89. umap/static/umap/locale/eu.js +167 -150
  90. umap/static/umap/locale/eu.json +167 -150
  91. umap/static/umap/locale/fa_IR.js +22 -5
  92. umap/static/umap/locale/fa_IR.json +22 -5
  93. umap/static/umap/locale/fi.js +22 -5
  94. umap/static/umap/locale/fi.json +22 -5
  95. umap/static/umap/locale/fr.js +22 -6
  96. umap/static/umap/locale/fr.json +22 -6
  97. umap/static/umap/locale/gl.js +22 -5
  98. umap/static/umap/locale/gl.json +22 -5
  99. umap/static/umap/locale/he.js +22 -5
  100. umap/static/umap/locale/he.json +22 -5
  101. umap/static/umap/locale/hr.js +22 -5
  102. umap/static/umap/locale/hr.json +22 -5
  103. umap/static/umap/locale/hu.js +89 -72
  104. umap/static/umap/locale/hu.json +89 -72
  105. umap/static/umap/locale/id.js +22 -5
  106. umap/static/umap/locale/id.json +22 -5
  107. umap/static/umap/locale/is.js +22 -5
  108. umap/static/umap/locale/is.json +22 -5
  109. umap/static/umap/locale/it.js +22 -5
  110. umap/static/umap/locale/it.json +22 -5
  111. umap/static/umap/locale/ja.js +22 -5
  112. umap/static/umap/locale/ja.json +22 -5
  113. umap/static/umap/locale/ko.js +22 -5
  114. umap/static/umap/locale/ko.json +22 -5
  115. umap/static/umap/locale/lt.js +22 -5
  116. umap/static/umap/locale/lt.json +22 -5
  117. umap/static/umap/locale/ms.js +22 -5
  118. umap/static/umap/locale/ms.json +22 -5
  119. umap/static/umap/locale/nl.js +22 -5
  120. umap/static/umap/locale/nl.json +22 -5
  121. umap/static/umap/locale/no.js +22 -5
  122. umap/static/umap/locale/no.json +22 -5
  123. umap/static/umap/locale/pl.js +22 -5
  124. umap/static/umap/locale/pl.json +22 -5
  125. umap/static/umap/locale/pl_PL.json +22 -5
  126. umap/static/umap/locale/pt.js +22 -6
  127. umap/static/umap/locale/pt.json +22 -6
  128. umap/static/umap/locale/pt_BR.js +22 -5
  129. umap/static/umap/locale/pt_BR.json +22 -5
  130. umap/static/umap/locale/pt_PT.js +22 -5
  131. umap/static/umap/locale/pt_PT.json +22 -5
  132. umap/static/umap/locale/ro.js +22 -5
  133. umap/static/umap/locale/ro.json +22 -5
  134. umap/static/umap/locale/ru.js +22 -5
  135. umap/static/umap/locale/ru.json +22 -5
  136. umap/static/umap/locale/sk_SK.js +22 -5
  137. umap/static/umap/locale/sk_SK.json +22 -5
  138. umap/static/umap/locale/sl.js +22 -5
  139. umap/static/umap/locale/sl.json +22 -5
  140. umap/static/umap/locale/sr.js +22 -5
  141. umap/static/umap/locale/sr.json +22 -5
  142. umap/static/umap/locale/sv.js +22 -5
  143. umap/static/umap/locale/sv.json +22 -5
  144. umap/static/umap/locale/th_TH.js +22 -5
  145. umap/static/umap/locale/th_TH.json +22 -5
  146. umap/static/umap/locale/tr.js +22 -5
  147. umap/static/umap/locale/tr.json +22 -5
  148. umap/static/umap/locale/uk_UA.js +22 -5
  149. umap/static/umap/locale/uk_UA.json +22 -5
  150. umap/static/umap/locale/vi.js +22 -5
  151. umap/static/umap/locale/vi.json +22 -5
  152. umap/static/umap/locale/vi_VN.json +22 -5
  153. umap/static/umap/locale/zh.js +22 -5
  154. umap/static/umap/locale/zh.json +22 -5
  155. umap/static/umap/locale/zh_CN.json +22 -5
  156. umap/static/umap/locale/zh_TW.Big5.json +22 -5
  157. umap/static/umap/locale/zh_TW.js +22 -5
  158. umap/static/umap/locale/zh_TW.json +22 -5
  159. umap/static/umap/map.css +9 -153
  160. umap/static/umap/vars.css +15 -0
  161. umap/static/umap/vendors/dompurify/purify.es.js +5 -59
  162. umap/static/umap/vendors/dompurify/purify.es.mjs.map +1 -1
  163. umap/static/umap/vendors/formbuilder/Leaflet.FormBuilder.js +410 -428
  164. umap/static/umap/vendors/geojson-to-gpx/index.js +155 -0
  165. umap/static/umap/vendors/osmtogeojson/osmtogeojson.js +1 -2
  166. umap/static/umap/vendors/togeojson/togeojson.es.js +1109 -0
  167. umap/static/umap/vendors/togeojson/{togeojson.umd.js.map → togeojson.es.mjs.map} +1 -1
  168. umap/static/umap/vendors/tokml/tokml.es.js +895 -0
  169. umap/static/umap/vendors/tokml/tokml.es.mjs.map +1 -0
  170. umap/storage.py +6 -2
  171. umap/templates/umap/components/alerts/alert.html +3 -3
  172. umap/templates/umap/css.html +3 -0
  173. umap/templates/umap/js.html +0 -6
  174. umap/tests/fixtures/categorized_highway.geojson +1 -0
  175. umap/tests/fixtures/test_import_osm_relation.json +130 -0
  176. umap/tests/integration/conftest.py +8 -1
  177. umap/tests/integration/test_browser.py +3 -2
  178. umap/tests/integration/test_categorized_layer.py +141 -0
  179. umap/tests/integration/test_conditional_rules.py +21 -0
  180. umap/tests/integration/test_datalayer.py +9 -4
  181. umap/tests/integration/test_edit_datalayer.py +1 -0
  182. umap/tests/integration/test_edit_polygon.py +1 -1
  183. umap/tests/integration/test_export_map.py +2 -3
  184. umap/tests/integration/test_import.py +22 -0
  185. umap/tests/integration/test_map_preview.py +36 -2
  186. umap/tests/integration/test_tableeditor.py +158 -4
  187. umap/tests/integration/test_websocket_sync.py +2 -2
  188. umap/tests/test_views.py +2 -2
  189. umap/views.py +3 -2
  190. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/METADATA +8 -8
  191. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/RECORD +194 -184
  192. umap/static/umap/js/umap.slideshow.js +0 -165
  193. umap/static/umap/js/umap.tableeditor.js +0 -118
  194. umap/static/umap/vendors/togeojson/togeojson.umd.js +0 -2
  195. umap/static/umap/vendors/togpx/togpx.js +0 -547
  196. umap/static/umap/vendors/tokml/tokml.js +0 -343
  197. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/WHEEL +0 -0
  198. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/entry_points.txt +0 -0
  199. {umap_project-2.4.1.dist-info → umap_project-2.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,49 +1,11 @@
1
- U.Share = L.Class.extend({
2
- EXPORT_TYPES: {
3
- geojson: {
4
- formatter: function (map) {
5
- return JSON.stringify(map.toGeoJSON(), null, 2)
6
- },
7
- ext: '.geojson',
8
- filetype: 'application/json',
9
- },
10
- gpx: {
11
- formatter: function (map) {
12
- return togpx(map.toGeoJSON())
13
- },
14
- ext: '.gpx',
15
- filetype: 'application/gpx+xml',
16
- },
17
- kml: {
18
- formatter: function (map) {
19
- return tokml(map.toGeoJSON())
20
- },
21
- ext: '.kml',
22
- filetype: 'application/vnd.google-earth.kml+xml',
23
- },
24
- csv: {
25
- formatter: function (map) {
26
- const table = []
27
- map.eachFeature((feature) => {
28
- const row = feature.toGeoJSON()['properties'],
29
- center = feature.getCenter()
30
- delete row['_umap_options']
31
- row['Latitude'] = center.lat
32
- row['Longitude'] = center.lng
33
- table.push(row)
34
- })
35
- return csv2geojson.dsv.csvFormat(table)
36
- },
37
- ext: '.csv',
38
- filetype: 'text/csv',
39
- },
40
- },
1
+ import { EXPORT_FORMATS } from './formatter.js'
41
2
 
42
- initialize: function (map) {
3
+ export default class Share {
4
+ constructor(map) {
43
5
  this.map = map
44
- },
6
+ }
45
7
 
46
- build: function () {
8
+ build() {
47
9
  this.container = L.DomUtil.create('div', '')
48
10
  this.title = L.DomUtil.createTitle(
49
11
  this.container,
@@ -69,16 +31,10 @@ U.Share = L.Class.extend({
69
31
 
70
32
  L.DomUtil.add('h4', '', this.container, L._('Download'))
71
33
  L.DomUtil.add('small', 'label', this.container, L._("Only visible layers' data"))
72
- for (const key in this.EXPORT_TYPES) {
73
- if (this.EXPORT_TYPES.hasOwnProperty(key)) {
74
- L.DomUtil.createButton(
75
- 'download-file',
76
- this.container,
77
- this.EXPORT_TYPES[key].name || key,
78
- () => this.download(key),
79
- this
80
- )
81
- }
34
+ for (const format of Object.keys(EXPORT_FORMATS)) {
35
+ L.DomUtil.createButton('download-file', this.container, format, () =>
36
+ this.download(format)
37
+ )
82
38
  }
83
39
  L.DomUtil.create('div', 'vspace', this.container)
84
40
  L.DomUtil.add(
@@ -141,7 +97,7 @@ U.Share = L.Class.extend({
141
97
  for (let i = 0; i < this.map.HIDDABLE_CONTROLS.length; i++) {
142
98
  UIFields.push(`queryString.${this.map.HIDDABLE_CONTROLS[i]}Control`)
143
99
  }
144
- const iframeExporter = new U.IframeExporter(this.map)
100
+ const iframeExporter = new IframeExporter(this.map)
145
101
  const buildIframeCode = () => {
146
102
  iframe.textContent = iframeExporter.build()
147
103
  exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
@@ -155,24 +111,24 @@ U.Share = L.Class.extend({
155
111
  L._('Embed and link options')
156
112
  )
157
113
  iframeOptions.appendChild(builder.build())
158
- },
114
+ }
159
115
 
160
- open: function () {
116
+ open() {
161
117
  if (!this.container) this.build()
162
118
  this.map.panel.open({ content: this.container })
163
- },
119
+ }
164
120
 
165
- format: function (mode) {
166
- const type = this.EXPORT_TYPES[mode]
167
- const content = type.formatter(this.map)
121
+ async format(mode) {
122
+ const type = EXPORT_FORMATS[mode]
123
+ const content = await type.formatter(this.map)
168
124
  let name = this.map.options.name || 'data'
169
125
  name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
170
126
  const filename = name + type.ext
171
127
  return { content, filetype: type.filetype, filename }
172
- },
128
+ }
173
129
 
174
- download: function (mode) {
175
- const { content, filetype, filename } = this.format(mode)
130
+ async download(mode) {
131
+ const { content, filetype, filename } = await this.format(mode)
176
132
  const blob = new Blob([content], { type: filetype })
177
133
  window.URL = window.URL || window.webkitURL
178
134
  const el = document.createElement('a')
@@ -182,50 +138,49 @@ U.Share = L.Class.extend({
182
138
  document.body.appendChild(el)
183
139
  el.click()
184
140
  document.body.removeChild(el)
185
- },
186
- })
187
-
188
- U.IframeExporter = L.Evented.extend({
189
- options: {
190
- includeFullScreenLink: true,
191
- currentView: false,
192
- keepCurrentDatalayers: false,
193
- viewCurrentFeature: false,
194
- },
195
-
196
- queryString: {
197
- scaleControl: false,
198
- miniMap: false,
199
- scrollWheelZoom: false,
200
- zoomControl: true,
201
- editMode: 'disabled',
202
- moreControl: true,
203
- searchControl: null,
204
- tilelayersControl: null,
205
- embedControl: null,
206
- datalayersControl: true,
207
- onLoadPanel: 'none',
208
- captionBar: false,
209
- captionMenus: true,
210
- },
141
+ }
142
+ }
211
143
 
212
- dimensions: {
213
- width: '100%',
214
- height: '300px',
215
- },
216
-
217
- initialize: function (map) {
144
+ class IframeExporter {
145
+ constructor(map) {
218
146
  this.map = map
219
147
  this.baseUrl = U.Utils.getBaseUrl()
148
+ this.options = {
149
+ includeFullScreenLink: true,
150
+ currentView: false,
151
+ keepCurrentDatalayers: false,
152
+ viewCurrentFeature: false,
153
+ }
154
+
155
+ this.queryString = {
156
+ scaleControl: false,
157
+ miniMap: false,
158
+ scrollWheelZoom: false,
159
+ zoomControl: true,
160
+ editMode: 'disabled',
161
+ moreControl: true,
162
+ searchControl: null,
163
+ tilelayersControl: null,
164
+ embedControl: null,
165
+ datalayersControl: true,
166
+ onLoadPanel: 'none',
167
+ captionBar: false,
168
+ captionMenus: true,
169
+ }
170
+
171
+ this.dimensions = {
172
+ width: '100%',
173
+ height: '300px',
174
+ }
220
175
  // Use map default, not generic default
221
176
  this.queryString.onLoadPanel = this.map.getOption('onLoadPanel')
222
- },
177
+ }
223
178
 
224
- getMap: function () {
179
+ getMap() {
225
180
  return this.map
226
- },
181
+ }
227
182
 
228
- buildUrl: function (options) {
183
+ buildUrl(options) {
229
184
  const datalayers = []
230
185
  if (this.options.viewCurrentFeature && this.map.currentFeature) {
231
186
  this.queryString.feature = this.map.currentFeature.getSlug()
@@ -245,9 +200,9 @@ U.IframeExporter = L.Evented.extend({
245
200
  const currentView = this.options.currentView ? window.location.hash : ''
246
201
  const queryString = L.extend({}, this.queryString, options)
247
202
  return `${this.baseUrl}?${U.Utils.buildQueryString(queryString)}${currentView}`
248
- },
203
+ }
249
204
 
250
- build: function () {
205
+ build() {
251
206
  const iframeUrl = this.buildUrl()
252
207
  let code = `<iframe width="${this.dimensions.width}" height="${this.dimensions.height}" frameborder="0" allowfullscreen allow="geolocation" src="${iframeUrl}"></iframe>`
253
208
  if (this.options.includeFullScreenLink) {
@@ -255,5 +210,5 @@ U.IframeExporter = L.Evented.extend({
255
210
  code += `<p><a href="${fullUrl}">${L._('See full screen')}</a></p>`
256
211
  }
257
212
  return code
258
- },
259
- })
213
+ }
214
+ }
@@ -0,0 +1,141 @@
1
+ import { WithTemplate } from './utils.js'
2
+ import { translate } from './i18n.js'
3
+
4
+ const TOOLBOX_TEMPLATE = `
5
+ <ul class="umap-slideshow-toolbox dark">
6
+ <li class="play" title="${translate('Start slideshow')}" data-ref="play">
7
+ <div class="spinner" style="animation: none;"></div>
8
+ </li>
9
+ <li class="stop" title="${translate('Stop slideshow')}" data-ref="stop"></li>
10
+ <li class="prev" title="${translate('Zoom to the previous')}" data-ref="previous"></li>
11
+ <li class="next" title="${translate('Zoom to the next')}" data-ref="next"></li>
12
+ </ul>
13
+ `
14
+
15
+ export default class Slideshow extends WithTemplate {
16
+ constructor(map, options) {
17
+ super()
18
+ this.map = map
19
+ this._id = null
20
+ this.CLASSNAME = 'umap-slideshow-active'
21
+ this.setOptions(options)
22
+ this._current = null
23
+
24
+ if (this.options.autoplay) {
25
+ this.map.onceDataLoaded(function () {
26
+ this.play()
27
+ }, this)
28
+ }
29
+ this.map.on(
30
+ 'edit:enabled',
31
+ function () {
32
+ this.stop()
33
+ },
34
+ this
35
+ )
36
+ }
37
+
38
+ set current(feature) {
39
+ this._current = feature
40
+ }
41
+
42
+ get current() {
43
+ if (!this._current) {
44
+ const datalayer = this.defaultDatalayer()
45
+ if (datalayer) this._current = datalayer.getFeatureByIndex(0)
46
+ }
47
+ return this._current
48
+ }
49
+
50
+ get next() {
51
+ if (this._current === null) {
52
+ return this.current
53
+ }
54
+ return this.current.getNext()
55
+ }
56
+
57
+ setOptions(options) {
58
+ this.options = Object.assign(
59
+ {
60
+ delay: 5000,
61
+ autoplay: false,
62
+ },
63
+ options
64
+ )
65
+ }
66
+
67
+ defaultDatalayer() {
68
+ return this.map.findDataLayer((d) => d.canBrowse())
69
+ }
70
+
71
+ startSpinner() {
72
+ const time = Number.parseInt(this.options.delay, 10)
73
+ if (!time) return
74
+ const css = `rotation ${time / 1000}s infinite linear`
75
+ const spinner = document.querySelector('.umap-slideshow-toolbox .play .spinner')
76
+ spinner.style.animation = css
77
+ }
78
+
79
+ stopSpinner() {
80
+ const spinner = document.querySelector('.umap-slideshow-toolbox .play .spinner')
81
+ spinner.style.animation = 'none'
82
+ }
83
+
84
+ play() {
85
+ if (this._id) return
86
+ if (this.map.editEnabled || !this.map.options.slideshow.active) return
87
+ L.DomUtil.addClass(document.body, this.CLASSNAME)
88
+ this._id = window.setInterval(L.bind(this.loop, this), this.options.delay)
89
+ this.startSpinner()
90
+ this.loop()
91
+ }
92
+
93
+ loop() {
94
+ this.current = this.next
95
+ this.step()
96
+ }
97
+
98
+ pause() {
99
+ if (this._id) {
100
+ this.stopSpinner()
101
+ L.DomUtil.removeClass(document.body, this.CLASSNAME)
102
+ window.clearInterval(this._id)
103
+ this._id = null
104
+ }
105
+ }
106
+
107
+ stop() {
108
+ this.pause()
109
+ this.current = null
110
+ }
111
+
112
+ forward() {
113
+ this.pause()
114
+ this.current = this.next
115
+ this.step()
116
+ }
117
+
118
+ backward() {
119
+ this.pause()
120
+ if (this.current) this.current = this.current.getPrevious()
121
+ this.step()
122
+ }
123
+
124
+ step() {
125
+ if (!this.current) return this.stop()
126
+ this.current.zoomTo({ easing: this.options.easing })
127
+ this.current.view()
128
+ }
129
+
130
+ toggle() {
131
+ this._id ? this.pause() : this.play()
132
+ }
133
+
134
+ renderToolbox(container) {
135
+ container.appendChild(this.loadTemplate(TOOLBOX_TEMPLATE))
136
+ this.elements.play.addEventListener('click', this.toggle.bind(this))
137
+ this.elements.stop.addEventListener('click', this.stop.bind(this))
138
+ this.elements.previous.addEventListener('click', this.backward.bind(this))
139
+ this.elements.next.addEventListener('click', this.forward.bind(this))
140
+ }
141
+ }
@@ -1,5 +1,5 @@
1
+ import { DataLayerUpdater, FeatureUpdater, MapUpdater } from './updaters.js'
1
2
  import { WebSocketTransport } from './websocket.js'
2
- import { MapUpdater, DataLayerUpdater, FeatureUpdater } from './updaters.js'
3
3
 
4
4
  export class SyncEngine {
5
5
  constructor(map) {
@@ -36,8 +36,8 @@ export class SyncEngine {
36
36
 
37
37
  // This method is called by the transport layer on new messages
38
38
  receive({ kind, ...payload }) {
39
- if (kind == 'operation') {
40
- let updater = this._getUpdater(payload.subject, payload.metadata)
39
+ if (kind === 'operation') {
40
+ const updater = this._getUpdater(payload.subject, payload.metadata)
41
41
  updater.applyMessage(payload)
42
42
  } else {
43
43
  throw new Error(`Unknown dispatch kind: ${kind}`)
@@ -35,7 +35,7 @@ class BaseUpdater {
35
35
  }
36
36
 
37
37
  applyMessage(payload) {
38
- let { verb } = payload
38
+ const { verb } = payload
39
39
  return this[verb](payload)
40
40
  }
41
41
  }
@@ -69,7 +69,7 @@ export class FeatureUpdater extends BaseUpdater {
69
69
 
70
70
  // Create or update an object at a specific position
71
71
  upsert({ metadata, value }) {
72
- let { id, layerId } = metadata
72
+ const { id, layerId } = metadata
73
73
  const datalayer = this.getDataLayerFromID(layerId)
74
74
  let feature = this.getFeatureFromMetadata(metadata, value)
75
75
 
@@ -84,17 +84,16 @@ export class FeatureUpdater extends BaseUpdater {
84
84
 
85
85
  // Update a property of an object
86
86
  update({ key, metadata, value }) {
87
- let feature = this.getFeatureFromMetadata(metadata)
87
+ const feature = this.getFeatureFromMetadata(metadata)
88
88
  if (feature === undefined) {
89
89
  console.error(`Unable to find feature with id = ${metadata.id}.`)
90
90
  }
91
- switch (key) {
92
- case 'geometry':
93
- const datalayer = this.getDataLayerFromID(metadata.layerId)
94
- datalayer.geoJSONToLeaflet({ geometry: value, id: metadata.id, feature })
95
- default:
96
- this.updateObjectValue(feature, key, value)
97
- feature.datalayer.indexProperties(feature)
91
+ if (key === 'geometry') {
92
+ const datalayer = this.getDataLayerFromID(metadata.layerId)
93
+ datalayer.geoJSONToLeaflet({ geometry: value, id: metadata.id, feature })
94
+ } else {
95
+ this.updateObjectValue(feature, key, value)
96
+ feature.datalayer.indexProperties(feature)
98
97
  }
99
98
 
100
99
  feature.render([key])
@@ -103,7 +102,7 @@ export class FeatureUpdater extends BaseUpdater {
103
102
  delete({ metadata }) {
104
103
  // XXX Distinguish between properties getting deleted
105
104
  // and the wole feature getting deleted
106
- let feature = this.getFeatureFromMetadata(metadata)
105
+ const feature = this.getFeatureFromMetadata(metadata)
107
106
  if (feature) feature.del(false)
108
107
  }
109
108
  }
@@ -15,7 +15,7 @@ export class WebSocketTransport {
15
15
  send(kind, payload) {
16
16
  const message = { ...payload }
17
17
  message.kind = kind
18
- let encoded = JSON.stringify(message)
18
+ const encoded = JSON.stringify(message)
19
19
  this.websocket.send(encoded)
20
20
  }
21
21