Ajouter des itinéraires à React
Deux adresses en entrée, une ligne sur la carte, plus la distance et la durée pour l'étiqueter. Le panneau copié couvre toute l'interaction, y compris le géocodage des deux extrémités. Le hook est l'appel d'itinéraire seul, pour quand le départ et l'arrivée existent déjà dans votre application.
Installation
npx @unmap/cli add routing-panelnpm i @unmap/reactLe panneau
Comme le géocodeur, <RoutingPanel> est un enfant de <Map> : il dessine sur la carte qu'il
trouve via map-context, et il résout les deux champs texte en coordonnées pour vous.
import { Map } from "@/components/ui/map";
import { RoutingPanel } from "@/components/ui/routing-panel";
export default function App() {
const apiKey = import.meta.env.VITE_UNMAP_KEY as string;
return (
<div className="h-dvh">
<Map apiKey={apiKey} center={[-114.07, 51.05]} zoom={11} className="h-full">
<div className="absolute left-3 top-3 z-10 w-80">
<RoutingPanel apiKey={apiKey} mode="auto" />
</div>
</Map>
</div>
);
}import { useEffect } from "react";
import { useDirections, useUnmap } from "@unmap/react";
export default function Leg() {
const apiKey = import.meta.env.VITE_UNMAP_KEY as string;
const { mapContainer, map, ready } = useUnmap({ apiKey, center: [-114.07, 51.05], zoom: 11 });
const { route } = useDirections({ apiKey });
useEffect(() => {
if (!ready || !map) return;
void route([-114.07, 51.05], [-113.99, 51.04], { mode: "auto" }).then((leg) => {
map.addSource("leg", {
type: "geojson",
data: { type: "Feature", properties: {}, geometry: leg.geometry },
});
map.addLayer({
id: "leg-line",
type: "line",
source: "leg",
layout: { "line-cap": "round", "line-join": "round" },
paint: { "line-color": "#FF3E9A", "line-width": 3 },
});
});
}, [ready, map, route]);
return <div ref={mapContainer} style={{ height: "100dvh" }} />;
}Attendez ready avant d'ajouter la source. Une carte qui n'a pas émis load n'a pas encore de
style, et addSource y lève une erreur.
Des coordonnées, pas des adresses
route prend des paires [lng, lat]. Si vos entrées sont du texte, géocodez-les d'abord, ce qui
fait un appel de plus chacune et explique l'existence du panneau copié :
import { useGeocoder, useDirections } from "@unmap/react";
export default function RouteBetween() {
const apiKey = import.meta.env.VITE_UNMAP_KEY as string;
const { search } = useGeocoder({ apiKey });
const { route } = useDirections({ apiKey });
async function go(fromText: string, toText: string) {
const [from] = await search(fromText, { limit: 1 });
const [to] = await search(toText, { limit: 1 });
if (!from || !to) throw new Error("could not resolve both endpoints");
return route([from.lng, from.lat], [to.lng, to.lat], { mode: "auto" });
}
return <button onClick={() => void go("Calgary Tower", "Bow Valley Square")}>Itinéraire</button>;
}Ce qui revient
distanceMeters, durationSeconds, et une LineString GeoJSON. C'est tout le résultat :
l'étiquette à côté de votre ligne ne demande donc pas un second appel. Cinq modes de déplacement
sont offerts, auto, car, bicycle, pedestrian et truck, et un mode inconnu donne un 400
plutôt qu'un trajet en voiture silencieux.
La durée est un modèle du réseau routier sans aucune donnée de trafic en direct. C'est une bonne estimation d'un dimanche calme et une estimation optimiste du vendredi à dix-sept heures.
Problèmes courants
addSource lève une erreur. La carte n'est pas chargée. Conditionnez sur ready.
L'itinéraire s'arrête à la frontière. Le graphe est l'extrait du Canada : il n'y a donc pas d'itinéraire transfrontalier. Deux extrémités de part et d'autre de la ligne n'ont pas de réponse plutôt qu'un détour.
Un itinéraire de camion est refusé. mode: "truck" exige un profil de véhicule valide ; la
documentation des itinéraires liste les dimensions et leurs limites.
Pour aller plus loin
- Obtenir un itinéraire pour la version sans framework
- Modes de déplacement pour les cinq modes côte à côte
- Ajouter une carte à React pour la carte sur laquelle cela se dessine