24 |
24 |
var isAnimationRunning = false
|
25 |
25 |
var data = []
|
26 |
26 |
|
|
27 |
//
|
|
28 |
// info = {
|
|
29 |
// DATASETNAME: {
|
|
30 |
// items: Array,
|
|
31 |
// number: Number,
|
|
32 |
// datasetName: String
|
|
33 |
// }
|
|
34 |
// }
|
|
35 |
//
|
27 |
36 |
var info = []
|
28 |
37 |
let currentInfo = 0
|
29 |
38 |
|
... | ... | |
49 |
58 |
// key: x and y, x + '' + y string
|
50 |
59 |
let globalMarkersChanged = {}
|
51 |
60 |
|
|
61 |
const globalPopup = {
|
|
62 |
coord: {
|
|
63 |
lat: 0,
|
|
64 |
lng: 0
|
|
65 |
},
|
|
66 |
_popup: null
|
|
67 |
}
|
|
68 |
const setGlobalPopupContent = (content) => {
|
|
69 |
globalPopup._popup.setContent(content)
|
|
70 |
globalPopup._popup.openOn(mymap)
|
|
71 |
}
|
|
72 |
const disablePopupControls = () => {
|
|
73 |
$('#previous-info-btn').prop('disabled', true)
|
|
74 |
$('#next-info-btn').prop('disabled', true)
|
|
75 |
$('.popup-controls').hide()
|
|
76 |
}
|
|
77 |
|
|
78 |
const areSameCoord = (first, second) => {
|
|
79 |
return first.lat === second.lat && first.lng === second.lng
|
|
80 |
}
|
|
81 |
|
52 |
82 |
const loadingCallbackNested = (func, delay) => {
|
53 |
83 |
setTimeout(() => {
|
54 |
84 |
func(loading)
|
... | ... | |
128 |
158 |
const genPopUpControlButtons = (currentPage, numPages, onNextClick, onPreviousClick) => ({
|
129 |
159 |
previousButton: '<button id="previous-info-btn" class="circle-button" onclick="previousInfo()"></button>',
|
130 |
160 |
nextButton: '<button id="next-info-btn" class="circle-button next" onclick="nextInfo()"></button>',
|
131 |
|
posInfo: `<div id="count-info">${currentPage} z ${numPages}</div>`
|
|
161 |
posInfo: `<div id="pages">${currentPage} z ${numPages}</div>`
|
132 |
162 |
})
|
133 |
163 |
|
134 |
164 |
const genPopUpControls = (controls) => {
|
... | ... | |
137 |
167 |
|
138 |
168 |
const genMultipleDatasetsPopUp = (sum, currentPos, maxPos, datasetName) => {
|
139 |
169 |
const popupHeader = `<strong id="dataset-info">${datasetName}</strong>`
|
140 |
|
const popupData = `<div id="number-info"><span id="digit-info">${sum}</span></div>`
|
|
170 |
const popupData = `<div id="number-info"><span id="current-number">${sum}</span></div>`
|
141 |
171 |
const { previousButton, nextButton, posInfo } = genPopUpControlButtons(currentPos, maxPos)
|
142 |
172 |
|
143 |
173 |
return `
|
... | ... | |
152 |
182 |
className: className
|
153 |
183 |
}).setLatLng([lat / num, lng / num])
|
154 |
184 |
|
155 |
|
const genPopUp = (datasetName, place, count, sum, currentPos, maxPos) => {
|
|
185 |
const genPopUp = (datasetName, place, currentCount, sum, currentPos, maxPos) => {
|
156 |
186 |
const popupHeader = `
|
157 |
187 |
<strong>${datasetName}</strong>
|
158 |
188 |
<div id="place-info">${place}</div>`
|
159 |
189 |
const popupData = `
|
160 |
190 |
<div id="number-info">
|
161 |
|
<span id="digit-info">${count}</span>
|
162 |
|
<span id="total-info">${(sum && (sum != count)) ? '/' + sum : ''}</span>
|
|
191 |
<span id="current-number">${currentCount}</span>
|
|
192 |
<span id="part-info">${(sum && (sum !== Number(currentCount))) ? '/' + sum : ''}</span>
|
163 |
193 |
</div>`
|
164 |
194 |
const { previousButton, nextButton, posInfo } = genPopUpControlButtons(currentPos, maxPos)
|
165 |
195 |
|
... | ... | |
172 |
202 |
|
173 |
203 |
const onCheckboxClicked = async (checkbox) => {
|
174 |
204 |
if ($(checkbox).prop('checked')) {
|
175 |
|
loadCurrentTimeHeatmap(dataSourceRoute, positionsSourceRoute, 0)
|
176 |
|
changeUrl()
|
|
205 |
await loadCurrentTimeHeatmap(dataSourceRoute, positionsSourceRoute, 0)
|
177 |
206 |
} else {
|
178 |
207 |
loadCheckboxDatasetNameData()
|
179 |
208 |
|
... | ... | |
185 |
214 |
})
|
186 |
215 |
drawHeatmap(data[currentTime])
|
187 |
216 |
})
|
188 |
|
|
189 |
|
changeUrl()
|
190 |
217 |
}
|
|
218 |
updatePopup()
|
|
219 |
changeUrl()
|
191 |
220 |
}
|
192 |
221 |
|
193 |
222 |
const onArrowLeftRightKeysDownRegister = () => {
|
... | ... | |
251 |
280 |
maxZoom: 19
|
252 |
281 |
}).addTo(mymap)
|
253 |
282 |
|
254 |
|
mymap.on('click', showInfo)
|
|
283 |
mymap.on('click', function (e) { showInfo(e) })
|
255 |
284 |
}
|
256 |
285 |
|
257 |
286 |
const getInfoLength = () => {
|
... | ... | |
276 |
305 |
function showInfo (e) {
|
277 |
306 |
info = []
|
278 |
307 |
currentInfo = 0
|
|
308 |
const currentPos = 1
|
279 |
309 |
|
280 |
310 |
// https://wiki.openstreetmap.org/wiki/Zoom_levels
|
281 |
311 |
// Todo change to variable - it is used in heatmap init
|
... | ... | |
289 |
319 |
let total = 0
|
290 |
320 |
|
291 |
321 |
const datasetsInRadius = {}
|
292 |
|
|
|
322 |
const eventCoord = {
|
|
323 |
lng: e.latlng.lng,
|
|
324 |
lat: e.latlng.lat
|
|
325 |
}
|
293 |
326 |
Object.keys(data[currentTime]).forEach((key) => {
|
294 |
327 |
const namedData = data[currentTime][key]
|
295 |
328 |
namedData.items.forEach(element => {
|
... | ... | |
303 |
336 |
}
|
304 |
337 |
})
|
305 |
338 |
})
|
306 |
|
|
307 |
339 |
// Process info for more then one dataset
|
308 |
|
|
309 |
340 |
info = info.reduce((acc, item) => {
|
310 |
341 |
if (!acc[item.datasetName]) {
|
311 |
342 |
acc[item.datasetName] = {
|
... | ... | |
319 |
350 |
acc[item.datasetName].number += Number(item.number)
|
320 |
351 |
return acc
|
321 |
352 |
}, {})
|
322 |
|
|
323 |
353 |
// There is one dataset
|
324 |
354 |
|
325 |
355 |
const numDatasets = Object.keys(datasetsInRadius).length
|
326 |
|
|
327 |
356 |
if (!numDatasets) {
|
|
357 |
if (mymap._popup) {
|
|
358 |
$('#part-info').text('')
|
|
359 |
$('#current-number').html(0)
|
|
360 |
disablePopupControls()
|
|
361 |
}
|
|
362 |
|
328 |
363 |
return
|
329 |
364 |
}
|
330 |
|
|
331 |
365 |
if (numDatasets === 1) {
|
332 |
366 |
const infoDict = getElFromObjectInfo(0)
|
333 |
367 |
const info_ = infoDict.items
|
334 |
368 |
const { place, number } = info_[currentInfo]
|
335 |
|
prepareLayerPopUp(lat, lng, i, `popup-${infoDict.datasetName}`)
|
336 |
|
.setContent(genPopUp(datasetDictNameDisplayName[infoDict.datasetName], place, number, total, currentInfo + 1, info_.length))
|
337 |
|
.openOn(mymap)
|
|
369 |
|
|
370 |
if (!globalPopup._popup || !areSameCoord(globalPopup.coord, eventCoord)) {
|
|
371 |
globalPopup._popup = prepareLayerPopUp(lat, lng, i, `popup-${infoDict.datasetName}`)
|
|
372 |
globalPopup.coord = eventCoord
|
|
373 |
}
|
|
374 |
|
|
375 |
setGlobalPopupContent(genPopUp(datasetDictNameDisplayName[infoDict.datasetName], place, number, total, currentPos, info_.length))
|
338 |
376 |
|
339 |
377 |
if (info_.length === 1) {
|
340 |
|
$('#previous-info-btn').prop('disabled', true)
|
341 |
|
$('#next-info-btn').prop('disabled', true)
|
342 |
|
$('.popup-controls').hide()
|
|
378 |
disablePopupControls()
|
343 |
379 |
}
|
344 |
380 |
} else {
|
345 |
381 |
const { datasetName, number } = getElFromObjectInfo(currentInfo)
|
346 |
382 |
|
347 |
|
prepareLayerPopUp(lat, lng, i, `popup-${datasetName}`)
|
348 |
|
.setContent(genMultipleDatasetsPopUp(number, currentInfo + 1, getInfoLength(), datasetDictNameDisplayName[datasetName]))
|
349 |
|
.openOn(mymap)
|
|
383 |
if (!globalPopup._popup || !areSameCoord(globalPopup.coord, eventCoord)) {
|
|
384 |
globalPopup._popup = prepareLayerPopUp(lat, lng, i, `popup-${datasetName}`)
|
|
385 |
globalPopup.coord = eventCoord
|
|
386 |
}
|
|
387 |
|
|
388 |
setGlobalPopupContent(genMultipleDatasetsPopUp(number, currentPos, getInfoLength(), datasetDictNameDisplayName[datasetName]))
|
350 |
389 |
}
|
351 |
390 |
}
|
352 |
391 |
|
... | ... | |
379 |
418 |
}
|
380 |
419 |
|
381 |
420 |
$('#place-info').html(info_.place ? info_.place : info_.datasetName)
|
382 |
|
$('#digit-info').html(info_.number)
|
383 |
|
$('#count-info').html(currentInfo + 1 + ' z ' + infoLength)
|
|
421 |
$('#current-number').html(info_.number)
|
|
422 |
$('#pages').html(currentInfo + 1 + ' z ' + infoLength)
|
384 |
423 |
|
385 |
424 |
$('.leaflet-popup').removeClass(`popup-${previousInfo.datasetName}`)
|
386 |
425 |
$('.leaflet-popup').addClass(`popup-${info_.datasetName}`)
|
... | ... | |
418 |
457 |
|
419 |
458 |
currentTime = (currentTime + 23) % 24
|
420 |
459 |
changeHour(currentTime)
|
421 |
|
mymap.closePopup()
|
|
460 |
// mymap.closePopup()
|
422 |
461 |
if (!lockedDay && (currentTime === 23)) {
|
423 |
462 |
addDayToCurrentDate(-1)
|
424 |
463 |
await loadCurrentTimeHeatmap(dataSourceRoute, positionsSourceRoute)
|
425 |
464 |
} else {
|
426 |
465 |
drawHeatmap(data[currentTime])
|
427 |
466 |
}
|
|
467 |
updatePopup()
|
428 |
468 |
}
|
429 |
469 |
|
430 |
470 |
async function next () {
|
... | ... | |
434 |
474 |
|
435 |
475 |
currentTime = (currentTime + 1) % 24
|
436 |
476 |
changeHour(currentTime)
|
437 |
|
mymap.closePopup()
|
438 |
477 |
if (!lockedDay && (currentTime === 0)) {
|
439 |
478 |
addDayToCurrentDate(1)
|
440 |
479 |
await loadCurrentTimeHeatmap(dataSourceRoute, positionsSourceRoute)
|
441 |
480 |
} else {
|
442 |
481 |
drawHeatmap(data[currentTime])
|
443 |
482 |
}
|
|
483 |
updatePopup()
|
444 |
484 |
}
|
445 |
485 |
|
446 |
486 |
/**
|
... | ... | |
490 |
530 |
updateHeaderControls()
|
491 |
531 |
setTimeline()
|
492 |
532 |
changeUrl()
|
|
533 |
updatePopup()
|
493 |
534 |
}
|
494 |
535 |
|
|
536 |
const updatePopup = () => {
|
|
537 |
const { _popup } = mymap
|
|
538 |
if (_popup) {
|
|
539 |
showInfo({
|
|
540 |
latlng: _popup.getLatLng()
|
|
541 |
}
|
|
542 |
)
|
|
543 |
}
|
|
544 |
}
|
495 |
545 |
/**
|
496 |
546 |
* Load and display heatmap layer for current data
|
497 |
547 |
* @param {string} opendataRoute route to dataset source
|
... | ... | |
518 |
568 |
})
|
519 |
569 |
|
520 |
570 |
loadingY(loaderDelay)
|
521 |
|
Promise.all(allPromises).then(
|
|
571 |
await Promise.all(allPromises).then(
|
522 |
572 |
() => {
|
523 |
573 |
loadingN(0)
|
524 |
574 |
drawDataSourceMarks(dataSourceMarks)
|
... | ... | |
594 |
644 |
const { x, y, number } = point
|
595 |
645 |
const key = x + '' + y
|
596 |
646 |
const holder = globalMarkersHolder[key]
|
597 |
|
|
598 |
647 |
if (!globalMarkersChanged[key] && number) {
|
599 |
|
// There is data for this marker => unbind popup with zero value
|
|
648 |
// There is data for this marker => unbind popup with zero value
|
600 |
649 |
holder[0] = holder[0].unbindPopup()
|
601 |
650 |
globalMarkersChanged[key] = holder
|
602 |
651 |
}
|
Feature Re #8189 visible and updated popup