@gis_victory/gismap
v2.0.57
Published
GISMap 是一个基于适配器模式设计的通用地图组件库,支持多种地图引擎(如 Mapbox GL、MapLibre 等),提供统一的 API 接口和丰富的功能模块。
Readme
GISMap - 通用地图组件库
GISMap 是一个基于适配器模式设计的通用地图组件库,支持多种地图引擎(如 Mapbox GL、MapLibre 等),提供统一的 API 接口和丰富的功能模块。
特性
- 多引擎支持:通过适配器模式,支持不同的地图引擎
- 丰富的管理器:提供图层、标记、雷达、地形、绘制、测量等多种管理器
- 响应式设计:基于 Vue 3 的 Composition API,提供响应式的地图状态管理
- 模块化架构:清晰的代码结构,易于扩展和维护
- TypeScript 支持:完整的类型定义,提供良好的开发体验
安装
# 使用 npm
npm install gismap
# 使用 yarn
yarn add gismap
# 使用 pnpm
pnpm add gismap基本使用
1. 基础地图组件
<template>
<div style="width: 100vw; height: 100vh;">
<GisMapContainer
:center="[120, 30]"
:zoom="10"
:access-token="'your-mapbox-access-token'"
:init-icons="initIcons"
>
<!-- 可以在这里添加地图控件 -->
</GisMapContainer>
</div>
</template>
<script setup lang="ts">
import { GisMapContainer } from 'gismap';
// 初始化图标配置
const initIcons = [
{
name: 'marker-icon',
url: 'https://example.com/marker.png'
},
{
name: 'icon-2',
url: 'https://example.com/icon2.png'
}
];
</script>2. 使用组合式函数
<template>
<div style="width: 100vw; height: 100vh;">
<GisMapContainer @ready="handleMapReady">
<button @click="addMarker" style="position: absolute; top: 10px; left: 10px; z-index: 1000;">
添加标记
</button>
</GisMapContainer>
</div>
</template>
<script setup lang="ts">
import { GisMapContainer } from 'gismap';
import { useMap, useMarker, useLayer } from 'gismap';
const { map, layers, markers } = useMap();
const handleMapReady = () => {
console.log('地图就绪');
};
const addMarker = () => {
// 添加标记
markers.value.add({
id: `marker-${Date.now()}`,
position: [120, 30],
options: {
draggable: true
}
});
};
</script>3. 使用 MapSwitch 组件
<template>
<div style="width: 100vw; height: 100vh; position: relative;">
<!-- 地图容器 -->
<GisMapContainer
:center="[120, 30]"
:zoom="10"
:access-token="'your-mapbox-access-token'"
>
<!-- 地图切换组件 -->
<template #top-right>
<GisMapSwitch :data="mapSwitchData" />
</template>
</GisMapContainer>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { GisMapContainer, GisMapSwitch } from 'gismap';
// 地图切换数据
const mapSwitchData = ref({
// 底图图层
layers: [
{
name: 'tdt-vec',
label: '矢量底图',
checked: true,
iconName: 'Picture'
},
{
name: 'tdt-img',
label: '影像底图',
checked: false,
iconName: 'Camera'
},
{
name: 'custom-layer',
label: '自定义底图',
checked: false,
iconName: 'Map'
}
],
// 叠加图层
extensions: [
{
name: 'tdt-cia',
label: '天地图注记',
checked: true
},
{
name: 'terrain',
label: '地形',
checked: false
},
{
name: 'custom-extension',
label: '自定义叠加层',
checked: false
}
]
});
</script>核心功能
1. 图层管理
import { useLayers } from 'gismap';
const { addLayer, removeLayer, layers } = useLayers();
// 添加 GeoJSON 图层
const layer = addLayer({
id: 'points',
type: 'circle',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [120, 30]
}
}
]
}
},
paint: {
'circle-radius': 10,
'circle-color': '#ff0000'
}
});
// 移除图层
removeLayer(layer.id);2. 标记管理
import { useMarkers } from 'gismap';
const { add, remove, getAll } = useMarkers();
// 添加标记
const marker = add({
id: 'marker-1',
position: [120, 30],
options: {
draggable: true,
anchor: 'bottom'
}
});
// 移除标记
remove('marker-1');
// 获取所有标记
const allMarkers = getAll();3. 绘制功能
import { useDraw } from 'gismap';
const { startDraw, stopDraw, isDrawing, selected } = useDraw();
// 开始绘制多边形
startDraw('polygon', (type, geoJson, wkt, feature) => {
console.log('绘制完成:', type, geoJson, wkt);
});
// 停止绘制
stopDraw();4. 测量功能
import { useMeasure } from 'gismap';
const { startMeasure, stopMeasure, isMeasuring, results } = useMeasure();
// 开始测量距离
startMeasure('line', (result) => {
console.log('测量结果:', result.value, result.unit);
});
// 停止测量
stopMeasure();5. 雷达图层
import { useMap } from 'gismap';
const { radarManager } = useMap();
// 添加雷达
radarManager.value?.add({
center: [120, 30],
radius: 500,
sectorVisible: true,
sectorAngle: 45
});
// 开始扫描
radarManager.value?.startScan();
// 停止扫描
radarManager.value?.stopScan();
// 移除雷达
radarManager.value?.remove();6. 地形管理
import { useMap } from 'gismap';
const { terrainManager } = useMap();
// 添加地形
terrainManager.value?.add({
source: {
tiles: ['https://example.com/terrain/{z}/{x}/{y}.png'],
minzoom: 0,
maxzoom: 14
},
layer: {
exaggeration: 1.5
}
});
// 添加山体阴影
terrainManager.value?.addHillshade();
// 移除地形
terrainManager.value?.remove();7. 图标管理
最佳实践:在地图初始化完成后立即加载图标
为了确保地图能够正确读取图标,应该在地图初始化完成后立即加载图标。推荐使用 useMapReady 组合式函数来监听地图就绪事件:
import { useMapReady } from 'gismap';
// 在地图就绪后立即加载图标
useMapReady(async (context) => {
try {
// 批量加载图标
await context.iconManager?.load([
{
name: 'marker-icon',
url: 'https://example.com/marker.png'
},
{
name: 'icon-2',
url: 'https://example.com/icon2.png'
}
], {
batchSize: 5, // 每批加载5个图标
batchInterval: 100, // 每批间隔100毫秒
onProgress: (loaded, total) => {
console.log(`加载进度: ${loaded}/${total}`);
}
});
console.log('图标加载完成');
// 图标加载完成后,再添加使用图标的图层
addIconLayer(context);
} catch (error) {
console.error('图标加载失败:', error);
}
});
// 添加使用图标的图层
function addIconLayer(context) {
if (context?.layerManager) {
context.layerManager.addLayer({
id: 'icon-layer',
type: 'symbol',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [120, 30]
}
}
]
}
},
layout: {
'icon-image': 'marker-icon', // 使用已加载的图标
'icon-size': 1.5
}
});
}
}其他用法
import { useMap } from 'gismap';
const { iconManager } = useMap();
// 批量加载图标(基本用法)
iconManager.value?.load([
{
name: 'marker-icon',
url: 'https://example.com/marker.png'
},
{
name: 'icon-2',
url: 'https://example.com/icon2.png'
}
]).then(() => {
console.log('图标加载完成');
});
// 加载单个图标
iconManager.value?.loadOne({
name: 'single-icon',
url: 'https://example.com/single.png'
}).then(() => {
console.log('单个图标加载完成');
});
// 检查图标是否已加载
if (iconManager.value?.hasIcon('marker-icon')) {
console.log('图标已加载');
}
// 移除图标
iconManager.value?.removeIcon('marker-icon');
// 清除所有图标记录
iconManager.value?.clear();高级功能
1. 自定义适配器
您可以通过实现 MapAdapter 或 VectorTileAdapter 接口来创建自定义适配器,支持其他地图引擎。
import type { MapAdapter, MapInitOptions, MapViewState } from 'gismap';
export class MyCustomAdapter implements MapAdapter {
private map: any = null;
async initialize(container: HTMLElement, options: MapInitOptions): Promise<void> {
// 初始化您的地图引擎
// this.map = new MyMapEngine(container, options);
}
dispose(): void {
// 清理资源
}
getMap(): any {
return this.map;
}
// 实现其他必要的方法...
}
// 使用自定义适配器
<GisMapContainer :adapter="new MyCustomAdapter()" />2. 扩展管理器
您可以通过继承现有管理器或创建新的管理器来扩展功能。
import { VectorTileAdapter } from 'gismap';
export class CustomManager {
private adapter: VectorTileAdapter;
constructor(adapter: VectorTileAdapter) {
this.adapter = adapter;
}
// 实现您的自定义功能
doSomething() {
// 使用 this.adapter 操作地图
}
}3. 事件系统
GISMap 提供了完善的事件系统,您可以监听各种地图事件。
import { useMapEvent } from 'gismap';
// 监听地图点击事件
useMapEvent('click', (event) => {
console.log('地图点击:', event.coordinates);
});
// 监听视图变化事件
useMapEvent('viewChange', (view) => {
console.log('视图变化:', view);
});项目结构
src/
├── adapters/ # 地图适配器
│ ├── mapbox/ # Mapbox GL 适配器
│ ├── types.ts # 适配器类型定义
│ └── index.ts # 适配器统一导出
├── components/ # Vue 组件
│ ├── MapContainer/ # 地图容器组件
│ └── ...
├── composables/ # 组合式函数
│ ├── useMap.ts # 地图核心组合式函数
│ ├── useLayer.ts # 图层组合式函数
│ └── ...
├── core/ # 核心功能
│ ├── event.ts # 事件系统
│ ├── StateStore.ts # 状态管理
│ └── ...
├── domain/ # 领域服务
│ ├── LayerService.ts # 图层服务
│ ├── MarkerService.ts # 标记服务
│ └── ...
├── manager/ # 管理器
│ ├── mapbox/ # Mapbox 专用管理器
│ ├── layer/ # 图层相关
│ ├── LayerManager.ts # 图层管理器
│ ├── RadarManager.ts # 雷达管理器
│ └── ...
├── services/ # 服务
│ ├── MapContext.ts # 地图上下文
│ └── ...
└── index.ts # 主入口浏览器兼容性
- Chrome/Edge >= 88
- Firefox >= 85
- Safari >= 14
许可证
MIT
贡献
欢迎提交 Issue 和 Pull Request!
联系方式
- 项目地址:https://github.com/your-username/gismap
- 问题反馈:https://github.com/your-username/gismap/issues
