demarches-normaliennes/app/javascript/components/shared/maplibre/styles/base.ts

234 lines
6.5 KiB
TypeScript
Raw Normal View History

import type { AnyLayer, Style, RasterLayer, RasterSource } from 'maplibre-gl';
import invariant from 'tiny-invariant';
import cadastreLayers from './layers/cadastre';
2020-10-15 17:22:08 +02:00
2022-03-17 11:55:08 +01:00
function ignServiceURL(
layer: string,
env = 'decouverte',
format = 'image/png'
) {
const url = `https://wxs.ign.fr/${env}/geoportail/wmts`;
2020-10-15 17:22:08 +02:00
const query =
'service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&style=normal';
return `${url}?${query}&layer=${layer}&format=${format}`;
}
const OPTIONAL_LAYERS: { label: string; id: string; layers: string[][] }[] = [
2020-10-15 17:22:08 +02:00
{
label: 'UNESCO',
id: 'unesco',
layers: [
['Aires protégées Géoparcs', 'PROTECTEDAREAS.GP'],
['Réserves de biosphère', 'PROTECTEDAREAS.BIOS']
]
},
{
label: 'Arrêtés de protection',
id: 'arretes_protection',
layers: [
['Arrêtés de protection de biotope', 'PROTECTEDAREAS.APB'],
['Arrêtés de protection de géotope', 'PROTECTEDAREAS.APG']
]
},
{
label: 'Conservatoire du Littoral',
id: 'conservatoire_littoral',
layers: [
[
'Conservatoire du littoral : parcelles protégées',
'PROTECTEDAREAS.MNHN.CDL.PARCELS'
],
[
'Conservatoire du littoral : périmètres dintervention',
'PROTECTEDAREAS.MNHN.CDL.PERIMETER'
]
]
},
{
label: 'Réserves nationales de chasse et de faune sauvage',
id: 'reserves_chasse_faune_sauvage',
layers: [
[
'Réserves nationales de chasse et de faune sauvage',
'PROTECTEDAREAS.RNCF'
]
]
},
{
label: 'Réserves biologiques',
id: 'reserves_biologiques',
layers: [['Réserves biologiques', 'PROTECTEDAREAS.RB']]
},
{
label: 'Réserves naturelles',
id: 'reserves_naturelles',
layers: [
['Réserves naturelles nationales', 'PROTECTEDAREAS.RN'],
[
'Périmètres de protection de réserves naturelles',
'PROTECTEDAREAS.MNHN.RN.PERIMETER'
],
['Réserves naturelles de Corse', 'PROTECTEDAREAS.RNC'],
[
'Réserves naturelles régionales',
'PROTECTEDSITES.MNHN.RESERVES-REGIONALES'
]
]
},
{
label: 'Natura 2000',
id: 'natura_2000',
layers: [
['Sites Natura 2000 (Directive Habitats)', 'PROTECTEDAREAS.SIC'],
['Sites Natura 2000 (Directive Oiseaux)', 'PROTECTEDAREAS.ZPS']
]
},
{
label: 'Zones humides dimportance internationale',
id: 'zones_humides',
layers: [
['Zones humides dimportance internationale', 'PROTECTEDAREAS.RAMSAR']
]
},
{
label: 'ZNIEFF',
id: 'znieff',
layers: [
[
'Zones naturelles dintérêt écologique faunistique et floristique de type 1 (ZNIEFF 1 mer)',
'PROTECTEDAREAS.ZNIEFF1.SEA'
],
[
'Zones naturelles dintérêt écologique faunistique et floristique de type 1 (ZNIEFF 1)',
'PROTECTEDAREAS.ZNIEFF1'
],
[
'Zones naturelles dintérêt écologique faunistique et floristique de type 2 (ZNIEFF 2 mer)',
'PROTECTEDAREAS.ZNIEFF2.SEA'
],
[
'Zones naturelles dintérêt écologique faunistique et floristique de type 2 (ZNIEFF 2)',
'PROTECTEDAREAS.ZNIEFF2'
]
]
},
{
label: 'Cadastre',
id: 'cadastres',
layers: [['Cadastre', 'CADASTRE']]
}
];
function buildSources() {
return Object.fromEntries(
2020-12-11 14:47:50 +01:00
OPTIONAL_LAYERS.filter(({ id }) => id !== 'cadastres')
2021-07-01 18:50:35 +02:00
.flatMap(({ layers }) => layers.map(([, code]) => code))
.map((code) => [
getLayerCode(code),
2022-03-17 11:55:08 +01:00
rasterSource(
[ignServiceURL(code, 'environnement')],
'IGN-F/Géoportail/MNHN'
)
2020-12-11 14:47:50 +01:00
])
2020-10-15 17:22:08 +02:00
);
}
function rasterSource(tiles: string[], attribution: string): RasterSource {
2020-10-15 17:22:08 +02:00
return {
type: 'raster',
tiles,
tileSize: 256,
attribution,
minzoom: 0,
maxzoom: 18
};
}
function rasterLayer(source: string, opacity: number): RasterLayer {
return {
id: source,
source,
type: 'raster',
2021-07-01 18:50:35 +02:00
paint: { 'raster-resampling': 'linear', 'raster-opacity': opacity }
};
}
export function buildOptionalLayers(
ids: string[],
opacity: Record<string, number>
): AnyLayer[] {
2020-10-15 17:22:08 +02:00
return OPTIONAL_LAYERS.filter(({ id }) => ids.includes(id))
2021-07-01 18:50:35 +02:00
.flatMap(({ layers, id }) =>
layers.map(([, code]) => [code, opacity[id] / 100] as const)
2021-07-01 18:50:35 +02:00
)
.flatMap(([code, opacity]) =>
2020-10-15 17:22:08 +02:00
code === 'CADASTRE'
? cadastreLayers
2021-07-01 18:50:35 +02:00
: [rasterLayer(getLayerCode(code), opacity)]
2020-10-15 17:22:08 +02:00
);
}
export const NBS = ' ' as const;
2021-07-01 18:50:35 +02:00
export function getLayerName(layer: string): string {
const name = OPTIONAL_LAYERS.find(({ id }) => id == layer);
invariant(name, `Layer "${layer}" not found`);
return name.label.replace(/\s/g, NBS);
}
function getLayerCode(code: string) {
2021-07-01 18:50:35 +02:00
return code.toLowerCase().replace(/\./g, '-');
}
2020-10-15 17:22:08 +02:00
export default {
version: 8,
metadat: {
'mapbox:autocomposite': false,
'mapbox:groups': {
1444849242106.713: { collapsed: false, name: 'Places' },
1444849334699.1902: { collapsed: true, name: 'Bridges' },
1444849345966.4436: { collapsed: false, name: 'Roads' },
1444849354174.1904: { collapsed: true, name: 'Tunnels' },
1444849364238.8171: { collapsed: false, name: 'Buildings' },
1444849382550.77: { collapsed: false, name: 'Water' },
1444849388993.3071: { collapsed: false, name: 'Land' }
},
'mapbox:type': 'template',
'openmaptiles:mapbox:owner': 'openmaptiles',
'openmaptiles:mapbox:source:url': 'mapbox://openmaptiles.4qljc88t',
'openmaptiles:version': '3.x',
'maputnik:renderer': 'mbgljs'
},
center: [0, 0],
zoom: 1,
bearing: 0,
pitch: 0,
sources: {
'decoupage-administratif': {
type: 'vector',
2021-08-31 18:14:04 +02:00
url: 'https://openmaptiles.geo.data.gouv.fr/data/decoupage-administratif.json'
2020-10-15 17:22:08 +02:00
},
openmaptiles: {
type: 'vector',
url: 'https://openmaptiles.geo.data.gouv.fr/data/france-vector.json'
},
'photographies-aeriennes': rasterSource(
2022-03-17 11:55:08 +01:00
[ignServiceURL('ORTHOIMAGERY.ORTHOPHOTOS', 'decouverte', 'image/jpeg')],
'IGN-F/Géoportail'
),
2020-10-15 17:22:08 +02:00
cadastre: {
type: 'vector',
url: 'https://openmaptiles.geo.data.gouv.fr/data/cadastre.json'
},
'plan-ign': rasterSource(
2022-03-17 11:55:08 +01:00
[ignServiceURL('GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2', 'decouverte')],
2020-10-15 17:22:08 +02:00
'IGN-F/Géoportail'
),
...buildSources()
},
sprite: 'https://openmaptiles.github.io/osm-bright-gl-style/sprite',
glyphs: 'https://openmaptiles.geo.data.gouv.fr/fonts/{fontstack}/{range}.pbf'
} as Style;