From fa4b90fdc077f2023b5e89dd08deabea58f6e106 Mon Sep 17 00:00:00 2001 From: Phil Owen <19691521+PhillipsOwen@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:10:16 -0400 Subject: [PATCH] adding a check to do nothing if the point was already selected --- src/components/map/adcirc-raster-layer.js | 170 ++++++++++++---------- 1 file changed, 92 insertions(+), 78 deletions(-) diff --git a/src/components/map/adcirc-raster-layer.js b/src/components/map/adcirc-raster-layer.js index 8bd15ad..8d5d07e 100644 --- a/src/components/map/adcirc-raster-layer.js +++ b/src/components/map/adcirc-raster-layer.js @@ -1,8 +1,8 @@ -import React, { useEffect, useMemo, useState, useCallback } from 'react'; -import { WMSTileLayer, useMap, useMapEvent } from 'react-leaflet'; +import React, {useEffect, useMemo, useState, useCallback} from 'react'; +import {WMSTileLayer, useMap, useMapEvent} from 'react-leaflet'; import SldStyleParser from 'geostyler-sld-parser'; -import { getNamespacedEnvParam, markClicked, restoreColorMapType } from '@utils/map-utils'; -import { useLayers, useSettings } from '@context'; +import {getNamespacedEnvParam, markClicked, restoreColorMapType} from '@utils/map-utils'; +import {useLayers, useSettings} from '@context'; const MAXELE = 'maxele'; const MAXWVEL = 'maxwvel'; @@ -10,7 +10,7 @@ const SWAN = 'swan'; export const AdcircRasterLayer = (layer) => { const sldParser = new SldStyleParser(); - const gs_wfs_url = `${ getNamespacedEnvParam('REACT_APP_GS_DATA_URL') }`; + const gs_wfs_url = `${getNamespacedEnvParam('REACT_APP_GS_DATA_URL')}`; const gs_wms_url = gs_wfs_url + 'wms'; const { @@ -22,18 +22,18 @@ export const AdcircRasterLayer = (layer) => { const [productType, setProductType] = useState(""); useEffect(() => { - if(layer.layer.properties) { + if (layer.layer.properties) { let style = ""; - switch(layer.layer.properties.product_type) { - case ("maxwvel63"): - style = mapStyle.maxwvel.current; - break; - case ("swan_HS_max63"): - style = mapStyle.swan.current; - break; - default: - style = mapStyle.maxele.current; - break; + switch (layer.layer.properties.product_type) { + case ("maxwvel63"): + style = mapStyle.maxwvel.current; + break; + case ("swan_HS_max63"): + style = mapStyle.swan.current; + break; + default: + style = mapStyle.maxele.current; + break; } sldParser @@ -42,29 +42,28 @@ export const AdcircRasterLayer = (layer) => { geostylerStyle.output.name = (' ' + layer.layer.layers).slice(1); const colorMapType = geostylerStyle.output.rules[0].symbolizers[0].colorMap.type; sldParser.writeStyle(geostylerStyle.output) - .then((sldStyle) => { - const updatedStyle = restoreColorMapType(colorMapType, sldStyle.output); - setCurrentStyle(updatedStyle); - }); - }); + .then((sldStyle) => { + const updatedStyle = restoreColorMapType(colorMapType, sldStyle.output); + setCurrentStyle(updatedStyle); + }); + }); } }, [mapStyle]); useEffect(() => { // get current product layer in order to set opacity - if (layer.layer.properties.product_type.includes(MAXWVEL)) + if (layer.layer.properties.product_type.includes(MAXWVEL)) setProductType(MAXWVEL); - else - if (layer.layer.properties.product_type.includes(SWAN)) + else if (layer.layer.properties.product_type.includes(SWAN)) setProductType(SWAN); else - setProductType(MAXELE); + setProductType(MAXELE); }, [layerOpacity]); - + // get the observation points selected, default layers and alert message from state const { - setSelectedObservations, + selectedObservations, setSelectedObservations, defaultModelLayers, setAlertMsg, } = useLayers(); @@ -78,63 +77,78 @@ export const AdcircRasterLayer = (layer) => { // create a list of worthy geo-point layer types const validLayerTypes = new Set(['Maximum Water Level', 'Maximum Significant Wave Height']); + /** + * determines if the point was already selected + * + * @param id + */ + const isAlreadySelected = (id) => { + // return true if the point was already selected + return (selectedObservations.find((o) => o.id === id) !== undefined); + }; + // create a callback to handle a map click event const onClick = useCallback((e) => { // get the visible layer on the map const layer = layers.find((layer) => layer.properties['product_type'] !== "obs" && layer.state.visible === true); - // if this is a layer we can geo-point on - if (validLayerTypes.has(layer.properties['product_name'])) { - // round the coordinates - const lon = Number(e.latlng.lng).toFixed(5); - const lat = Number(e.latlng.lat).toFixed(5); - - // create an id for the point - const id = lon + ', ' + lat; - - // create a marker target icon around the observation clicked - markClicked(map, e, id); - - // get the FQDN of the UI data server - const data_url = `${getNamespacedEnvParam('REACT_APP_UI_DATA_URL')}`; - - // create the correct TDS URL without the hostname - const tds_url = layer.properties['tds_download_url'].replace('catalog', 'dodsC').replace('catalog.html', (layer.id.indexOf('swan') < 0 ? - 'fort' : 'swan_HS') + '.63.nc').split('/thredds')[1]; - - // get the hostname - const tds_svr = layer.properties['tds_download_url'].split('https://')[1].split('/thredds')[0].split('.')[0]; - - // generate the full url - const fullTDSURL = data_url + "get_geo_point_data?lon=" + e.latlng.lng + "&lat=" + e.latlng.lat + "&ensemble=nowcast&url=" + - tds_url + '&tds_svr=' + tds_svr; - - const l_props = layer.properties; - - // create a set of properties for this object - const pointProps = - { - "station_name": l_props['product_name'] + " " + id, - "lat": lat, - "lon": lon, - "location_name": l_props['product_name'] + "s over time (lon, lat): " + id, - "model_run_id": layer.group, - "data_source": (l_props['event_type'] + '_' + l_props['grid_type']).toUpperCase(), - "source_name": l_props['model'], - "source_instance": l_props['instance_name'], - "source_archive": l_props['location'], - "forcing_metclass": l_props['met_class'], - "location_type": "GeoPoint", - "grid_name": l_props['grid_type'].toUpperCase(), - "csvurl": fullTDSURL, - "id": id - }; - - // populate selectedObservations list with the newly selected observation point - setSelectedObservations(previous => [...previous, pointProps]); + // round the coordinates + const lon = Number(e.latlng.lng).toFixed(5); + const lat = Number(e.latlng.lat).toFixed(5); + + // create an id for the point + const id = lon + ', ' + lat; + + // if the point selected is new + if (!isAlreadySelected(id)) { + // if this is a layer we can geo-point on + if (validLayerTypes.has(layer.properties['product_name'])) { + // create a marker target icon around the observation clicked + markClicked(map, e, id); + + // get the FQDN of the UI data server + const data_url = `${getNamespacedEnvParam('REACT_APP_UI_DATA_URL')}`; + + // create the correct TDS URL without the hostname + const tds_url = layer.properties['tds_download_url'].replace('catalog', 'dodsC').replace('catalog.html', + (layer.id.indexOf('swan') < 0 ? 'fort' : 'swan_HS') + '.63.nc').split('/thredds')[1]; + + // get the hostname + const tds_svr = layer.properties['tds_download_url'].split('https://')[1].split('/thredds')[0].split('.')[0]; + + // generate the full url + const fullTDSURL = data_url + "get_geo_point_data?lon=" + e.latlng.lng + "&lat=" + e.latlng.lat + "&ensemble=nowcast&url=" + + tds_url + '&tds_svr=' + tds_svr; + + const l_props = layer.properties; + + // create a set of properties for this object + const pointProps = + { + "station_name": l_props['product_name'] + " " + id, + "lat": lat, + "lon": lon, + "location_name": l_props['product_name'] + "s over time (lon, lat): " + id, + "model_run_id": layer.group, + "data_source": (l_props['event_type'] + '_' + l_props['grid_type']).toUpperCase(), + "source_name": l_props['model'], + "source_instance": l_props['instance_name'], + "source_archive": l_props['location'], + "forcing_metclass": l_props['met_class'], + "location_type": "GeoPoint", + "grid_name": l_props['grid_type'].toUpperCase(), + "csvurl": fullTDSURL, + "id": id + }; + + // populate selectedObservations list with the newly selected observation point + setSelectedObservations(previous => [...previous, pointProps]); + } else + setAlertMsg({ + 'severity': 'warning', + 'msg': 'Geo-point selection is not available for the ' + layer.properties['product_name'] + ' product.' + }); } - else - setAlertMsg({'severity': 'warning', 'msg': 'Geo-point selection is not available for the ' + layer.properties['product_name'] + ' product.'}); }); // assign the map click event for geo-point selections