Merge pull request #6316 from tchak/carto-layers

Make IGN layers opacity configurable
This commit is contained in:
Paul Chavard 2021-07-06 11:17:46 +02:00 committed by GitHub
commit 50ebd6d17a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 32 deletions

View file

@ -46,6 +46,7 @@
margin-bottom: $default-spacer;
ul {
list-style: none;
padding: $default-spacer;
padding-bottom: 0;
margin-bottom: -$default-spacer;

View file

@ -42,7 +42,7 @@ const MapReader = ({ featureCollection, options }) => {
<Mapbox
onStyleLoad={(map) => onLoad(map)}
style={style}
containerStyle={{ height: '400px' }}
containerStyle={{ height: '500px' }}
>
<SelectionUtilisateurPolygonLayer
featureCollection={featureCollection}

View file

@ -3,8 +3,10 @@ import PropTypes from 'prop-types';
import { Popover, RadioGroup } from '@headlessui/react';
import { usePopper } from 'react-popper';
import { MapIcon } from '@heroicons/react/outline';
import { Slider } from '@reach/slider';
import '@reach/slider/styles.css';
import { getMapStyle, getLayerName } from './styles';
import { getMapStyle, getLayerName, NBS } from './styles';
const STYLES = {
ortho: 'Satellite',
@ -16,7 +18,10 @@ function optionalLayersMap(optionalLayers) {
return Object.fromEntries(
optionalLayers
.filter((layer) => 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,8 +125,10 @@ function MapStyleControl({ style, layers, setStyle, setLayerEnabled }) {
</RadioGroup>
{Object.keys(layers).length ? (
<ul className="layers-list">
{Object.entries(layers).map(([layer, { enabled }]) => (
<li key={layer} className="flex">
{Object.entries(layers).map(
([layer, { enabled, opacity, name }]) => (
<li key={layer}>
<div className="flex mb-1">
<input
className="m-0 p-0 mr-1"
type="checkbox"
@ -121,9 +137,28 @@ function MapStyleControl({ style, layers, setStyle, setLayerEnabled }) {
setLayerEnabled(layer, event.target.checked);
}}
/>
<label>{getLayerName(layer)}</label>
<label className="m-0">{name}</label>
</div>
<Slider
min={10}
max={100}
step={5}
value={opacity}
onChange={(value) => {
setLayerOpacity(layer, value);
}}
className="mb-1"
title={`Réglage de lopacité de la couche «${NBS}${name}${NBS}»`}
getAriaLabel={() =>
`Réglage de lopacité de la couche «${NBS}${name}${NBS}»`
}
getAriaValueText={(value) =>
`Lopacité de la couche «${NBS}${name}${NBS}» est à ${value}${NBS}%`
}
/>
</li>
))}
)
)}
</ul>
) : null}
</Popover.Panel>

View file

@ -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: {

View file

@ -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;
}