Next.js 13中Leaflet Routing Machine路线显示问题求助
在Next.js 13中使用Leaflet Routing Machine实现路线展示
你遇到的核心问题是没有正确封装Leaflet Routing Machine的控制组件,同时useMap的使用方式有误。下面是具体的解决步骤和修改后的代码:
步骤1:封装Leaflet Routing Machine组件
react-leaflet并未内置Leaflet Routing Machine的组件,需要用createControlComponent手动封装:
import { createControlComponent } from "@react-leaflet/core"; import L from "leaflet"; import "leaflet-routing-machine"; const createRoutingMachineLayer = (props) => { const instance = L.Routing.control({ waypoints: [ L.latLng(...props.start), L.latLng(...props.end), ], lineOptions: { styles: [{ color: "#6FA1EC", weight: 4 }] }, show: false, addWaypoints: false, routeWhileDragging: true, draggableWaypoints: true, fitSelectedRoutes: true, showAlternatives: false }); return instance; }; const RoutingMachine = createControlComponent(createRoutingMachineLayer);
步骤2:修正代码中的无效逻辑
你的route函数对useMap的调用错误,且该函数本身无实际作用,封装完组件后可直接使用RoutingMachine组件替代。
步骤3:整合到你的Home组件中
修改后的完整代码如下:
import Image from 'next/image' import 'leaflet/dist/leaflet.css' import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'; import { useState } from 'react'; import { Switch } from '@headlessui/react'; import bus from '../public/bus.jpg' import { createControlComponent } from "@react-leaflet/core"; import L from "leaflet"; import "leaflet-routing-machine"; // 封装Routing Machine组件 const createRoutingMachineLayer = (props) => { const instance = L.Routing.control({ waypoints: [ L.latLng(...props.start), L.latLng(...props.end), ], lineOptions: { styles: [{ color: "#6FA1EC", weight: 4 }] }, show: false, addWaypoints: false, routeWhileDragging: true, draggableWaypoints: true, fitSelectedRoutes: true, showAlternatives: false }); return instance; }; const RoutingMachine = createControlComponent(createRoutingMachineLayer); const busStops: string[] = [ "ATM/ LIBRARY", "ADMIN", "MURNI", "BW", "AMANAH", "DSS", "ILMU", "COE", ]; export default function Home() { const [show, setShow] = useState(false); // 替换为你实际的起点和终点坐标(对应地图上的两个Marker) const startPoint = [2.976644517019155, 101.73402673751899]; // 图书馆 const endPoint = [2.9776400979295072, 101.73074640990319]; // Admin楼 return ( <div className='w-screen bg-red-500 h-screen flex'> <div className='w-[400px] bg-white flex flex-col '> <div className='w-full h-[80px] flex justify-center items-center'> <h1 className=' text-black'>Route Infomation</h1> </div> <div className=' h-full bg-white justify-center items-center flex flex-col p-10 space-y-12'> {busStops.map(stop => ( <div key={stop} className=' w-full bg-white text-black text-center'>{stop}</div> ))} </div> </div> <MapContainer center={[2.976644517019155, 101.73402673751899]} zoom={16} scrollWheelZoom={true} className=' w-full h-full z-10'> <TileLayer attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> <Marker position={endPoint}> <Popup> UNITEN Admin Building<br /> </Popup> </Marker> <Marker position={startPoint}> <Popup> <div className='w-[300px] h-[400px] flex flex-col rounded-lg'> <div className=' h-1/3 w-full bg-white ease-in-out'> <Image className='rounded-xl h-full' src={bus} alt='Bus' /> </div> <div className='flex justify-between items-center px-5'> <div>Uniten Library</div> <p>ETA</p> <p>Arrival Status</p> </div> <div className='flex'> <div className=' h-1/3 w-full p-5'>Driver 1 </div> <div className=' h-1/3 w-full p-5'>ETA: 7:45 AM</div> <Switch checked={show} onChange={setShow} className={`${show ? 'bg-green-500' : 'bg-gray-700'} relative inline-flex h-[28px] w-[64px] shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75`} > <span className="sr-only">Use setting</span> <span aria-hidden="true" className={`${show ? 'translate-x-9' : 'translate-x-0'} pointer-events-none inline-block h-[24px] w-[24px] transform rounded-full bg-white shadow-lg ring-0 transition duration-200 ease-in-out`} /> </Switch> </div> </div> </Popup> </Marker> {/* 渲染路线组件 */} <RoutingMachine start={startPoint} end={endPoint} /> </MapContainer> </div> ) }
关键说明
- 封装的
RoutingMachine组件接收start和end属性,对应起点和终点的经纬度数组 - 调整地图
zoom值为16,避免层级过大导致的显示异常 - 移除了无用的Google Maps相关导入,简化代码结构
- 用
map方法渲染公交站点列表,提升代码可维护性
内容的提问来源于stack exchange,提问作者Ibrahim
相关产品推荐
相关产品推荐

