Appearance
公共 API
以下约定按 0.1.0 的导出类型与实现编写。SDK 只暴露业务地图接口,不提供直接访问 Cesium Viewer 的公共方法。
createMap(options)
ts
import { createMap, MapSDKError } from '@shardx-map/sdk';
import type { MapInstance, MapFeature, CameraView } from '@shardx-map/sdk';
// options 见快速开始;必须在容器连接到 DOM 后执行。
const map: MapInstance = await createMap(options);| 参数 | 类型 | 约定 |
|---|---|---|
container | string | HTMLElement | 已连接的元素或元素 ID;字符串不是 CSS 选择器 |
assetBaseUrl | string | HTTP(S) 资源目录,可相对 document.baseURI;不能含 query/hash |
source | MapSource | 必填;天地图、XYZ 或 WMTS |
view | CameraView? | 相机参数;省略时中心约 [114.05,22.55],高度 600000 米 |
lighting | 'day' | 'night' | 默认 day;固定昼夜光照预设,不自动走时 |
geofence | GeofenceLayerOptions? | GeoJSON 围栏配置,此处 id 可省略,默认为 geofence |
返回 Promise<MapInstance>。初始化错误使 Promise reject;不要用实例的 error 监听器捕获创建之前的错误。 一个容器只能存在一个活跃实例。同一页面所有实例必须使用相同的规范化 assetBaseUrl,销毁地图也不会重置此全局约束。 初始化不会等待远程瓦片全部加载。
地理围栏
addGeofenceLayer({ id, url, enabled?, fillColor?, fillOpacity?, outlineColor?, outlineWidth?, maskEnabled?, maskColor?, maskOpacity? }) 返回 Promise<void>。 支持 GeoJSON Polygon / MultiPolygon 及内环。使用 setLayerVisible 开关、flyToLayer 定位、removeLayer 删除。 初始化时可直接配置 geofence;围栏不会限制相机范围或执行进出判断,详细行为见地理围栏指南。
updateGeofenceStyle(id, patch: GeofenceStyle) 部分更新填充颜色、填充透明度、边线颜色及宽度,不重新请求 GeoJSON,不改变显隐状态。fillOpacity 为 0–1;省略时保留填充色自身的 alpha。边线宽度必须为正数,单位像素。无效配置抛出 CONFIG,保留原样式。加载中的围栏可以预设样式,数据返回后应用。
同时支持围栏外地面掩模:maskEnabled 默认为 false,maskColor 为 CSS 颜色(默认 rgba(16, 24, 40, 0.6)),maskOpacity 为可选的 0–1 alpha 覆盖值。对所有围栏面的并集取外部区域,保留岛屿、重叠区域与内环语义;掩模随图层显隐和删除,不裁剪模型或 DOM。具体用法见地理围栏指南。
ts
map.updateGeofenceStyle('shenzhen-geofence', {
fillColor: '#ffff00',
fillOpacity: 0.5,
outlineColor: '#d4a900',
outlineWidth: 3,
});Feature 与图层
ts
map.addLayer({ id: 'business', visible: true, features: [] });
map.addFeature('business', {
id: 'p1',
type: 'point',
position: [113.88, 22.56, 0],
color: '#22c55e',
size: 12,
popup: '点位信息',
});
map.addFeature('business', {
id: 'l1',
type: 'line',
positions: [
[113.88, 22.56],
[113.89, 22.57],
],
color: '#38bdf8',
width: 3,
});
map.addFeature('business', {
id: 'a1',
type: 'polygon',
positions: [
[113.88, 22.56],
[113.89, 22.56],
[113.89, 22.57],
],
color: '#f59e0b',
});
const marker = document.createElement('button');
marker.textContent = '详情';
map.addFeature('business', {
id: 'd1',
type: 'dom',
position: [113.885, 22.565],
element: marker,
});| 类型 | 必填字段 | 可选字段与显示 |
|---|---|---|
point | id, type, position | color、size(像素)、outlineColor、outlineWidth;有 icon 时使用图片标注 |
line | id, type, positions | color、width(像素,正数)、lineType、dashLength、outlineColor、outlineWidth,至少两个点 |
polygon | id, type, positions | fillColor、fillOpacity、outline、outlineColor、outlineWidth;兼容 color,至少三个点,单外环 |
dom | id, type, position, element | element 必须为 HTMLElement,样式由业务设置 |
所有类型都支持 popup?: string | HTMLElement、visible?: boolean;默认可见。颜色为 Cesium 可解析的 CSS 颜色字符串。 普通点默认大小 12 像素,有 icon 时默认 32×32 像素,线默认宽度 3 像素,默认颜色 #42c6ff。 DOM 标注的外观取自元素样式,color 不会自动设置 DOM 颜色;图片标注的 color 不作为图片着色配置。
点线面样式
普通点通过 Cesium PointGraphics 显示圆点,默认白色 2px 描边。图片 Marker 通过 BillboardGraphics 显示图片,属于同一 point 接口的另一种显示方式;outlineColor 和 outlineWidth 只影响普通点。
线型 lineType 支持 solid(默认实线)、dashed(虚线)、arrow(朝向坐标数组末端的箭头)、outline(描边线)。dashLength 是虚线重复周期,默认 16px,须为正数;outlineWidth 是每侧描边宽度,默认 1px,非负数。描边线的 width 是总宽度,必须大于两侧描边宽度之和,避免遮住中间线色。
面填充优先使用 fillColor,未设置时回退到 color。fillOpacity 范围为 0–1,默认 0.4,会覆盖填充色自身的 alpha。边线默认关闭,设置 outline: true 开启;默认白色 2px。边线使用闭合折线绘制,保持 PC 不同 WebGL 驱动下的像素宽度一致。
ts
map.addFeature('business', {
id: 'route-dashed',
type: 'line',
positions: [
[114.01, 22.53, 100],
[114.08, 22.56, 100],
],
color: '#76c9ed',
width: 6,
lineType: 'dashed',
dashLength: 24,
});
map.addFeature('business', {
id: 'area-yellow',
type: 'polygon',
positions: [
[114.01, 22.53],
[114.08, 22.53],
[114.05, 22.57],
],
fillColor: '#ffff00',
fillOpacity: 0.5,
outline: true,
outlineColor: '#d4a900',
outlineWidth: 2,
});
map.updateFeature('business', 'route-dashed', { lineType: 'arrow', width: 12 });
map.updateFeature('business', 'area-yellow', { fillOpacity: 0.25 });上述参数均支持 addFeature 和 updateFeature。无效颜色、线型或数值抛出 CONFIG;更新验证失败保留原要素。示例左侧点线面卡片提供整层样式控制,拖动控件会实时更新该层全部要素,并显示原先隐藏的图层;SDK 本身的 updateFeature 只更新指定要素。
图层 ID 全局唯一,要素 ID 在图层内唯一,不同图层可复用同一要素 ID。ID 必须是非空字符串。 输入坐标数组会被复制;修改原数组不会更新地图,应调用 updateFeature。
| 方法 | 返回 | 行为 |
|---|---|---|
addLayer({id, features?, visible?}) | void | 新增图层,可一次添加要素;重复 ID 抛错 |
addFeature(layerId, feature) | void | 图层须已存在;同层重复要素 ID 抛错 |
updateFeature(layerId, id, patch) | void | 合并后验证并重建要素;不能传入 id 或 type |
setLayerVisible(id, visible) | void | 同时控制该层所有要素;不会覆盖要素自身的 visible: false |
removeLayer(id) | void | 删除图层及其要素 |
removeFeature(layerId, id) | void | 删除指定要素 |
访问不存在的图层/要素(包括重复删除)抛 NOT_FOUND;不是静默忽略。 更新线/面的 positions 会替换整个数组。已通过验证的更新会重建要素,所以由该要素打开的弹窗会关闭。 删除要素、删除图层或隐藏所属图层也会关闭关联弹窗;直接通过 openPopup() 打开的独立弹窗没有图层关联。
ts
map.updateFeature('business', 'p1', {
position: [113.881, 22.561, 0],
color: '#ef4444',
size: 16,
});
map.setLayerVisible('business', false);
map.setLayerVisible('business', true);
map.removeFeature('business', 'l1');传入的 DOM 元素会被移动到 SDK 的覆盖层中,不会克隆或自动移回原父元素。 不要将同一个元素同时交给多个标注或弹窗。业务自行注册在元素上的事件、定时器和订阅由业务清理。 DOM 标注跟随场景帧更新位置,地球背面的覆盖物隐藏;不提供建筑物深度遮挡保证。
图片 Marker 与点聚合
ts
map.addLayer({
id: 'icons',
features: [
{
id: 'pin',
type: 'point',
position: [114.05, 22.55, 80],
icon: '/marker-pin.svg',
size: 48,
popup: '图片 Marker',
},
],
});
map.addLayer({
id: 'sites',
clustering: { enabled: true, pixelRange: 50, minimumClusterSize: 2 },
features: sites, // 业务提供的 point(普通点或图片标记)数组
});
map.setLayerClustering('sites', { enabled: false });聚合随缩放自动计算;屏幕范围 pixelRange 默认 50 像素(非负数),minimumClusterSize 默认 2(整数且 ≥2)。 圆形聚合标记支持 color(默认 #171717)和 badgeSize(默认 38px,范围 16–128);数量较多时可自动加宽圆标以容纳数字。通过 setLayerClustering 重新配置后实时生效。该方法按完整配置处理,未传字段使用默认值,宿主应合并需要保留的参数后传入。 enabled 默认 true。聚合图层只接收 point;DOM、线、面请使用独立图层。关闭聚合后允许添加其他类型,再开启时会检查并拒绝混合图层。 点击数字触发 {layerId, featureIds},不自动弹出某一个成员的弹窗,也不自动飞行;放大后可拾取单个点。 图层显隐、要素更新与删除同普通图层。
3D Tiles
ts
await map.addTilesetLayer({
id: 'project-model',
url: 'https://models.example.com/tileset.json', // 替换为已授权服务
visible: true,
maximumScreenSpaceError: 16,
opacity: 1,
debugShowBoundingVolume: false,
// headers: { Authorization: 'Bearer …' }, // 从业务内存提供,勿提交凭据
});
await map.flyToLayer('project-model');
map.setLayerVisible('project-model', false);
map.removeLayer('project-model');addTilesetLayer 返回 Promise<void>;根元数据加载成功即返回,不等待全部子瓦片。 模型 ID 与普通图层共享命名空间,加载中也占用 ID。请求头传递到相对派生的子资源;仅加载可信的 tileset,跨域需服务端允许请求头。 未加载完成时 flyToLayer 返回 false;完成后按模型原生包围球定位并返回飞行完成结果。 模型取景按容器宽高与相机视场计算距离,保留 35% 距离余量,以 -50° 俯角查看整个模型。 SDK 不按业务经纬度移动或重投影模型;必须使用模型自己的地理变换。示例「定位模型」与加载完成后使用同一取景逻辑,只改变相机,不移动模型。 根加载失败拒绝 Promise 并释放 ID;子瓦片失败发出 MODEL_LOAD。删除/销毁后未完成加载的模型不会重新挂载;网络请求可能仍完成。 点击模型返回其 layerId,当前不导出模型属性表或单体化接口。模型不使用 addFeature/updateFeature/setLayerClustering。
updateTilesetStyle(id, patch: TilesetStyle) 部分更新已加载模型,保留原来的位置、显隐和数据;不会重新加载整个 tileset。opacity 范围为 0–1,1 为不透明,作用于原模型材质;maximumScreenSpaceError 必须为正数,越小越精细,也可能请求更多细节瓦片;debugShowBoundingVolume 为布尔值,用于显示瓦片包围体。无效配置抛出 CONFIG,保留原样式。尚未加载完成或不存在的模型抛出 NOT_FOUND。
ts
map.updateTilesetStyle('project-model', { opacity: 0.6, maximumScreenSpaceError: 8 });示例配置面板
示例中图片 Marker、DOM Marker、点聚合与点线面使用相同的整层配置布局。修改 Marker 或聚合设置会显示该图层并实时预览;DOM 标签文字按纯文本处理。图片地址在输入提交后生效,使用同源资源或支持跨域的图片服务。
围栏与模型的配置在未启用时作为预设,加载后直接更新。调整配置不会自动开启围栏或加载模型;模型加载期间禁用设置,更换模型地址或认证须先移除模型。显隐按钮独立于样式设置,初始仍只显示图片 Marker 和 DOM Marker。
视角、底图与昼夜
| 方法 | 返回 | 行为 |
|---|---|---|
setView(view) | void | 立即设置相机 |
flyTo(view) | void | 发起飞行,当前时长约 1.2 秒;不返回动画完成通知 |
flyToLayer(id) | Promise<boolean> | 普通图层按所有要素(含隐藏要素)计算范围,空层返回 false,否则发起飞行并返回 true;模型图层返回飞行完成结果 |
setSource(source) | Promise<void> | 配置新底图并替换旧底图;保留业务图层与要素,瓦片错误后续通过事件报告 |
setLighting(mode) | void | day / night;更改场景预设和 SDK 弹窗主题,应用界面主题由宿主控制 |
最小图层定位球半径为 500 米,避免单点定位过近。flyToLayer 不排除 visible: false 要素。 方法参数错误通过同步异常或 Promise rejection 暴露,调用异步方法应使用 await 和 try/catch。
day 关闭地球明暗计算,使底图保持明亮;night 开启太阳光照并固定为北京时间午夜附近(2026-06-22 00:00),主要面向本示例的中国区域。 全球其他经度可能位于太阳照亮的一侧;这不是全球同时变黑、实时太阳模拟或另一套夜间瓦片服务。时钟停止走时。 夜间 SDK 弹窗自动使用深色变量;业务 DOM Marker 与弹窗内部元素的文字颜色由应用管理。
事件
ts
const offClick = map.on('click', (event) => {
console.log(event.position, event.layerId, event.featureId);
});
const offError = map.on('error', (event) => {
console.warn(event.code, event.message, event.sourceId, event.recoverable);
});
offClick();
offError();on('click' | 'error', handler) 返回取消订阅函数。只支持这两个事件名,不提供通用 off 方法。
click 载荷为 {position?: Coordinate, layerId?: string, featureId?: string, featureIds?: string[]}。聚合返回成员 ID 数组;模型返回 layerId。 点/DOM 命中返回要素锚点;线/面使用相机射线与 WGS84 椭球的交点(高度约为 0),无法取得时回退首点。 点击背景不含要素标识;点击天空时 position 可以缺失。 要素配置了 popup 时,点击会自动打开关联弹窗,再触发 click 回调。
error 载荷为 {code, message, sourceId?, recoverable},详见错误。 相同 code/sourceId 的错误当前按约 3 秒窗口节流,不适合作为逐瓦片失败计数器。 业务事件回调抛出的异常会被隔离,不会通过 error 再次上报,应由业务自行记录。
弹窗与销毁
ts
map.openPopup({ position: [113.88, 22.56], content: '<b>显示为文本</b>' });
map.closePopup();
map.destroy();openPopup({position, content}) / closePopup() 返回 void。同一实例只保留一个弹窗。 字符串以 textContent 显示,不解析 HTML;HTMLElement 按原节点插入,由业务负责安全构建与内容净化。 弹窗位置不会因要素后来移动而自动绑定更新。
默认弹窗使用白色背景、近黑文字、细边框和轻阴影,与示例站的 ShardX 风格一致。 宿主已加载 Geist 时会使用该字体,否则使用系统字体;SDK 不会从外部加载字体。 可在应用样式中覆盖地图根节点的变量(放在 SDK CSS 之后):
css
#map .shardx-map-root {
--shardx-popup-background: #fff;
--shardx-popup-color: #171717;
--shardx-popup-border: rgb(0 0 0 / 8%);
--shardx-popup-radius: 8px;
--shardx-popup-shadow: 0 12px 24px -6px rgb(0 0 0 / 12%);
--shardx-focus-color: #0070f3;
}DOM 标记和弹窗内容的排版仍由业务元素样式控制。
destroy() 返回 void,可重复调用。它释放 SDK 管理的 Viewer、事件、观察器和覆盖层,保留宿主容器。 销毁后其余实例方法抛出 DESTROYED(异步方法表现为 rejected Promise);已经取得的取消订阅函数仍可安全调用。