diff --git a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx index 6e9dab2e..16eff7ba 100644 --- a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx +++ b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx @@ -24,6 +24,42 @@ import navigationSVG from '@plone/volto/icons/navigation.svg'; import 'ol/ol.css'; import './style.css'; +const pinSVG = (fill = '#000') => { + return ``; +}; + +const factorySVG = () => { + return ``; +}; + +const refinerieSVG = () => { + return ``; +}; + +const nop = () => { + return null; +}; + +const SVG_COLLECTION = { + Chemicals: nop, + 'Electricity and heat production': nop, + 'Extractive industry': nop, + 'Ferrous metal': nop, + 'Food and drink': nop, + 'Fuel processing': nop, + 'Incineration with energy recovery': nop, + Landfill: nop, + Livestock: nop, + 'Non-ferrous metal': nop, + 'Non-metallic minerals': nop, + 'Other manufacturing': nop, + 'Other waste management': nop, + 'Pulp, paper and wood': nop, + Refineries: refinerieSVG, + 'Waste management': nop, + 'Wastewater treatment': nop, +}; + const splitBy = (arr, delimiter) => { if (Array.isArray(arr)) { return ( @@ -47,6 +83,7 @@ let Map, toLonLat, toStringHDMS, createXYZ, + Icon, CircleStyle, Fill, Stroke, @@ -78,6 +115,7 @@ const OpenlayersMapView = (props) => { popup: { element: null, properties: {} }, popupDetails: { element: null, properties: {} }, locationTerm: null, + siteTerm: null, updateMapPosition: null, }); const [state, setState] = useState({ @@ -90,6 +128,7 @@ const OpenlayersMapView = (props) => { popup: { element: null, properties: {} }, popupDetails: { element: null, properties: {} }, locationTerm: null, + siteTerm: null, updateMapPosition: null, }); const [loader, setLoader] = useState(false); @@ -97,6 +136,7 @@ const OpenlayersMapView = (props) => { const [firstFilteringUpdate, setFirstFilteringUpdate] = useState(false); const ToggleSidebarControl = useRef(null); const ViewYourAreaControl = useRef(null); + const siteTermRef = useRef(null); const history = useHistory(); const draggable = !!props.data?.draggable?.value; const hasPopups = !!props.data?.hasPopups?.value; @@ -119,12 +159,15 @@ const OpenlayersMapView = (props) => { queryParams = {}; } } + const locationTerm = props.discodata_query.search.locationTerm || null; + const siteTerm = + filterSource !== 'query_params' + ? props.discodata_query.search.siteTerm || null + : props.discodata_query.search[queryParams?.siteName?.param] || null; - const searchQueryParams = isObject(queryParams) - ? Object.entries(queryParams).map(([key, value]) => { - return props.discodata_query.search[value.param] || null; - }) - : []; + useEffect(() => { + siteTermRef.current = siteTerm; + }, [siteTerm]); if (mapRendered && !firstFilteringUpdate) { updateFilters(); @@ -146,6 +189,7 @@ const OpenlayersMapView = (props) => { toLonLat = require('ol/proj').toLonLat; toStringHDMS = require('ol/coordinate').toStringHDMS; createXYZ = require('ol/tilegrid').createXYZ; + Icon = require('ol/style/Icon.js').default; CircleStyle = require('ol/style/Circle.js').default; Fill = require('ol/style/Fill.js').default; Stroke = require('ol/style/Stroke.js').default; @@ -218,21 +262,7 @@ const OpenlayersMapView = (props) => { } /* eslint-disable-next-line */ }, [ - JSON.stringify(props.discodata_query.search.siteTerm), - JSON.stringify(props.discodata_query.search.locationTerm), - JSON.stringify(props.discodata_query.search.EEASubSector), - JSON.stringify(props.discodata_query.search.siteCountry), - JSON.stringify(props.discodata_query.search.region), - JSON.stringify(props.discodata_query.search.riverBasin), - JSON.stringify(props.discodata_query.search.townVillage), - JSON.stringify(props.discodata_query.search.pollutantGroup), - JSON.stringify(props.discodata_query.search.pollutant), - JSON.stringify(props.discodata_query.search.reportingYear), - JSON.stringify(props.discodata_query.search.batConclusionCode), - JSON.stringify(props.discodata_query.search.batConclustionYear), - JSON.stringify(props.discodata_query.search.permitType), - JSON.stringify(props.discodata_query.search.permitYear), - JSON.stringify(searchQueryParams), + JSON.stringify(props.discodata_query.search.filtersCounter), ]); useEffect(() => { @@ -242,36 +272,25 @@ const OpenlayersMapView = (props) => { useEffect(() => { if (mapRendered) { - if (state.updateMapPosition === 'byLocationTermNoRefresh') { - const options = { - duration: 2000, - maxZoom: 15, - }; - getLocation(options, true); - setState({ - ...state, - updateMapPosition: null, - }); - } else { + if (['byLocationTerm', 'bySiteTerm'].includes(state.updateMapPosition)) { + onSourceChange(state.map.sitesSourceLayer.getSource()); + } else if ( + state.map.sitesSourceQuery.where !== state.map.oldSitesSourceQuery.where + ) { state.map.sitesSourceLayer && state.map.sitesSourceLayer.getSource().refresh(); } } /* eslint-disable-next-line */ - }, [state.map.sitesSourceQuery?.where, state.locationTerm?.text]) + }, [state.map.sitesSourceQuery?.where, state.updateMapPosition]) function updateFilters() { const sitesSourceQuery = { ...state.map.sitesSourceQuery }; - const locationTerm = props.discodata_query.search.locationTerm || null; if (hasSidebar && filterSource === 'eprtr_filters') { sitesSourceQuery.whereStatements = { ...sitesSourceQuery.whereStatements, - siteTerm: { - sql: `(siteName LIKE ':options%')`, - type: 'string', - }, // Industries - EEASubSector: { + EEAActivity: { sql: `(eea_activities LIKE '%:options%')`, type: 'multiple', }, @@ -360,25 +379,29 @@ const OpenlayersMapView = (props) => { if ( sitesSourceQuery.where !== state.map.sitesSourceQuery.where || - locationTerm?.text !== state.locationTerm?.text + locationTerm?.text || + siteTerm ) { let updateMapPosition = null; if ( - sitesSourceQuery.whereStatements.siteId?.sql || - sitesSourceQuery.whereStatements.siteTerm?.sql || - sitesSourceQuery.whereStatements.siteName?.sql + filterSource !== 'query_params' && + sitesSourceQuery.where === state.map.sitesSourceQuery.where && + !props.discodata_query.search.advancedFiltering ) { - updateMapPosition = 'bySiteTerm'; - } else if (locationTerm?.text) { - updateMapPosition = 'byLocationTerm'; - } else if ( - sitesSourceQuery.whereStatements.siteCountry?.sql || - sitesSourceQuery.whereStatements.region?.sql - ) { - updateMapPosition = 'byRegion'; + if (siteTerm) { + updateMapPosition = 'bySiteTerm'; + } else if (locationTerm?.text) { + updateMapPosition = 'byLocationTerm'; + } + } else if (filterSource === 'query_params') { + if (siteTerm) { + updateMapPosition = 'bySiteTerm'; + } } - // setLoader(true); - if (sitesSourceQuery.where !== state.map.sitesSourceQuery.where) { + if ( + sitesSourceQuery.where !== state.map.sitesSourceQuery.where || + updateMapPosition !== stateRef.current.updateMapPosition + ) { setState({ ...state, map: { @@ -387,12 +410,7 @@ const OpenlayersMapView = (props) => { }, updateMapPosition, locationTerm, - }); - } else if (locationTerm?.text !== state.locationTerm?.text) { - setState({ - ...state, - updateMapPosition: 'byLocationTermNoRefresh', - locationTerm, + siteTerm, }); } } @@ -447,47 +465,69 @@ const OpenlayersMapView = (props) => { return false; } - function getLocation(options, noRefresh = false) { - axios - .get( - encodeURI( - 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates?SingleLine=' + - stateRef.current.locationTerm?.text + - '&f=json&outSR={"wkid":102100,"latestWkid":3857}&outFields=Match_addr,Addr_type,StAddr,City&magicKey=' + - stateRef.current.locationTerm?.magicKey + - '&maxLocations=6', - ), - ) - .then((response) => { - const data = JSON.parse(response.request.response) || {}; - if (data.error) { - // setLoader(false); - } else if (data.candidates?.length > 0) { - stateRef.current.map.element - .getView() - .fit( - [ - data.candidates[0].extent.xmin, - data.candidates[0].extent.ymin, - data.candidates[0].extent.xmax, - data.candidates[0].extent.ymax, - ], - { - ...options, - callback: function () { - if (noRefresh) { - // setLoader(false); - stateRef.current.map.sitesSourceLayer && - stateRef.current.map.sitesSourceLayer - .getSource() - .refresh(); - } + function getLocation(options) { + if ( + stateRef.current.locationTerm?.text && + stateRef.current.locationTerm?.magicKey + ) { + axios + .get( + encodeURI( + 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates?SingleLine=' + + stateRef.current.locationTerm?.text + + '&f=json&outSR={"wkid":102100,"latestWkid":3857}&outFields=Match_addr,Addr_type,StAddr,City&magicKey=' + + stateRef.current.locationTerm?.magicKey + + '&maxLocations=6', + ), + ) + .then((response) => { + const data = JSON.parse(response.request.response) || {}; + if (data.error) { + // setLoader(false); + } else if (data.candidates?.length > 0) { + stateRef.current.map.element + .getView() + .fit( + [ + data.candidates[0].extent.xmin, + data.candidates[0].extent.ymin, + data.candidates[0].extent.xmax, + data.candidates[0].extent.ymax, + ], + { + ...options, + callback: function () {}, }, - }, - ); - } - }) - .catch((error) => {}); + ); + } + }) + .catch((error) => {}); + } + } + + function getSiteTermLocation(options) { + if (stateRef.current.siteTerm) { + axios + .get( + encodeURI( + `${settings.providerUrl}?query=SELECT DISTINCT * FROM [IED].[latest].[Browse3_4_infotable] WHERE site LIKE '%${stateRef.current.siteTerm}%' ORDER BY [reportingYear] DESC`, + ), + ) + .then((response) => { + const data = JSON.parse(response.request.response); + const item = data.results?.[0]; + if (item) { + const x_3857 = item.x_3857; + const y_3857 = item.y_3857; + stateRef.current.map.element.getView().animate({ + center: [x_3857, y_3857], + duration: filterSource !== 'query_params' ? 1000 : 0, + zoom: 15, + }); + } + }) + .catch((error) => {}); + } } function onSourceChange(source) { @@ -495,26 +535,12 @@ const OpenlayersMapView = (props) => { duration: 2000, maxZoom: 15, }; - const extent = source.getExtent().map((coordinate, index) => { - if (coordinate === Infinity || coordinate === -Infinity) { - return initialExtent[index]; - } - return coordinate; - }); - if (stateRef.current.updateMapPosition === 'bySiteTerm' && extent) { - stateRef.current.map.element.getView().fit(extent, options); + if (stateRef.current.updateMapPosition === 'bySiteTerm') { + getSiteTermLocation(options); } - if ( - stateRef.current.updateMapPosition === 'byLocationTerm' && - stateRef.current.locationTerm?.text && - stateRef.current.locationTerm?.magicKey && - extent - ) { + if (stateRef.current.updateMapPosition === 'byLocationTerm') { getLocation(options); } - if (stateRef.current.updateMapPosition === 'byRegion' && extent) { - stateRef.current.map.element.getView().fit(extent); - } // UPDATE OLD FILTERS if ( stateRef.current.map.sitesSourceQuery.where !== @@ -557,12 +583,15 @@ const OpenlayersMapView = (props) => { JSON.stringify(stateRef.current.popupDetails.properties) !== JSON.stringify(featuresProperties) ) { - // axios.get() setState({ ...stateRef.current, popupDetails: { ...stateRef.current.popupDetails, - properties: { ...featuresProperties, hdms }, + properties: { + ...featuresProperties, + hdms, + flatCoordinates: features[0].getGeometry().flatCoordinates, + }, }, }); } else if ( @@ -574,7 +603,11 @@ const OpenlayersMapView = (props) => { ...stateRef.current, popup: { ...stateRef.current.popup, - properties: { ...featuresProperties, hdms }, + properties: { + ...featuresProperties, + hdms, + flatCoordinates: features[0].getGeometry().flatCoordinates, + }, }, }); } @@ -657,23 +690,18 @@ const OpenlayersMapView = (props) => { let reqs = 0; sitesSource = new VectorSource({ loader: function (extent, resolution, projection) { - const updateMapPosition = - !!stateRef.current.updateMapPosition && - !['byLocationTerm', 'byLocationTermNoRefresh'].includes( - stateRef.current.updateMapPosition, - ); var url = 'https://services.arcgis.com/LcQjj2sL7Txk9Lag/arcgis/rest/services/SiteMap_v2/FeatureServer/0/query/?f=json&' + 'returnGeometry=true&spatialRel=esriSpatialRelIntersects&geometry=' + encodeURIComponent( '{"xmin":' + - (updateMapPosition ? initialExtent[0] : extent[0]) + + extent[0] + ',"ymin":' + - (updateMapPosition ? initialExtent[1] : extent[1]) + + extent[1] + ',"xmax":' + - (updateMapPosition ? initialExtent[2] : extent[2]) + + extent[2] + ',"ymax":' + - (updateMapPosition ? initialExtent[3] : extent[3]) + + extent[3] + ',"spatialReference":{"wkid":102100}}', ) + '&geometryType=esriGeometryEnvelope&inSR=102100&outFields=*' + @@ -761,13 +789,47 @@ const OpenlayersMapView = (props) => { // Sites source layer sitesSourceLayer = new VectorLayer({ source: sitesSource, - style: new Style({ - image: new CircleStyle({ - radius: 3, - fill: new Fill({ color: '#000' }), - stroke: new Stroke({ color: '#6A6A6A', width: 1 }), - }), - }), + style: (feature, resolution) => { + const featureProperties = feature.getProperties(); + if ( + featureProperties.siteName === siteTermRef.current || + (SVG_COLLECTION[featureProperties.eea_activities]?.() && + stateRef.current.map.element.getView().getZoom() > 11) + ) { + return new Style({ + image: new Icon({ + src: + featureProperties.siteName === siteTermRef.current + ? `data:image/svg+xml;utf8,${encodeURIComponent( + pinSVG('#50C878'), + )}` + : `data:image/svg+xml;utf8,${encodeURIComponent( + SVG_COLLECTION[featureProperties.eea_activities](), + )}`, + opacity: 1, + scale: 1, + }), + zIndex: + featureProperties.siteName === siteTermRef.current ? 1 : 0, + }); + } else { + return new Style({ + image: new CircleStyle({ + radius: 3, + fill: + featureProperties.siteName === siteTermRef.current + ? new Fill({ color: '#50C878' }) + : new Fill({ color: '#000' }), + stroke: + featureProperties.siteName === siteTermRef.current + ? new Stroke({ color: '#6A6A6A', width: 1 }) + : new Stroke({ color: '#6A6A6A', width: 1 }), + zIndex: + featureProperties.siteName === siteTermRef.current ? 1 : 0, + }), + }); + } + }, visible: true, title: 'ly_IED_SiteMap_WM', }); @@ -808,7 +870,7 @@ const OpenlayersMapView = (props) => { }), ); // Center by user location - if (navigator.geolocation) { + if (navigator.geolocation && filterSource !== 'query_params') { navigator.geolocation.getCurrentPosition((position) => { return centerPosition(map, position, 12); }); @@ -894,8 +956,9 @@ const OpenlayersMapView = (props) => { queryParam: { siteInspireId: data.results[0].siteInspireId, siteId: state.popupDetails.properties.id, - siteName: state.popupDetails.properties.sitename, - reportingYear: state.popupDetails.properties.rep_yr, + siteName: state.popupDetails.properties.siteName, + siteReportingYear: + state.popupDetails.properties.Site_reporting_year, }, }); }) @@ -973,9 +1036,15 @@ const OpenlayersMapView = (props) => {

{state.popupDetails.properties.nFacilities || 0}{' '} @@ -986,6 +1055,12 @@ const OpenlayersMapView = (props) => {

{

{state.popupDetails.properties.nInstallations || 0}{' '} @@ -1055,9 +1136,7 @@ const OpenlayersMapView = (props) => { - @@ -1122,6 +1197,17 @@ const View = ({ content, ...props }) => { 0, true, ); + props.setQueryParam({ + queryParam: { + ...props.discodata_query.search, + advancedFiltering: true, + filtersCounter: props.discodata_query.search[ + 'filtersCounter' + ] + ? props.discodata_query.search['filtersCounter'] + 1 + : 1, + }, + }); }} placeholder={ state.filtersMeta['reporting_years']?.placeholder @@ -1141,10 +1227,21 @@ const View = ({ content, ...props }) => { 0, true, ); + props.setQueryParam({ + queryParam: { + ...props.discodata_query.search, + advancedFiltering: true, + filtersCounter: props.discodata_query.search[ + 'filtersCounter' + ] + ? props.discodata_query.search['filtersCounter'] + 1 + : 1, + }, + }); }} placeholder={state.filtersMeta['industries']?.placeholder} options={state.filtersMeta['industries']?.options} - value={state.filters['EEASubSector']?.[0]} + value={state.filters['EEAActivity']?.[0]} />

diff --git a/src/components/manage/Blocks/FiltersBlock/style.css b/src/components/manage/Blocks/FiltersBlock/style.css index 05d9be96..f20d66ee 100644 --- a/src/components/manage/Blocks/FiltersBlock/style.css +++ b/src/components/manage/Blocks/FiltersBlock/style.css @@ -134,15 +134,32 @@ .filters-container .search-results .ui.list .item, .filters-block.ui.modal .search-results .ui.list .item { cursor: pointer; + padding: 4px; +} + +.filters-container .search-results .ui.list .item .mark, +.filters-block.ui.modal .search-results .ui.list .item .mark { + background-color: transparent; + color: #000; + font-weight: bold; +} + +.filters-container .search-results .ui.list .item.selected, +.filters-block.ui.modal .search-results .ui.list .item.selected { + background-color: #EFEFEF; } .filters-container .search-results .ui.list .item .info, .filters-block.ui.modal .search-results .ui.list .item .info { position: absolute; - right: 1em; + right: calc(1em + 4px); color: #B8C6C8; } +.filters-container .search-results .ui.list .item.selected .info, +.filters-block.ui.modal .search-results .ui.list .item.selected .info { +} + .filters-container .search-results .ui.list .item:hover .info, .filters-block.ui.modal .search-results .ui.list .item:hover .info { color: #000; diff --git a/theme/site/globals/site.overrides b/theme/site/globals/site.overrides index 82fc7720..04ae7410 100644 --- a/theme/site/globals/site.overrides +++ b/theme/site/globals/site.overrides @@ -1600,4 +1600,10 @@ b { transform: translateY(-50%); left: -26px } +} + +.disabled-link { + pointer-events: none; + color: #333; + text-decoration: none !important; } \ No newline at end of file