From 0503b9d06317e799f749412694be5ec2c0548bea Mon Sep 17 00:00:00 2001 From: Tariq Soliman Date: Thu, 26 Sep 2024 13:39:43 -0700 Subject: [PATCH] #587 Raster and Vector Refresh Intervals --- .../src/metaconfigs/layer-data-config.json | 20 ----- .../src/metaconfigs/layer-model-config.json | 20 ----- .../src/metaconfigs/layer-query-config.json | 20 ----- src/essence/Ancillary/TimeControl.js | 50 ++++++++++-- src/essence/Basics/Layers_/Layers_.js | 50 ++++++------ src/essence/Basics/Map_/Map_.js | 14 +++- src/essence/Tools/Layers/LayersTool.css | 15 +++- src/essence/Tools/Layers/LayersTool.js | 78 ++++++++++++------- 8 files changed, 139 insertions(+), 128 deletions(-) diff --git a/configure/src/metaconfigs/layer-data-config.json b/configure/src/metaconfigs/layer-data-config.json index 3d6714ce..1f8ecf1d 100644 --- a/configure/src/metaconfigs/layer-data-config.json +++ b/configure/src/metaconfigs/layer-data-config.json @@ -369,26 +369,6 @@ "defaultChecked": false } ] - }, - { - "components": [ - { - "field": "time.refreshIntervalEnabled", - "name": "Refresh Interval Enabled", - "description": "If 'Time Enabled' and 'Refresh Interval Enabled', this layer will automatically refresh/requery its data every 'Refresh Every N Seconds'. This is useful when the layer's data updates at some uniform cadence. Be aware that this may be an expensive operation depending on the amount of data a layer needs and the number of layers that have this enabled.", - "type": "switch", - "width": 5, - "defaultChecked": false - }, - { - "field": "time.refreshIntervalAmount", - "name": "Refresh Every N Seconds", - "description": "If 'Time Enabled' and 'Refresh Interval Enabled', this layer will automatically refresh/requery its data every n seconds.", - "type": "number", - "min": 1, - "width": 3 - } - ] } ] }, diff --git a/configure/src/metaconfigs/layer-model-config.json b/configure/src/metaconfigs/layer-model-config.json index 9224fa96..7726b6f9 100644 --- a/configure/src/metaconfigs/layer-model-config.json +++ b/configure/src/metaconfigs/layer-model-config.json @@ -408,26 +408,6 @@ "width": 6 } ] - }, - { - "components": [ - { - "field": "time.refreshIntervalEnabled", - "name": "Refresh Interval Enabled", - "description": "If 'Time Enabled' and 'Refresh Interval Enabled', this layer will automatically refresh/requery its data every 'Refresh Every N Seconds'. This is useful when the layer's data updates at some uniform cadence. Be aware that this may be an expensive operation depending on the amount of data a layer needs and the number of layers that have this enabled.", - "type": "switch", - "width": 5, - "defaultChecked": false - }, - { - "field": "time.refreshIntervalAmount", - "name": "Refresh Every N Seconds", - "description": "If 'Time Enabled' and 'Refresh Interval Enabled', this layer will automatically refresh/requery its data every n seconds.", - "type": "number", - "min": 1, - "width": 3 - } - ] } ] }, diff --git a/configure/src/metaconfigs/layer-query-config.json b/configure/src/metaconfigs/layer-query-config.json index 3b5d862c..bd347abb 100644 --- a/configure/src/metaconfigs/layer-query-config.json +++ b/configure/src/metaconfigs/layer-query-config.json @@ -531,26 +531,6 @@ "width": 6 } ] - }, - { - "components": [ - { - "field": "time.refreshIntervalEnabled", - "name": "Refresh Interval Enabled", - "description": "If 'Time Enabled' and 'Refresh Interval Enabled', this layer will automatically refresh/requery its data every 'Refresh Every N Seconds'. This is useful when the layer's data updates at some uniform cadence. Be aware that this may be an expensive operation depending on the amount of data a layer needs and the number of layers that have this enabled.", - "type": "switch", - "width": 5, - "defaultChecked": false - }, - { - "field": "time.refreshIntervalAmount", - "name": "Refresh Every N Seconds", - "description": "If 'Time Enabled' and 'Refresh Interval Enabled', this layer will automatically refresh/requery its data every n seconds.", - "type": "number", - "min": 1, - "width": 3 - } - ] } ] }, diff --git a/src/essence/Ancillary/TimeControl.js b/src/essence/Ancillary/TimeControl.js index a1d7752b..35f12466 100644 --- a/src/essence/Ancillary/TimeControl.js +++ b/src/essence/Ancillary/TimeControl.js @@ -184,7 +184,8 @@ var TimeControl = { layer, evenIfOff, evenIfControlled, - forceRequery + forceRequery, + skipOrderedBringToFront ) { // reload layer if (typeof layer == 'string') { @@ -204,7 +205,8 @@ var TimeControl = { layer.url = await TimeControl.performTimeUrlReplacements( layer.url, - layer + layer, + forceRequery ) let changedUrl = null if (layer.url !== originalUrl) changedUrl = layer.url @@ -269,11 +271,38 @@ var TimeControl = { // refresh map if (evenIfControlled === true || layer.controlled !== true) if (L_.layers.on[layer.name] || evenIfOff) { - return await Map_.refreshLayer(layer, () => { - // put start/endtime keywords back - if (layer.time && layer.time.enabled === true) - layer.url = originalUrl - }) + return await Map_.refreshLayer( + layer, + () => { + if (layer.time && layer.time.enabled === true) { + // put start/endtime keywords back + layer.url = originalUrl + + // if requery was force, remember to timeFilter after load + if ( + layer.type === 'vector' && + layer.time.type === 'local' && + layer.time.endProp != null && + forceRequery === true + ) { + if ( + evenIfControlled === true || + layer.controlled !== true + ) + L_.timeFilterVectorLayer( + layer.name, + new Date( + layer.time.start + ).getTime(), + new Date( + layer.time.end + ).getTime() + ) + } + } + }, + skipOrderedBringToFront + ) } } } @@ -281,7 +310,7 @@ var TimeControl = { if (layer.time && layer.time.enabled === true) layer.url = originalUrl return true }, - performTimeUrlReplacements: async function (url, layer) { + performTimeUrlReplacements: async function (url, layer, forceRequery) { return new Promise(async (resolve, reject) => { let layerTimeFormat = layer.time?.format == null @@ -322,6 +351,11 @@ var TimeControl = { } } } + if (forceRequery === true) { + nextUrl += `${ + nextUrl.indexOf('?') === -1 ? '?' : '&' + }nocache=${new Date().getTime()}` + } resolve(nextUrl) }) }, diff --git a/src/essence/Basics/Layers_/Layers_.js b/src/essence/Basics/Layers_/Layers_.js index 07d82592..851cbf2f 100644 --- a/src/essence/Basics/Layers_/Layers_.js +++ b/src/essence/Basics/Layers_/Layers_.js @@ -245,7 +245,7 @@ const L_ = { //Takes in config layer obj //Toggles a layer on and off and accounts for sublayers //Takes in a config layer object - toggleLayer: async function (s) { + toggleLayer: async function (s, skipOrderedBringToFront) { if (s == null) return const wasNeverOn = L_.layers.layer[s.name] === false @@ -254,7 +254,7 @@ const L_ = { if (L_.layers.on[s.name] === true) on = true else on = false - await L_.toggleLayerHelper(s, on) + await L_.toggleLayerHelper(s, on, null, null, skipOrderedBringToFront) Object.keys(L_._onLayerToggleSubscriptions).forEach((k) => { L_._onLayerToggleSubscriptions[k](s.name, !on) @@ -292,7 +292,8 @@ const L_ = { s, on, ignoreToggleStateChange, - globeOnly + globeOnly, + skipOrderedBringToFront ) { if (s.type !== 'header') { if (on) { @@ -303,7 +304,7 @@ const L_ = { try { $('.drawToolContextMenuHeaderClose').click() } catch (err) {} - L_.Map_.map.removeLayer(L_.layers.layer[s.name]) + L_.Map_.rmNotNull(L_.layers.layer[s.name]) if (L_.layers.attachments[s.name]) { for (let sub in L_.layers.attachments[s.name]) { switch (L_.layers.attachments[s.name][sub].type) { @@ -588,7 +589,11 @@ const L_ = { if (s.type === 'vector') L_._updatePairings(s.name, !on) - if (!on && s.type === 'vector') { + if ( + !on && + s.type === 'vector' && + skipOrderedBringToFront !== true + ) { L_.Map_.orderedBringToFront() } L_._refreshAnnotationEvents() @@ -1639,6 +1644,10 @@ const L_ = { } } L_.layers.opacity[name] = newOpacity + + if (L_.activeFeature?.layer && L_.activeFeature.layerName === name) { + L_.highlight(L_.activeFeature.layer) + } }, getLayerOpacity: function (name) { var l = L_.layers.layer[name] @@ -3540,13 +3549,6 @@ function parseConfig(configData, urlOnLayers) { L_.layers.refreshIntervals[d[i].name] = setInterval( async () => { if (L_.layers.on[d[i].name] === true) { - console.log( - JSON.stringify( - L_.activeFeature - ? L_.activeFeature.layerName - : '' - ) - ) let savedActiveFeature if ( L_.activeFeature && @@ -3563,24 +3565,22 @@ function parseConfig(configData, urlOnLayers) { d[i].name, false, false, + true, true ) // Reselect activeFeature - - setTimeout(() => { - if ( - savedActiveFeature && - savedActiveFeature.layerName === d[i].name - ) { - L_.selectFeature( - savedActiveFeature.layerName, - savedActiveFeature.feature - ) - } - }, 800) + if ( + savedActiveFeature && + savedActiveFeature.layerName === d[i].name + ) { + L_.selectFeature( + savedActiveFeature.layerName, + savedActiveFeature.feature + ) + } } }, - d[i].time.refreshIntervalAmount * 1000 + (d[i].time.refreshIntervalAmount || 30) * 1000 ) } //Save the prevName for easy tracing back diff --git a/src/essence/Basics/Map_/Map_.js b/src/essence/Basics/Map_/Map_.js index 9caf994b..5e5e7dd4 100644 --- a/src/essence/Basics/Map_/Map_.js +++ b/src/essence/Basics/Map_/Map_.js @@ -311,7 +311,7 @@ let Map_ = { removeTempTileLayer: function () { this.rmNotNull(this.tempTileLayer) }, - //Removes the map layer if it isnt null + //Removes the map layer if it isn't null rmNotNull: function (layer) { if (layer != null) { this.map.removeLayer(layer) @@ -395,7 +395,7 @@ let Map_ = { ) } }, - refreshLayer: async function (layerObj, cb) { + refreshLayer: async function (layerObj, cb, skipOrderedBringToFront) { // We need to find and remove all points on the map that belong to the layer // Not sure if there is a cleaner way of doing this for (var i = L_._layersOrdered.length - 1; i >= 0; i--) { @@ -407,7 +407,10 @@ let Map_ = { if (L_._layersBeingMade[layerObj.name] !== true) { const wasOn = L_.layers.on[layerObj.name] if (wasOn) - await L_.toggleLayer(L_.layers.data[layerObj.name]) // turn off if on + L_.toggleLayer( + L_.layers.data[layerObj.name], + skipOrderedBringToFront + ) // turn off if on // fake on L_.layers.on[layerObj.name] = true await makeLayer(layerObj, true, null) @@ -415,7 +418,10 @@ let Map_ = { // turn off if was off if (wasOn) L_.layers.on[layerObj.name] = false - await L_.toggleLayer(L_.layers.data[layerObj.name]) // turn back on/off + L_.toggleLayer( + L_.layers.data[layerObj.name], + skipOrderedBringToFront + ) // turn back on/off L_.enforceVisibilityCutoffs() } else { diff --git a/src/essence/Tools/Layers/LayersTool.css b/src/essence/Tools/Layers/LayersTool.css index d560fab0..f344242c 100644 --- a/src/essence/Tools/Layers/LayersTool.css +++ b/src/essence/Tools/Layers/LayersTool.css @@ -202,6 +202,17 @@ padding: 0; margin: 0; } +#layersTool .settings .layerTimeTitle { + display: flex; + height: 30px; + line-height: 30px; +} +#layersTool .settings .layerTimeTitle > div:first-child { + color: var(--color-h); + text-transform: uppercase; + font-size: 12px; +} + #layersTool .settings .layerSettingsTitle { display: flex; height: 30px; @@ -213,7 +224,6 @@ font-size: 12px; } #layersTool .settings .layerSettingsTitle > div:last-child { - } #layersTool .settings ul > li { line-height: 30px; @@ -620,7 +630,6 @@ } } - .layersToolExport { cursor: default; height: unset !important; @@ -674,4 +683,4 @@ } .layersToolExportGo:hover { background-color: var(--color-a1-5); -} \ No newline at end of file +} diff --git a/src/essence/Tools/Layers/LayersTool.js b/src/essence/Tools/Layers/LayersTool.js index e5eba40c..ebdfdaad 100644 --- a/src/essence/Tools/Layers/LayersTool.js +++ b/src/essence/Tools/Layers/LayersTool.js @@ -304,20 +304,22 @@ function interfaceWithMMGIS(fromInit) { case 'tile': layerExport = '' // Add download URL for raster layers - if(node[i].hasOwnProperty('variables')) { - if(node[i].variables.hasOwnProperty('downloadURL')) { + if (node[i].hasOwnProperty('variables')) { + if (node[i].variables.hasOwnProperty('downloadURL')) { layerExport = [ '', ].join('\n') } } - break + break default: layerExport = '' } @@ -326,28 +328,48 @@ function interfaceWithMMGIS(fromInit) { var timeDisplay = '' if (node[i].time != null) { if (node[i].time.enabled == true) { + // prettier-ignore timeDisplay = [ '', ].join('\n') }