Changelog
All notable changes to @geoleaf/core are documented here.
Format: Keep a Changelog — Semantic Versioning.
[Unreleased]
Added
@geoleaf-plugins/cog: nouveau plugin premium de rendu Cloud Optimized GeoTIFF (COG). Lecture native viageotiff@^3.0.5avec sélection d'overview automatique selon le viewport, rendu multi-bandes (1/3/4 canaux, nodata transparent, LUT colorMap), injection comme sourceimageMapLibre GL JS. API :GeoLeaf.COG.addLayer(url, map, opts?),GeoLeaf.COG.removeLayer(map, id),GeoLeaf.COG.getInfo(url, opts?). Bundle séparé du core, licence commerciale, distribué via GitHub Packages.@geoleaf-plugins/flatgeobuf: nouveau plugin MIT de chargement FlatGeobuf. Streaming via async iterator (flatgeobufv4.4.0), filtrage spatial bbox via R-tree index + HTTP Range requests, auto-refresh debounced sur viewport. API :GeoLeaf.FlatGeobuf.load(url),loadBbox(url, bbox),loadAsLayer(url, options?),loadBboxAsLayer(url, bbox, options?). Bundle séparé du core (~91 KB raw / 20 KB gzip).@geoleaf-plugins/file-import: nouveau plugin MIT d'import de fichiers géospatiaux. Formats supportés : GPX, KML, KMZ, CSV (lat/lng ou WKT), TopoJSON. API :GeoLeaf.FileImport.convert(file),importAsLayer(file, options?),getSupportedFormats(),registerConverter(ext, converter). Bundle séparé du core (~276 KB raw).Geocoding: 31ème export nommé ESM. Module de recherche d'adresse lazy-loadé (_loadModule("geocoding")), APIGeoLeaf.Geocoding. Quatre fournisseurs intégrés :addok,nominatim,photon, URL personnalisée.geoleaf:geocoding:result: nouvel événement émis lors de la sélection d'un résultat de géocodage — payload{ label, lat, lng, bounds? }.GeocodingConfigdansui.jsonougeoleaf.config.json: paramètresenabled,provider,position,placeholder,minChars,resultLimit,debounceMs,flyToZoom.- Terrain 3D : support du relief 3D sur basemaps raster (
type: "tile") et vectoriels (type: "maplibre"). Configuration viabasemaps.{id}.terrain(enabled,demUrl,demEncoding,demMaxZoom,exaggeration,default3D,pitch,bearing). Activation automatique sans toggle UI —default3D: trueactive le terrain au switch vers le basemap,falsele désactive. Source DEM validée en production : AWS Terrarium (~30m). map.maxPitchdansprofile.json: plafond d'inclinaison caméra configurable. GeoLeaf lève la limite MapLibre GL JS par défaut (60°) à 80°. Valeur par défaut :80. Configurable viaprofile.json > map.maxPitch.- Fill-Extrusion : support des polygones 3D via le type de layer MapLibre GL JS
fill-extrusion. Configurergeometry: "fill-extrusion"dans le fichier config de couche, puis définirfillExtrusionColor,fillExtrusionOpacity,fillExtrusionHeightetfillExtrusionBasedans le fichier style.fillExtrusionHeightaccepte une valeur fixe (mètres) ou un nom de champ feature (ex."hauteur"). La validation est assurée parstyle-validator-extrusion.ts: erreur sifillExtrusionHeightmanquant, warning si le champ n'est pas trouvé dans les propriétés du premier feature. GeoLeaf.Utils.wktToGeoJSON(wkt): convertit une chaîne WKT en objet géométrie GeoJSON. Supporte les 7 types standardisés (Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection) en 2D et 3D/Z. Supporte le préfixe SRID (SRID=4326;…) et les qualificateursZ/M/ZM. Retournenullsans exception si l'entrée est invalide.- OGC API Features : support natif du chargement de couches GeoJSON depuis un endpoint OGC API Features. Configurer
data.ogcApidans la définition de couche :url,collectionId,bbox,maxFeatures,limit,autoRefresh,autoRefreshDebounce,headers. Pagination automatique via liensnext, garde-foumaxFeatures, annulation viaAbortController, conversion automatique des géométries WKT. ModeautoRefresh: true: re-fetch surmoveendavec bbox viewport courant. .topojsonet.fgbajoutés à la validationFileValidator(préparation plugins Sprint 3/4).- Basemap
type: "image": nouveau type de fond de carte pour images géoréférencées statiques (format natif MapLibreimage). Configuration viabasemaps.{id}.imageSource(url,coordinates,opacity). L'image est positionnée selon 4 coins[lng, lat]; sanscoordinates, les limites monde sont utilisées par défaut. - Basemap
type: "hillshade": ombrage du relief via couche MapLibrehillshade. Configuration viabasemaps.{id}.hillshade(demUrl,demEncoding,demMaxZoom,shadowColor,highlightColor,accentColor,exaggeration,illuminationDirection,illuminationAnchor). Réutilise automatiquement la source DEMterrain-demsi elle est déjà présente avec la même URL (compatible avectype: "tile"terrain 3D). - Basemap
type: "wmts": support des serveurs WMTS OGC via résolution dynamique duGetCapabilities. Configuration viabasemaps.{id}.wmts(getCapabilitiesUrl,layer,tileMatrixSet,format). Parsing XML namespace-safe, cache in-memory des URL résolues, annulation viaAbortController. - Basemap
type: "wms": support des serveurs WMS OGC (flux raster). Configuration viabasemaps.{id}.wms(url,layers,version,crs,format,tileSize,transparent,styles). Construit l'URL template avec placeholder{bbox-epsg-3857}compatible MapLibre GL JS.
Changed
- Extraction GPX du core : la conversion GPX→GeoJSON (méthode
DataConverter.convertGpxToGeoJSON()+ helpers privés) a été retirée de@geoleaf/coreet migrée vers@geoleaf-plugins/file-import. Le pipeline route (route-utils.ts::parseGPX()) et la normalisation (normalizer.ts::normalizeFromGPX()) ne sont pas affectés. InterfaceDataConverterLikemise à jour (retrait deconvertGpxToGeoJSON()). Le loadersingle-layer.tsn'a plus de brancheisGpx— simplification du flux de chargement.
Fixed
- Fill-extrusion plates au chargement : les couches
fill-extrusions'affichaient à plat (hauteur 0) au chargement initial et après changement de style. Cause : l'objet style complet{ id, label, style: {…} }était passé directement aux fonctions de rendu au lieu du paint plat —toFillExtrusionPaint()ne trouvait pas les clésfillExtrusionHeightetc. à la racine. Corrigé danstheme-applier/visibility.tsetvector-tiles.ts. - Style actif perdu après changement de basemap : les couches GeoJSON (dont fill-extrusion) revenaient systématiquement au style par défaut après chaque switch de basemap. Cause :
_rebuildGeoJSONLayers()lisait.defaultStylesur un paint plat, toujoursundefined. Corrigé par la lecturecurrentStyle.style ?? currentStyle. - Sous-couche
lineparasite sur les couches fill-extrusion : une sous-couchelineétait générée par-dessus les volumes 3D, produisant un rendu parasite. Corrigé par un guardgeometry !== "fill-extrusion"dansmaplibre-helpers.ts. - Couches vector tiles invisibles après switch de basemap : les couches VT n'étaient pas rechargées après un changement de basemap (elles étaient ignorées dans
_rebuildGeoJSONLayerscarfeatures: []). Corrigé par une branche dédiéeisVectorTile === truedéclenchantloadVectorTileLayer().
[2.0.0] - 2026-03-22
First public release on npm. See the full release notes for complete details.
⚠️ Breaking Changes
- Leaflet → MapLibre GL JS v5 : moteur de rendu remplacé. Supprimer
leaflet/leaflet.markercluster, ajoutermaplibre-gl@^5.0.0en peer dependency. - Convention coordonnées :
[lat, lng](Leaflet) →[lng, lat](GeoJSON/MapLibre standard). - Scope npm renommé :
geoleaf→@geoleaf/core. - UMD supprimé : distribution ESM-only. Remplacer
<script src="geoleaf.umd.js">par<script type="module">. container:→mapId:: clé d'initialisation du conteneur carte renommée.applyTheme(theme)→applyTheme(layerId, themeId): signature changée.- CSS : classes
.leaflet-*→.maplibregl-*(MapLibre) +.gl-*(GeoLeaf interne).
Added
- MaplibreAdapter : implémentation complète de
IMapAdapter(33 méthodes) — rendu WebGL, clustering GPU natif, MVT/PBF vector tiles. @geoleaf/connectorv1.0.0 (MIT, npm public) : intercepteur fetch universel pour sources géospatiales authentifiées (GeoJSON, WFS, vector tiles, PMTiles).- Basemaps : CARTO Positron / Dark Matter / Voyager, ESRI Street, support
pmtiles://. - Performance marks :
window.__GEOLEAF_PERF__ = trueactive 8 paires de marks (TTI, boot, modules...). - Architecture TypeScript :
lazy-module-loader.ts,loader-types.ts(13 interfaces service locator), contracts enrichis (api.contract.ts,ui-controls.contract.ts,map-adapter.contract.ts). - Sécurité : module CSRF complet (
csrf-token.ts),DOMSecurity.setSafeHTML()systématique,CSS.escape()sur POI IDs. - Accessibilité :
prefers-reduced-motion,:focus-visible,aria-label+role="img"sur markers MapLibre. - Documentation : site VitePress
geoleaf.dev/docs/, TypeDoc dual entries, 273 fichiers déployés.
Changed
- Build : UMD supprimé — 3 sorties ESM (bundle full chunked, preserveModules, lite sans table/labels/route/search).
- Tests : migration complète Jest → Vitest 3 + Istanbul — 323 suites, 8 317 tests, couverture branches 77,97 %.
- TypeScript strict : 30
@ts-nochecksupprimés, 0 erreurtsc --noEmit --strict. - Dead code : 7 fichiers orphelins et 172 exports morts supprimés (Knip).
- Filtres GeoJSON : nouveau chemin MapLibre via
updateLayerData()sans corruption du dataset source.
Fixed
- Basemap raster s'affichait au-dessus de toutes les couches GeoJSON/POI/route.
- Style selector niveau racine — wrapper non déroulé avant
normalizeToFlat(). - Clustering natif MapLibre — options
cluster/clusterRadius/clusterMaxZoomnon propagées à la source. - Side panel vide — objets imbriqués sérialisés en JSON string par MapLibre lors des clics.
- Échelle graphique invisible — classes CSS
.gl-scale-graphicabsentes. - Labels glyphs 404 —
_resolveMapFontStack()avec fallback dynamique. - Visibilité zoom ignorée après changement de thème.
- StyleRules data-driven inopérantes — préfixe
"properties."incorrect dans les expressions MapLibre.
Performance
| Métrique | v1.x (Leaflet) | v2.0.0 (MapLibre) |
|---|---|---|
| 10 000 markers | 4 FPS (DOM) | 60 FPS (GPU) |
| 10 000 GeoJSON | 572 ms | < 100 ms WebGL |
| ESM bundle gzip | 35 KB | ~35 KB |
| UMD bundle | 196 KB gzip | ❌ supprimé |
Migration
- V1 → V2 : voir MIGRATION_V1_V2
- Release notes complètes v2.0.0 : voir Patchnote V2.0.0
