From c3a14faf0b7781cad28d9f9f7431b3b6f21b9148 Mon Sep 17 00:00:00 2001 From: Matteo V Date: Mon, 18 Sep 2023 16:39:28 +0200 Subject: [PATCH] Fix #9455 Longitudinal profile fixes (#9456) --- web/client/epics/longitudinalProfile.js | 9 +- .../plugins/LongitudinalProfileTool.jsx | 2 + .../plugins/longitudinalProfile/Menu.jsx | 87 ++++++++++++------- .../plugins/longitudinalProfile/constants.js | 2 + web/client/reducers/longitudinalProfile.js | 3 +- .../__tests__/longitudinalProfile-test.js | 13 ++- web/client/selectors/longitudinalProfile.js | 4 +- web/client/translations/data.fr-FR.json | 20 ++--- 8 files changed, 95 insertions(+), 45 deletions(-) diff --git a/web/client/epics/longitudinalProfile.js b/web/client/epics/longitudinalProfile.js index 852a8dc9c3..1623a80f17 100644 --- a/web/client/epics/longitudinalProfile.js +++ b/web/client/epics/longitudinalProfile.js @@ -76,7 +76,8 @@ import { isDockOpenSelector, isListeningClickSelector, isMaximizedSelector, - isSupportedLayerSelector + isSupportedLayerSelector, + noDataThresholdSelector } from "../selectors/longitudinalProfile"; import {mapSelector} from "../selectors/map"; import { @@ -182,6 +183,7 @@ export const LPonChartPropsChangeEpic = (action$, store) => const referential = configSelector(state)?.referential; const distance = configSelector(state)?.distance; const wpsBody = profileEnLong({identifier, geometry, distance, referential }); + const noDataThreshold = noDataThresholdSelector(state); return executeProcess(wpsurl, wpsBody, {outputsExtractor: makeOutputsExtractor()}) .switchMap((result) => { if (typeof result === "string" && result.includes("ows:ExceptionReport")) { @@ -207,7 +209,8 @@ export const LPonChartPropsChangeEpic = (action$, store) => f, geometry.projection )) : styledFeatures; - return infos && points ? Rx.Observable.from([ + const filteredPoints = points.filter(point => point.altitude < noDataThreshold); + return infos && filteredPoints ? Rx.Observable.from([ updateAdditionalLayer( LONGITUDINAL_VECTOR_LAYER_ID, LONGITUDINAL_OWNER, @@ -238,7 +241,7 @@ export const LPonChartPropsChangeEpic = (action$, store) => visibility: true }), zoomToExtent([minx, minY, maxX, maxY], 'EPSG:4326', 21), - addProfileData(infos, points, geometry.projection) + addProfileData(infos, filteredPoints, geometry.projection) ]) : Rx.Observable.empty(); }) .catch(e => { diff --git a/web/client/plugins/LongitudinalProfileTool.jsx b/web/client/plugins/LongitudinalProfileTool.jsx index 9c70e21e83..ffb72433fe 100644 --- a/web/client/plugins/LongitudinalProfileTool.jsx +++ b/web/client/plugins/LongitudinalProfileTool.jsx @@ -70,6 +70,7 @@ import { createPlugin } from '../utils/PluginsUtils'; * @prop {Object} cfg.config the plugin configuration * @prop {string} cfg.config.wpsurl optional, the geoserver url the the wps endpoint to use. It can be an absolute url. default is "/geoserver/wps". * @prop {string} cfg.config.chartTitle the default title of the chart + * @prop {number} cfg.config.noDataThreshold the number that beyond it will exclude data * @prop {number} cfg.config.defaultDistance the default distance value in meters * @prop {string} cfg.config.identifier the profile to use in the wps request, defaulted to gs:LongitudinalProfile * @prop {string} cfg.config.defaultReferentialName the default referential name @@ -86,6 +87,7 @@ import { createPlugin } from '../utils/PluginsUtils'; * "wpsurl": "/geoserver/wps", * "chartTitle": "Longitudinal profile", * "defaultDistance": 75, + * "noDataThreshold": 999999, * "defaultReferentialName": "sfdem", * "referentials": [{ * "layerName": "sfdem", diff --git a/web/client/plugins/longitudinalProfile/Menu.jsx b/web/client/plugins/longitudinalProfile/Menu.jsx index ebe0234554..1466b87e4e 100644 --- a/web/client/plugins/longitudinalProfile/Menu.jsx +++ b/web/client/plugins/longitudinalProfile/Menu.jsx @@ -5,7 +5,7 @@ * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ -import React, { useCallback } from 'react'; +import React, { useState, useCallback } from 'react'; import PropTypes from 'prop-types'; import {DropdownButton, Glyphicon, MenuItem, NavDropdown} from 'react-bootstrap'; import {connect} from "react-redux"; @@ -34,6 +34,7 @@ const UserMenu = ({ className, dataSourceMode, initialized, + menuItem, isParametersOpen, menuIsActive, nav, @@ -49,36 +50,63 @@ const UserMenu = ({ onActivateTool(); onToggleSourceMode(toolName); }, []); + const [open, setMenuOpen ] = useState(false); - return initialized ? ( - - + {showDrawOption ? + + : null} + + + + + + + + + + + ); + const DropDownMenu = ( setMenuOpen(val)} + id="longitudinal-tool" + className={className} + pullRight + bsStyle={menuIsActive ? "primary" : "tray"} + title={} + tooltipId="longitudinalProfile.title" + tooltipPosition={tooltipPosition} + noCaret + > + {body} + ); - id="longitudinal-tool" - className={className} - pullRight - bsStyle={menuIsActive ? "primary" : "tray"} - title={} - tooltipId="longitudinalProfile.title" - tooltipPosition={tooltipPosition} - noCaret - > - {showDrawOption ? - - : null} - - - - - - - - - - - - - ) : false; + let Menu; + if (menuItem) { + // inside extra tools + Menu = (<> { + open ? <> +
+ +
+ setMenuOpen(!open)}> + + + : + setMenuOpen(!open)}> + + + } + ); + } else { + Menu = DropDownMenu; + } + + return initialized ? Menu : false; }; UserMenu.propTypes = { @@ -87,6 +115,7 @@ UserMenu.propTypes = { initialized: PropTypes.bool, isParametersOpen: PropTypes.bool, menuIsActive: PropTypes.bool, + menuItem: PropTypes.bool, nav: PropTypes.bool, showDrawOption: PropTypes.bool, tooltipPosition: PropTypes.string, diff --git a/web/client/plugins/longitudinalProfile/constants.js b/web/client/plugins/longitudinalProfile/constants.js index e871c19e23..796d5b3d0e 100644 --- a/web/client/plugins/longitudinalProfile/constants.js +++ b/web/client/plugins/longitudinalProfile/constants.js @@ -20,6 +20,8 @@ export const FILE_TYPE_ALLOWED = [ "application/x-zip-compressed", "application/zip" ]; +export const DEFAULT_NODATA_THRESHOLD = 999999; + export const LONGITUDINAL_DISTANCES = [ 1, 5, diff --git a/web/client/reducers/longitudinalProfile.js b/web/client/reducers/longitudinalProfile.js index 073a213225..953d645e27 100644 --- a/web/client/reducers/longitudinalProfile.js +++ b/web/client/reducers/longitudinalProfile.js @@ -19,7 +19,7 @@ import { TOGGLE_MAXIMIZE, TOGGLE_MODE } from "../actions/longitudinalProfile"; -import { LONGITUDINAL_DISTANCES } from '../plugins/longitudinalProfile/constants'; +import { LONGITUDINAL_DISTANCES, DEFAULT_NODATA_THRESHOLD } from '../plugins/longitudinalProfile/constants'; const DEFAULT_STATE = { initialized: false, @@ -107,6 +107,7 @@ export default function longitudinalProfile(state = DEFAULT_STATE, action) { ...state, config: { ...state.config, + noDataThreshold: DEFAULT_NODATA_THRESHOLD, ...action.config } }; diff --git a/web/client/selectors/__tests__/longitudinalProfile-test.js b/web/client/selectors/__tests__/longitudinalProfile-test.js index 0dac205d9b..f5e61ae2b6 100644 --- a/web/client/selectors/__tests__/longitudinalProfile-test.js +++ b/web/client/selectors/__tests__/longitudinalProfile-test.js @@ -11,7 +11,8 @@ import { CONTROL_NAME, CONTROL_DOCK_NAME, CONTROL_PROPERTIES_NAME, - LONGITUDINAL_VECTOR_LAYER_ID + LONGITUDINAL_VECTOR_LAYER_ID, + DEFAULT_NODATA_THRESHOLD } from '../../plugins/longitudinalProfile/constants'; import { @@ -28,6 +29,7 @@ import { pointsSelector, projectionSelector, configSelector, + noDataThresholdSelector, referentialSelector, chartTitleSelector, distanceSelector, @@ -176,6 +178,15 @@ describe('Test longitudinalProfile selectors', () => { }; expect(referentialSelector({longitudinalProfile})).toEqual(""); }); + it('noDataThresholdSelector', () => { + expect(noDataThresholdSelector({longitudinalProfile: { + config: {noDataThreshold: 1234} + }})).toEqual(1234); + + expect(noDataThresholdSelector({longitudinalProfile: { + config: {} + }})).toEqual(DEFAULT_NODATA_THRESHOLD); + }); it('chartTitleSelector', () => { const longitudinalProfile = { config: {chartTitle: ""} diff --git a/web/client/selectors/longitudinalProfile.js b/web/client/selectors/longitudinalProfile.js index 2f9951176e..8b8c50bddc 100644 --- a/web/client/selectors/longitudinalProfile.js +++ b/web/client/selectors/longitudinalProfile.js @@ -12,7 +12,8 @@ import { CONTROL_NAME, CONTROL_PROPERTIES_NAME, LONGITUDINAL_VECTOR_LAYER_ID, - LONGITUDINAL_VECTOR_LAYER_ID_POINT + LONGITUDINAL_VECTOR_LAYER_ID_POINT, + DEFAULT_NODATA_THRESHOLD } from '../plugins/longitudinalProfile/constants'; import {additionalLayersSelector} from '../selectors/additionallayers'; import {getSelectedLayer} from "../selectors/layers"; @@ -38,6 +39,7 @@ export const infosSelector = (state) => state?.longitudinalProfile?.infos; export const pointsSelector = (state) => state?.longitudinalProfile?.points; export const projectionSelector = (state) => state?.longitudinalProfile?.projection; export const configSelector = (state) => state?.longitudinalProfile?.config; +export const noDataThresholdSelector = (state) => configSelector(state)?.noDataThreshold || DEFAULT_NODATA_THRESHOLD; export const referentialSelector = (state) => configSelector(state)?.referential; export const chartTitleSelector = (state) => configSelector(state)?.chartTitle; export const distanceSelector = (state) => configSelector(state)?.distance; diff --git a/web/client/translations/data.fr-FR.json b/web/client/translations/data.fr-FR.json index 9ef8c3b135..ab5841123d 100644 --- a/web/client/translations/data.fr-FR.json +++ b/web/client/translations/data.fr-FR.json @@ -426,9 +426,9 @@ "noMapAvailable": "Aucune carte disponible", "createNewOne": "Créer une nouvelle carte", "unsavedMapConfirmTitle": "Modifications non enregistrées", - "unsavedMapConfirmMessage": "Êtes-vous sûr de vouloir laisser des modifications non enregistrées ?", - "unsavedMapConfirmButtonText": "Laisser", - "unsavedMapCancelButtonText": "Fermer" + "unsavedMapConfirmMessage": "Êtes-vous sûr de vouloir quitter la carte sans enregistrer les modifications ?", + "unsavedMapConfirmButtonText": "Quitter sans enregistrer", + "unsavedMapCancelButtonText": "Annuler" }, "geostories": { "newGeostory": "Nouvelle GeoStory", @@ -2899,7 +2899,7 @@ "cancel": "Annuler", "saveSuccessTitle": "Succès", "saveSuccessMessage": "Enregistré avec succès", - "saveTooltip": "Salvar", + "saveTooltip": "Enregistrer", "saveAsTooltip": "Enregistrer sous" }, "mapEditor": { @@ -2923,7 +2923,7 @@ "selectService": "Sélectionner un service", "add": "Ajouter", "back": "Retour", - "save": "Salvar", + "save": "Enregistrer", "edit": "Modifier", "sourcePlaceholder": "Entrer une source", "source": "Source", @@ -3818,7 +3818,7 @@ "infos": "Information", "preferences": "Préférences", "CRS": "CRS", - "uom": "Unités de mesure", + "uom": "Unité de mesure", "fileSelected": "Fichier sélectionné: ", "uomMeters": "mètres", "source": "Source", @@ -3826,11 +3826,11 @@ "downloadPNG": "PNG", "downloadPDF": "PDF", "info": { - "points": " points:", + "points": " points", "totalPoints": "Nombre de points traités:", - "layer":"Layer:", + "layer":"Couche:", "line":"Distance:", - "up":"Gain d'altitude cumulé.", + "up":"Gain d'altitude cumulé:", "down":"Perte d'altitude cumulée:", "noInfos": "Aucune information disponible" }, @@ -3851,7 +3851,7 @@ "outsideCoverage": "La ligne fournie est en dehors de la couverture du profil", "loadingError": "Erreur lors du chargement des données pour le profil longitudinal", "unableToSetupPlugin": "Impossible de configurer l'extension du profil longitudinal.", - "defaultReferentialNotFound": "Le référentiel par défaut est configuré mais introuvable dans la liste des référentiels. Veuillez mettre à jour la configuration de l'extension.", + "defaultReferentialNotFound": "Le référentiel par défaut est configuré mais introuvable dans la liste des référentiels. Veuillez mettre à jour la configuration de l'extension Profil en long.", "projectionNotSupported": "Le référentiel avec projection prise en charge par la carte est introuvable. Veuillez mettre à jour la configuration de l'extension ou ajouter la projection souhaitée dans la configuration de l'application.", "cannotDownloadPDF": "Il n'est pas possible d'imprimer la carte actuelle car elle contient des références à un domaine externe, veuillez les supprimer, enregistrer la carte, actualiser la page et réessayer.", "cannotDownloadPNG": "Impossible de télécharger le graphique en tant qu'image."