fr

Éditer un fond de carte vectoriel : Maputnik et les alternatives libres à l'éditeur MapTiler

Guide complet et sourcé des éditeurs de style vectoriel libres et gratuits : ce qu'un éditeur fait vraiment, les murs de MapTiler Map Designer, Maputnik, Charites (YAML/git), les fausses pistes, et comment brancher ses propres data sources et ses propres sprites.

Conversation ayant produit cet article

Tu as stylé un fond de carte dans le Map Designer de MapTiler. C’est confortable tant que tu restes dans leur jardin : leurs tuiles, leur compte, leur gestionnaire d’icônes. Puis tu veux tes tuiles (un OpenFreeMap auto-hébergé, un tileserver-gl maison) et tes icônes (un sprite Pinhead que tu régénères en CI), et tu te heurtes à des murs : quota de sprite, perte du jeu d’icônes précédent à chaque upload, lock-in au compte.

D’où la question : quels éditeurs libres et gratuits permettent d’éditer un style vectoriel en branchant ses propres sources ? La réponse courte est « Maputnik », mais le champ mérite d’être cartographié — parce que le vrai critère de choix n’est pas l’UI, c’est la façon dont l’outil te laisse pointer vers ton infrastructure.

Cet article couvre l’écosystème (MapTiler Map Designer, Maputnik, Charites, et les fausses pistes), puis détaille les deux opérations qui comptent vraiment : fournir ses data sources et fournir ses sprites.

Cet article s’appuie sur deux articles précédents. Self-héberger OpenFreeMap couvre la production des tuiles vectorielles ; Sprites d’icônes MapLibre : intégrer Pinhead couvre la génération du sprite. Ici, on branche les deux dans un éditeur.


1. Le vrai critère : un éditeur écrit un style.json, il n’héberge rien

Avant de comparer les outils, il faut être au clair sur ce qu’un éditeur de style fait et ne fait pas.

Un style MapLibre/Mapbox GL est un fichier JSON qui ne contient aucune donnée cartographique. Il contient des références (des URLs) vers trois ressources externes, plus la description des couches :

{
  "version": 8,
  "sources": {
    "openmaptiles": {
      "type": "vector",
      "url": "https://tiles.example.com/planet.json"
    }
  },
  "sprite": "https://cdn.example.com/sprites/sprite",
  "glyphs": "https://fonts.example.com/{fontstack}/{range}.pbf",
  "layers": [
    /* ... */
  ]
}

Source : MapLibre Style Spec — Root.

Les trois ressources externes :

RessourceRôleCe que tu fournis
sourcesLes tuiles vectorielles ou GeoJSONL’URL de ton TileJSON ou de ton endpoint XYZ
spriteL’atlas d’icônes (PNG + JSON)L’URL de base de ton sprite
glyphsLes fontes SDF pour les labelsL’URL de ton serveur de glyphes
┌──────────────────────────┐
│      Éditeur de style      │   ← ne stocke QUE du JSON
│  (Maputnik / MapTiler…)    │
└──────────────────────────┘
              │ écrit des URLs vers ↓
   ┌──────────┼───────────────────┐
   ▼          ▼                   ▼
 tuiles     sprite              glyphes
(OpenFree-  (Pinhead +        (fontstack
 Map…)       Spreet…)          SDF)
   ▲          ▲                   ▲
   └──────────┴───────────────────┘
        TON infrastructure, hébergée où tu veux

Conséquence directe : « fournir mes data sources » = pointer l’éditeur vers l’URL de mes tuiles. « fournir mes sprites » = renseigner l’URL de mon sprite. Un éditeur qui rend ces deux champs libres et éditables coche l’essentiel. Un éditeur qui te force à héberger sprite et tuiles chez lui (MapTiler) est le seul vrai obstacle.

C’est pour cela que la comparaison qui suit juge chaque outil sur une question : est-ce qu’il te laisse écrire ces URLs vers ton infra, ou est-ce qu’il te les impose ?


2. MapTiler Map Designer — le point de départ et ses murs

Le Map Designer de MapTiler est un éditeur visuel hébergé, intégré à MapTiler Cloud. Il est excellent pour démarrer : rendu temps réel, thèmes prêts à l’emploi, gestion d’icônes intégrée.

Ce qu’il permet côté sources

Contrairement à une idée reçue, MapTiler accepte tes propres données. Dans le gestionnaire de sources, tu peux ajouter, en plus des tuiles MapTiler, tes propres jeux sous deux formes : Tiles (conteneur GeoPackage ou MBTiles, tuiles raster PNG/JPG/WebP ou vectorielles MVT) ou Vector data file (GeoJSON). Tes tuiles apparaissent alors dans une section « My Tiles ».

Source : MapTiler — Data sources.

Où sont les murs

Le problème n’est pas l’absence de fonctionnalité, c’est le modèle : tout vit dans MapTiler Cloud, sous ton compte, sous quota.

  • Upload chez eux. Pour utiliser tes tuiles dans le Designer, tu les téléverses dans MapTiler Cloud (GeoPackage/MBTiles). Tu ne pointes pas vers un tiles.example.com que tu contrôles ; tu héberges chez MapTiler. Source : MapTiler — Data sources.
  • Sprite : quota strict. Les sprites raster sont bornés par une limite globale : une image 4000×4000 px, ou 4 images 1000×1000, etc. Source : MapTiler — Using Sprites.
  • Sprite : écrasement. « Quand tu téléverses un nouveau jeu d’icônes, tu perds automatiquement le précédent. » Il n’y a pas de versionnement ni de composition de plusieurs sprites côté Designer. Source : MapTiler — Using Sprites.
  • Lock-in. Le style produit référence des URLs api.maptiler.com/...?key=<clé>. Migrer vers une infra maison demande de réécrire ces URLs à la main.

MapTiler Map Designer n’est donc ni libre ni auto-hébergeable dans son édition Cloud (il existe une offre serveur payante, MapTiler Server, mais ce n’est pas l’éditeur gratuit dont on parle). C’est le confort au prix du contrôle — exactement ce qu’on veut dépasser.


3. Maputnik — l’alternative de référence, libre et auto-hébergeable

Maputnik est l’éditeur visuel officiel de la MapLibre Style Specification. C’est la réponse par défaut à la question de départ.

  • Licence : MIT.
  • Version : v3.1.0 (juillet 2026).
  • Techno : TypeScript, React, MapLibre GL JS.
  • Usage : en ligne sur maplibre.org/maputnik (tout est en localStorage, rien n’est envoyé à un serveur), ou auto-hébergé.

Source : github.com/maplibre/maputnik.

Auto-hébergement en une commande

docker run -it --rm -p 8888:8000 ghcr.io/maplibre/maputnik:main
# → http://localhost:8888

L’image Docker embarque toute l’app statique. --help liste les options CLI (montage de volume pour travailler sur des fichiers locaux). Source : github.com/maplibre/maputnik.

Brancher ses data sources

C’est le point clé : Maputnik ne t’impose aucune source. Dans le panneau Data Sources, tu ajoutes une source et choisis son type dans un menu déroulant :

  • Vector (XYZ URLs) — pour un endpoint .../{z}/{x}/{y}.pbf ou un TileJSON
  • Raster / Raster DEM
  • GeoJSON (URL ou inline)

Puis tu renseignes l’URL. Source : GeoServer Training — Styling Vector Tile Layers in Maputnik.

Concrètement, pour un OpenFreeMap auto-hébergé (cf. l’article dédié), tu pointes la source openmaptiles vers ton TileJSON :

https://tiles.example.com/planet.json

Brancher ses sprites (et ses glyphes)

Dans Style Settings, deux champs libres :

  • Sprite URL — l’URL de base de ton sprite. Maputnik cherchera sprite.json + sprite.png (et les variantes @2x). Renseigne https://cdn.example.com/sprites/sprite.
  • Glyphs URL — le template de fontes, ex. https://fonts.example.com/{fontstack}/{range}.pbf.

Source : GeoServer Training — Styling Vector Tile Layers in Maputnik.

Piège CORS. Maputnik tourne dans le navigateur : il fait des requêtes cross-origin vers ton serveur de tuiles/sprites. Si celui-ci n’envoie pas Access-Control-Allow-Origin, la source restera vide sans message clair. C’est la cause n°1 de « ma source locale ne s’affiche pas » (cf. issue #402 et #208). Servir les tuiles derrière un Caddy avec header Access-Control-Allow-Origin "*" règle le problème.

Verdict

Maputnik coche les deux cases sans réserve : sources 100 % libres, sprite/glyphs 100 % libres, auto-hébergeable, MIT. Pour la plupart des besoins, c’est la fin de la recherche. Les sections suivantes couvrent les cas où on veut autre chose : un workflow versionné dans git (Charites), ou l’édition à la main.


4. Charites — styler en YAML, versionné dans git

Charites (projet UNVT) n’est pas un éditeur graphique : c’est un outil en ligne de commande qui compile un style écrit en YAML vers un style.json MapLibre. L’« éditeur », c’est ton éditeur de texte.

Pourquoi ça compte : un style.json de fond de carte fait facilement 3 000 à 5 000 lignes de JSON illisible, impossible à relire en diff. Charites inverse l’approche.

Source : github.com/unvt/charites et documentation Charites.

Ce qu’il apporte

  • YAML au lieu de JSON — commentaires, ancres, lisibilité.
  • Découpage multi-fichiers — via la directive !!inc/file <chemin>, on éclate les groupes de couches en fichiers séparés. Source : documentation Charites.
  • Variables$backgroundColor, etc., pour factoriser les couleurs.
  • Aperçu livecharites serve <source> lance un serveur local et recompile à la volée pendant l’édition.
  • Import — convertit un style.json existant en arborescence YAML pour reprendre un style existant.

Sources et sprites avec Charites

Charites ne gère pas les sources différemment : elles vivent dans le YAML comme dans le JSON. Tu écris tes URLs de tuiles, de sprite et de glyphs directement — c’est du YAML qui deviendra le JSON de la section 1. Aucune contrainte imposée : tout pointe vers ton infra.

version: 8
sources:
  openmaptiles:
    type: vector
    url: https://tiles.example.com/planet.json
sprite: https://cdn.example.com/sprites/sprite
glyphs: https://fonts.example.com/{fontstack}/{range}.pbf
layers: !!inc/file layers/index.yml

Validation et autocomplétion : ce qu’on a, et ce qu’on n’a pas

C’est la vraie limite de l’approche YAML, et elle mérite d’être posée sans détour.

Charites valide, mais en compile-time, dans le terminal. L’outil embarque un format linter qui s’exécute à chaque charites build et à chaque sauvegarde pendant charites serve (qui recompile à la volée). Les erreurs s’affichent dans le terminal, pas inline dans l’éditeur. Et Charites étant une CLI et non un language server, il n’offre ni autocomplétion, ni suggestion de valeurs : ton éditeur de texte ne connaît pas la spec. La doc mentionne par ailleurs une validation contre Mapbox GL JS v2.x — à surveiller si tu emploies des propriétés MapLibre récentes.

Pour de la validation live inline, deux voies, chacune avec sa limite :

  • L’extension VSCode MapLibre (Kanahiro/maplibre-vscode-extension, v0.2.1) valide en temps réel via @maplibre/maplibre-gl-style-spec et offre un aperçu live (avec support HTTPS et PMTiles). Mais elle ne cible que le JSON (fichiers *style.json), donc le fichier compilé — pas tes sources YAML — et ne documente pas d’autocomplétion : elle diagnostique, elle ne complète pas.
  • redhat.vscode-yaml + JSON Schema serait la voie pour avoir complétion et valeurs adaptées dans du YAML. Sauf que le v8.json de référence MapLibre/Mapbox n’est pas un JSON Schema standard : c’est un format de descripteur interne (l’objet de l’issue #634, non résolue). Il n’existe donc pas de schéma officiel à associer — sans schéma converti par la communauté, aucune complétion. Et de toute façon, les fragments !!inc/file n’étant pas des styles complets, une association de schéma casserait sur les fragments.

La validation fiable reste donc la CLI officielle, à câbler en pre-commit ou en CI sur le JSON compilé :

npm i -g @maplibre/maplibre-gl-style-spec
gl-style-validate dist/style.json   # erreurs sur stdout, --json pour un rapport machine

Source : maplibre/maplibre-style-spec.

BesoinSolution réaliste (2026)
Validation en éditant du YAML❌ pas de JSON Schema officiel → ni inline, ni complétion
Validation live + aperçuExtension Kanahiro, sur le style.json compilé
Autocomplétion / valeurs adaptéesAucune en YAML ; la plus proche = éditer le JSON compilé, ou tâtonner dans Maputnik
Validation fiable CI/pre-commitgl-style-validate sur le JSON compilé

Autrement dit : la complétion « intelligente » avec propositions de valeurs valides, on ne l’a qu’en UI dans Maputnik (qui n’expose que des valeurs valides par construction). En YAML, on troque cette assistance contre la lisibilité et le versionnement.

Quand préférer Charites

  • Le style est un artefact versionné dans un repo, relu en PR, régénéré en CI.
  • Plusieurs personnes éditent — le diff YAML est humainement lisible, contrairement au diff d’un style.json monolithique.
  • On veut factoriser (couleurs, groupes de couches réutilisés).

Le compromis : pas de rendu WYSIWYG ni d’assistance à la saisie. En pratique, on combine — Charites pour la source de vérité versionnée, gl-style-validate en CI, et Maputnik ponctuellement pour l’ajustement visuel fin (on importe le JSON compilé, on tâtonne, on reporte les valeurs dans le YAML).


5. Les fausses pistes (et pourquoi)

Plusieurs outils apparaissent dans les recherches « éditeur de style » mais ne sont pas de bons candidats aujourd’hui pour ce besoin.

Fresco — abandonné et Mapbox-only

Fresco (go-spatial) est un éditeur de style « qui n’essaie pas de cacher la complexité » — philosophie séduisante. Deux problèmes rédhibitoires :

  • Il cible Mapbox GL, pas MapLibre (sa doc ne mentionne que la Mapbox Style Spec). Les divergences de spec depuis le fork MapLibre ne sont pas prises en compte.
  • Sa dernière release (v1.0.1) date de juin 2020. Le projet est en pratique en sommeil.

Licence Apache-2.0, donc techniquement libre, mais pour un fond de carte MapLibre en 2026, c’est un cul-de-sac. Source : github.com/go-spatial/fresco.

L’extension VSCode MapLibre

L’extension VSCode de Kanahiro valide et prévisualise un style.json directement dans l’éditeur (cf. §4 pour ses limites : JSON uniquement, pas d’autocomplétion). Utile en complément d’un workflow à la main ou pour vérifier le JSON compilé par Charites — mais ce n’est pas un éditeur visuel complet à la Maputnik.

L’édition à la main + serveur de dev

L’approche la plus brute : éditer le style.json (ou le YAML Charites) dans son IDE et le charger dans une page MapLibre locale. C’est ce que font les styles générés par code comme OpenStreetMap Americana, qui produisent le style en JavaScript plutôt que de l’éditer. Viable pour un style très paramétrique, mais on perd l’itération visuelle rapide.


6. Fournir ses data sources — la recette concrète

Quel que soit l’éditeur, brancher ses tuiles suit toujours le même schéma. Récapitulatif opérationnel.

6.1 Exposer un TileJSON

Un éditeur préfère une URL de TileJSON (un descripteur JSON qui liste les endpoints de tuiles, les bornes de zoom, l’attribution) plutôt qu’un template XYZ nu. Un OpenFreeMap ou tileserver-gl auto-hébergé en expose un :

{
  "tilejson": "3.0.0",
  "tiles": ["https://tiles.example.com/{z}/{x}/{y}.pbf"],
  "minzoom": 0,
  "maxzoom": 14,
  "vector_layers": [
    /* ... */
  ]
}

Dans le style, on référence par url (le TileJSON) ou par tiles (le template direct) :

"sources": {
  "openmaptiles": {
    "type": "vector",
    "url": "https://tiles.example.com/planet.json"
  }
}

Source : MapLibre Style Spec — Sources.

6.2 CORS, toujours CORS

L’éditeur tournant dans le navigateur, ton serveur de tuiles doit autoriser l’origine de l’éditeur. Configuration Caddy minimale :

tiles.example.com {
  reverse_proxy localhost:8080          # tileserver-gl / openfreemap
  header Access-Control-Allow-Origin "*"
}

Sans ça : source vide, aucune erreur explicite dans l’UI. C’est le piège documenté des issues Maputnik #402 / #208.

6.3 Faire correspondre source-layer

Point souvent oublié : chaque couche type: fill/line/symbol référence une source et une source-layer (la couche interne du MVT : water, transportation, place…). Si tu changes de fournisseur de tuiles (MapTiler → OpenFreeMap), les noms de source-layer peuvent différer selon le schéma (OpenMapTiles, Shortbread…). Un style conçu pour un schéma ne se rebranche pas gratuitement sur un autre.

En pratique : partir d’un style déjà écrit pour ton schéma de tuiles (ex. un style OpenMapTiles si tes tuiles sont OpenMapTiles) et le personnaliser, plutôt que de rebrancher un style d’un autre schéma.


7. Fournir ses icônes — brancher son sprite

La partie sprite renvoie directement à l’article Pinhead + Spreet, qui détaille la génération. Ici, seul le branchement dans l’éditeur nous intéresse.

7.1 Un seul champ : l’URL de base

Un sprite MapLibre, c’est une paire sprite.png + sprite.json (plus les @2x). Dans le style, on ne renseigne que l’URL de base sans extension :

"sprite": "https://cdn.example.com/sprites/sprite"

MapLibre en dérive sprite.json, sprite.png, sprite@2x.json, sprite@2x.png. Dans Maputnik : Style Settings → Sprite URL. Dans Charites : la clé sprite: du YAML. Source : MapLibre Style Spec — Sprite.

7.2 Plusieurs sprites : étendre sans casser

Là où le Designer MapTiler écrase l’ancien jeu, la spec MapLibre v2+ permet de déclarer plusieurs sprites en passant un tableau d’objets {id, url}. On garde le sprite du fond de carte et on ajoute le sien :

"sprite": [
  { "id": "default", "url": "https://cdn.example.com/sprites/base" },
  { "id": "pin",     "url": "https://cdn.example.com/sprites/pinhead" }
]

Les icônes du second se référencent alors "icon-image": "pin:hospital". Source : MapLibre Style Spec — Sprite.

C’est l’avantage décisif d’un éditeur/style libre sur le Designer MapTiler : pas d’écrasement, pas de quota 4096, composition explicite. Le sprite est auto-hébergé (bucket S3, CDN, ou dossier statique derrière Caddy), versionné par URL, servi avec les bons headers CORS + cache — exactement le workflow décrit dans l’article Pinhead.

7.3 Édition graphique : attention

Petit avertissement : dans Maputnik, tu choisis une icon-image parmi celles du sprite déclaré, mais tu n’édites pas le sprite lui-même (ajout/retrait d’icônes). La gestion du sprite reste un pipeline externe (Spreet + CI). L’éditeur consomme le sprite ; il ne le fabrique pas. C’est cohérent avec la section 1 : l’éditeur écrit des URLs, il n’héberge/ne génère pas les ressources.


8. Comparatif et recommandation

CritèreMapTiler Map DesignerMaputnikCharitesFresco
Libre / gratuitFreemium, propriétaire✅ MIT✅ (doc CC-BY-SA)✅ Apache-2.0
Auto-hébergeable❌ (Cloud)✅ Docker✅ CLI✅ (mais…)
Éditeur visuel❌ (YAML)
Data sources libres⚠️ upload chez eux✅ URL libre✅ URL libre✅ URL libre
Sprite libre⚠️ quota, écrasement✅ URL libre✅ URL libre✅ URL libre
Multi-sprites❌ (spec Mapbox)
Cible MapLibre❌ (Mapbox GL)
Versionnable git⚠️ export JSON✅ natif⚠️
Maintenu (2026)✅ v3.1.0❌ (2020)

Recommandation

Pour remplacer l’éditeur MapTiler tout en gardant le confort visuel : Maputnik, auto-hébergé en Docker. Il coche les deux exigences sans réserve — tes tuiles via Data Sources → Vector (XYZ URLs), ton sprite via Style Settings → Sprite URL — et il est le seul éditeur visuel libre activement maintenu et aligné sur la spec MapLibre.

Ajoute Charites dès que le style devient un artefact d’équipe versionné : la source de vérité en YAML dans git, régénérée en CI, et Maputnik utilisé ponctuellement pour l’ajustement visuel.

Écarte Fresco (Mapbox-only, abandonné) et n’attends pas d’un éditeur qu’il fabrique ton sprite : ça reste un pipeline externe (Spreet), l’éditeur ne fait que le consommer.

Le fil rouge des trois articles : le fond de carte auto-hébergé est un assemblage de briques ouvertes et indépendantes — tuiles (OpenFreeMap), icônes (Pinhead + Spreet), style (Maputnik/Charites). L’éditeur n’est qu’une des briques, et surtout : celle qui écrit les URLs vers toutes les autres. Le choisir libre, c’est garder la main sur l’ensemble.