diff --git a/constants/layers.js b/constants/layers.js index 74dc3cc6..a6c7f96e 100644 --- a/constants/layers.js +++ b/constants/layers.js @@ -35,6 +35,43 @@ const FMU_LEGEND = [ } ]; +const ISO3_TO_ISO2 = { + CMR: 'CM', + CAF: 'CF', + COG: 'CG', + GAB: 'GA', + COD: 'CD' +}; + +export function getOtpCountriesLayerFilter(countriesIso3) { + const countriesIso2 = countriesIso3.map(iso3 => ISO3_TO_ISO2[iso3]); + + return [ + 'all', + ['==', ['get', 'admin_level'], 2], // weird that not 0, but ok + // ['==', ['get', 'maritime'], 0], + ['==', ['get', 'disputed'], 0], + ['any', + ...countriesIso2.map(iso2 => [">=", ["index-of", iso2, ["get", "iso_3166_1"]], 0]) + ] + ] +} + +export const BASEMAP_LAYERS = [ + { + id: 'otp_countries', + type: 'line', + source: 'composite', + 'source-layer': 'admin', + paint: { + 'line-color': '#333333', + 'line-width': 2, + 'line-opacity': 0.8 + }, + filter: getOtpCountriesLayerFilter(process.env.OTP_COUNTRIES) + } +]; + export const LAYERS = [ { id: 'integrated-alerts', diff --git a/pages/operators/index.js b/pages/operators/index.js index 93e20843..d815c2da 100644 --- a/pages/operators/index.js +++ b/pages/operators/index.js @@ -17,7 +17,7 @@ import { getOperatorsUrl, getIntegratedAlertsMetadata } from 'modules/operators-ranking'; -import { getActiveLayers, getActiveInteractiveLayers, getActiveInteractiveLayersIds, getLegendLayers, getPopup, getTable } from 'selectors/operators-ranking'; +import { getActiveLayers, getActiveInteractiveLayers, getActiveInteractiveLayersIds, getLegendLayers, getPopup, getTable, getActiveCountries } from 'selectors/operators-ranking'; import modal from 'services/modal'; @@ -39,6 +39,7 @@ import ZoomControl from 'components/map/controls/zoom-control'; import OperatorsFilters from 'components/operators/filters'; import OperatorsTable from 'components/operators/table'; +import { BASEMAP_LAYERS, getOtpCountriesLayerFilter } from 'constants/layers'; class OperatorsPage extends React.Component { static async getInitialProps({ store }) { @@ -78,6 +79,12 @@ class OperatorsPage extends React.Component { document.getElementById('forest-atlas-attribution').removeEventListener('click', this.onCustomAttribute); } + componentDidUpdate(prevProps) { + if (prevProps.activeCountries !== this.props.activeCountries && this.map) { + this.map.setFilter("otp_countries", getOtpCountriesLayerFilter(this.props.activeCountries)); + } + } + onClick = (e) => { if (e.features && e.features.length && !e.target.classList.contains('mapbox-prevent-click')) { // No better way to do this const { features, lngLat } = e; @@ -87,6 +94,15 @@ class OperatorsPage extends React.Component { } } + onLoad = (map) => { + const countriesLayer = BASEMAP_LAYERS.find(x => x.id === 'otp_countries'); + if (countriesLayer) { + map.map.addLayer(countriesLayer); + } + this.map = map.map; + document.getElementById('forest-atlas-attribution').addEventListener('click', this.onCustomAttribute); + } + onHover = (e) => { if (e.features && e.features.length) { const { features, lngLat } = e; @@ -156,12 +172,7 @@ class OperatorsPage extends React.Component { interactiveLayerIds={activeInteractiveLayersIds} onClick={this.onClick} onHover={this.onHover} - - onLoad={() => { - // Attribution listener - document.getElementById('forest-atlas-attribution').addEventListener('click', this.onCustomAttribute); - }} - + onLoad={this.onLoad} mapOptions={{ customAttribution: 'Forest Atlas' }} @@ -228,6 +239,7 @@ export default withRouter(withDeviceInfo(injectIntl(connect( operatorsRanking: state.operatorsRanking, map: state.operatorsRanking.map, sidebar: state.operatorsRanking.sidebar, + activeCountries: getActiveCountries(state, props), activeLayers: getActiveLayers(state, props), activeInteractiveLayers: getActiveInteractiveLayers(state, props), activeInteractiveLayersIds: getActiveInteractiveLayersIds(state, props), diff --git a/selectors/operators-ranking/index.js b/selectors/operators-ranking/index.js index 42361a2b..01288b33 100644 --- a/selectors/operators-ranking/index.js +++ b/selectors/operators-ranking/index.js @@ -33,55 +33,23 @@ const latlng = state => state.operatorsRanking.latlng; const countryOptions = state => state.operatorsRanking.filters.options.country; const countryActive = state => state.operatorsRanking.filters.data.country; +export const getActiveCountries = createSelector(countryOptions, countryActive, (_countryOptions, _countryActive) => { + return _countryOptions.map((c) => { + if (!_countryActive || !_countryActive.length) { + return c.iso; + } + + if (_countryActive.includes(c.value)) { + return c.iso; + } + return null; + }).filter(x => !!x); +}); // Create a function to compare the current active datatasets and the current datasetsIds export const getActiveLayers = createSelector( - layersActive, layers, layersSettings, interactions, hoverInteractions, countryOptions, countryActive, - (_layersActive, _layers, _layersSettings, _interactions, _hoverInteractions, _countryOptions, _countryActive) => { - const cIsoCodes = _countryOptions.map((c) => { - if (!_countryActive || !_countryActive.length) { - return c.iso; - } - - if (_countryActive.includes(c.value)) { - return c.iso; - } - return null; - }).filter(x => !!x); - - // Country layers - const cLayers = _countryOptions.map((c) => { - let opacity = 1; - - if (_countryActive && _countryActive.length) { - opacity = Number(_countryActive.includes(c.value)); - } - - - return { - id: c.iso, - type: 'geojson', - opacity, - source: { - type: 'geojson', - provider: { - type: 'countries', - url: `https://api.resourcewatch.org/v2/geostore/admin/${c.iso}?simplify=0.0000001` - } - }, - render: { - layers: [{ - type: 'line', - paint: { - 'line-color': '#333333', - 'line-width': 2, - 'line-opacity': 0.8 - } - }] - } - }; - }); - + layersActive, layers, layersSettings, interactions, hoverInteractions, getActiveCountries, + (_layersActive, _layers, _layersSettings, _interactions, _hoverInteractions, cIsoCodes) => { // Layers const aLayers = _layers.map((l) => { const { id, paramsConfig, decodeConfig, decodeFunction, timelineConfig } = l; @@ -108,10 +76,7 @@ export const getActiveLayers = createSelector( return null; }); - return [ - ...cLayers, - ...aLayers - ].filter(x => !!x); + return aLayers.filter(x => !!x); } );