From 400440c1627de7494129af7e2aaed34c91998906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCnzi?= Date: Tue, 25 Jun 2024 10:46:54 +0200 Subject: [PATCH 1/2] PB-186: pre processing tool for URL parameters Issue : some parameters needed to be handled in a special way before we load the map viewer, and this pre-processing happened within the legacy router. This worked fine, but this was not the place to handle it. Fix : we now have an additional router, called only once between the legacy view and the map view, which handles the pre-processing of parameters. We ensure this pre processor wait for the legacy parser to finish its work before applying its own changes. For now, the only parameter with a special process is the 3d, for which we ensure we have the correct spatial reference. --- src/router/index.js | 3 + .../legacyPermalinkManagement.routerPlugin.js | 10 --- .../parametersPreProcess.routerPlugin.js | 86 +++++++++++++++++++ 3 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/router/parametersPreProcess.routerPlugin.js diff --git a/src/router/index.js b/src/router/index.js index cca7720d8..495fac5b1 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -17,6 +17,8 @@ import EmbedView from '@/views/EmbedView.vue' import LegacyParamsView from '@/views/LegacyParamsView.vue' import MapView from '@/views/MapView.vue' +import parametersPreProcessRouterPlugin from './parametersPreProcess.routerPlugin' + const history = createWebHashHistory() /** @@ -76,6 +78,7 @@ router.onError((error) => { appLoadingManagementRouterPlugin(router, store) legacyPermalinkManagementRouterPlugin(router, store) +parametersPreProcessRouterPlugin(router, store) storeSyncRouterPlugin(router, store) // exposing the router to Cypress, so that we may change URL param on the fly (without app reload), diff --git a/src/router/legacyPermalinkManagement.routerPlugin.js b/src/router/legacyPermalinkManagement.routerPlugin.js index acfbfc65e..c91936e4a 100644 --- a/src/router/legacyPermalinkManagement.routerPlugin.js +++ b/src/router/legacyPermalinkManagement.routerPlugin.js @@ -129,16 +129,6 @@ const handleLegacyParam = ( // they're not called multiple times for nothing break - case '3d': - // if the 3d flag is given without being placed behind the hash (meaning at startup), - // we need to make sure the projection is set to Mercator, otherwise the startup sequence - // ends up not working properly and center the view wrongly - if ((typeof legacyValue === 'string' && legacyValue === 'true') || legacyValue) { - newQuery['sr'] = WEBMERCATOR.epsgNumber - } - newValue = legacyValue - break - case 'elevation': cameraPosition[2] = Number(legacyValue) break diff --git a/src/router/parametersPreProcess.routerPlugin.js b/src/router/parametersPreProcess.routerPlugin.js new file mode 100644 index 000000000..23c05055e --- /dev/null +++ b/src/router/parametersPreProcess.routerPlugin.js @@ -0,0 +1,86 @@ +import { MAP_VIEWS } from '@/router/viewNames' +import { WEBMERCATOR } from '@/utils/coordinates/coordinateSystems' +import log from '@/utils/logging' +import { isNumber } from '@/utils/numberUtils' + +/** + * @param {String} param_name + * @param {any} param_value + * @param {Object} newQuery The modified query for the router + */ +const preProcessParam = (param_name, param_value, query) => { + switch (param_name) { + case '3d': + // if the 3d flag is set, we need to ensure that we are in the webmercator projection + if ( + ((typeof param_value === 'boolean' && param_value) || + param_value === 'true' || + param_value === null) && + (!isNumber(query.sr) || Number(query.sr) !== WEBMERCATOR.epsgNumber) + ) { + log.info( + `[URL Param pre process] 3d parameter found. Ensuring spatial reference system is set to web mercator` + ) + query['sr'] = WEBMERCATOR.epsgNumber + } + break + default: + break + } +} + +const handleParams = async (query) => { + // if so, we transfer all old param (stored before vue-router's /#) and transfer them to the MapView + // we will also transform legacy zoom level here (see comment below) + const newQuery = structuredClone(query) + for (const [param_name, param_value] of Object.entries(query)) { + preProcessParam(param_name, param_value, newQuery) + } + return { + query: newQuery, + replace: true, + } +} + +/** + * Go through all params that need pre-processing before being handed to the map view. + * + * For example : 3d needs the projection to be web mercator to work. + * + * @param {Router} router + * @param {Store} store + */ +const parametersPreProcessRouterPlugin = (router, store) => { + let wentThrough = false + const unsubscribeRouter = router.beforeEach(async (to) => { + if (MAP_VIEWS.includes(to.name)) { + if (!wentThrough && store.state.app.isReady) { + // We process the parameters once we are ready to enter the mapview. This means the legacy + // router has finished his job. + log.info( + `[URL Param Pre Process] : handling all parameters that require pre processing` + ) + const newRoute = await handleParams(to.query) + log.info(`[URL Param Pre Process] redirect to the converted params`, newRoute) + log.debug( + `[URL Param Pre Process]: finished pre processing, preparing to deactivate the router.` + ) + newRoute.name = to.name + wentThrough = true + return newRoute + } + + if (wentThrough && store.state.app.isReady) { + log.info('[URL Param Pre Process] Work is done, deactivating the router') + unsubscribeRouter() + + log.debug('[URL Param Pre Process] exiting the parameter pre processor.') + return true + } + return undefined + } + return undefined + }) +} + +export default parametersPreProcessRouterPlugin From 7864ef7400b35d0c0ff4701a8907a072c9b8fb08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCnzi?= Date: Thu, 27 Jun 2024 16:21:10 +0200 Subject: [PATCH 2/2] PB-186: removing pre processor plugin The 3d / 2d switch is handled by the 2d-to-3d-management plugin, and 3d at startup works out of the box. We don't need an extra router to handle this case. --- src/router/index.js | 3 - .../parametersPreProcess.routerPlugin.js | 86 ------------------- 2 files changed, 89 deletions(-) delete mode 100644 src/router/parametersPreProcess.routerPlugin.js diff --git a/src/router/index.js b/src/router/index.js index 495fac5b1..cca7720d8 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -17,8 +17,6 @@ import EmbedView from '@/views/EmbedView.vue' import LegacyParamsView from '@/views/LegacyParamsView.vue' import MapView from '@/views/MapView.vue' -import parametersPreProcessRouterPlugin from './parametersPreProcess.routerPlugin' - const history = createWebHashHistory() /** @@ -78,7 +76,6 @@ router.onError((error) => { appLoadingManagementRouterPlugin(router, store) legacyPermalinkManagementRouterPlugin(router, store) -parametersPreProcessRouterPlugin(router, store) storeSyncRouterPlugin(router, store) // exposing the router to Cypress, so that we may change URL param on the fly (without app reload), diff --git a/src/router/parametersPreProcess.routerPlugin.js b/src/router/parametersPreProcess.routerPlugin.js deleted file mode 100644 index 23c05055e..000000000 --- a/src/router/parametersPreProcess.routerPlugin.js +++ /dev/null @@ -1,86 +0,0 @@ -import { MAP_VIEWS } from '@/router/viewNames' -import { WEBMERCATOR } from '@/utils/coordinates/coordinateSystems' -import log from '@/utils/logging' -import { isNumber } from '@/utils/numberUtils' - -/** - * @param {String} param_name - * @param {any} param_value - * @param {Object} newQuery The modified query for the router - */ -const preProcessParam = (param_name, param_value, query) => { - switch (param_name) { - case '3d': - // if the 3d flag is set, we need to ensure that we are in the webmercator projection - if ( - ((typeof param_value === 'boolean' && param_value) || - param_value === 'true' || - param_value === null) && - (!isNumber(query.sr) || Number(query.sr) !== WEBMERCATOR.epsgNumber) - ) { - log.info( - `[URL Param pre process] 3d parameter found. Ensuring spatial reference system is set to web mercator` - ) - query['sr'] = WEBMERCATOR.epsgNumber - } - break - default: - break - } -} - -const handleParams = async (query) => { - // if so, we transfer all old param (stored before vue-router's /#) and transfer them to the MapView - // we will also transform legacy zoom level here (see comment below) - const newQuery = structuredClone(query) - for (const [param_name, param_value] of Object.entries(query)) { - preProcessParam(param_name, param_value, newQuery) - } - return { - query: newQuery, - replace: true, - } -} - -/** - * Go through all params that need pre-processing before being handed to the map view. - * - * For example : 3d needs the projection to be web mercator to work. - * - * @param {Router} router - * @param {Store} store - */ -const parametersPreProcessRouterPlugin = (router, store) => { - let wentThrough = false - const unsubscribeRouter = router.beforeEach(async (to) => { - if (MAP_VIEWS.includes(to.name)) { - if (!wentThrough && store.state.app.isReady) { - // We process the parameters once we are ready to enter the mapview. This means the legacy - // router has finished his job. - log.info( - `[URL Param Pre Process] : handling all parameters that require pre processing` - ) - const newRoute = await handleParams(to.query) - log.info(`[URL Param Pre Process] redirect to the converted params`, newRoute) - log.debug( - `[URL Param Pre Process]: finished pre processing, preparing to deactivate the router.` - ) - newRoute.name = to.name - wentThrough = true - return newRoute - } - - if (wentThrough && store.state.app.isReady) { - log.info('[URL Param Pre Process] Work is done, deactivating the router') - unsubscribeRouter() - - log.debug('[URL Param Pre Process] exiting the parameter pre processor.') - return true - } - return undefined - } - return undefined - }) -} - -export default parametersPreProcessRouterPlugin