Utiliser les fonds de carte unmap avec mapcn
mapcn est un ensemble de composants cartographiques React à la manière de
shadcn, bâtis sur MapLibre : un <Map>, des contrôles, des marqueurs, des fenêtres contextuelles
et des tracés, copiés dans votre projet comme n'importe quel composant shadcn. unmap donne à ces
composants un fond de carte conçu au Canada, en douze styles, avec des libellés en français sur
demande. Tout le changement tient en deux URL de style passées à <Map>. Vos composants, vos
marqueurs et vos couches restent exactement comme ils sont.
Installation
Ajoutez le composant de carte de mapcn. Il copie components/ui/map.tsx dans votre projet et
installe maplibre-gl :
npx shadcn@latest add @mapcn/mapObtenez ensuite une clé dans le tableau de bord et placez-la dans votre fichier d'environnement public :
# .env.local
NEXT_PUBLIC_UNMAP_KEY=um_live_...Une clé utilisée par une carte dans un navigateur est lisible par quiconque charge la page, chez
tous les fournisseurs de cartes. Restreignez-la à vos origines de production dans le tableau de
bord plutôt que de tenter de la cacher, et servez-vous d'une clé um_test_ pendant le
développement. Avec Vite, la même clé s'appelle VITE_UNMAP_KEY et se lit dans
import.meta.env. Voir Authentification.
Brancher la carte sur unmap
Une petite fonction construit l'URL du style, pour que la clé et le nom du style vivent à un seul endroit :
// lib/unmap.ts
const key = process.env.NEXT_PUBLIC_UNMAP_KEY;
export function unmapStyle(mode: "light" | "dark", style = "base") {
return `https://api.unmap.dev/styles/${style}.json?key=${key}&mode=${mode}`;
}Passez une URL par mode à la propriété styles de mapcn :
// components/city-map.tsx
import { Map, MapControls } from "@/components/ui/map";
import { unmapStyle } from "@/lib/unmap";
const styles = { light: unmapStyle("light"), dark: unmapStyle("dark") };
export function CityMap() {
return (
<div className="h-[420px] w-full">
<Map styles={styles} center={[-114.0719, 51.0447]} zoom={11}>
<MapControls />
</Map>
</div>
);
}C'est toute l'intégration. mapcn choisit le mode lui-même : il surveille une classe dark ou
light, ou un attribut data-theme, sur <html>, se rabat sur la préférence du système
d'exploitation, et passe d'une URL à l'autre quand l'une ou l'autre change. center et zoom
sont des options MapLibre que <Map> transmet telles quelles.
Aucun transformRequest à écrire. La passerelle recopie la clé qui a servi à charger le style dans
chaque URL de tuile, de glyphe et de sprite qu'il contient, donc MapLibre authentifie chaque
requête de lui-même.
L'URL accepte tout le reste de ce qu'une carte unmap sait faire :
- Style.
baseest le style par défaut. Les autres sontmuted,outdoor,blueprint,blush,orchid,canopy,lagoon,tropic,sunset,boldetpastel, chacun dans les deux modes :unmapStyle("dark", "outdoor")donne une carteoutdooren mode sombre. Ils sont tous décrits dans l'API de cartes. - Langue. Ajoutez
&lang=frpour des libellés en français. Sans ce paramètre, la passerelle lit l'Accept-Languagedu navigateur : une personne dont le navigateur préfère le français obtient des libellés en français sans une ligne de code. - Thème. Ajoutez
&theme=<code>avec un code tiré de /create pour appliquer votre propre cartographie. Cela n'a rien à voir avec la propriététhemede mapcn, qui force son choix entre clair et sombre.
Le style porte sa propre attribution (unmap et les contributeurs d'OpenStreetMap), et le contrôle d'attribution compact de mapcn l'affiche. Gardez-la visible : la licence d'OpenStreetMap l'exige.
Si votre site envoie une politique de sécurité du contenu (CSP) stricte, ajoutez
https://api.unmap.dev à connect-src, à côté des entrées pour le worker que liste la
page d'installation de mapcn.
Itinéraires et recherche
Le <MapRoute> de mapcn trace n'importe quelle liste de paires [lng, lat], et ses marqueurs
prennent une longitude et une latitude. Les clients typés d'unmap renvoient exactement cela : vous
gardez les composants de mapcn et appelez les nôtres pour les données.
npm i @unmap/routing @unmap/geocodingDans une page App Router de Next.js, un Server Component peut faire les deux appels avant son rendu :
// app/directions/page.tsx
import { Geocoder } from "@unmap/geocoding";
import { Router } from "@unmap/routing";
import { Map, MapControls, MapMarker, MarkerContent, MarkerPopup, MapRoute } from "@/components/ui/map";
import { unmapStyle } from "@/lib/unmap";
// Server-side calls send no Origin header, so they use an unrestricted server key.
const key = process.env.UNMAP_API_KEY ?? "";
const geocoder = new Geocoder({ key });
const router = new Router({ key });
export default async function Directions() {
const [[from], [to]] = await Promise.all([
geocoder.search("Calgary Tower", { limit: 1 }),
geocoder.search("Calgary Zoo", { limit: 1 }),
]);
const route = await router.route([from.lng, from.lat], [to.lng, to.lat], { mode: "auto" });
return (
<div className="h-[420px] w-full">
<Map styles={{ light: unmapStyle("light"), dark: unmapStyle("dark") }} center={[from.lng, from.lat]} zoom={12}>
<MapRoute coordinates={route.geometry.coordinates} />
{[from, to].map((place) => (
<MapMarker key={place.id} longitude={place.lng} latitude={place.lat}>
<MarkerContent />
<MarkerPopup>{place.name}</MarkerPopup>
</MapMarker>
))}
<MapControls />
</Map>
</div>
);
}route.geometry est une LineString GeoJSON : ses coordinates vont dans <MapRoute> sans
transformation. Chaque résultat de géocodage porte id, name, lng et lat, et
geocoder.autocomplete(q) renvoie la même forme pour une boîte de recherche. Ne mettez jamais
cette clé serveur dans une variable NEXT_PUBLIC_. Hors de Next.js, ou dans un composant client,
faites les deux mêmes appels dans un effet, avec la clé du navigateur.
mode accepte aussi car, bicycle, pedestrian et truck. Les pages
API d'itinéraires et API de géocodage
décrivent toutes les options.
Ce que coûte une requête
unmap facture à la requête. Chaque document de style compte pour un appel, tout comme chaque
tuile, chaque requête de géocodage et chaque itinéraire; les glyphes et les sprites ne sont jamais
facturés. Une carte qui charge 40 tuiles coûte 40 appels, autant que 40 frappes de saisie
semi-automatique, et passer du mode clair au mode sombre charge l'autre document de style. Les
requêtes venant de localhost et des autres origines dev sont comptées, mais jamais facturées.
Un domaine en production demande un forfait payant, puisqu'une clé Hobby n'accepte que des
origines dev. Les chiffres sont dans Forfaits et limites.
Le fond de carte par défaut de mapcn est celui de CARTO. Le
README de mapcn précise qu'un
usage commercial des fonds de carte CARTO exige une licence CARTO Enterprise; les détails sont dans
les conditions des fonds de carte de CARTO. Passer vos propres
styles, comme ci-dessus, remplace entièrement ce fond par défaut.
Quand choisir plutôt le registre unmap
mapcn convient bien quand vous voulez ses composants et qu'il ne vous manque qu'un fond de carte. unmap publie aussi son propre registre shadcn à registry.unmap.dev, et il convient mieux dans ces cas :
- Vous développez en Vue ou en Nuxt. mapcn ne fait que du React. Le registre unmap a une voie shadcn-vue avec les mêmes éléments.
- Vous voulez la recherche et les itinéraires tout faits. Les éléments
geocoderetrouting-panelsont déjà branchés sur la passerelle, sur vos propres Combobox, Field, Input, Button et Alert de shadcn. - Vous voulez que la carte suive votre système de design. Les contrôles et les fenêtres
contextuelles de MapLibre prennent vos jetons, les marqueurs et les tracés utilisent par défaut
votre
--primary, et le style et le thème sont des propriétés plutôt qu'une URL à construire.
Commencez par npx @unmap/cli add map. Composants donne la liste
complète et les deux façons d'installer.