@zym-test-zerog/map-test-ol
v1.0.3
Published
MFD 2D 地图(OpenLayers 实现),与 zgc_ui_2.1.0 同级的独立包
Readme
@zym-test-zerog/map-test-ol
Vue 3 二维地图组件包(OpenLayers 实现),面向 MFD 场景:底图切换、航线/航点、围栏、备降点、飞机实时位置与测距。
与 @zym-test-zerog/map-test-leaflet 公开 API 一致,业务侧只需替换包名即可切换引擎。
| 项 | 说明 |
| --- | --- |
| 引擎 | OpenLayers ol ^10.6.1 |
| 框架 | Vue ^3.5.0(peer) |
| 包形态 | 源码包(直接导出 .ts / .vue),需 Vite / Vue CLI 等能处理 SFC |
| 默认中心 | 与 Leaflet 包一致的业务默认视野 |
| 缩放范围 | MAP_MIN_ZOOM ~ MAP_MAX_ZOOM(见常量) |
目录
安装
npm i @zym-test-zerog/map-test-ol
# 或
pnpm add @zym-test-zerog/map-test-olPeer 依赖(需自行安装):
npm i vue@^3.5.0本包会自动安装:
ol@makeapie/vue-component-helpers
工程配置
Vite 示例
// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@zerog/mfd-map': '@zym-test-zerog/map-test-ol',
},
},
optimizeDeps: {
include: ['ol'],
},
});业务代码可写成:
import { ZMap, mapService } from '@zerog/mfd-map';容器样式
ZMap 内部铺满父级,父级必须是定位容器且有宽高:
<div style="position: relative; width: 100%; height: 100vh">
<ZMap @map-ready="onMapReady" />
</div>OpenLayers 相关样式由组件 / ol 包引入,一般无需额外配置。
快速开始
<script setup lang="ts">
import { ref } from 'vue';
import {
ZMap,
mapService,
type MapScaleResult,
} from '@zym-test-zerog/map-test-ol';
const scaleText = ref('');
function onMapReady() {
mapService.setMapStyle('vec');
mapService.setScaleListener((scale: MapScaleResult) => {
scaleText.value = scale.text;
});
mapService.focusOnPoints(
[{ lat: 31.82, lng: 117.23 }],
1,
0,
200,
{ x: 0, y: 0 },
);
mapService.initAirworthiness([
{ sid: '1', lat: 31.82, lng: 117.20, attribute: 1 },
{ sid: '2', lat: 31.85, lng: 117.25, attribute: 2 },
{ sid: '3', lat: 31.88, lng: 117.30, attribute: 4 },
]);
}
</script>
<template>
<div class="map-page">
<div class="scale">比例尺:{{ scaleText }}</div>
<ZMap :page-index="0" @map-ready="onMapReady" />
</div>
</template>
<style scoped>
.map-page {
position: relative;
width: 100%;
height: 100vh;
}
.scale {
position: absolute;
z-index: 10;
left: 12px;
bottom: 12px;
color: #fff;
}
</style>组件 ZMap
Props
| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| pageIndex | number | 0 | 业务页索引,透传给上层逻辑 |
Events
| 事件名 | 载荷 | 说明 |
| --- | --- | --- |
| map-ready | 无 | OpenLayers Map 已创建,且已执行 mapService.init(map)。此后才能调用 mapService |
行为说明
- 挂载后创建 OpenLayers 地图实例。
- 调用
mapService.init(map),挂载业务图层与默认底图。 - 触发
map-ready。 - 监听容器尺寸变化并
updateSize/ 刷新比例尺。 - 卸载时
mapService.destroy()并销毁地图。
生命周期
挂载 ZMap
→ 创建 OpenLayers Map
→ mapService.init(map)
→ emit('map-ready')
→ 【业务】setMapStyle / 灌航线 / 围栏 / 备降点 / 飞机点
卸载 ZMap
→ mapService.destroy()
→ 销毁 Map规则:
- 任何
mapService.*必须在map-ready之后(或先判断mapService.viewer)。 - 组件销毁后需在重新挂载后再次灌入业务数据。
坐标与通用数据结构
点坐标(多处通用)
{ lat: 31.82, lng: 117.23 }
{ latitude: 31.82, longitude: 117.23 }
[117.23, 31.82] // [lng, lat]MapScaleResult
interface MapScaleResult {
value: number;
unit: string; // 'm' | 'km'
text: string; // 如 '500m'、'2km'
calculatedWidth: number; // 建议 UI 条宽度(px)
}航点 attribute / type
| 值 | 含义 | 地图表现 |
| --- | --- | --- |
| 1 | 起飞点 | 起飞图标 |
| 4 | 降落点 | 降落图标 |
| 5 | 起降点 | 起降图标 |
| 其他 | 普通航点 | 序号圆点 |
mapService API
mapService 为单例。也可使用类 MapService。
if (!mapService.viewer) return;以下 API 与 Leaflet 包对齐,业务代码可原样复用。
1. 底图与视野
setMapStyle(style: 'vec' | 'img')
| 值 | 说明 |
| --- | --- |
| vec | 矢量底图 |
| img | 影像底图 |
瓦片默认指向内部地图服务;外网环境需自行改源或替换图层。
setZoom(type?: 'in' | 'out')
放大 / 缩小一级。
updateSize()
容器尺寸变化后刷新地图与比例尺(全屏、侧栏动画结束后调用)。
setScaleListener(listener?) / refreshScale()
mapService.setScaleListener((scale) => {
// scale.text / scale.calculatedWidth
});
mapService.setScaleListener(); // 取消focusOnPoints(points, ratio?, duration?, minRadius?, screenOffset?)
| 参数 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| points | 坐标数组 | — | 见坐标格式 |
| ratio | number | 6 | 视野相对图形放大倍数,越大越远 |
| duration | number | 1 | 动画秒数;0 立即跳转 |
| minRadius | number | 1000 | 最小包围半径(米) |
| screenOffset | { x, y } | { x: 200, y: 150 } | 屏幕留白(像素) |
mapService.focusOnPoints(waypoints, 5, 0.8, 800, { x: 100, y: -300 });
mapService.focusOnPoints([{ lat, lng }], 1, 0, 200, { x: 0, y: 0 });clearAllData() / destroy()
清空全部业务图层;destroy 一般由组件卸载调用。
2. 航线(适航航点)
await mapService.initAirworthiness(waypoints);
await mapService.setAirworthinessPositions(waypoints);
await mapService.previewAirworthiness();
mapService.setFocusWaypointIndex(2); // 业务序号(从 1 起)
await mapService.clearAirworthiness();航点数据示例
type Waypoint = {
sid?: string | number;
lat: number;
lng: number;
alt?: number;
attribute?: number; // 1 起飞 / 4 降落 / 5 起降
type?: number;
};
const waypoints = [
{ sid: 'wp-1', lat: 31.80, lng: 117.20, attribute: 1 },
{ sid: 'wp-2', lat: 31.83, lng: 117.24, attribute: 2 },
{ sid: 'wp-3', lat: 31.86, lng: 117.28, attribute: 4 },
];| 方法 | 说明 |
| --- | --- |
| initAirworthiness(positionList?) | 写入并渲染 |
| setAirworthinessPositions(positions) | 替换并渲染 |
| setFocusWaypointIndex(index) | 高亮焦点;业务序号从 1 起 |
| setAirworthinessPointPosition(position) | 按 sid 更新单点 |
| setAirworthinessActivePointSid(sid) | 设置激活点 |
| setAirworthinessWaypointInfo(info) | 合并航点信息 |
| delAirworthinessPosition(sid) | 删除 |
| drawAirworthiness() / previewAirworthiness() | 重绘 / 预览 |
| clearAirworthiness() / destroyAirworthiness() | 清空 |
| setDiffHeight(height) | 高差相关(OL 侧按实现生效) |
3. 飞机实时位置与尾迹
mapService.seedAircraftTrail([
{ lat: 31.80, lng: 117.20 },
{ lat: 31.82, lng: 117.22 },
]);
mapService.sendRouteData({
lat: 31.825,
lng: 117.225,
heading: 45,
});
mapService.setCameraOptions({ type: 'gs' }); // 跟随
mapService.setCameraOptions({ type: '' }); // 取消
mapService.destroyRouteManager();| 方法 | 说明 |
| --- | --- |
| initRouteManager(force?) | 初始化轨迹图层 |
| seedAircraftTrail(points?) | 批量历史轨迹 |
| sendRouteData(data) | 实时点推送 |
| setCameraOptions({ type }) | type === 'gs' 跟随飞机 |
| destroyRouteManager() | 清除飞机与尾迹 |
4. 备降点
mapService.sendAlternatePointData([
{
id: 'alt-1', // 或 airportId
lat: 31.90,
lng: 117.10,
name: '备降场 A',
linked: true,
},
]);
mapService.setAlternatePointLinked('alt-1', false);
mapService.updateAlternatePoint({ id: 'alt-1', lat: 31.91, lng: 117.11, name: '备降场 A' });
mapService.deleteAlternatePoint('alt-1');
mapService.clearAllAlternatePoints();| 方法 | 说明 |
| --- | --- |
| sendAlternatePointData(data) | 全量替换 |
| updateAlternatePoint(data) | 新增/更新单个 |
| setAlternatePointLinked(id, linked) | 关联样式 |
| deleteAlternatePoint(id) / clearAllAlternatePoints() | 删除 / 清空 |
| selectAlternatePoint / setAllowHighlightOnClick / setAlternatePointEditMode / setPointDraw / setAlternateName | 与 Leaflet 包对齐的扩展 API |
5. 围栏
- 预览围栏:
sendFenceData/deleteFence/setFenceLinked - 编辑围栏:
drawFence/setPositions/setFenceName/clearPolygon
mapService.sendFenceData(
[
{
fenceId: 'f-1',
fenceName: '围栏甲',
linked: true,
positions: [
{ lat: 31.80, lng: 117.20 },
{ lat: 31.80, lng: 117.25 },
{ lat: 31.85, lng: 117.25 },
{ lat: 31.85, lng: 117.20 },
],
},
],
true,
);
mapService.setFenceLinked('f-1', false);
mapService.deleteFence('f-1');
await mapService.drawFence({ name: '新建围栏', positions: [/* ... */] });
mapService.setFenceName('重命名');
mapService.setPositions([/* 新顶点 */]);
mapService.clearPolygon();| 方法 | 说明 |
| --- | --- |
| sendFenceData(data, showName?) | 全量同步预览围栏 |
| deleteFence(id) / setFenceLinked(id, linked) | 删除 / 关联态 |
| drawFence(data) | 编辑多边形 |
| setPositions / setFenceName | 更新顶点 / 名称 |
| clearPolygon / clearFencePositions | 清除编辑态 |
| setActivePointSid / setSectorHeight / changeFenceMode / setPointPosition / delFencePosition / setAllowPopup | 扩展 API |
围栏顶点字段支持 positions 或 polygonVertices,至少 3 个点。
6. 测距
mapService.measureWork();
// 交互加点测距(具体手势与 OL 实现一致)
mapService.clearMeasureWork();7. 事件监听
mapService.setEventListener((e, eventName) => {
console.log(eventName, e);
});
mapService.setEventListener(); // 取消
mapService.setOnEvent(payload, 'custom-event');8. 常量
import {
MAP_MIN_ZOOM,
MAP_MAX_ZOOM,
MAP_NATIVE_ZOOM,
} from '@zym-test-zerog/map-test-ol';完整业务示例
<script setup lang="ts">
import { onUnmounted, ref } from 'vue';
import { ZMap, mapService, type MapScaleResult } from '@zym-test-zerog/map-test-ol';
const scale = ref<MapScaleResult | null>(null);
let timer: number | undefined;
function onMapReady() {
mapService.setMapStyle('img');
mapService.setScaleListener((s) => {
scale.value = s;
});
const airline = [
{ sid: '1', lat: 31.80, lng: 117.20, attribute: 1 },
{ sid: '2', lat: 31.84, lng: 117.26, attribute: 2 },
{ sid: '3', lat: 31.88, lng: 117.32, attribute: 4 },
];
mapService.initAirworthiness(airline);
mapService.sendFenceData([
{
fenceId: 'fence-1',
fenceName: '作业区',
linked: true,
positions: [
{ lat: 31.81, lng: 117.22 },
{ lat: 31.81, lng: 117.28 },
{ lat: 31.86, lng: 117.28 },
{ lat: 31.86, lng: 117.22 },
],
},
]);
mapService.sendAlternatePointData([
{ id: 'alt-1', lat: 31.90, lng: 117.15, name: '备降 A', linked: true },
]);
mapService.focusOnPoints(airline, 5, 0, 800, { x: 100, y: -200 });
mapService.initRouteManager();
let t = 0;
timer = window.setInterval(() => {
t += 0.01;
mapService.sendRouteData({
lat: 31.80 + t * 0.08,
lng: 117.20 + t * 0.12,
heading: 50,
});
}, 500);
}
function zoomIn() {
mapService.setZoom('in');
}
function zoomOut() {
mapService.setZoom('out');
}
function toggleMeasure(on: boolean) {
if (on) mapService.measureWork();
else mapService.clearMeasureWork();
}
onUnmounted(() => {
if (timer) clearInterval(timer);
});
</script>
<template>
<div class="wrap">
<div class="toolbar">
<button @click="zoomIn">放大</button>
<button @click="zoomOut">缩小</button>
<button @click="toggleMeasure(true)">测距</button>
<button @click="toggleMeasure(false)">清除测距</button>
<span v-if="scale">{{ scale.text }}</span>
</div>
<ZMap @map-ready="onMapReady" />
</div>
</template>
<style scoped>
.wrap {
position: relative;
width: 100%;
height: 100vh;
}
.toolbar {
position: absolute;
z-index: 20;
top: 12px;
left: 12px;
display: flex;
gap: 8px;
}
</style>切换 Leaflet
npm uninstall @zym-test-zerog/map-test-ol
npm i @zym-test-zerog/map-test-leaflet- import { ZMap, mapService } from '@zym-test-zerog/map-test-ol';
+ import { ZMap, mapService } from '@zym-test-zerog/map-test-leaflet';若使用 @zerog/mfd-map 别名,只改 Vite alias 即可。
导出清单
import {
ZMap,
default as MapComponent,
mapService,
MapService,
mapProps,
mapEmits,
MAP_MIN_ZOOM,
MAP_MAX_ZOOM,
MAP_NATIVE_ZOOM,
// 兼容旧名(已 deprecated)
olMapProps,
olMapEmits,
} from '@zym-test-zerog/map-test-ol';
import type {
MapProps,
MapEmits,
MapScaleResult,
OlMapProps,
OlMapEmits,
} from '@zym-test-zerog/map-test-ol';注意事项与常见问题
- 必须等
map-ready,否则mapService.viewer为空。 - 源码包:需支持 Vue SFC + TypeScript(组件内可能含 less)。
- 底图域名:默认内部瓦片服务,外网可能空白。
sendAlternatePointData/sendFenceData为全量同步。setFocusWaypointIndex传业务序号(从 1 起)。- 单例:不建议同一应用并行挂载多个
ZMap争用mapService。 - 与 Leaflet 包 API 对齐;个别能力在某一引擎上可能为增强或空实现,以源码为准。
License
ISC
