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

venus-amap

v0.1.6

Published

Amap utils library

Readme

venus-amap

目录:packages/venus-amap | npm 包名:venus-amap

高德地图(AMap JSAPI v2)工具库,封装自定义重投影底图、矢量线/面图层、MassMarks 海量点管理、动画标注与交互。

特性

  • 自定义重投影底图:基于 AMap.TileLayer.Flexible,把以 EPSG:4326 切片的杭州规自瓦片在 GCJ02 下逐瓦片重采样拼接,支持暗色/亮色,内置图片缓存。
  • MassMarks 海量点:按状态值生成多套样式(默认 + 激活),支持伴生线/面图层、悬停信息窗、动态动画标注。
  • 矢量线/面图层:将业务数据组装为 Polyline/Polygon 装入 OverlayGroup,支持点击高亮。
  • 单例地图实例:内部维护全局 instance,其上挂载 _massMarksLayers 统一管理海量点图层。
  • 事件总线:内置 mitt 实例 emitter

项目结构

packages/venus-amap/
├── src/
│   ├── base-layer.ts       # EPSG:4326 瓦片重投影与自定义底图
│   ├── create-amap.ts      # 高德地图单例的创建、获取和销毁
│   ├── emitter.ts          # mitt 事件总线
│   ├── layer-utils.ts      # 矢量图层、MassMarks 与动画标注
│   ├── types.ts            # 地图、图层和业务数据类型
│   └── index.ts            # 唯一公共 API 入口
├── test/                   # node:test 回归测试
├── package.json            # 包入口、依赖和构建脚本
├── tsdown.config.ts        # ESM/CJS 与类型声明构建配置
└── README.md               # 安装、API 与使用约定

安装

pnpm add venus-amap gcoord

使用前需在页面中先异步加载高德 JSAPI v2(全局 AMap)。@amap/amap-jsapi-types 仅作类型提示(开发依赖)。

快速开始

import { createAMapInstance, addMassMarksLayer, emitter } from 'venus-amap'

const map = createAMapInstance('map-container', {
  zoom: 10,
  center: [119.72, 29.95],
  layerStyle: 'dark'
})

const add = addMassMarksLayer(
  (baseUrl) => (name, ext) => `${baseUrl}/${name}${ext}`
)
const layer = add(dataList, {
  baseUrl: '/icons',
  markerIcon: 'alarm',
  markerSize: [32, 32],
  statusNum: 5,
  isDynamic: true
})

emitter.on('marker-click', (data) => console.log('点位点击:', data))
emitter.on('layer-click', (extData) => console.log('矢量点击:', extData))

接口(API)详解

一、地图管理(create-amap.ts

createAMapInstance(container?, mapConfig?)

创建地图单例(已存在则复用)。默认挂载自定义底图,mapConfig.layerStyle === 'dark' 时用暗色瓦片。创建后会初始化 instance._massMarksLayers = []

function createAMapInstance(
  container?: string, // 默认 'container',地图容器 DOM id
  mapConfig?: CustomMapOptions // 见下;含高德 MapOptions + layerStyle
): CustomMap

interface CustomMapOptions extends AMap.MapOptions {
  layerStyle?: string // 'dark' 使用暗色底图
}

mapConfig 默认值(节选):{ pitch: 0, zoom: 9.25, zooms: [9.25, 20], viewMode: '3D', dragEnable: true, pitchEnable: false, center: [119.72, 29.95], layerStyle: 'dark' }

未传 mapConfig.layers 时自动创建与 layerStyle 匹配的自定义底图;显式传入 layers 时完全使用调用方图层,不再额外添加默认底图。

const map = createAMapInstance('map', {
  zoom: 11,
  center: [120.2, 30.3],
  layerStyle: 'dark'
})

getAMapInstance(container?)

function getAMapInstance(container?: string): CustomMap // 不存在则创建,默认 'container'

resetZoomAndCenter(center?)

function resetZoomAndCenter(center?: [number, number]): void // 动画复位到 zoom 9.25

resetMap(config?)

function resetMap(config?: {
  center?: [number, number]
  isClearAll?: boolean
}): void
// 默认 { center: 上次中心, isClearAll: true }

清除图层(removeAllLayers)并复位视图。

disposeMap()

function disposeMap(): void // instance.destroy() 后置空

instance

let instance: CustomMap // 含 _massMarksLayers?: MassMarks[]

二、自定义底图(base-layer.ts

createBaseImageLayer(baseConfig?, isDark?)

function createBaseImageLayer(
  baseConfig?: BaseLayerConfig, // 默认内置 layerConfig(杭州规自暗色,多路 upstream)
  isDark?: boolean // 默认 true;false 时把 upstream 中的 '_dark' 去掉
): AMap.TileLayer // 实为 CustomFlexibleLayer,_layerName = 'baseImageLayer'

type BaseLayerConfig = {
  tileSize: number
  cacheSize: number
  resolutions: number[]
  origin: [number, number]
  upstream: string[]
  bounds: [[number, number], [number, number]]
}

实现原理AMap.TileLayer.FlexiblecreateTile 中——根据请求瓦片 XYZ 计算其 WGS84 四至 → GCJ02 → WGS84(gcoord)→ 反算源瓦片行列号与像素偏移 → 按缩放比例从 upstream 拉取源瓦片并 drawImage 拼接到画布;ImgLoader 负责跨域加载,每个图层实例按 cacheSize 独立缓存图片(有限非负整数,最大 5000)。

const base = createBaseImageLayer() // 暗色
base.setMap(map)
// 或在 createAMapInstance 的 mapConfig.layers 中传入

三、矢量线/面(layer-utils.ts

createVectorLineLayer(dataList?, config)

function createVectorLineLayer(
  dataList: any[],
  config: LineConfig
): AMap.OverlayGroup

type LineConfig = {
  key?: string // 坐标字段名,默认 'facilitytrajectory'
  width?: number // 线宽,默认 4
  isRaw?: boolean // 是否保留原始 options(重置时复原)
  openClick?: boolean // 是否点击高亮,默认 true
  strokeColor?: string
  strokeStyle?: string // 'solid' | 'dashed'
}

把数据组装为 Polyline 列表装入 OverlayGroup_isCustom = true)。openClick 时点击派发 layer-click(载荷为 getExtData())。每个 Polyline 附带 _id / _uuid / _isActive / _isRaw / _options

createVectorFaceLayer(dataList?, config)

function createVectorFaceLayer(
  dataList: any[],
  config: {
    key?: string // 默认 'coordinates'
    fillColor?: string
    fillOpacity?: number // 默认 1
    strokeColor?: string
    strokeWeight?: number
    strokeStyle?: string // 默认 'solid'
    colorKey?: string // 按字段值取色
    colorMap?: Map<any, string>
    isRaw?: boolean
    openClick?: boolean
  }
): AMap.OverlayGroup

把数据组装为 Polygon 列表装入 OverlayGroup,点击派发 layer-click

resetActiveVector(type?)

function resetActiveVector(type?: string): void // 默认 'polygon'

重置当前激活的矢量要素:原始要素复原配置、非原始要素从地图移除,并移除 _layerName === 'river-marker' 的附带图层。


四、MassMarks 海量点(layer-utils.ts

buildMassMarksStyles(getImgUrlFn)

function buildMassMarksStyles(
  getImgUrlFn: GetImgUrlFn
): (iconConfig: IconConfig) => AMap.MassMarkersStyleOptions[]

type GetImgUrl = (name: string, ext?: string) => string
type GetImgUrlFn = (baseUrl: string) => GetImgUrl

statusNum 生成「默认 + 激活」样式数组(长度 statusNum * 2),图标地址按 ${markerIcon}-${i} / ${markerIcon}-${i}-active.webp)拼接。

createMassMarksLayer(dataList, styleList?, openClick?)

function createMassMarksLayer(
  dataList: MassData[],
  styleList?: AMap.MassMarkersStyleOptions[],
  openClick?: boolean // 默认 true
): AMap.MassMarks

创建 AMap.MassMarkszIndex: 240),openClick 时绑定点击(派发 marker-click)与悬停信息窗。图层会被推入 instance._massMarksLayers,并标记 _isMassMarksLayer_statusNum_dataList

addMassMarksLayer(getImgUrlFn)

function addMassMarksLayer(
  getImgUrlFn: GetImgUrlFn
): (
  dataList?: MassData[],
  iconConfig: IconConfig,
  openClick?: boolean
) => AMap.MassMarks

type IconConfig = {
  baseUrl: string
  markerIcon: string
  markerSize: [number, number]
  statusNum: number
  hasLine?: boolean // 附带折线图层
  hasFace?: boolean // 附带多边形图层
  isDynamic?: boolean // 激活时附加动画标注
  activeScale?: number // 激活图标缩放,默认 1.3
}

生成样式 → 创建海量点图层 → 按 hasLine/hasFace 追加伴生矢量图层 → setMap(instance)

const add = addMassMarksLayer((baseUrl) => (n, e) => `${baseUrl}/${n}${e}`)
add(dataList, {
  baseUrl: '/icons',
  markerIcon: 'alarm',
  markerSize: [32, 32],
  statusNum: 5,
  hasLine: true
})

updateMarksLayersByStatus(checkedStatusList?)

function updateMarksLayersByStatus(checkedStatusList?: any[]): MassData[]

按状态字段(优先 _status,仅在其为 null/undefined 时回退 status)过滤各海量点图层数据并 setData,同步显隐该 MassMarks 自己的伴生线图层;返回过滤后的数据集合。

createAnimationMarker(lnglat, config)

function createAnimationMarker(
  lnglat: AMap.LngLat,
  config: {
    alarmLevel: number | string
    getAnimationUrl: GetImgUrl
    size: [number, number]
  }
): AMap.Marker // _isAnimation = true

创建动画标注 Marker(图标地址 marker-${alarmLevel}-active.png)。

resetActiveMarker()

function resetActiveMarker(): void

把所有激活海量点图层的样式索引复位(style -= _statusNum)并移除动画标注 Marker。

activeMarkerByUid(getAnimationUrl)

function activeMarkerByUid(
  getAnimationUrl: GetImgUrl
): (uid: string, setFitView?: boolean) => void

高阶函数:先复位激活态,再按 _uuid 在各海量点图层中将该点样式切到激活段(style + _statusNum);setFitView 默认聚焦该点;动态图层会附加动画标注。

const active = activeMarkerByUid((n, e) => `/icons/${n}${e}`)
active('uuid-123', true)

removeAllLayers(isClearAll?)

function removeAllLayers(isClearAll?: boolean): void // 默认 true

清空并移除所有海量点图层、按需 clearMap(),并移除带 _isCustom 的图层。


五、事件总线(emitter

import { emitter } from 'venus-amap'

| 事件名 | 载荷 | 触发时机 | | -------------- | ------------------------- | ------------------- | | layer-click | extData(要素 extData) | 点击矢量线/面要素 | | marker-click | data | 点击 MassMarks 点位 |


六、类型定义(export * from './types'

主要类型(多为 AMap.* 扩展,附带内部标记):

interface CustomMap extends AMap.Map {
  _massMarksLayers?: MassMarks[]
}
interface CustomMapOptions extends AMap.MapOptions {
  layerStyle?: string
}

interface MassData extends AMap.MassData {
  style?: number
  _uuid?: string
  lnglat: any
  status?: number | string
  _status?: number | string
}

interface MassMarks extends AMap.MassMarks {
  _uuid?: string
  _isCustom?: boolean
  _hasLine?: boolean
  _hasFace?: boolean
  _isActive?: boolean
  _statusNum?: number
  _isDynamic?: boolean
  _hasActive?: boolean
  _dataList?: MassData[]
  _isMassMarksLayer?: boolean
}

interface Polyline extends AMap.Polyline {
  _id?
  _uuid?
  _isRaw?
  _options?
  _isActive?
}
interface Polygon extends AMap.Polygon {
  _id?
  _uuid?
  _isRaw?
  _options?
  _isActive?
}

还包括 LngLatBaseLayerConfigLineConfigIconConfigMarkerTileLayerOverlayGroupFlexibleLayerOptions 等。

构建

pnpm --dir packages/venus-amap build       # 或仓库根 pnpm build:amap
pnpm --dir packages/venus-amap check:types # tsc --noEmit,目前覆盖 src
pnpm --dir packages/venus-amap test        # build + check:types + node:test
pnpm --dir packages/venus-amap dev

注意事项

  • 依赖全局 AMap:使用前确保 JSAPI v2 已加载完成。
  • 单例副作用:先 createAMapInstance / getAMapInstance,再调用其它依赖 instance 的函数。
  • 上游底图地址在 base-layer.tslayerConfig 中配置(默认指向杭州城市大脑服务)。