2024-09-20 18:22:49 +02:00
|
|
|
|
import type {
|
|
|
|
|
LayerSpecification,
|
|
|
|
|
RasterLayerSpecification,
|
|
|
|
|
RasterSourceSpecification,
|
|
|
|
|
StyleSpecification
|
|
|
|
|
} from 'maplibre-gl';
|
2022-02-08 12:49:51 +01:00
|
|
|
|
import invariant from 'tiny-invariant';
|
|
|
|
|
|
2024-09-20 18:22:49 +02:00
|
|
|
|
import cadastreLayers from './layers/cadastre.json';
|
2020-10-15 17:22:08 +02:00
|
|
|
|
|
2024-02-08 16:14:03 +01:00
|
|
|
|
function ignServiceURL(layer: string, style: string, format = 'image/png') {
|
2023-11-09 16:07:13 +01:00
|
|
|
|
const url = `https://data.geopf.fr/wmts`;
|
2020-10-15 17:22:08 +02:00
|
|
|
|
const query =
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}';
|
2020-10-15 17:22:08 +02:00
|
|
|
|
|
2024-02-08 16:14:03 +01:00
|
|
|
|
return `${url}?${query}&layer=${layer}&format=${format}&style=${style}`;
|
2020-10-15 17:22:08 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-08 12:49:51 +01:00
|
|
|
|
const OPTIONAL_LAYERS: { label: string; id: string; layers: string[][] }[] = [
|
2020-10-15 17:22:08 +02:00
|
|
|
|
{
|
|
|
|
|
label: 'UNESCO',
|
|
|
|
|
id: 'unesco',
|
|
|
|
|
layers: [
|
2024-02-08 16:14:03 +01:00
|
|
|
|
['Aires protégées Géoparcs', 'PROTECTEDAREAS.GP', 'normal'],
|
|
|
|
|
['Réserves de biosphère', 'PROTECTEDAREAS.BIOS', 'PROTECTEDAREAS.BIOS']
|
2020-10-15 17:22:08 +02:00
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Arrêtés de protection',
|
|
|
|
|
id: 'arretes_protection',
|
|
|
|
|
layers: [
|
2024-02-08 16:14:03 +01:00
|
|
|
|
[
|
|
|
|
|
'Arrêtés de protection de biotope',
|
|
|
|
|
'PROTECTEDAREAS.APB',
|
|
|
|
|
'PROTECTEDAREAS.APB'
|
|
|
|
|
],
|
|
|
|
|
['Arrêtés de protection de géotope', 'PROTECTEDAREAS.APG', 'normal']
|
2020-10-15 17:22:08 +02:00
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Conservatoire du Littoral',
|
|
|
|
|
id: 'conservatoire_littoral',
|
|
|
|
|
layers: [
|
|
|
|
|
[
|
|
|
|
|
'Conservatoire du littoral : parcelles protégées',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'PROTECTEDAREAS.MNHN.CDL.PARCELS',
|
2020-10-15 17:22:08 +02:00
|
|
|
|
'PROTECTEDAREAS.MNHN.CDL.PARCELS'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'Conservatoire du littoral : périmètres d’intervention',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'PROTECTEDAREAS.MNHN.CDL.PERIMETER',
|
|
|
|
|
'normal'
|
2020-10-15 17:22:08 +02:00
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
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',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'PROTECTEDAREAS.RNCF',
|
|
|
|
|
'normal'
|
2020-10-15 17:22:08 +02:00
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Réserves biologiques',
|
|
|
|
|
id: 'reserves_biologiques',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
layers: [['Réserves biologiques', 'PROTECTEDAREAS.RB', 'normal']]
|
2020-10-15 17:22:08 +02:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Réserves naturelles',
|
|
|
|
|
id: 'reserves_naturelles',
|
|
|
|
|
layers: [
|
2024-02-08 16:14:03 +01:00
|
|
|
|
[
|
|
|
|
|
'Réserves naturelles nationales',
|
|
|
|
|
'PROTECTEDAREAS.RN',
|
|
|
|
|
'PROTECTEDAREAS.RN'
|
|
|
|
|
],
|
2020-10-15 17:22:08 +02:00
|
|
|
|
[
|
|
|
|
|
'Périmètres de protection de réserves naturelles',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'PROTECTEDAREAS.MNHN.RN.PERIMETER',
|
|
|
|
|
'normal'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'Réserves naturelles de Corse',
|
|
|
|
|
'PROTECTEDAREAS.RNC',
|
|
|
|
|
'PROTECTEDAREAS.RNC'
|
2020-10-15 17:22:08 +02:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'Réserves naturelles régionales',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'PROTECTEDSITES.MNHN.RESERVES-REGIONALES',
|
2020-10-15 17:22:08 +02:00
|
|
|
|
'PROTECTEDSITES.MNHN.RESERVES-REGIONALES'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Natura 2000',
|
|
|
|
|
id: 'natura_2000',
|
|
|
|
|
layers: [
|
2024-02-08 16:14:03 +01:00
|
|
|
|
[
|
|
|
|
|
'Sites Natura 2000 (Directive Habitats)',
|
|
|
|
|
'PROTECTEDAREAS.SIC',
|
|
|
|
|
'PROTECTEDAREAS.SIC'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'Sites Natura 2000 (Directive Oiseaux)',
|
|
|
|
|
'PROTECTEDAREAS.ZPS',
|
|
|
|
|
'PROTECTEDAREAS.ZPS'
|
|
|
|
|
]
|
2020-10-15 17:22:08 +02:00
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Zones humides d’importance internationale',
|
|
|
|
|
id: 'zones_humides',
|
|
|
|
|
layers: [
|
2024-02-08 16:14:03 +01:00
|
|
|
|
[
|
|
|
|
|
'Zones humides d’importance internationale',
|
|
|
|
|
'PROTECTEDAREAS.RAMSAR',
|
|
|
|
|
'PROTECTEDAREAS.RAMSAR'
|
|
|
|
|
]
|
2020-10-15 17:22:08 +02:00
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'ZNIEFF',
|
|
|
|
|
id: 'znieff',
|
|
|
|
|
layers: [
|
|
|
|
|
[
|
|
|
|
|
'Zones naturelles d’intérêt écologique faunistique et floristique de type 1 (ZNIEFF 1 mer)',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'PROTECTEDAREAS.ZNIEFF1.SEA',
|
|
|
|
|
'normal'
|
2020-10-15 17:22:08 +02:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'Zones naturelles d’intérêt écologique faunistique et floristique de type 1 (ZNIEFF 1)',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'PROTECTEDAREAS.ZNIEFF1',
|
2020-10-15 17:22:08 +02:00
|
|
|
|
'PROTECTEDAREAS.ZNIEFF1'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'Zones naturelles d’intérêt écologique faunistique et floristique de type 2 (ZNIEFF 2 mer)',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'PROTECTEDAREAS.ZNIEFF2.SEA',
|
|
|
|
|
'normal'
|
2020-10-15 17:22:08 +02:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'Zones naturelles d’intérêt écologique faunistique et floristique de type 2 (ZNIEFF 2)',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
'PROTECTEDAREAS.ZNIEFF2',
|
2020-10-15 17:22:08 +02:00
|
|
|
|
'PROTECTEDAREAS.ZNIEFF2'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
label: 'Cadastre',
|
|
|
|
|
id: 'cadastres',
|
2024-02-08 16:14:03 +01:00
|
|
|
|
layers: [
|
|
|
|
|
['Cadastre', 'CADASTRE', 'DECALAGE DE LA REPRESENTATION CADASTRALE']
|
|
|
|
|
]
|
2020-10-15 17:22:08 +02:00
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
function buildSources() {
|
|
|
|
|
return Object.fromEntries(
|
2020-12-11 14:47:50 +01:00
|
|
|
|
OPTIONAL_LAYERS.filter(({ id }) => id !== 'cadastres')
|
2024-02-08 16:14:03 +01:00
|
|
|
|
.flatMap(({ layers }) => layers)
|
|
|
|
|
.map(([, code, style]) => [
|
2021-07-01 18:50:35 +02:00
|
|
|
|
getLayerCode(code),
|
2024-02-08 16:14:03 +01:00
|
|
|
|
rasterSource([ignServiceURL(code, style)], 'IGN-F/Géoportail/MNHN')
|
2020-12-11 14:47:50 +01:00
|
|
|
|
])
|
2020-10-15 17:22:08 +02:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-20 18:22:49 +02:00
|
|
|
|
function rasterSource(
|
|
|
|
|
tiles: string[],
|
|
|
|
|
attribution: string
|
|
|
|
|
): RasterSourceSpecification {
|
2020-10-15 17:22:08 +02:00
|
|
|
|
return {
|
|
|
|
|
type: 'raster',
|
|
|
|
|
tiles,
|
|
|
|
|
tileSize: 256,
|
|
|
|
|
attribution,
|
|
|
|
|
minzoom: 0,
|
|
|
|
|
maxzoom: 18
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-20 18:22:49 +02:00
|
|
|
|
function rasterLayer(
|
|
|
|
|
source: string,
|
|
|
|
|
opacity: number
|
|
|
|
|
): RasterLayerSpecification {
|
2021-05-06 18:51:19 +02:00
|
|
|
|
return {
|
|
|
|
|
id: source,
|
|
|
|
|
source,
|
|
|
|
|
type: 'raster',
|
2021-07-01 18:50:35 +02:00
|
|
|
|
paint: { 'raster-resampling': 'linear', 'raster-opacity': opacity }
|
2021-05-06 18:51:19 +02:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-08 12:49:51 +01:00
|
|
|
|
export function buildOptionalLayers(
|
|
|
|
|
ids: string[],
|
|
|
|
|
opacity: Record<string, number>
|
2024-09-20 18:22:49 +02:00
|
|
|
|
): LayerSpecification[] {
|
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 }) =>
|
2022-02-08 12:49:51 +01:00
|
|
|
|
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'
|
2024-09-20 18:22:49 +02:00
|
|
|
|
? (cadastreLayers as LayerSpecification[])
|
2021-07-01 18:50:35 +02:00
|
|
|
|
: [rasterLayer(getLayerCode(code), opacity)]
|
2020-10-15 17:22:08 +02:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-08 12:49:51 +01:00
|
|
|
|
export const NBS = ' ' as const;
|
2021-07-01 18:50:35 +02:00
|
|
|
|
|
2022-02-08 12:49:51 +01: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);
|
2021-06-30 10:28:02 +02:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-08 12:49:51 +01:00
|
|
|
|
function getLayerCode(code: string) {
|
2021-07-01 18:50:35 +02:00
|
|
|
|
return code.toLowerCase().replace(/\./g, '-');
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-20 18:22:49 +02:00
|
|
|
|
export const style: StyleSpecification = {
|
2020-10-15 17:22:08 +02:00
|
|
|
|
version: 8,
|
2024-09-20 18:22:49 +02:00
|
|
|
|
metadata: {
|
2020-10-15 17:22:08 +02:00
|
|
|
|
'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'
|
|
|
|
|
},
|
2021-09-01 21:58:12 +02:00
|
|
|
|
'photographies-aeriennes': rasterSource(
|
2024-02-08 16:14:03 +01:00
|
|
|
|
[ignServiceURL('ORTHOIMAGERY.ORTHOPHOTOS', 'normal', 'image/jpeg')],
|
2021-09-01 21:58:12 +02:00
|
|
|
|
'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(
|
2024-02-08 16:14:03 +01:00
|
|
|
|
[ignServiceURL('GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2', 'normal')],
|
2020-10-15 17:22:08 +02:00
|
|
|
|
'IGN-F/Géoportail'
|
|
|
|
|
),
|
|
|
|
|
...buildSources()
|
|
|
|
|
},
|
|
|
|
|
sprite: 'https://openmaptiles.github.io/osm-bright-gl-style/sprite',
|
2024-09-20 18:22:49 +02:00
|
|
|
|
glyphs: 'https://openmaptiles.geo.data.gouv.fr/fonts/{fontstack}/{range}.pbf',
|
|
|
|
|
layers: []
|
|
|
|
|
};
|