npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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(见常量) |


目录

  1. 安装
  2. 工程配置
  3. 快速开始
  4. 组件 ZMap
  5. 生命周期
  6. 坐标与通用数据结构
  7. mapService API
  8. 完整业务示例
  9. 切换 Leaflet
  10. 导出清单
  11. 注意事项与常见问题

安装

npm i @zym-test-zerog/map-test-ol
# 或
pnpm add @zym-test-zerog/map-test-ol

Peer 依赖(需自行安装):

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 |

行为说明

  1. 挂载后创建 OpenLayers 地图实例。
  2. 调用 mapService.init(map),挂载业务图层与默认底图。
  3. 触发 map-ready。
  4. 监听容器尺寸变化并 updateSize / 刷新比例尺。
  5. 卸载时 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. 围栏

  1. 预览围栏:sendFenceData / deleteFence / setFenceLinked
  2. 编辑围栏: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';

注意事项与常见问题

  1. 必须等 map-ready,否则 mapService.viewer 为空。
  2. 源码包:需支持 Vue SFC + TypeScript(组件内可能含 less)。
  3. 底图域名:默认内部瓦片服务,外网可能空白。
  4. sendAlternatePointData / sendFenceData 为全量同步。
  5. setFocusWaypointIndex 传业务序号(从 1 起)。
  6. 单例:不建议同一应用并行挂载多个 ZMap 争用 mapService。
  7. 与 Leaflet 包 API 对齐;个别能力在某一引擎上可能为增强或空实现,以源码为准。

License

ISC