Skip to content

MapLibre 版 API(@geoverse/core-libre)

@geoverse/core-libre 是以 MapLibre GL JS v5 为渲染引擎、镜像 geoverse(OpenLayers 版)公共 API 的独立核心包。全部为命名导出,从 @geoverse/core-libre 单一入口引入:

ts
import { GMap, Marker, GVectorLayer /* ... */ } from '@geoverse/core-libre';
import '@geoverse/core-libre/style.css';
import 'maplibre-gl/dist/maplibre-gl.css'; // 须自行引入 maplibre 样式
  • 模块顶层零副作用,可安全用于 SSR;DOM/WebGL 操作只发生在构造函数/方法内部。
  • maplibre-glpeerDependency(^5),需使用者自行安装。
  • UMD 全局名 GeoVerseLibre

选 OL 版还是 MapLibre 版? 需要矢量瓦片、3D/倾斜、GPU 渲染海量要素、或已有 MapLibre 生态,选本包;需要 WMS/WMTS/ArcGIS/超图等丰富栅格服务、自定义投影与瓦片网格、或要素编辑高级能力,选 OL 版 @geoverse/core-ol。指南见 MapLibre 版

与 OL 版的范式差异

MapLibre 是声明式的(要素=GeoJSON、图层=style-spec JSON、style 异步加载),无法像 OL 那样全程继承。本包采用混合式继承

层级MapLibre 有基类?本包做法
地图有(maplibregl.MapGMap extends maplibregl.Map
弹窗有(maplibregl.PopupInfoWindow extends maplibregl.Popup
要素自建基类 GFeatureMarker/Circle/Polygon/Polyline 继承之
图层自建基类 GLayerGVectorLayer/GVectorTileLayer 继承之

约定:所有面向使用者的经纬度入参/出参一律为 WGS-84[经度, 纬度])。国内底图(高德 GCJ-02 / 百度 BD-09)的偏移由本包在数据边界自动变换消除——使用者无感知,详见坐标与基准面


GMap

继承 maplibregl.MapMap 的全部公开方法(addSource / getSource / getLayer / setPaintProperty / on / once / off / addControl / getZoom / setZoom / getBearing / getPitch / addImage / loadImage / remove …)均原样可用。

GeoVerse Libre 的地图容器,相对原生 Map 增强四点:

  • style 异步加载的就绪门控whenReady / isReady):GLayer 在样式就绪后才安装,切底图后自动重装
  • 内置标准 + 国内底图与 setBase 切换(含跨基准面无漂移锚定)
  • 地图级 pointer 事件统一派发为要素级 click / mouseover / mouseout
  • 国内坐标系数据边界变换:相机/查询/弹窗坐标契约恒为 WGS-84
ts
import { GMap } from '@geoverse/core-libre';

const map = new GMap({
  container: 'map',
  base: 'amap', // 高德底图(GCJ-02,自动无偏移)
  center: [118.18, 24.49], // WGS-84
  zoom: 12,
});

map.whenReady(() => {
  map.addLayer(
    new GVectorLayer({
      features: [
        /* ... */
      ],
    }),
  );
});

构造选项 GMapOptions

继承 maplibregl.MapOptions(去除 container / style,其余如 minZoom / maxZoom / bearing / pitch / attributionControl / hash 等仍可用),新增/覆盖下列字段:

字段类型默认说明
containerHTMLElement | string—(必填)地图容器元素或其 id
targetHTMLElement | stringcontainer 的别名(对齐 core 的 target 命名)
baseBaseInput'osm'内置底图代号 / style 对象 / style URL / false(空白底图)
baseConfigBaseLayerConfig底图配置:glyphs / tiles / token / datum
centerLngLatLike[118.15, 24.56]初始中心(WGS-84 经纬度)
zoomnumber12初始层级

BaseInput = BaseLayerReference | StyleSpecification | string | false

就绪门控

方法签名说明
isReady() => booleanstyle 是否就绪(可安全 addSource/addLayer
whenReady(cb: () => void) => void就绪后执行回调(已就绪则立即执行)

⚠️ 用 isReady() 判断就绪,不要用 maplibre 的 isStyleLoaded()——后者在本库 style.load 回调内同步加图层时会短暂翻回 false,造成误判。

坐标 / 基准面(datum)

方法签名说明
getDatum() => Datum当前底图基准面('WGS84' / 'GCJ02' / 'BD09'
fromWGS84(ll: LngLatLike) => [number, number]WGS-84 → 地图空间坐标
toWGS84(ll: LngLatLike) => [number, number]地图空间坐标 → WGS-84

相机方法(入参 / 出参均 WGS-84)

重写了高层方法,把经纬度/边界由 WGS-84 变换到地图空间后委派 super;WGS-84 底图下为恒等(零开销)。

方法签名说明
setCenter / getCenter(center) => this / () => LngLat中心点(WGS-84)
panTo(lnglat, options?, eventData?) => this平滑平移到经纬度
panBy(offset, options?, eventData?) => this按像素偏移平移
flyTo(options, eventData?) => this飞行动画(options.center 为 WGS-84)
fitBounds(bounds, options?, eventData?) => this缩放至边界(WGS-84 西南/东北角)
getBounds() => LngLatBounds当前视野范围(WGS-84)
setZoomAndCenter(zoom: number, center: LngLatLike) => void同时设置层级与中心
queryRenderedFeatures(...args) => MapGeoJSONFeature[]渲染要素查询,几何反算回 WGS-84

⚠️ 不要直接调用终端 easeTo / jumpTo 并传 center——它们不做 WGS-84 变换(国内底图下会偏移)。请改用上表的 setCenter / flyTo / panTo。同理 project / unproject 保持 maplibre 原生语义(地图空间),需要 WGS-84↔屏幕换算请显式用 fromWGS84 / toWGS84

底图

方法签名说明
setBase(base: BaseInput, config?: BaseLayerConfig) => void切换底图:以 WGS-84 视觉中心为锚跨基准面不漂移、自动重装托管图层、通知叠加物重定位
switchBase(base: BaseInput, config?: BaseLayerConfig) => voidsetBase 的别名(对齐 core 命名)

图层 / 图像

方法签名说明
addLayer(layer: GLayer) => this(亦兼容原生 style 图层重载)加入 GLayer(走就绪门控)或原生 style 图层
removeLayer(layer: GLayer | string) => this移除 GLayer 实例或原生图层 id
getLayerById(id: string) => GLayer | undefined按 id 获取本库管理的 GLayer
ensureImage(url: string) => Promise<void>确保图标图像已加载并注册到当前 style(幂等)

其它

方法签名说明
setCursor(cursor: string) => void设置鼠标样式,'default' 视为恢复默认
destroy() => void销毁地图(释放 WebGL 上下文与 DOM,等价 remove

要素级事件 · datumchange

GMap 在地图层面监听 pointer 事件,向命中的 GFeature 派发 FeaturePointerEvent,业务侧通过要素订阅(见 GFeature.on)。命中遵循要素的 cancelBubble 冒泡控制。

此外 GMap 在 setBase 改变基准面后派发 datumchange 事件,供叠加物(如 InfoWindow)按新基准面重新定位。


InfoWindow

继承 maplibregl.PopupPopup 的方法(addTo / remove / setHTML / setDOMContent / setText / setMaxWidth / trackPointer / on('open'|'close') …)均可用。

信息弹窗,位置统一使用 WGS-84 经纬度;挂到 GMap 时按其当前 datum 自动投影到地图空间(国内底图无偏移),切底图时随 datumchange 重新定位。

ts
import { InfoWindow } from '@geoverse/core-libre';

const win = new InfoWindow({
  content: '<div class="popup">你好</div>',
  map,
  position: [118.18, 24.49], // WGS-84
});
win.open(map, [118.2, 24.5]);

构造选项 InfoWindowOptions

继承 maplibregl.PopupOptionsoffset / anchor / closeButton / closeOnClick / className / maxWidth 等),新增:

字段类型说明
contentstring | HTMLElement内容:HTML 字符串、元素 id 或 DOM 元素
positionLngLatLike初始位置(WGS-84 经纬度)
mapmaplibregl.Map创建后立即挂载(需同时提供 position

方法

方法签名说明
open(map, lngLat?) => this打开弹窗(可选传入新经纬度)
close() => this关闭并从地图移除(派发 close
setContent(content: string | HTMLElement) => this设置内容(HTML 字符串自动 setHTML;纯文本若为元素 id 则取该 DOM,否则 setText
setLngLat(lngLat: LngLatLike) => this设置位置(WGS-84,按当前 datum 投影)
getLngLat() => LngLat获取位置(WGS-84)
addTo(map) => this挂载地图,记录 datum 并订阅 datumchange

FeaturePointerEvent

要素级交互事件对象,由 GMap 派发给命中要素。

成员类型说明
type'click' | 'mouseover' | 'mouseout'事件类型(FeaturePointerEventType
targetGFeature命中要素
mapEventmaplibregl.MapMouseEvent原始地图事件(含 point / 原生 lngLat
lngLat[number, number](getter)命中点经纬度,已反算为 WGS-84

要素(Feature)

GFeature

自建抽象基类(对齐 core 的 GFeature)。持有一个 GeoJSON Feature,样式以属性形式存放,由 GVectorLayer 的声明式表达式渲染。

成员签名说明
gidstring(只读)内部要素 id(写入 properties.__gid,供命中回查)
getId() => stringgid
getGeometry / getType() => Geometry / () => Geometry['type']几何(WGS-84)/ 几何类型
toGeoJSON() => Feature序列化为 GeoJSON(注入 __gid
setProperty / getProperty(key, value) => void / (key) => unknown任意属性读写(写后刷新图层)
setStrokeColor / getStrokeColor(color: string) => void / () => string | undefined描边颜色
setStrokeWeight / getStrokeWeight(w: number) => void / () => number | undefined描边宽度
setFillColor / getFillColor(color: string) => void / () => string | undefined填充颜色
setVisible / getVisible(v: boolean) => void / () => boolean显隐(经 __hidden 属性 + 图层 filter)
setPositions / getPositions(pos: Position) => void / () => Position | null点坐标(WGS-84)
setPath / getPath(path: Position[]) => void / () => Position[] | null线/面路径(面取/设单外环)
on(type, listener) => () => void订阅 click/mouseover/mouseout,返回退订函数
off(type, listener) => void取消订阅
cancelBubbleboolean(getter)是否阻止事件冒泡到下层要素

Marker

继承 GFeature。GeoJSON 点要素,由矢量图层以 circle(无 icon)/ symbol(有 icon)样式渲染——继承 maplibregl.Marker(DOM 标注)。

new Marker(opts?: MarkerOptions)

字段类型默认说明
positionPosition[0, 0]位置(WGS-84)
iconstring图标地址;不传则渲染为圆点
scalenumber1图标缩放
sizenumber6圆点半径(无图标时)
colorstring#3388ff圆点颜色(无图标时)
titlestring文本标注(需底图 style 提供 glyphs 字体)
cancelBubblebooleanfalse阻止事件冒泡

新增方法:setPosition(pos) / getPosition()(等价基类 setPositions/getPositions)。

Circle

继承 GFeature。地理米制圆。MapLibre 无圆几何,用 @turf/circle 生成多边形近似。

new Circle(opts?: CircleOptions)

字段类型默认说明
centerPosition[0, 0]圆心(WGS-84)
radiusnumber20半径(米)
stepsnumber64圆周边数(精度)
strokeColorstringblue描边颜色
strokeWeightnumber1描边宽度
fillColorstringlightblue填充颜色
fillOpacitynumber0.4填充透明度
cancelBubblebooleanfalse阻止事件冒泡

方法:setCenter(c) / getCenter() / setRadius(m) / getRadius()(改圆心/半径后重建多边形)。

Polygon

继承 GFeature。GeoJSON Polygon(单外环)。

new Polygon(opts?: PolygonOptions)path?: Position[](外环,WGS-84)、strokeColor(默认 #3388ff)、strokeWeight(默认 1)、fillColor(默认 lightblue)、fillOpacity(默认 0.4)、name?(中心标注,需 glyphs)、cancelBubble

Polyline

继承 GFeature。GeoJSON LineString。

new Polyline(opts?: PolylineOptions)path?: Position[](WGS-84)、strokeColor(默认 #3388ff)、strokeWeight(默认 2)、cancelBubble


图层(Layer)

GLayer

自建抽象基类。统一封装:加入/移除地图、就绪门控接入、切底图后重装。具体 source/style-layer 安装由子类实现。

成员:id(抽象只读)、内部 _attach / _detach / _reinstall(由 GMap 调用,业务侧一般不直接使用)。

GVectorLayer

继承 GLayer。通用矢量要素图层:内部维护一个 GeoJSON 源 + 4 个 style 图层(fill / line / circle / symbol),按几何类型与是否带 icon 分流渲染。

new GVectorLayer(options?: GVectorLayerOptions)

字段类型默认说明
idstring自动生成(gvl-…图层 id
featuresGFeature[]初始要素
textFontstring[]['Open Sans Regular']symbol 文本字体(需底图 style 提供 glyphs)
方法签名说明
addFeature / addFeatures(f: GFeature) => void / (fs[]) => void添加要素
removeFeature / removeFeatureById(f) => void / (gid: string) => void移除要素
clear() => void清空全部要素
getFeatures() => GFeature[]获取全部要素
getFeatureByGid(gid: string) => GFeature | undefined按 gid 获取要素
refresh() => void重新下发数据到地图源

出站时要素几何(WGS-84)按当前底图基准面自动 forward(国内底图无偏移),WGS-84 底图为恒等。

GVectorTileLayer

继承 GLayer。矢量切片图层:向地图加一个 vector 源 + 一个引用其 source-layer 的 style 图层,用于叠加自有矢量瓦片(与底图相互独立)。

new GVectorTileLayer(options: GVectorTileLayerOptions)

字段类型默认说明
idstring自动生成(gvt-…图层 id
tilesstring[]瓦片地址模板(与 url 二选一)
urlstringTileJSON 端点(与 tiles 二选一,提供时优先)
sourceLayerstring—(必填)矢量瓦片内的 source-layer 名
typeVectorTileLayerType'line'渲染类型:'fill' / 'line' / 'circle' / 'symbol'
paintRecord<string, unknown>透传 maplibre paint 规格
layoutRecord<string, unknown>透传 maplibre layout 规格
minzoom / maxzoomnumber源层级范围
attributionstring版权信息
beforeIdstring插入到该 style 图层之前(控制叠放次序)

tilesurl 均不提供时构造抛错。


底图

ts
import {
  createBaseLayer,
  resolveStyle,
  datumOf,
  RASTER_BASEMAPS,
  VECTOR_BASEMAPS,
  DEFAULT_GLYPHS,
  rasterStyle,
  blankStyle,
} from '@geoverse/core-libre';

内置底图代号 BaseLayerReference

代号类型基准面说明
osm栅格WGS84OpenStreetMap(仅本地调试,生产请自托管)
carto-light / carto-dark / carto-voyager栅格WGS84CARTO 栅格底图
amap / amap-img栅格GCJ02高德矢量 / 影像(火星坐标,自动无偏移)
tianditu-vec / tianditu-img栅格WGS84天地图矢量 / 影像(CGCS2000≈WGS-84,需 token
baidu栅格WGS84¹百度(经 baidu:// 协议画布 warp 纠偏,须先注册协议+同源代理)
ofm-liberty / ofm-positron / ofm-bright矢量切片WGS84OpenFreeMap 免 key 矢量 style
blank空白WGS84无瓦片,纯叠加场景

¹ 百度底图本身用 BD-09 不兼容网格,经瓦片纠偏 warp 后落入 WGS-84 空间,故 datum:'WGS84',但必须先 registerBaiduProtocol(...) 且瓦片走同源代理,见百度 BD-09 瓦片协议

BaseLayerConfig

字段类型说明
glyphsstring自定义 glyphs(字体)服务地址
tilesstring[]覆盖预设的瓦片地址模板
attributionstring覆盖预设版权
maxzoomnumber覆盖预设最大层级
tokenstring注入瓦片地址 {tk} 占位(天地图等)
datumDatum显式声明基准面:当 base 为原始 style / URL 且瓦片为国内偏移坐标时告知 GMap 做边界变换(缺省 'WGS84'

函数

函数签名说明
createBaseLayer(ref: BaseLayerReference, config?) => StyleSpecification | string创建内置底图 style;栅格/空白→对象,矢量切片→ style URL
resolveStyle(base: BaseInput, config?) => StyleSpecification | stringbase 选项解析为 maplibre 可用 style(代号/对象/URL/false)
datumOf(base: BaseInput, config?) => Datum解析底图基准面(预设栅格取声明值,其余取 config.datum ?? 'WGS84'
rasterStyle(def: RasterBasemapDef, glyphs?) => StyleSpecification由栅格底图定义构造完整 style
blankStyle(glyphs?) => StyleSpecification空白底图 style

常量:RASTER_BASEMAPS / VECTOR_BASEMAPS(预设表)、DEFAULT_GLYPHShttps://fonts.openmaptiles.org/{fontstack}/{range}.pbf)。


坐标与基准面(datum)

MapLibre 仅有单一坐标空间(WGS-84 经 Web Mercator 渲染),无法注册自定义投影。本包以「数据边界变换」消除国内底图偏移:把当前底图的原生基准面当作地图空间,在数据出入边界做 WGS-84 ↔ datum 互转,使用者侧 API 恒为 WGS-84。

ts
import {
  getDatumConverter,
  transformGeometry,
  transformFeature,
  transformFeatureCollection,
  gcj02,
  bd09,
  sphericalMercator,
  baiduMercator,
  outOfChina,
} from '@geoverse/core-libre';

类型

  • Datum = 'WGS84' | 'GCJ02' | 'BD09'
  • PositionFn = (pos: Position) => Position(保留高程/M 等附加维度)
  • DatumConverter = { forward: PositionFn; inverse: PositionFn }(forward 为 WGS84→datum,inverse 为 datum→WGS84)

函数

函数签名说明
getDatumConverter(datum: Datum) => DatumConverter取转换器;WGS84 返回恒等转换器(零开销快路径)
transformGeometry(geom: Geometry, fn: PositionFn) => Geometry深度变换单个几何(含 GeometryCollection),返回新对象
transformFeature(feature: Feature, fn: PositionFn) => Feature深度变换要素几何(属性原样保留)
transformFeatureCollection(fc: FeatureCollection, fn: PositionFn) => FeatureCollection深度变换要素集

坐标数学内核(纯函数)

导出形态说明
gcj02{ toWGS84, fromWGS84 }WGS-84 ↔ 高德火星坐标互转
bd09{ toWGS84, fromWGS84 }WGS-84 ↔ 百度坐标互转
sphericalMercator{ forward, inverse }经纬度 ↔ 球面墨卡托
baiduMercator{ forward, inverse }BD-09 经纬度 ↔ 百度墨卡托
outOfChina(lon: number, lat: number) => boolean点是否在国境框外

数值表移植自 @geoverse/core,但剥离了 ol/proj 依赖与墨卡托空间互转导出,仅保留经纬度层面 datum 互转。


百度 BD-09 瓦片协议

百度用独立瓦片网格(origin[0,0]、分辨率 2^(18-z)、y 向上、范围 ±2^25),与 MapLibre 锁定的标准 XYZ 网格不兼容,不能像高德那样用数据边界变换对齐。本包用 addProtocol 拦截标准瓦片请求、把覆盖该范围的百度瓦片在画布上 warp 重采样为标准瓦片(详见 RFC-0005)。

⚠️ CORS 硬边界:百度 *.bdimg.com 既无 CORS 头又有防盗链 403,瓦片字节必须经同源代理获取(开发期 Vite 代理 / 生产边缘函数)。Worker+OffscreenCanvas 只优化性能、绕过 CORS。

ts
import maplibregl from 'maplibre-gl';
import { GMap, registerBaiduProtocol } from '@geoverse/core-libre';

const unregister = registerBaiduProtocol(maplibregl, {
  tileUrl: (x, y, z) => `/baidu-tile/${z}/${x}/${y}`, // 同源代理
  useWorker: true,
});
const map = new GMap({
  container: 'map',
  base: 'baidu',
  center: [116.39, 39.9],
  zoom: 12,
});
// 卸载时:unregister();

导出

导出签名 / 类型说明
registerBaiduProtocol(maplibre, options?: BaiduProtocolOptions) => () => void注册 baidu:// 协议;返回注销函数(移除协议 + 回收 Worker)
createBaiduProtocol(options?: BaiduProtocolOptions) => ProtocolAction构造协议处理器(自行 addProtocol 时用)
BAIDU_PROTOCOL'baidu'协议名常量
defaultBaiduTileUrl(tx, ty, z) => string默认百度瓦片 URL(⚠️ 须经同源代理)
warpBaiduTiles(z, x, y, fetchTile, signal, gridN?) => Promise<ImageBitmap>按计划 warp 单张输出瓦片
planTileWarp(z, x, y, gridN?) => WarpPlan规划纠偏(覆盖瓦片 + 分格仿射,纯函数可单测)
makeTileBitmapFetcher(tileUrl) => TileBitmapFetcher由同源 URL 构造瓦片获取器
warpWorkerSupported() => boolean是否具备 Worker warp 运行时能力
disposeBaiduWorker() => void释放共享 warp Worker

BaiduProtocolOptions

字段类型默认说明
tileUrl(tx, ty, z) => string百度官方地址百度瓦片地址,须指向同源代理
fetchTileTileBitmapFetcher覆写瓦片获取(测试注入);设置后 useWorker 失效
useWorkerbooleanfalse在内联 Blob Worker 内执行 warp(CPU 移出主线程)
warpGridnumber8warp 分格数(N×N 分片仿射,降低低层级/高纬度变形;规整到 1/2/4/8/16)

工具函数与常量

ts
import {
  formatLength,
  formatArea,
  isHexColor,
  SnowflakeIdGenerator,
  fitChinaView,
  stringToDom,
  domToString,
  hasClass,
  addClass,
  removeClass,
  version,
  LayerKind,
  CANCEL_BUBBLE_KEY,
  GID_KEY,
  HIDDEN_KEY,
} from '@geoverse/core-libre';
导出签名 / 值说明
formatLength(line: GeoJSON 线) => string线长度人类可读(>100m 显示 km)
formatArea(polygon: GeoJSON 面) => string面面积人类可读(>10000m² 显示 km²)
isHexColor(value: string) => boolean是否十六进制颜色(#fff / #ffffff
SnowflakeIdGeneratorclassnew (workerId=0, dataCenterId=0, sequence=0)雪花 ID(16 位精简版),generate(): number
fitChinaView(map: GMap) => void视图调整为中国全境(中心约 [102.7, 30.05],zoom 5)
stringToDom / domToString(html) => ChildNode|null / (node) => stringDOM ↔ 字符串
hasClass / addClass / removeClass(el, name) => boolean | voidclass 操作
version'0.1.0'包版本号
LayerKind{ Base: 'geoverse-libre:base', Vector: 'geoverse-libre:vector' }图层种类标记
CANCEL_BUBBLE_KEY'cancelBubble'要素阻止冒泡属性键
GID_KEY'__gid'内部要素 id 属性键
HIDDEN_KEY'__hidden'要素隐藏标记属性键