UNPKG

atchain-mapbox-vue

Version:

A Vue 3 MapBox component library with subway lines, stations, markers and polygons support. Zero dependencies except Vue 3 and Mapbox GL JS.

458 lines (348 loc) 10.6 kB
# MapBox Vue 组件库 一个基于 Vue 3 和 Mapbox GL JS 的高性能地图组件库,支持地铁线路、站点显示、标记点和多边形等功能。 ## ✨ 特性 - 🚀 **零外部依赖** - 除 Vue 3 和 Mapbox GL JS 外无其他依赖 - 📦 **模块化设计** - 可按需导入,支持 Tree Shaking - 🎨 **样式独立** - 内置样式系统,可选择性使用 Tailwind CSS - 🔧 **TypeScript 支持** - 完整的类型定义 - 🎯 **交互丰富** - 支持点击、悬停等交互效果 - 📱 **响应式** - 支持地图移动、缩放等响应式更新 ## 📦 安装 ### 方式一:NPM 安装(推荐) ```bash npm install atchain-mapbox-vue mapbox-gl # 或 yarn add atchain-mapbox-vue mapbox-gl ``` ### 方式二:复制组件文件 将整个 `mapbox` 文件夹复制到你的项目中: ``` src/components/mapbox/ ├── MapBox.vue # 主容器组件 ├── MapBoxMarker.vue # 标记组件 ├── MapBoxPolygon.vue # 多边形组件 ├── MapBoxStations.vue # 地铁站点组件 ├── MapBoxSubWay.vue # 地铁线路组件 ├── useMapBox.ts # 统一入口 ├── composables/ # 核心逻辑 ├── styles/ # 样式系统 └── utils/ # 工具函数 ``` 然后安装依赖: ```bash npm install mapbox-gl ``` ## 🚀 快速开始 ### 基础用法 ```vue <template> <div class="w-full h-screen"> <MapBox :token="mapboxToken" :center="[121.431502, 31.214212]" :zoom="14" > <!-- 在地图上添加标记点 --> <MapBoxMarker src="/images/marker.png" id="marker-1" width="50px" height="50px" /> <!-- 添加多边形 --> <MapBoxPolygon id="polygon-1" /> <!-- 添加地铁线路 --> <MapBoxSubWay subway-json-path="/data/subway.geojson" :subway-render-radius-km="10" /> <!-- 添加地铁站点 --> <MapBoxStations station-json-path="/data/stations.geojson" :show-station-names="true" :station-render-radius-km="15" /> </MapBox> </div> </template> <script setup lang="ts"> // NPM 安装方式 import { MapBox, MapBoxMarker, MapBoxPolygon, MapBoxSubWay, MapBoxStations } from 'atchain-mapbox-vue' // 或复制文件方式 // import { MapBox, MapBoxMarker, MapBoxPolygon, MapBoxSubWay, MapBoxStations } from '@/components/mapbox' const mapboxToken = 'your-mapbox-access-token' </script> ``` ## 📚 组件 API ### MapBox (主容器) 主地图容器组件,所有其他组件都需要在其内部使用。 #### Props | 属性 | 类型 | 默认值 | 描述 | |------|------|--------|------| | `token` | `string` | - | Mapbox 访问令牌 | | `mapStyle` | `string` | - | 地图样式 URL | | `center` | `[number, number]` | `[121.431502, 31.214212]` | 地图中心点 | | `zoom` | `number` | `14` | 缩放级别 | | `jsonPath` | `string` | `'./data/landmark.geojson'` | 地标数据路径 | | `class` | `string` | `''` | 外部 CSS 类名 | | `customStyle` | `Record<string, string>` | `{}` | 自定义样式对象 | | `useBuiltinStyles` | `boolean` | `true` | 是否使用内置样式 | #### 示例 ```vue <MapBox token="pk.eyJ1..." map-style="mapbox://styles/mapbox/streets-v11" :center="[116.404, 39.915]" :zoom="12" class="w-full h-96" :use-builtin-styles="true" /> ``` ### MapBoxMarker (标记点) 在地图上显示自定义标记点。 #### Props | 属性 | 类型 | 默认值 | 描述 | |------|------|--------|------| | `id` | `string` | - | 标记点 ID(对应 GeoJSON 中的 id) | | `src` | `string` | - | 图片源路径 | | `jsonPath` | `string` | `'./data/landmark.geojson'` | 地标数据文件路径 | | `width` | `string` | - | 标记点宽度 | | `height` | `string` | - | 标记点高度 | | `class` | `string` | `''` | 外部 CSS 类名 | | `customStyle` | `Record<string, string>` | `{}` | 自定义样式对象 | #### 示例 ```vue <MapBoxMarker id="landmark-1" src="/images/poi.png" json-path="/data/my-landmarks.geojson" width="40px" height="40px" class="cursor-pointer" /> ``` ### MapBoxPolygon (多边形) 显示多边形区域。 #### Props | 属性 | 类型 | 默认值 | 描述 | |------|------|--------|------| | `id` | `string` | - | 多边形 ID(对应 GeoJSON 中的 id) | | `jsonPath` | `string` | `'./data/landmark.geojson'` | 地标数据文件路径 | #### 示例 ```vue <MapBoxPolygon id="area-1" json-path="/data/my-areas.geojson" /> ``` ### MapBoxSubWay (地铁线路) 显示地铁线路,支持动画效果。 #### Props | 属性 | 类型 | 默认值 | 描述 | |------|------|--------|------| | `subwayJsonPath` | `string` | `'./data/shanghai-subway.geojson'` | 地铁线路数据路径 | | `subwayRenderRadiusKm` | `number` | `8` | 渲染半径(公里) | #### 示例 ```vue <MapBoxSubWay subway-json-path="/data/metro-lines.geojson" :subway-render-radius-km="15" /> ``` ### MapBoxStations (地铁站点) 显示地铁站点。 #### Props | 属性 | 类型 | 默认值 | 描述 | |------|------|--------|------| | `stationJsonPath` | `string` | `'./data/shanghai-subway-stations.geojson'` | 站点数据路径 | | `showStationNames` | `boolean` | `true` | 是否显示站点名称 | | `stationRenderRadiusKm` | `number` | `15` | 渲染半径(公里) | #### 示例 ```vue <MapBoxStations station-json-path="/data/metro-stations.geojson" :show-station-names="false" :station-render-radius-km="20" /> ``` ## 🎨 样式自定义 ### 使用内置样式 组件默认使用内置样式,无需额外配置: ```vue <MapBox :use-builtin-styles="true"> <!-- 组件内容 --> </MapBox> ``` ### 使用 Tailwind CSS 如果项目中使用 Tailwind CSS,可以直接使用 Tailwind 类名: ```vue <MapBox class="w-full h-screen bg-gray-100"> <MapBoxMarker class="hover:scale-110 transition-transform" /> </MapBox> ``` ### 自定义样式 通过 `customStyle` 属性传入自定义样式: ```vue <MapBox :custom-style="{ borderRadius: '8px', boxShadow: '0 4px 6px rgba(0,0,0,0.1)' }" /> ``` ## 📄 数据格式 ### GeoJSON 格式要求 #### 地标数据 (landmark.geojson) ```json { "type": "FeatureCollection", "features": [ { "type": "Feature", "id": "marker-1", "properties": { "point": "地标名称" }, "geometry": { "type": "Point", "coordinates": [121.431502, 31.214212] } }, { "type": "Feature", "id": "polygon-1", "properties": { "polygon": "区域名称" }, "geometry": { "type": "Polygon", "coordinates": [[[lng1, lat1], [lng2, lat2], ...]] } } ] } ``` #### 地铁线路数据 ```json { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "1号线", "color": "#E4002B" }, "geometry": { "type": "LineString", "coordinates": [[lng1, lat1], [lng2, lat2], ...] } } ] } ``` #### 地铁站点数据 ```json { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "人民广场", "interchange": true, "line_numbers": ["1", "2", "8"], "color": "#E4002B" }, "geometry": { "type": "Point", "coordinates": [121.431502, 31.214212] } } ] } ``` ## 🔧 高级用法 ### 使用 Composables 如果需要更细粒度的控制,可以直接使用 composables: ```vue <script setup lang="ts"> import { useMapBoxCore, useMapBoxData, useMapBoxLayers } from 'atchain-mapbox-vue' const { mapInstance, mapLoaded, createMap } = useMapBoxCore() const { loadMapData } = useMapBoxData() const { renderSubwayLines } = useMapBoxLayers() // 自定义地图初始化 const initMap = () => { createMap({ token: 'your-token', style: 'mapbox://styles/mapbox/streets-v11', center: [121.431502, 31.214212], zoom: 14, container: 'custom-map' }) } </script> ``` ### 自定义数据获取 ```typescript import { defaultDataFetcher, type DataFetcher } from 'atchain-mapbox-vue' // 自定义数据获取函数 const customFetcher: DataFetcher = async (url, options) => { // 自定义逻辑 const response = await fetch(url, { headers: { 'Authorization': 'Bearer token' } }) return response.json() } // 使用自定义 fetcher await loadMapData({ url: '/api/map-data', fetcher: customFetcher }) ``` ## 🎯 交互事件 组件支持丰富的交互事件: ### 标记点交互 - **点击**: 控制台输出标记点信息 - **悬停**: 标记点放大 1.1 倍 ### 多边形交互 - **点击**: 控制台输出多边形信息 - **悬停**: 高亮显示(橙色填充) ### 自定义交互 可以通过修改 `useMapBoxLayers.ts` 中的交互函数来自定义行为。 ## 🚀 性能优化 ### 按需渲染 地铁线路和站点支持基于地图中心点的按需渲染: ```vue <MapBoxSubWay :subway-render-radius-km="10" /> <MapBoxStations :station-render-radius-km="15" /> ``` ### 数据缓存 组件内置数据缓存机制,避免重复加载。 ### 图层管理 自动管理图层的创建、更新和清理,防止内存泄漏。 ## 🔍 故障排除 ### 常见问题 1. **地图不显示** - 检查 Mapbox token 是否正确 - 确认容器有明确的宽高 2. **标记点不显示** - 检查 GeoJSON 数据格式 - 确认 id 匹配 3. **样式问题** - 检查是否正确引入 Mapbox GL CSS - 确认 `useBuiltinStyles` 设置 ### 调试模式 取消注释调试函数以获得详细日志: ```typescript // 在 MapBoxSubWay.vue 中 const logSubwayFeatureEndpoints = (geojson: any) => { console.log('[Debug] Feature count:', geojson.features.length) } ``` ## 📄 许可证 本组件库基于 MIT 许可证开源。 ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! --- **注意**: 使用前请确保已获得有效的 Mapbox 访问令牌。