From 87fb98f5ed519bea96ef2163e6c5b04a230961f4 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 1 Jul 2021 18:50:35 +0200 Subject: [PATCH] Make IGN layers opacity configurable --- app/assets/stylesheets/carte.scss | 1 + app/javascript/components/MapReader/index.jsx | 2 +- .../shared/mapbox/MapStyleControl.jsx | 69 ++++++++++++++----- .../components/shared/mapbox/styles/base.js | 28 +++++--- .../components/shared/mapbox/styles/index.js | 8 +-- 5 files changed, 76 insertions(+), 32 deletions(-) diff --git a/app/assets/stylesheets/carte.scss b/app/assets/stylesheets/carte.scss index 722edb3b8..33f065583 100644 --- a/app/assets/stylesheets/carte.scss +++ b/app/assets/stylesheets/carte.scss @@ -46,6 +46,7 @@ margin-bottom: $default-spacer; ul { + list-style: none; padding: $default-spacer; padding-bottom: 0; margin-bottom: -$default-spacer; diff --git a/app/javascript/components/MapReader/index.jsx b/app/javascript/components/MapReader/index.jsx index ae5081ba7..2d245b046 100644 --- a/app/javascript/components/MapReader/index.jsx +++ b/app/javascript/components/MapReader/index.jsx @@ -42,7 +42,7 @@ const MapReader = ({ featureCollection, options }) => { onLoad(map)} style={style} - containerStyle={{ height: '400px' }} + containerStyle={{ height: '500px' }} > layer != 'cadastres') - .map((layer) => [layer, { enabled: true, opacity: 100 }]) + .map((layer) => [ + layer, + { enabled: true, opacity: 70, name: getLayerName(layer) } + ]) ); } @@ -43,7 +48,10 @@ export function useMapStyle( () => getMapStyle( styleId, - enabledLayers.map(([layer]) => layer) + enabledLayers.map(([layer]) => layer), + Object.fromEntries( + enabledLayers.map(([layer, { opacity }]) => [layer, opacity]) + ) ), [ styleId, @@ -56,7 +64,13 @@ export function useMapStyle( return { style, layers, setStyle, setLayerEnabled, setLayerOpacity }; } -function MapStyleControl({ style, layers, setStyle, setLayerEnabled }) { +function MapStyleControl({ + style, + layers, + setStyle, + setLayerEnabled, + setLayerOpacity +}) { const [buttonElement, setButtonElement] = useState(); const [panelElement, setPanelElement] = useState(); const { styles, attributes } = usePopper(buttonElement, panelElement, { @@ -111,19 +125,40 @@ function MapStyleControl({ style, layers, setStyle, setLayerEnabled }) { {Object.keys(layers).length ? (
    - {Object.entries(layers).map(([layer, { enabled }]) => ( -
  • - { - setLayerEnabled(layer, event.target.checked); - }} - /> - -
  • - ))} + {Object.entries(layers).map( + ([layer, { enabled, opacity, name }]) => ( +
  • +
    + { + setLayerEnabled(layer, event.target.checked); + }} + /> + +
    + { + setLayerOpacity(layer, value); + }} + className="mb-1" + title={`Réglage de l’opacité de la couche «${NBS}${name}${NBS}»`} + getAriaLabel={() => + `Réglage de l’opacité de la couche «${NBS}${name}${NBS}»` + } + getAriaValueText={(value) => + `L’opacité de la couche «${NBS}${name}${NBS}» est à ${value}${NBS}%` + } + /> +
  • + ) + )}
) : null} diff --git a/app/javascript/components/shared/mapbox/styles/base.js b/app/javascript/components/shared/mapbox/styles/base.js index f90c6956c..172187d57 100644 --- a/app/javascript/components/shared/mapbox/styles/base.js +++ b/app/javascript/components/shared/mapbox/styles/base.js @@ -119,9 +119,9 @@ const OPTIONAL_LAYERS = [ function buildSources() { return Object.fromEntries( OPTIONAL_LAYERS.filter(({ id }) => id !== 'cadastres') - .flatMap(({ layers }) => layers) - .map(([, code]) => [ - code.toLowerCase().replace(/\./g, '-'), + .flatMap(({ layers }) => layers.map(([, code]) => code)) + .map((code) => [ + getLayerCode(code), rasterSource([ignServiceURL(code)], 'IGN-F/Géoportail/MNHN') ]) ); @@ -138,32 +138,40 @@ function rasterSource(tiles, attribution) { }; } -function rasterLayer(source) { +function rasterLayer(source, opacity) { return { id: source, source, type: 'raster', - paint: { 'raster-resampling': 'linear' } + paint: { 'raster-resampling': 'linear', 'raster-opacity': opacity } }; } -export function buildOptionalLayers(ids) { +export function buildOptionalLayers(ids, opacity) { return OPTIONAL_LAYERS.filter(({ id }) => ids.includes(id)) - .flatMap(({ layers }) => layers) - .flatMap(([, code]) => + .flatMap(({ layers, id }) => + layers.map(([, code]) => [code, opacity[id] / 100]) + ) + .flatMap(([code, opacity]) => code === 'CADASTRE' ? cadastreLayers - : [rasterLayer(code.toLowerCase().replace(/\./g, '-'))] + : [rasterLayer(getLayerCode(code), opacity)] ); } +export const NBS = ' '; + export function getLayerName(layer) { return OPTIONAL_LAYERS.find(({ id }) => id == layer).label.replace( /\s/g, - ' ' + NBS ); } +function getLayerCode(code) { + return code.toLowerCase().replace(/\./g, '-'); +} + export default { version: 8, metadat: { diff --git a/app/javascript/components/shared/mapbox/styles/index.js b/app/javascript/components/shared/mapbox/styles/index.js index 90d288a78..ed97b2aee 100644 --- a/app/javascript/components/shared/mapbox/styles/index.js +++ b/app/javascript/components/shared/mapbox/styles/index.js @@ -1,11 +1,11 @@ -import baseStyle, { buildOptionalLayers, getLayerName } from './base'; +import baseStyle, { buildOptionalLayers, getLayerName, NBS } from './base'; import orthoStyle from './layers/ortho'; import vectorStyle from './layers/vector'; import ignLayers from './layers/ign'; -export { getLayerName }; +export { getLayerName, NBS }; -export function getMapStyle(id, optionalLayers) { +export function getMapStyle(id, layers, opacity) { const style = { ...baseStyle, id }; switch (id) { @@ -23,7 +23,7 @@ export function getMapStyle(id, optionalLayers) { break; } - style.layers = style.layers.concat(buildOptionalLayers(optionalLayers)); + style.layers = style.layers.concat(buildOptionalLayers(layers, opacity)); return style; }