跳到主要内容

SqsMap JavaScript 脚本 API 使用指南

契约版本:0.5-session(兼容 0.4-p2 及既有版本声明)。本指南面向在软件内编写脚本的用户;逐个接口的权限与签名见 参考文档(由代码生成),完整类型声明见 gis.d.ts。

维护规则:新增、修改或删除任何脚本接口时,必须同时更新本目录下的文档——重新生成 reference/,并核对本指南中受影响的说明和示例。

网页与客户端共用一套文档

网页脚本与客户端脚本共用本指南和接口参考,通用接口不按平台重复编写。只有支持范围、参数或行为存在差异时,才在对应接口和专题中标注;以接口参考的平台说明和当前宿主能力为准。

客户端从 Ctrl+F12 调试板运行;网页从官网示例页的脚本控制台运行,作用于示例地图。网页版工作台是独立环境。浏览器不能按任意本地路径读写文件,客户端文件访问与原生 GIS 能力不能直接照搬到网页脚本中。

差异点客户端网页脚本
本地路径与工作区调试板可设置工作目录,使用本地路径;AI 写出和修改仍走确认不能直接使用本地路径;map.open、map.workspace.save/load 未接入网页脚本宿主
数据与空间分析可使用已接通的原生 GIS 接口已接通 gis.data.fromGeoJSON 和 data.info;网页版工作台的格式读取、SQL、分析与导出不等于脚本接口已接通
地图语言map.setLocale/getLocale 未接入从 gis 导入的兼容地图接口提供这两项方法
地图能力与事件按运行时能力及事件列表判断使用同样的能力查询与事件列表;无需另一套脚本语法

移动端平台标签不代表移动宿主或设备验收已完成。独立动态库仅提供其原生脚本中列出的可选模块,不自动包含客户端全部 GIS 接口。

共用地图门面与双语参考

推荐地图脚本通过 sqsmap 导入 map;共同相机、图源、图层、样式、事件与持续会话的已实现范围见同一份共同地图参考。运行时用 await map.sqs.getCapabilities() 核对当前宿主能力,不凭相似方法名或平台标签推断全部支持。map.on 按 MapLibre 6.13.0 返回可取消订阅;off 返回地图,once 带监听返回地图、不带监听返回 Promise。调用 map.sqs.events() 核对真实事件,ready() 只保证宿主连接。详见 持续会话、英文指南 与 英文参考。英文参考由同一登记表和审核过的翻译生成,接口或中文语义变化时必须同步审核英文。

资源请求配置使用 await map.sqs.resources.configure / getConfiguration / plan。网页和桌面自动执行;原生动态库仍由宿主执行轮询计划。配置完整替换,只影响之后派发的请求;sqs.resourceschange 提供不可变历史快照。移动脚本宿主待接入。范围和示例见共同资源请求配置与资源策略指南。

1. 在哪里运行脚本

入口说明
调试板在主窗口按 Ctrl+F12 打开「JavaScript 调试」窗口。粘贴脚本后点「运行」;「停止」可中断正在执行的任务。脚本作用于当前地图,结果或错误显示在下方。
路径脚本可直接使用绝对路径读写任意本地文件;相对路径需先在调试板设置工作目录(点「工作目录(可选)」指定),例如 gis.data.open('polygons.geojson')。
AI 助手AI 助手会根据你的自然语言请求生成并运行同一套脚本,规则与调试板相同,但写文件与编辑仍需确认;相对路径默认落在最近打开数据所在目录。

写文件(export.write)额外要求:调试板运行的脚本直接写出,不弹确认;AI 助手生成的脚本每次写出仍需在主窗口确认;账号需有导出权限。

筛选成果上图与本地查询

query.select 返回筛选集合,不能直接作为图层的 source;地图需要数据集、影像或已注册数据源。通过 query.sql 的 features 结果可取得独立数据集再上图。查询的默认几何列是 geom,若显式改列名,geometryColumn 必须同步;结果坐标系从来源信息读取,不能用计量投影替代。筛选值始终用 ? 与 bindings 绑定。地图引用先经 query.select(layer,{scope:'all'}) 转成集合后再放入查询来源。

错误引用会返回 args[0].source 或 args[1].data 等公开参数路径和转换建议;不会回显数据值。完整可运行示例见下述场景脚本。

方法检索与组合脚本

本轮数据发现、融合统计、空间关联、栅格及本地查询接口配有方法说明:包含输入、输出、单位、适用前提、完整最小脚本和知识来源。Agent 的接口检索返回同源说明;参数校验错误附公开参数路径,例如 args[1].grid.width,不回显私有参数值。

完整场景脚本 演示“发现实际子层 → 分页读取字段 → 确认业务字段 → 分析与地图显示”。内置三个场景:分类融合及覆盖面积、分区栅格统计、本地只读筛选。修改开头配置后分步运行;文件、字段和投影必须来自真实数据,方法卡的合成示例仅用于演示。成果返回原生引用和有限样本;导出/修改继续沿用原有确认门,不增加本地路径或在线图源授权。

2. 脚本骨架

网页与客户端共同示例

下面使用内联演示数据,不依赖本地文件。每个地图实例运行一次;重复运行前删除同名图层及图源,或使用控制台的清理功能。确认只代表命令应用,不代表网络资源或动画完成。

// @gis-api 0.5-session
// @permissions ["project.read", "map.write"]
import { map } from 'sqsmap';
map.addSource('guide-point', {
  type: 'geojson',
  data: { type: 'Feature', id: 1, properties: {},
    geometry: { type: 'Point', coordinates: [116.4, 39.9] } }
});
map.addLayer({ id: 'guide-point', type: 'circle', source: 'guide-point',
  paint: { 'circle-radius': 8, 'circle-color': '#2563eb' } });
map.jumpTo({ center: [116.4, 39.9], zoom: 8 });
await map.sqs.flush();
export default await map.getCenter();

客户端本地文件示例

下面使用本地路径,仅用于客户端;先将路径改为实际数据。

// @gis-api 0.5-session
// @permissions ["project.read", "map.write"]
import {gis, map, expr, sleep} from 'gis';

const data = await gis.data.open('polygons.geojson');
const source = await map.sources.add('demo-source', {type: 'dataset', data});
const layer = await map.layers.add({
  id: 'demo-fill', name: '示例面', type: 'fill', source,
  paint: {'fill-color': '#36a873', 'fill-opacity': 0.55},
});
await map.camera.fitLayer(layer, {padding: 48});
export default {layer, featureCount: (await data.info()).featureCount};

规则:

  • 前 16 行内必须有 // @gis-api 0.5-session(兼容 0.4-p2、0.3-p1、0.2-host)和 // @permissions [...] 两行声明。
  • 脚本是 ES Module,支持顶层 await。允许导入 'gis' 或 'sqsmap'。前者导出既有 GIS 兼容接口,后者导出共用地图门面;两者均导出 gis、map、expr、sleep,但 map 的范围不同。没有单独的 data、query 导出,数据接口写 gis.data.*,查询写 gis.query.*,地图写 map.*。
  • 用顶层 export default 返回结果(对象、引用或摘要);不能在函数或 if 里 export,也不能顶层 return。
  • 脚本长度上限 128 KB,内存 32 MB,默认总超时 60 秒;结果最多 64 KB。

3. 权限声明

权限允许的操作
project.read读取数据、字段、代码表、查询、地图状态(几乎所有脚本都需要)
map.write添加/修改/移除地图数据源、图层、样式、相机、图像、场景草稿
analysis.execute缓冲、叠加、拓扑检查等分析,冻结实时快照
data.edit属性、顶点、几何编辑及历史撤销/重做
export.write写出成果文件(AI 助手脚本需确认)
scene.run启动场景、播放动画、连接实时数据源

在线瓦片、样式底图与实时数据不需要声明权限,也不会弹授权框。

一次最多声明 8 项。声明多余的权限不会报错,但缺少权限的调用会以 PERMISSION_DENIED 失败。调试板与 AI 助手均放行上表全部权限,文件写出仍受账号导出权限限制。

4. 核心概念

Operation:所有异步接口的返回值

接口返回 Operation<T>,await 后直接得到 T:

const info = await data.info();          // info 就是 DatasetInfo
const page = await map.layers.list();    // page.items 是数组

需要摘要时在 await 前调用 op.result(),得到 {value, summary, warnings, artifacts, truncated}。op.cancel() 取消,op.onProgress(fn) 订阅进度。

既有 GIS 异步宿主接口返回 Operation,需要 await;表达式构造、API/能力辅助方法与事件订阅等同步方法除外。把未完成的调用作为要求成果引用的参数,或提前读取字段、调用成果方法(如 op.items、op.info()),会以 INVALID_ARGUMENT 失败并提示补上 await。共用地图门面的同步/异步返回按各方法声明,不以这条规则推断。

引用而不是数据

gis.data.open、gis.query.select、gis.analysis.* 等返回引用(DatasetRef、FeatureSetRef、MapLayerRef…),几何和属性留在本地引擎中,脚本只拿到句柄。引用只在本次脚本有效;跨脚本请用 map.layers.get(id 或名称) 重新取得地图图层引用。不再需要时可 ref.dispose() 提前释放。

分页

返回 Page<T> 的接口用 {limit, cursor} 控制,limit 最大 100(默认 20):

let cursor;
do {
  const page = await gis.query.rows(data, {limit: 100, cursor});
  for (const row of page.items) { /* ... */ }
  cursor = page.nextCursor;
} while (cursor);

数据变化后旧游标失效,会返回 STALE_HANDLE。

ChangePlan:修改与写出必须经用户确认

编辑、写文件、移除场景等高影响操作不会立即执行,而是同步返回 ChangePlan:

const plan = gis.export.dataset(buffered, {path: 'buffer.geojson'});  // 没有 await
const preview = await plan.preview();   // 查看将写出的文件、影响的要素数
// 可查看 preview.fileWrites 与 preview.affectedFeatureCount;共用脚本不依赖 console。
const result = await plan.apply();      // 弹出确认框,用户同意后才执行

调试板运行的脚本 apply() 直接执行、不弹确认框;AI 助手生成的脚本每次都需主窗口确认。

用户拒绝时 apply() 以 CANCELLED 失败,脚本应就此停止,不要换其他方式绕过。plan.discard() 放弃计划。

筛选表达式

expr 是同步构造器,直接组合使用:

const selected = await gis.query.select(data, {
  where: expr.all(expr.eq(expr.get('category'), 'A'), expr.gt(expr.get('AREA'), 1000)),
});

常用:get/has/literal、eq/ne/gt/gte/lt/lte、all/any/not/in、contains/startsWith/endsWith、isNull/isBlank、geometryArea(unit)/geometryLength(unit)、intersects/within(target)。样式表达式另支持 zoom()、step/interpolate、match/case、lineProgress()、heatmapDensity()。

等待与事件

await sleep(ms) 暂停脚本(0~60000 毫秒,同时最多 32 个),界面保持响应。一次性脚本保留 60 秒总预算、256 次等待和 256 次接口调用;持续会话初始化后按每 60 秒 256 次计算等待/调用预算,仍限制同时最多 32 个接口调用。旧 gis 模块中的 map.on('viewchange' | 'layerschange' | 'load' | 'error' | 'taskprogress', handler) 和 map.once(type, handler) 均保留返回 Subscription 的行为。

持续地图会话(0.5-session)

默认仍为一次性任务,顶层结束后释放运行器。显式 export const sessionMode = 'persistent' 后,顶层完成只表示初始化完成,地图监听保持运行,不需要无限循环。网页示例页显示“正在监听”,可停止或重新运行;切换示例、完整网页预览和页面退出先停止旧会话。原生 TaskInfo.initialized=true 表示初始化完成,state 仍为 running,结果保存初始化摘要;取消后等待终态再清理或重启。

新的 sqsmap 内建模块已交付事件、命令确认和共同相机门面,其他地图操作继续通过旧模块接入;完整 MapLibre 风格地图方法逐项实施,不因模块存在就宣称全部兼容。

// @gis-api 0.5-session
// @permissions ["project.read"]
import { map } from 'sqsmap';
import { map as legacy } from 'gis';
export const sessionMode = 'persistent';

await map.sqs.ready(); // 已连接到宿主地图,不表示图源或渲染已空闲。
let changed = 0;
const listener = async (event) => {
  changed++;
  const state = await legacy.state();
  // 在这里处理状态;event.target === map,身份与序号由宿主提供。
};
const subscription = map.on('sqs.viewchange', listener);
// subscription.unsubscribe() 幂等;map.off(type, listener) 返回 map。
map.once('sqs.viewchange', event => { /* 只执行一次;返回 map。 */ });
map.once('sqs.viewchange').then(event => { /* 返回 Promise。 */ });
export default { initialized: true, events: map.sqs.events() };

共同门面已经接通标准相机move/zoom/pitch/rotate起止、样式和图源加载、实际render/idle/首次load、remove、指针及按图层的要素/悬停事件;另有sqs.viewchange、sqs.layerschange等SqsMap扩展。具体事件以 await map.sqs.events() 和能力查询为准,不能把旧viewchange当作实际帧或idle。事件带本地target、稳定mapInstanceId和递增sequence;可合并状态保持最新值,离散事件保持顺序,超限明确失败。未知事件或错误回调参数返回INVALID_ARGUMENT,平台未实现的事件返回CAPABILITY_UNAVAILABLE。

旧gis模块的load保留图层加载通知语义,新sqsmap模块的load表示首次完整地图帧。持续监听需导出sessionMode;一次性脚本不保留监听器。网页主线程/Worker及原生动态库支持范围见中英文事件契约和地图生命周期。AndroidJava/JNI独立宿主已接入共同脚本会话,但移动GIS/iOS应用和真实设备仍待验收。

同步或异步监听回调失败以及未处理的异步拒绝会结束会话,已应用地图内容不会回滚。停止关闭 Worker/QuickJS、订阅、计时器和待执行操作,等待以 CANCELLED 结束;已经应用的普通地图内容默认保留。原生回调有 2 秒连续执行预算;网页前台用 Worker 心跳监测,约 5 秒不让出运行器时终止,后台节流不作为失败。宿主在销毁地图前关闭运行器;原生宿主退出调用 ScriptService.close()。

共同脚本、真实验收宿主与 Windows/macOS 外机验收说明见 会话验收目录。Android独立Java/JNI宿主已有构建和Linux/JVM运行证据;移动GIS/iOS应用与设备另行验收,不以编译代替设备支持。

地图界面语言(网页端)

map.setLocale('auto' | 'zh' | 'en') 设置地图控件、右键菜单与地图错误提示的语言,返回实际使用的 'zh' 或 'en';map.getLocale() 读取实际语言。设置需要 map.write,读取需要 project.read。这两项接口目前仅支持网页端,桌面与移动端运行前检查会提示不支持。

官网的 auto 模式跟随网页语言:首次访问无语言前缀的页面时识别浏览器偏好,后续优先使用顶部语言选择记录。指定 zh 或 en 后地图保持固定语言,直到再次设置 auto;它不会更改底图中的地名或用户数据。切换示例时恢复跟随网页语言。

// @gis-api 0.4-p2
// @permissions ["project.read", "map.write"]
import { map } from 'gis';
await map.setLocale('auto'); // 改为 'en' 固定英文,或 'zh' 固定中文
export default { language: await map.getLocale() };

二维与三维视图中的相机

map.camera.state() 的 mode 返回 "2d"、"3d" 或 "globe"。三维建筑视图中,center 是地面焦点,resolution 和 zoom 是焦点处的水平地面分辨率,bounds 是视锥落在地面的包围盒。地球仪中,surfaceCenter 给出实际 WGS84 球面中心(可到两极);center、resolution、zoom 和 bounds 为对应的 Web Mercator 平面视角及近似范围,不能用于判断球面可见性。state() 另返回 pitch(俯仰,0 为正下视)与 bearing(顺时针方位)。map.camera.setView({center?, zoom|resolution, pitch?, bearing?}) 可设置两者:pitch > 0 会自动进入平面三维视图,pitch: 0 且当前没有地形、点云、模型或高斯内容时回到二维;pitch 取 0~60°;bearing 在二维、三维和球面都可设置(二维地图同样可旋转,state().bearing 返回当前方位)。适配范围操作保留当前倾角与方位角。二维地图旋转后,map.features.query 的像素坐标仍按屏幕所见换算。

5. 常见任务

打开数据并上图

// @gis-api 0.4-p2
// @permissions ["project.read", "map.write"]
import {gis, map} from 'gis';
const data = await gis.data.open('polygons.gpkg', {layer: 'polygons'});
const source = await map.sources.add('plots', {type: 'dataset', data});
const layer = await map.layers.add({id: 'plots-fill', name: '地块', type: 'fill', source,
  paint: {'fill-color': '#19a795', 'fill-opacity': 0.6, 'fill-outline-color': '#086a5f'}});
await map.camera.fitLayer(layer, {padding: 48});
export default {layer};

读字段与代码表

const fields = await gis.data.fields(data);                 // fields.items[i].name / displayName / hasCodeList
const codes = await gis.data.codes(data, {field: 'DI_LEI'}); // codes.items[i].value / label

字段名常是拼音缩写、属性值常是代码;回答业务含义前先用这两个接口翻译,不要猜。

筛选、缓冲并导出

// @gis-api 0.4-p2
// @permissions ["project.read", "analysis.execute", "map.write", "export.write"]
import {gis, map, expr} from 'gis';
const data = await gis.data.open('polygons.gpkg', {layer: 'polygons'});
const selected = await gis.query.select(data, {where: expr.eq(expr.get('category'), 'A')});
const buffered = await gis.analysis.buffer(selected, {distance: {value: 10, unit: 'm'}, name: 'A 类 10 米缓冲'});
const layer = await map.layers.add({id: 'buffer', type: 'fill', source: buffered, paint: {'fill-color': '#19a795'}});
await map.camera.fitLayer(layer);
const plan = gis.export.dataset(buffered, {path: 'a-buffer.geojson'});
export default {layer, plan, summary: `已生成 ${(await gis.query.metrics(buffered)).featureCount} 个缓冲面,等待确认导出`};

分析结果不会自动上图,需要 map.layers.add。距离必须带单位。

裁剪、擦除与属性叠加

gis.analysis.clip(input, boundary) 和 gis.analysis.erase(input, boundary) 的边界现在也接受 DatasetRef,不必为了类型转换先筛选全部要素;原有 FeatureRef / FeatureSetRef 调用继续有效。边界数据集使用全部面,筛选集合只使用所选面;不会修改输入。空边界仍报“没有有效几何”,不作为隐式全选范围。

clip 支持线和面输入,面边界可以是 Polygon / MultiPolygon,保留孔洞。裁剪线时保留源属性和坐标系,仅保留线段;只在边界上接触一个点的部分不会生成点成果。无相交线段时返回保留字段声明的空线数据集。erase 与 split 的输入仍按各自现有几何类型约束执行。

新增 gis.analysis.intersect(left, right, options),左右接受 DatasetRef | FeatureSetRef,逐对计算二维面交集并携带显式选择的两侧属性。只在边界接触时不生成面;不自动修复无效几何、不静默丢弃 Z/M。重叠输入可能形成重复覆盖,统计总占地前需要按业务要求处理输入重叠。

下面是假定样例文件确有 parcel_id / road_id 字段、位于 UTM 47N 适用范围的完整脚本。实际使用前先读取数据范围和字段,再选择投影与映射。

// @gis-api 0.4-p2
// @permissions ["project.read", "analysis.execute"]
import {gis} from 'gis';
const parcels = await gis.data.open('parcels.gpkg');
const roads = await gis.data.open('road_corridors.gpkg');
const occupied = await gis.analysis.intersect(parcels, roads, {
  workingCrs: 'EPSG:32647',
  fields: {
    left: {parcel_id: 'parcelId'},
    right: {road_id: 'roadId'},
  },
  name: '道路占地叠加',
});
const totals = await gis.query.groupMetrics(occupied, {
  field: 'parcelId', measurementCrs: 'EPSG:32647',
});
const page = await gis.query.rows(occupied, {limit: 20});
export default {occupied, totals, sample: page.items, truncated: page.truncated};

fields.left/right 必须是“源字段名 → 输出别名”的对象,空对象表示不保留该侧业务字段。输出没有自动前缀;左右别名重复、源字段不存在或使用保留名称均报错。结果还包含整数列 __leftIndex / __rightIndex,表示对应原数据集的零基行索引(筛选后仍保留原行索引),只用于本次输入快照的追溯,不保证跨任务稳定。空成果仍保留这些字段及所选字段的结构。

当前叠加使用覆盖两侧数据所在分带和半球的 UTM 米制投影。workingCrs 省略时,仅接受两侧同为适用 UTM 投影;经纬度输入须显式指定。outputCrs 默认保持左侧坐标系。单次最多一百万对候选要素,输出受任务资源预算约束,超限报错而不返回部分成果。

metrics/groupMetrics 保持兼容;新增 aggregate/dissolve/spatialJoin/nearest 已接通,分区统计 zonalStats 已接通。分页初次请求不传 cursor,后续传 page.nextCursor 字符串;无下一页时该属性可缺省,应按真值判断,不要只比较 !== null。

表格统计、融合与空间关联

query.aggregate、query.nearest 返回不可变 TableRef,不自动上图。用 data.fields(table) 查询成果字段,table.info() 查询总行数,再用 query.rows 分页;表格行只有 values,空间数据行继续为 {feature, values}。统计作用于完整输入,不能先读取一页再冒充全量统计。

// @gis-api 0.4-p2
// @permissions ["project.read", "analysis.execute"]
import {gis} from 'gis';
const parcels = await gis.data.open('parcels.gpkg', {layer: 'parcels'});
// 示例字段 town 必须替换为 data.fields(parcels) 查到的真实字段。
const merged = await gis.analysis.dissolve(parcels, {
  groupBy: ['town'], workingCrs: 'EPSG:32647',
});
const table = await gis.query.aggregate(merged, {
  groupBy: [], // 全部融合成果总计一行;若需每镇一行,写 ['town']。
  measures: {count: {op: 'count'}, areaHa: {op: 'sumArea', unit: 'ha'}},
  measurementCrs: 'EPSG:32647', // 示例适用于剑川;其它地区须选择适用 UTM。
});
export default table;
  • dissolve 仅处理有效二维面,按组消除重叠,只保留分组字段。groupBy: [] 为全体融合;空成果保留 schema。
  • aggregate 必须指定 groupBy 和非空 measures。count 计所有记录;sum/min/max/mean 指定数值 field、忽略 null;全空为 null。sumArea 指定 m2/ha/mu/km2,sumLength 指定 mm/cm/m/km,两者须提供 measurementCrs;线长不把面周长混入。
  • spatialJoin(left,right,{relation,join,match,fields,...}) 的关系是左相对右,保留左几何。relation 为 intersects/within/contains,join 为 left/inner,match 为 all/first;fields.left/right 是源字段到输出别名映射。first 取原始顺序最前的右记录,left 无匹配时右列为 null。边界点 intersects 为真,within 为假。
  • nearest(input,candidates,{k,maxDistance,measurementCrs,ties}) 按几何最短距离匹配;maxDistance 为 {value,unit} 且包含边界。ties:all 保留第 k 名完全等距的候选,first 最多 k 条。输出 __leftIndex/__rightIndex/distanceM,距离固定米;同一输入不自动排除自身。
  • 两类关联的来源列是输入快照原始行索引,筛选后不重新编号。运算接受 DatasetRef/FeatureSetRef,不接受显示图层或 TableRef。
  • 表格分页默认 20、最大 100 行,页内预算 60 KiB;只接受 fields/limit/cursor,不接受 where/search/scope。后续页保持相同参数,末页省略 nextCursor。一个表最多十万行、128 列、8 MiB,仍受共享内存与引用预算限制。
  • 几何处理仅支持契约列明的有效二维几何和覆盖输入范围的 UTM 工作投影;不自动修复、转换单位或降低分辨率。关联首期用有界候选遍历,超过一百万候选对明确失败。取消和超限不交付部分成果。

要求分页对象时 export default await gis.query.rows(table,{limit:20});要求有限字段对象数组时取 page.items.map(row=>row.values),必须先检查 nextCursor,不能把一页样本当全部结果。需要完整大结果时直接返回 TableRef;临时引用可 dispose,释放后引用和游标失效。

捕获的原生错误包含 code/message/retryable,可选 details 给出期望类型和最多八个字段候选;不含属性值。export default 放在模块顶层,不能放进 try/catch。

查询当前地图上的要素

const hits = await map.features.query({point: [102.71, 25.04], layers: [layer], limit: 10});
const first = hits.items[0];
if (first && first.kind !== 'cluster') await map.features.select(first.ref);   // 单个要素

select 只接受单个要素引用;整批选择用 map.features.selectSet(featureSet),读取当前选择用 map.features.selection()。

查询本地 DEM 高程

// @gis-api 0.4-p2
// @permissions ["project.read"]
import {gis} from 'gis';
const dem = await gis.data.open('dem.tif');
const info = await gis.raster.elevationInfo(dem, {band: 1, unit: 'm'});
const point = await gis.raster.sampleElevation(dem, [102.71, 25.04], {band: 1, unit: 'm', method: 'bilinear'});
const profile = await gis.raster.profileElevation(dem,
  [[102.71, 25.04], [102.72, 25.04]], {spacingM: 100, band: 1, unit: 'm'});
export default {info, point, profile};

坐标均为 WGS84 [经度, 纬度]。单位或垂直基准没有写在文件里时,应先核实并在选项中声明;未知单位不会被默认为米。point.missingReason 区分范围外和无效像元。剖面最多返回 64 个明细点,sampleCount 和 missingCount 是完整取样统计,空洞点保留 null 值。

已启用在线 Terrain-RGB 等高线时,可用 await map.contours.sampleElevation([102.71, 25.04]) 查询同一图源的点高程。返回米值、瓦片层级和近似地面分辨率;透明像元返回 missingReason: 'noData',垂直基准仍标为未知。在线请求失败会返回错误,不会当作零高程。

读取内置地形等高线矢量

map.contours.snapshot(options?) 按范围生成冻结的等高线矢量数据,只需 project.read。优先使用工作台已配置的在线等高线图源,未配置时使用内置高程图源;不要求先打开等高线,也不改变图源、显示开关或相机。读取的是范围内的高程数据,不限于屏幕上已经加载的瓦片。

// @gis-api 0.4-p2
// @permissions ["project.read"]
import {gis, map} from 'gis';
const snapshot = await map.contours.snapshot({
  bounds: [100.215, 27.07, 100.225, 27.08],
  zoom: 13, intervalM: 100
});
const rows = await gis.query.rows(snapshot.data, {
  scope: 'all', fields: ['elevation_m'], limit: 10
});
export default {snapshot, sample: rows.items};
参数含义与默认值
boundsWGS84 [最小经度, 最小纬度, 最大经度, 最大纬度],省略则固定调用时的当前视野;经度范围 ±180°、纬度范围 ±85.05112878°,不支持跨日期变更线。
zoom0~14 的整数;省略取当前地图级别向下取整并限制到此范围,再按图源支持的级别调整。返回值 zoom 是实际使用级别。
intervalM等高距,1~10000 米;省略采用实际瓦片级别对应的工作台等高距。
maxPoints顶点上限,2~100000,默认 100000。
targetCrs输出坐标系,默认 EPSG:3857,也支持 EPSG:4326;输入范围始终用 WGS84。

snapshot.data 是 DatasetRef,支持查看字段、查询、添加图层等已有数据接口;完整几何留在宿主,不进入脚本结果或助手上下文。数值高程字段固定为 elevation_m,单位米。结果按高程分组为 MultiLineString,每组包含裁剪后的线段;featureCount 表示高程分组数量,不能当作连续等高线条数。pointCount 是这些线段的全部顶点数,包含共享端点。

返回摘要还包括 bounds、intervalM、crs、unit、tileCount、minElevationM、maxElevationM、noDataPixelCount、verticalReference、warnings 和 truncated: false。最小/最大高程来自生成的等高线;没有线时两者为 null。缺测像元计数包括边界插值所需的邻近像元,含缺测的网格跳过生成,不补成零高程。服务未声明垂直基准时,不能将返回高程认定为某一基准下的海拔。

单次最多读取 16 块瓦片(含边界插值所需的邻瓦片)、生成 4096 个高程分组,并受 maxPoints 限制;超限以 RESOURCE_LIMIT 整体拒绝,不返回截断成果。请缩小范围、降低瓦片级别或增大等高距后重试。下载失败整体失败;没有可生成的等高线时返回空数据和原因提示。世界边缘或图源覆盖外缘缺少插值样本时会报错,需将范围向内缩。取消检查贯穿生成过程,正在进行的下载仍需等待已有网络请求结束。

要将快照用于立体显示,可在含 map.write 权限的脚本中继续:

if (snapshot.featureCount > 0) {
  // 先将地图切换至 Web 墨卡托三维视图。
  await map.setProjection({type: 'mercator'});
  await map.camera.setView({center: [100.22, 27.075], zoom: 13, pitch: 45});
  const source = await map.sources.add('builtin-contour-source', {
    type: 'dataset', data: snapshot.data
  });
  const layer = await map.layers.add({
    id: 'builtin-contours', name: '内置地形等高线', type: 'line', source,
    paint: {'line-color': '#34B6B7', 'line-width': 1}
  });
  await map.layers.setHeight(layer, {
    field: 'elevation_m', base: snapshot.minElevationM, exaggeration: 1
  });
}

上例以最低等高线为显示基准,保留真实米制高程差;使用 base: 0 则按数值高程相对平面零点抬升。显示高度不会修改原始高程,也不会自动贴合真实地形。结果生成后不会随着平移、缩放或图源变化而更新,需要时重新取数。

按多边形片区裁剪地形等高线

取数范围先用片区的外包矩形,再用真实多边形裁剪;最终成果只保留片区内的线段,而非整个矩形。边界可来自已有面文件、所选面要素或 gis.places.boundary() 返回的行政区数据集,裁剪时自动转换到等高线的坐标系。

// @gis-api 0.4-p2
// @permissions ["project.read", "analysis.execute"]
import {gis, map} from 'gis';
const boundary = await gis.data.open('片区边界.geojson', {targetCrs: 'EPSG:4326'});
const area = await boundary.info();
if (area.geometryType !== 'polygon' || !area.bounds) throw new Error('请使用有效的片区面边界。');
const snapshot = await map.contours.snapshot({
  bounds: area.bounds.bbox, zoom: 12, intervalM: 100, targetCrs: 'EPSG:3857'
});
const contours = await gis.analysis.clip(snapshot.data, boundary, {name: '片区等高线'});
export default {data: contours, info: await contours.info()};

裁剪后仍保留米制字段 elevation_m,可继续用它分级设色或设置三维高度。高程范围、要素数和顶点数应从裁剪成果重新统计,不能沿用裁剪前快照的摘要。裁剪不改写输入数据,不自动上图或导出文件。矩形取数仍受瓦片和顶点预算限制,超限时先缩小范围、降低瓦片级别或增大等高距。

顶栏“演示 → 玉龙雪山(多边形裁剪)”展示这一流程:在线地形取数、示意多边形裁剪、米制高程分级及三维抬升。其范围文件是雪山周边演示范围,定位参考云南省林业和草原局公布的四至坐标,不能作为正式景区或保护区边界。需要正式范围时请替换为相应矢量数据。

生成随顶点高程起伏的地形剖面线

map.contours.profileLines(options?) 从同一在线地形图源读取平行剖面。每条线沿东西方向采样,剖面沿南北方向排列;每个顶点都有独立的第三坐标高程。结果是冻结的三维线 DatasetRef,XY 为 EPSG:3857,Z 为米制高程,不改变地图显示。

// @gis-api 0.4-p2
// @permissions ["project.read", "analysis.execute", "map.write"]
import {gis, map} from 'gis';
const boundary = await gis.data.open('苍山演示范围.geojson', {targetCrs: 'EPSG:4326'});
const area = await boundary.info();
if (!area.bounds || area.geometryType !== 'polygon') throw new Error('请使用有效的片区面边界。');
const profiles = await map.contours.profileLines({
  bounds: area.bounds.bbox, zoom: 11, rowSpacingM: 600, pointSpacingM: 150
});
const data = await gis.analysis.clip(profiles.data, boundary, {name: '地形剖面'});
let height = null;
if ((await data.info()).featureCount > 0) {
  await map.setProjection({type: 'mercator'});
  const b = area.bounds.bbox;
  await map.camera.setView({center: [(b[0]+b[2])/2, (b[1]+b[3])/2], zoom: 11, pitch: 60, bearing: 33});
  const source = await map.sources.add('profile-source', {type: 'dataset', data});
  const layer = await map.layers.add({
    id: 'terrain-profiles', name: '地形剖面', type: 'line', source,
    paint: {'line-color': '#0D5EFF', 'line-width': 1}
  });
  const initial = await map.layers.setVertexHeight(layer, {exaggeration: 1});
  height = await map.layers.setVertexHeight(layer, {
    base: initial.minElevationM, exaggeration: 1
  });
}
export default {profiles, data, height};
参数含义与默认值
boundsWGS84 外包矩形,省略固定调用时的当前视野;范围限制与等高线快照一致。
zoom0~14 的整数,默认当前地图级别向下取整并限制到此范围,再按图源可用级别调整。
rowSpacingM剖面间距,50~10000 米,默认 500。
pointSpacingM同一剖面的采样点间距,10~10000 米,默认 200。
maxPoints全部请求采样点的上限,2~100000,默认 100000;缺测点也计入请求预算。

间距按范围中心纬度估算地面米数,实际步长不超过对应的投影估算值。双线性插值读取相邻像元;缺测处断开线条,不补零、不跨空洞连接,孤立单点不生成线段。单次最多 16 块瓦片(含插值邻瓦片)、4096 条剖面和指定采样预算,超限整体失败。下载与取消规则沿用等高线快照。

返回摘要含 featureCount、pointCount、tileCount、minElevationM、maxElevationM、noDataPointCount、warnings、verticalReference 及实际使用的 zoom,不包含全量坐标。每个要素代表一个有连续线段的剖面,可能是缺测处断开的 MultiLineString;noDataPointCount 是请求采样点中的缺测数。裁剪会在边界交点插值并保留 Z 高程,裁剪后应重新统计成果。

map.layers.setVertexHeight(layer, options?) 从各顶点的第三坐标读取米制高程,显示高度为 (Z - base) * exaggeration + offset,默认参数为 0 / 1 / 0。返回原始高程范围、显示高度范围、要素数与顶点数。它可以让同一条线沿途升降,无须创建高程属性字段;当前支持 Web 墨卡托静态实线及其颜色、线宽和透明度,不支持动画、虚线、渐变或贴地形混用。

设置前会完整检查顶点、数值和显示几何,失败保留原设置。顶点高程缺失时不会默认为零。启用期间线数据只读,传 null 清除高度并恢复此前的只读状态:await map.layers.setVertexHeight(layer, null)。顶点高度和按字段高度互相替换;都只改变显示,不改写源坐标或高程。场景草稿可以先设置高度,开始时一并应用。外部绘图库的高度缩放可能使用绘图单位,不能直接将示例倍率当作米制夸张倍数。

“演示 → 大理苍山(顶点高程剖面)”采用与 L7 height 示例相同的蓝色顶点剖面方式,改用苍山在线地形、60° 倾角和旋转视角。演示范围是参考公开地理范围绘制的示意多边形,正式范围应替换为对应的矢量边界。

高程显示、地形与三维内容

高程与三维沿用 MapLibre 的“数据源 → 图层”写法,名称尽量与 MapLibre 一致:

// @gis-api 0.4-p2
// @permissions ["project.read", "map.write"]
import {map} from 'gis';
await map.sources.add('dem', {type: 'raster-dem', path: 'D:/data/dem.tif', unit: 'm', verticalReference: 'EGM96'});
await map.layers.add({id: 'shade', type: 'hillshade', source: 'dem', paint: {'hillshade-illumination-direction': 315}});
await map.layers.add({id: 'relief', type: 'color-relief', source: 'dem', paint: {'color-relief-range': [0, 1500], 'color-relief-opacity': 0.6}});
const terrain = await map.setTerrain({source: 'dem', exaggeration: 1.5});   // 自动进入三维视图
await map.camera.setView({center: [102.71, 25.04], zoom: 13, pitch: 60, bearing: 30});
const h = await map.queryTerrainElevation([102.71, 25.04]);                  // 真实高程,不乘夸张
export default {terrain, elevation: h.elevation};
数据源 type图层 type说明
raster-dem(path 或 data,可选 band/unit/verticalReference)hillshade、color-relief二维晕渲/分层设色仅支持 WGS84、未旋转 DEM,需在二维视图中添加;分层设色为固定色带,用 color-relief-range 设高程范围
raster-dem(url 为在线 TileJSON,可选 token/verticalReference)无(仅供 map.setTerrain)编码取 TileJSON 的 encoding:mapbox(Terrain-RGB,缺省)或 terrarium;瓦片须为 PNG 或无损 WebP、与 TileJSON 同一站点,最高取到 14 级;verticalReference 缺省为“服务未声明”
pointcloud(path 为 LAS/LAZ/COPC 或 url 为 HTTP COPC;verticalReference 必填,Z 为米)pointcloudpaint:point-size、point-color(rgb/intensity/classification/elevation/#rrggbb)、point-color-range、point-show-withheld;filter 只支持分类,如 ['in',['get','classification'],['literal',[2,6]]]
model(glTF/GLB,lngLat 必填,可选 height/verticalReference/bearing/scale)model无样式;定位改动请重新加载
3dtiles(path 本地入口或 url HTTP(S)/OSS 入口,二选一)3dtilespaint:tiles-max-screen-space-error(默认 16)
gaussian-splat(二进制 PLY;不给 lngLat 为局部浏览,给 lngLat 时须有 verticalReference 与 registrationNote)gaussian-splat可选 bearing/pitch/roll/scale/upAxis/sourceOrigin/maxSplats
  • 图层的 source 可写数据源标识字符串或引用。三维图层可用 setVisible、setPaint、setFilter(仅点云)、rename、remove、get、list、camera.fitLayer;高程显示另可 setOpacity、move。不适用的操作返回 CAPABILITY_UNAVAILABLE。
  • 容量:三维地形 1 个、点云 4 个、模型与 3D Tiles 合计 1 个、高斯 1 个;超出直接拒绝,先移除旧内容。三维内容不随场景启停,不要传 owner。
  • map.layers.list() 对三维图层返回 state(loading/ready/degraded/failed)、displayedCount、sourceCount、verticalReference 等;工作台手动打开的点云、模型、高斯以 scriptManaged: false 列出。await map.layers.ready(layer, {timeoutMs}) 等待当前视野加载到位,超时返回当前状态并带警告。
  • 在线三维切片可直接使用 OSS 上的入口地址;入口、子层级、切片和纹理均须可访问,关联地址按各文件所在目录解析。支持 HTTP 重定向,内容按当前视野下载;移除后清理本次打开的临时缓存。保存工作台或模型项目时保留在线入口,下次打开重新读取。当前仍限显式层级与 glTF/GLB/b3dm 静态三角网格;不支持隐式层级、原生三维矢量线或多个模型/切片叠加。单次打开的磁盘缓存最多 256 MiB,其他原有显示和解析预算仍生效。
    // 将地址替换为你已上传的切片入口。
    const source = await map.sources.add('bridge', {
      type: '3dtiles', url: 'https://your-oss.example/bridge/tileset.json'
    });
    const layer = await map.layers.add({id: 'bridge', type: '3dtiles', source});
    export default await map.layers.ready(layer, {timeoutMs: 30000});
    

    准备自托管数据时,可运行 python tools/download_3d_tiles.py --url <可访问的入口> --out <新目录> 下载显式层级及关联资源,然后整体上传输出目录,入口为 tileset.json。工具会重写关联路径,不会修改源站文件;遇到隐式层级或不支持的容器会明确失败,不将未完成目录标为成功。仅有 Cesium ion 资源编号时,仍需获得可访问的切片入口或原始导出包。
  • 在线地形与 MapLibre 写法一致:
    await map.sources.add('terrainSource', {type: 'raster-dem', url: 'https://terrain.sjs.pub/mapterhorn/tiles.json'});
    await map.setTerrain({source: 'terrainSource', exaggeration: 1});
    await map.camera.setView({center: [11.39085, 47.27574], zoom: 12, pitch: 60});
    

    覆盖级别以服务为准:Mapterhorn 在国内多数地区只到 12 级,更高级别缺瓦片会在近处出现空洞;国内山区演示可改用 https://terrain.sjs.pub/tiles.json(Terrain-RGB,最高 14 级)。在线高程与图层面板的等高线共用同一个在线高程源:图层面板正在显示其他地址的等高线时会拒绝开启,需先关闭等高线;同一数据源重复调用会重新显示地形并更新夸张系数;脚本自己接入的在线高程源在 map.setTerrain(null) 后释放。在线地形不能用 map.queryTerrainElevation 查询,请用 map.contours.sampleElevation;在线高程不能做 hillshade/color-relief 图层,三维地形自带光照晕渲。
  • map.getTerrain() 读取地形状态(在线地形 online 为 true),map.setTerrain(null) 关闭;map.setProjection({type: 'globe' | 'mercator'}) 切换球面/平面,地形仅在平面三维可用。
  • 三维拾取沿用 map.features.query({point: [x, y]})(地图区逻辑像素):命中项 kind 为 terrain(地表,含源数据高程)、point(已显示点,含分类代码与中文说明)、model/tile(节点与最多 64 个属性)、splat(可视近似,不能测量)。await gis.geometry.distance3d(a, b) 用两个命中或 {lngLat, height, verticalReference} 计算水平、垂直和空间距离,高度基准不一致时拒绝。

DEM 与点云分析

// @gis-api 0.4-p2
// @permissions ["project.read", "map.write", "analysis.execute", "export.write"]
import {gis, map} from 'gis';
const dem = await gis.data.open('D:/data/utm-dem.tif');                 // 投影米制 DEM
const slope = await gis.raster.slope(dem, {addToMap: true});             // 坡度(度)
const lines = await gis.raster.contours(dem, {interval: 10});            // 等高线,字段 ELEV_M
await map.sources.add('pc', {type: 'pointcloud', path: 'D:/data/a.laz', verticalReference: 'EGM96'});
const density = await gis.pointClouds.density('pc', {cellSize: 1});      // 全源点密度
const ground = await gis.pointClouds.classifyGround('pc', {cellSize: 1});
const plan = gis.export.pointCloudClassification(ground, {path: 'D:/out/ground.csv'});
export default {slope, lines, density, ground: ground.summary, plan};
  • gis.raster.hillshade/slope/aspect 需要未旋转、水平单位为米的投影 DEM,且第 1 波段为米值;contours 需 interval(米)。结果是临时成果,脚本结束且不再显示时清理;需要长期保留请用 gis.export.raster(GeoTIFF,≤64 MiB)或 gis.export.dataset。
  • gis.pointClouds.* 的第一个参数是 pointcloud 数据源(标识或引用),只支持本地、UTM 米制、已声明高度基准的全源数据,不使用屏幕上的抽稀点;在线 COPC 需先下载。neighbors 的 center 为 [经度, 纬度, 高度],最多返回 100 个点;toDem/density 返回栅格;classifyGround 返回分类引用,只能导出 CSV,不改写原点云。slope 是坡度比(米/米,0~5,默认 0.15),groundThreshold 单位为米(默认 0.3)。
  • gis.export.splatPreview(layer, {path, resolutionScale, transparent}) 把当前视角下的高斯资产单独渲染为 PNG,不含地图其他内容。
  • map.workspace.save({path}) 把地形、点云、模型/切片、高斯与视角写成 JSON 清单(路径相对清单目录);map.workspace.load(path, {mode: 'append' | 'replace'}) 预演后整批恢复,结果 layers 中的标识可用 map.layers.get 取得;地形由工作台异步开启。

加载 MapLibre 样式底图

// @gis-api 0.4-p2
// @permissions ["project.read", "map.write"]
import {map} from 'gis';
const load = await map.basemap.load({url: 'https://terrain.sjs.pub/demotiles/style.json', compatibility: 'strict'});
const status = await load.ready();      // 等待初始视野提交;status.state 为 'ready' 或 'degraded'
export default {state: status.state, readyTiles: status.readyTiles, warnings: status.warnings};

camera: 'preserve' 保留当前视野,'style' 采用样式自带的初始视野;也可用 initialView: {center, zoom} 指定。加载可用 load.cancel() 取消,map.basemap.status() 随时读取状态。compatibility 目前只接受 'strict'(或省略);'degraded' 表示底图已显示但部分内容(如文字)尚未完整加载,此时地图导出会被拒绝。

内置浅色 OpenFreeMap 底图可用 url: 'https://tiles.openfreemap.org/styles/openfreemap-simple' 加载,暗色用 url: 'https://tiles.openfreemap.org/styles/openfreemap-dark'。这些地址使用随程序发布的样式,地图瓦片和地名字体仍联网加载,不需要地图服务密钥。网络加载较慢时可导出加载引用让底图在后台继续加载,并通过 map.basemap.status() 查看进度;等值线和立体等高线演示采用这一方式。

按高程字段设置三维高度

map.layers.setHeight(layer, options) 按完整源数据的数值字段设置三维显示高度,单位为米,计算式为 (字段值 - base) * exaggeration + offset。base、offset 默认 0,exaggeration 默认 1,允许 0~1000。以下 ELEV 是 L7 公开等高线示例的字段;自己的数据请先确认实际高程字段及单位,不要照抄字段名或基准值。

// @permissions ["project.read", "map.write"]
import {gis, map} from 'gis';
const data = await gis.data.open('本地等高线文件.geojson', {targetCrs:'EPSG:3857'});
const source = await map.sources.add('elevation-source', {type:'dataset', data});
const layer = await map.layers.add({
  id:'elevation-lines', name:'立体等高线', type:'line', source,
  paint:{'line-color':'#34B6B7', 'line-width':1}
});
const height = await map.layers.setHeight(layer, {
  field:'ELEV', base:1400, exaggeration:1, offset:0
});
await map.camera.setView({center:[102.597971,23.110479], zoom:13.34, pitch:45});
export default height;

exaggeration: 1 保留米制高程差,只有明确需要夸张时才增大倍数。其他绘图库的高度参数可能使用绘图坐标单位,不能直接当作米;立体等高线演示将 L7 的 heightfixed 单位换算为米后再显示。

返回摘要包括字段、完整源要素数、最小/最大显示高度和实际参数,不返回全量高程或几何。传 null 清除设置并恢复默认三维高度:await map.layers.setHeight(layer, null)。场景所属图层可在 scene.start() 前设置,开始时一并应用;高度随图层保留,脚本退出后仍生效。

当前支持 Web 墨卡托视图中的静态 line 图层及普通属性/分级颜色、线宽、透明度样式;三维高度采用平面基准,不是地形上的真实海拔,不自动转换垂直高程基准。开启真实地形时,平面基准高度图层沿用工作台规则暂不显示。动画线、渐变/虚线、点面专题符号、热力、聚合和实时源暂不支持这项设置。字段缺失、空值、非数字或计算溢出会整层拒绝,保留已有设置。此操作只改变显示,不改写源高程、原始几何或二维显示,不需破坏性操作确认。

调整地球仪与三维建筑的光照

// @gis-api 0.4-p2
// @permissions ["project.read", "map.write"]
import {map} from 'gis';
// 北京时间 2024-06-21 18:00 的真实太阳位置;地球仪上可看到晨昏线
await map.lighting.set({view: 'globe', mode: 'sun', sunTime: Date.parse('2024-06-21T18:00:00+08:00'), utcOffsetMinutes: 480, ambient: 0.25});
// 三维建筑改为从正西方 30° 高度照射
await map.lighting.set({view: 'building', mode: 'fixed', azimuth: 270, elevation: 30});
export default await map.lighting.state();

地球仪和三维建筑各有一套设置,map.lighting.state() 同时返回两者,active 表示当前正在显示哪个视图(都不在时为 null)。map.lighting.set 省略 view 时调整当前视图,二维地图下必须指定。字段只改传入的部分:

  • mode:'default' 内置方向(地球仪随视角在左上方,三维建筑来自东南);'fixed' 按 azimuth(0~360°,正北顺时针)和 elevation(-10~90°)从视野中心照来;'sun' 按 sunTime 计算真实太阳位置。
  • sunTime:'now' 实时跟随(每分钟刷新),或 Unix 毫秒时间戳(可用 Date.parse 生成)。
  • utcOffsetMinutes:界面显示太阳时间所用的时区偏移(分钟,-720~840,默认 480 即 UTC+8),不改变 sunTime 表示的时刻。
  • strength:光照强度 0~2;ambient:背光/夜面亮度 0~1,地球仪默认 0.25,三维建筑默认 0.6。
  • reset: true 先恢复该视图默认值,再应用同一次调用里的其他字段。

设置随应用保存,也可在地图右下角「光照」按钮或地球仪工具栏中调整。

共同光照与历史事件

首选 import {map} from 'sqsmap' 后使用 map.setLight({anchor:'viewport',position:[1.15,210,30],color:'#ffffff',intensity:0.75}),await map.sqs.flush() 确认,await map.getLight() 读取。共同设置应用到 globe/building;旧 map.lighting.set 只覆盖选中视图并清除其 mapLight,另一个视图不变。sqs.lightingchange 返回不可变历史 lightingState。网页、桌面和内置原生脚本保持同一形状,细节、支持限制与完整 HTML 见光照指南。

地名、坐标与行政区边界

内置全国省、市、县、乡镇地名库(名称、区划代码、驻地坐标、范围)。不要在脚本里手写地名的坐标或范围,一律先查询;用户给的坐标文本用 gis.places.parseCoordinate 解析(十进制、度分秒、东经北纬或 E/N 标记,顺序写反自动纠正)。

// @gis-api 0.4-p2
// @permissions ["project.read", "map.write", "analysis.execute"]
import {gis, map} from 'gis';

// 1. 查地名:返回按 score 排序的候选;重名时交给用户确认
const page = await gis.places.search('五华区', {limit: 5});
const unique = page.items.length === 1 || (page.items[0]?.exact && !page.items[1]?.exact);
let result;
if (!unique) {
  result = {needConfirm: page.items.map(p => p.fullName)};
} else {
  const place = page.items[0];
  // 2. 取边界(需联网,已下载过的走本地缓存),上图并定位
  const boundary = await gis.places.boundary(place);
  const source = await map.sources.add('place-boundary', {type: 'dataset', data: boundary});
  await map.layers.add({id: 'place-line', type: 'line', source,
    paint: {'line-color': '#0b61f4', 'line-width': 2}});
  await map.camera.centerOn(place);            // 按级别缩放:省 7 / 市 11 / 县 12 / 乡镇 15
  // 3. 与业务数据组合:用行政区边界裁剪图层
  const clipped = await gis.analysis.clip(await map.layers.get('小班'), boundary);
  result = {place: place.fullName, count: (await clipped.info()).featureCount};
}
export default result;
  • Place 字段:code(6 位省/市/县、9 位乡镇代码)、name、fullName(如"云南省 昆明市 五华区")、level('province'|'city'|'county'|'town')、center([lng, lat],驻地优先,centerIsSeat 为 false 时是区域内代表点)、bbox、parentCode;search 另有 score(0~100)与 exact。
  • 需要传地名的参数都接受 Place 对象、区划代码(字符串或数字)或唯一的地名,简称如"大理州""广西"也可用;地名不唯一时以 AMBIGUOUS_NAME 失败并列出候选。选项里的 level 可写 'province'|'city'|'county'|'town',也可写中文 '省'|'市'|'县'|'乡镇'。
接口返回
gis.places.search(text, {limit, level, within})Page<Place>:读 page.items;within 限定在某行政区内,如 {within: '甘肃省', level: '乡镇'} 找甘肃的"城关镇"
gis.places.get(place)Place
gis.places.children(place, {limit, cursor})Page<Place>:直属下级
gis.places.parseCoordinate(text)[lng, lat] 数组,无法解析时为 null
gis.places.reverse([lng, lat]){province, city, county, town},每项为 Place 或 null;按行政区边界判断,需联网
gis.places.nearest([lng, lat], {level, limit})Place 数组(不是分页),每项另有 distanceM(米),按距离升序;level 默认乡镇
gis.places.boundary(place, {children})DatasetRef(WGS84 面);children: true 返回全部直属下级的边界
map.camera.centerOn(target, {zoom, padding})target 可为地名、[lng, lat](默认保持当前级别)、[minX, minY, maxX, maxY] 或图层引用;zoom 为地图显示级别

map.camera.fitBounds 也可直接传 [minX, minY, maxX, maxY](按 WGS84)。

场景与动画(阶段 7 能力)

// @gis-api 0.4-p2
// @permissions ["project.read", "map.write", "scene.run"]
import {gis, map} from 'gis';
const scene = await map.scenes.create({id: 'tour', name: '巡视'});
const data = await gis.data.open('lines.geojson');
const source = await map.sources.add('route', {type: 'dataset', data}, {owner: scene});
await map.layers.add({id: 'route-line', type: 'line', source, paint: {'line-color': '#174c37', 'line-width': 3}}, {owner: scene});
const fly = await map.camera.flyTo({center: [102.7, 25.0], durationMs: 3000}, {owner: scene}); // zoom 仅在 Web Mercator 视图可用
await scene.start();          // 需要 scene.run;场景在脚本结束后继续由软件管理
await fly.finished();
export default {scene};

草稿场景不显示;scene.start() 后资源归场景所有,脚本退出不会清理。控制用 scene.pause()/resume()/stop(),移除用 map.scenes.remove(scene)(确认计划)。

线条动画

map.animations.line(options, {owner: scene}) 为同一场景中的二维线图层创建播放对象。源需启用 lineMetrics: true,最多 4096 条线、十万顶点;多段线的各段独立计算进度,不会在断开的两段间绘制连接线。图层须是已注册的线图层,且每层最多一个活动控制器。

// @gis-api 0.4-p2
// @permissions ["project.read", "map.write", "scene.run"]
import {gis, map} from 'gis';
// 人工流向示意;实际任务须使用真实线路或已确认的风场数据。
const data = await gis.data.fromGeoJSON({
  type: 'FeatureCollection',
  features: [{type: 'Feature', properties: {}, geometry: {
    type: 'LineString', coordinates: [[102.7, 25], [102.71, 25.008], [102.72, 25.01]]
  }}]
});
const scene = await map.scenes.create({id: 'flow-demo', name: '流向示意'});
const owner = {owner: scene};
const source = await map.sources.add('flow-source', {type: 'dataset', data, lineMetrics: true}, owner);
const playbacks = [];
for (const [id, width, effects] of [
  ['flow-dash', 3, [{type: 'dash', unit: 'pixels', on: 12, gap: 8}]],
  ['flow-arrows', 10, [{type: 'arrows', unit: 'pixels', spacing: 80, length: 14}, {type: 'glow', radius: 4}]]
]) {
  const layer = await map.layers.add({id, type: 'line', source, paint: {
    'line-color': '#2277cc', 'line-width': width
  }}, owner);
  playbacks.push(await map.animations.line({layer, timing: {durationMs: 2000, loop: true}, effects}, owner));
}
await scene.start();
await map.camera.fitBounds([102.7, 25, 102.72, 25.01]);
export default {scene, playbacks}; // 保留场景和播放引用;循环动画不等待 finished()

同层的 flow、dash、reveal、arrows、pattern 效果使用遮罩相乘,因此叠加流动拖尾、虚线和箭头时,只显示各遮罩共同覆盖的部分,画面可能很稀疏。连续流动虚线加大箭头采用上例的同源两层:虚线宽 3、亮段 12/间隙 8 逻辑像素;箭头层宽 10 加 4 逻辑像素光晕;各用独立控制器,同属一个场景,单程周期均为 2 秒。箭头可覆盖虚线间隙;glow 自身不会取消同层其它效果的遮罩。

源、图层、动画都使用同一 owner,先注册源、后注册层、再创建动画,最后开始场景。export default 返回 SceneRef 和 PlaybackRef,场景在脚本退出后继续播放。当前画面导出使用 gis.export.map(确认计划);不要把播放对象当作数据集导出。

最小循环拖尾示例可通过 describe_api('map.animations.line') 获取,也见方法与完整示例。另一个完整可运行示例见 tools/examples/line_animation.js:从内存构造弧线,再通过 gis.data.fromGeoJSON 创建数据集、以 type: 'dataset' 注册场景源,生成循环拖尾。示例为人工流向示意,不代表实际风场。

较大的接口说明在 arguments.schema、typeSchemas 和 $defs 使用本次响应内的 JSON Pointer(如 #/$defs/T0)复用同一份类型或参数定义;递归解引用后与完整参数契约一致。typeSchemas 只替代重复 DTO 展示,场景及播放控制方法仍在 declarations 中;LineKeyframe 保留通用数字值声明,透明度和宽度倍率的具体范围分别由轨道参数约束。

配置规则
timing.durationMs必填,单程周期 1~86400000 毫秒
timing.loop默认 false;true 为持续循环
timing.direction默认 forward;支持 reverse、往返 alternate,往返完整周期为单程两倍
timing.easing默认 linear,可用 ease-in-out
timing.delayMs初次开始前等待 0~86400000 毫秒;指定进度跳过初始等待
timing.fill默认 forwards,完成后保留最后画面;none 恢复静态样式
effects1~6 项,flow、dash、reveal、arrows、glow、pattern 每类最多一项;可选 id 为 1~64 字符且不能重复
cap默认 butt 为平头;round 为圆头
stagger默认 false;开启后按稳定要素标识错开各条线
phaseField / speedField可选数字字段名;相位须在 -1000000~1000000,速度倍率在 0~100。缺字段或值非有效数字报错,不自动猜测或转换
tracks.opacity / tracks.widthScale2~32 个 {offset,value} 关键帧,进度严格递增并包含 0、1;透明度 0~1,宽度倍率 0~8
tracks.color2~32 个 {offset,value} 关键帧,进度同样严格递增并包含 0、1;颜色仅支持 #RRGGBB 或 #RRGGBBAA,不支持颜色名称或缩写

颜色关键帧在相邻颜色间按 RGBA 分量插值,并与基础线色、沿线渐变相乘。例如 color: [{offset: 0, value: '#ffffff'}, {offset: 1, value: '#ffffff80'}] 保持原始颜色并逐步降低透明度。白色 #ffffff 不改变底色;要得到指定颜色本身,可将基础线色设为白色。颜色中的透明度还会与 tracks.opacity 及各效果遮罩相乘。

flow 接受 unit(默认 progress,另支持逻辑像素 pixels)、spacing(默认 1,须大于 0)、trailLength(默认 0.6,须大于 0 且不超过间距)、fade(默认 linear,或 none)和 phase(默认 0,范围 -1000000~1000000)。比例单位的 1 表示整条路径,像素单位在缩放与 DPI 变化时保持视觉长度。phase 为周期比例,每单程周期前进一个 spacing。

dash 接受相同的 unit,必填的 on 和 gap 分别为亮段长度与间隙,均须大于 0,每单程周期前进一个 on + gap。这四个长度参数的上限均为 1000000。reveal 接受 start(默认 0)和 end(默认 1),均为路径比例,且起点严格小于终点。效果可组合,最终透明度叠乘。

arrows 沿路径重复显示流动箭头,接受相同的 unit、spacing(默认 1)与 length(默认 0.2),要求 0 < length <= spacing <= 1000000;每单程周期移动一个间距。glow 为线外柔和光晕,接受 radius(默认 4,范围 0~64 逻辑像素)和 intensity(默认 0.5,范围 0~1),与线体使用相同颜色;不读取外部纹理。

pattern 读取本地静态 PNG/WebP 沿线重复铺设图案,path 必填,接受相同的 unit、spacing(默认 1,须大于 0 且不超过 1000000),每单程周期移动一个间距。文件不超过 4 MiB、边长不超过 1024、解码后的 RGBA 不超过 4 MiB;不支持网络图片和动态图像。加载时检查资源预算,播放时不重复读文件。

播放控制复用 play/pause/seek/stop/info/finished:暂停保留当前画面,停止恢复静态样式;seek 按完整周期的毫秒进度定位,往返时范围为两倍单程周期。无限循环的线动画不会自然完成,调用 finished() 会持续等待,直到显式停止后以 CANCELLED 拒绝;旧路线动画的等待语义保持不变。源几何变化会使播放失效,需重新创建;图层、场景移除后释放对应资源。

当前只支持二维平面线条动画;米制移动速度、三维贴地动画尚未发布。后续通过新增效果类型扩展,同一套场景和播放控制继续沿用。

相位使用双精度计算,允许正负一万亿周期。pixels 模式下单条路径的累计屏幕长度不得超过一千万逻辑像素;放大后超限会明确停止并恢复静态样式,建议改用 progress 或降低放大倍数。超限画面不能静默漏画后导出。原生同时最多 32 个动画层,动画 GPU 资源合计不超过 256 MiB。

6. 错误码

错误码含义处理建议
INVALID_ARGUMENT参数或语法不符合接口声明对照参考文档修正参数;错误信息会带脚本行号
PERMISSION_DENIED权限未声明或账号无导出权限补权限声明或检查账号导出权限
NOT_FOUND数据、图层、字段或地名不存在先用 gis.data.fields、map.layers.list、gis.places.search 查询真实名称
AMBIGUOUS_NAME同名数据层或地名不唯一改用 id、区划代码或明确的名称;地名把候选交给用户确认
STALE_HANDLE引用已释放、源数据已变化或游标过期重新获取引用 / 重新查询
CONFLICT标识已被使用,或目标在预演后发生变化换 id 或重新预演
CANCELLED用户拒绝确认、停止脚本或动画被打断停止后续步骤
RESOURCE_LIMIT超出超时、内存、结果或数量预算拆分处理、缩小范围
UNSUPPORTED_FORMAT / IO_ERROR / ENGINE_ERROR文件格式、读写或本地引擎问题检查文件路径与权限
CAPABILITY_UNAVAILABLE当前视图或环境不支持该能力(如非 Web Mercator 视图使用 zoom)查看参考文档中的前提条件

错误对象有 code 与 message,可在 try/catch 中读取。

7. 跨端编写规范

同一份脚本要在桌面、移动端与网页上得到相同结果。桌面与移动端用 QuickJS 运行,网页用浏览器 Worker,两者的全局对象与引擎行为不同, 请遵守以下规则:

  • 只用模块导出:只用 gis、map、expr、sleep。不要使用 console、setTimeout、fetch、WebSocket、importScripts 等全局对象 (桌面没有;网页 Worker 启动时也会移除),需要联网时用 gis.* 的在线接口,由宿主统一处理跨域、代理与审计。
  • 不依赖本地化与引擎差异:不用 Intl、toLocaleString、Date 解析日期字符串等行为(QuickJS 不支持或结果不同);需要格式化的数值 在返回结果里保留原值,由界面格式化。
  • 错误只认 code 与 message:不解析 stack,各引擎的堆栈格式不同。
  • 按能力而非环境分支:用 gis.capabilities.get() 判断平台能力(platform、lineAnimation、localFiles、gdal 等),不按 gis.api.runtime() 返回的字符串猜测运行环境;可用接口名用 gis.capabilities.list()。
  • 文件位置:桌面可用任意本地路径,移动端仅限应用沙箱,网页没有文件路径。需要跨端运行的脚本,文件参数用 FileRef(由用户选择 或导出得到)或 https:// 地址,不要写死 D:\... 之类的本地路径。让用户选择文件用 gis.files.pick,返回的 FileRef 可直接作为 模型、DEM、点云、3D Tiles、高斯泼溅、矢量文件、栅格文件、精灵图与线型图案的 path:
    const [file] = await gis.files.pick({accept: ['glb', 'gltf'], title: '选择三维模型'});
    if (file) await map.sources.add('bridge', {type: 'model', path: file, lngLat: [102.71, 25.04]});
    

    用户取消时返回空数组;multiple: true 允许多选。3D Tiles 的 FileRef 需指向入口 tileset.json,其引用的子文件按相对路径读取(网页端 单个 FileRef 无法读取同目录文件,请改用 url)。
  • 网页版:官网示例栏目的脚本控制台(map.sqsh.com/example)在浏览器 Worker 中运行同一份脚本(同一套参数校验与权限),目前提供地图显示、相机、数据源与图层、 内存 GeoJSON(gis.data.fromGeoJSON)与样式底图;图层 paint 暂按默认样式显示,地名库与其余接口在网页端返回 CAPABILITY_UNAVAILABLE。
  • 运行前检查:调试板(Ctrl+F12)的「检查跨端兼容」按移动端与网页端的接口表扫描脚本,列出不支持的接口与写死的本地路径,不运行脚本。 宿主可调用 sqs_script_contract::check_platform(源码, 平台) 做同样的检查。
  • 重计算交给宿主:QuickJS 为解释执行,大循环可能比浏览器慢一个数量级;统计、分析、几何运算请调用 gis.analysis.*、gis.query.* 等接口,不在脚本里逐要素计算。

8. 边界与不支持项

  • 三维能力以宿主已验收的子集为准:分层设色为固定色带,模型不支持俯仰/横滚与局部模式,3D Tiles 支持本地或 HTTP(S)/OSS 显式层级静态网格,高斯仅 SH0~SH3 二进制 PLY;在线地形请用 map.contours.*。
  • 样式底图只支持 MapLibre Style 规范的子集,不兼容项通过 status.warnings 报告。
  • 脚本图层样式为 MapLibre 风格的子集:fill/line/circle/symbol/heatmap/raster 及上文的高程与三维图层,只接受已声明的 paint 属性,不接受完整 Style JSON。表达式在 CPU 计算,每层最多 4096 要素、50 万顶点。
  • 场景最多 16 个,每场景 128 项资源;聚合与实时源首批最多 4096 个点。
  • 脚本不能访问文件系统、网络或系统 API,只能通过上述接口;联网无需授权。
  • 地名库为内置离线数据;gis.places.boundary 与 gis.places.reverse 需要联网获取行政区边界(本地缓存),不可用时以 CAPABILITY_UNAVAILABLE 失败。
  • 参考文档中未列出的方法即不存在,不要臆造。
  • 每个接口标注了可用平台(参考文档中的「平台」一项):桌面与移动端支持全部接口;网页端目前只提供地图、地名、实时数据等能力,数据读写、编辑、分析、导出、凭据以及读写本地文件的接口不可用。为网页端编写脚本时请对照 gis.web.d.ts。
  • 运行时能力用 gis.capabilities.get() 查询(同步返回、只读):platform(desktop / mobile / web)、graphics(实际图形后端,地图未初始化时为 null)、computeShaders、lineAnimation、gaussianSplats、localFiles(any 任意路径 / sandbox 应用沙箱 / picker 仅用户选择的文件)、corsRestricted、gdal。按能力选择写法,不要按 api.runtime() 字符串猜测环境;可用接口名仍用 gis.capabilities.list()。
const caps = gis.capabilities.get();
if (caps.lineAnimation) map.animations.line({layer, timing: {durationMs: 4000, loop: true}, effects: [{type: "flow"}]}, {owner: scene});
else await map.layers.setPaint(layer, {"line-color": "#0b61f4"}); // 不支持线动画时保留静态样式

三维建筑视图中的地图导出使用当前透视画面,包含已加载的本地影像与在线图层。透视画面没有统一比例尺,固定朝上的指北针也不能代表旋转后的真北方向,因此省略这两项默认制图元素;如显式要求显示,导出会说明原因并拒绝。

平面三维可在 gis.export.map 的选项中设置 resolutionScale: 2(允许 1~4),以当前画面范围和同一视点在更大的离屏画布重新绘制,线宽、文字和点标记随倍率放大;例如 gis.export.map({path: "map-2x.png", format: "png", resolutionScale: 2})。输出最多 1000 万地图像素,单边不超过显卡支持的纹理尺寸。目标倍率所需内容未就绪时严格导出会拒绝,只有显式设置 allowIncomplete: true 才允许带不完整标记的结果。二维地图与球面模式只支持按当前画面尺寸导出(resolutionScale 须为 1):二维放大画布相当于换了缩放级别,线宽、符号和随级别变化的样式都会不同,不是同一画面的高清版。

completeness 明确完整性策略:'loaded' 按当前已加载内容导出(等同允许不完整);'targetView' 固定当前视角与内容,异步等待目标细节,超时由 timeoutMs 指定(默认 30000,上限 120000),未设置 allowIncomplete: true 时缺块、缺纹理或超时均会失败。

平面三维含可见点云时,高清导出会先按目标倍率准备点云细节,异步等待(默认最长 60 秒),不阻塞地图操作;等待期间改变视角、图层内容或点源会中止本次导出,需重新发起。取消脚本、等待超时、失败及成功导出后,都会恢复屏幕浏览的点云密度。allowIncomplete: true 可跳过完整细节等待,但仍须生成当前目标画面的有效帧,不能使用旧帧。

9. 相关文件

数据转换与影像窗口(GISAPI-11)

data.layers(path) 发现矢量子层,data.open(path,{layer}) 打开指定子层,data.fields 读取字段。data.reproject(dataset,{outputCrs,name?}) 返回独立二维数据引用,保留字段和顺序;转换不会修改源文件。

影像使用 data.open(path),通过 await raster.info() 获取 bandInfo、geoTransform、nativeBounds。bands 仍是数量;波段从 1 开始。无效值声明 noData 为数值、"nan" 或 null(未声明),未声明比例为 scale=1、offset=0。缺地理参照时范围/仿射信息为 null,允许检查像元,但不能转换或按地理位置上图。

import {gis} from 'gis';
// dem 是此前打开的 RasterRef,范围与尺寸来自已确认的目标网格。
const converted = await gis.raster.warp(dem, {
  outputCrs: 'EPSG:32647',
  grid: {bounds: [500000, 0, 500040, 40], width: 4, height: 4},
  resampling: 'nearest', dataKind: 'continuous', name: '转换成果'
});
const block = await gis.raster.readPixels(converted, {
  band: 1, window: {xOffset: 0, yOffset: 0, width: 4, height: 4},
  values: 'physical'
});
export default {converted, sample: block.values};
  • grid.bounds 使用 outputCrs,精确采用指定范围;不扩大对齐。所有必填参数须明确提供。分类数据 dataKind=categorical 只能 nearest;连续数据允许 nearest/bilinear。
  • cutline 可传二维有效面 DatasetRef/FeatureSetRef;按真实几何转换和默认栅格化掩膜裁剪。处理所有波段,保留原始存储值及 scale/offset/unit,输出 Float64,以 NaN 标记覆盖外或无效像元。
  • readPixels 返回行优先 values 数组;raw 不换算,physical 对有效样本计算 raw×scale+offset,无效为 null,有效 0 保留。窗口不自动裁短,每次最多 4096 像元及 60 KiB;超限应缩小窗口。
  • 每轴最多 65536,输出所有波段合计最多 16777216 个样本(128 MiB 原始数据)。首期还将源规范化限制为同样样本预算、最多32波段;块不超过256×256。源/输出和中间文件共享256 MiB临时磁盘预算,保守开销预留可能提前拒绝接近上限的任务,不能静默降低分辨率。
  • 新影像是临时成果,最后一个脚本/地图引用释放时清理;返回引用可跨任务结束保留。任务取消、异常和超限不交付半成品。正常释放覆盖生命周期;进程被强制终止可能遗留系统临时目录。
  • 需要随程序更新的 sjs 运行库及 PROJ/GDAL 数据。旧库会明确报能力不支持,不要求用户自行安装命令行工具。Windows 实机验收仍待完成;分区统计见下节。

栅格分区统计(GISAPI-12)

raster 为已打开的影像引用,zones 为面数据集或已筛选的面集合,字段名必须来自实际数据:

const table = await gis.raster.zonalStats(raster, zones, {
  zoneIdField: 'zone_id',
  band: 1,
  statistics: ['min', 'max', 'mean', 'sum', 'count'],
  values: 'physical',
  nodata: 'exclude',
  pixelInclusion: 'center',
});
const info = await table.info();
const page = await gis.query.rows(table, {limit: 20});
// page.items 中每行的 values 保存分区 ID 和统计结果;后续使用 page.nextCursor。
  • 除 name 外,上述选项均必填。分区 ID 必须唯一、非空,类型为字符串或安全整数;不能与输出列重名。统计项不可重复,仅输出请求的统计列,另固定包含 validCount/noDataCount。
  • 使用原始分析栅格,按像元中心判定,中心恰在分区边界也纳入;孔洞被排除,重叠分区独立统计。自动将分区转换到影像坐标系,不重采样影像。只统计影像覆盖范围内的像元。
  • 掩膜、NoData 和非有限数值均排除。count 等于 validCount;无有效像元时两者为0,min/max/mean/sum 为 null。覆盖范围外不会增加 noDataCount。
  • raw 使用原始数值;physical 在有效性判断后应用 scale/offset。info.rasterValues 记录 band/mode/sourceUnit/unit/scale/offset;非平凡比例下 raw 的 unit 为 null。数值统计列提供已知单位,计数列不继承影像单位。
  • 分块最大256×256;全部分区累计候选像元最多100万(保守包围窗口,含重叠重复计数)。沿用十万条面记录、百万顶点以及表格8 MiB和共享资源预算;超限、取消或源文件变化会失败,不返回部分成果。复杂面耗时取决于原生空间判断,单次原生调用不能中途打断。

本地只读查询(GISAPI-13)

先用 gis.data.fields 核对真实字段,再把已有数据集、筛选集合或表格引用注册为来源。下面假设已取得 parcels,且实际存在 owner 与 parcel_id 字段:

const table = await gis.query.sql({
  text: 'SELECT parcel_id FROM p WHERE owner = ?',
  sources: {p: parcels},
  bindings: ["O'Reilly"],
  dialect: 'sqlite',
  result: {type: 'table'},
});
const page = await gis.query.rows(table, {limit: 20});
export default page.items.map(row => row.values);

text/sources/bindings/dialect/result 必填,name 可选。无参数也传 bindings: [];只接受匿名 ? 与位置数组,不接受命名参数或 ?1。绑定支持字符串、有限数字、安全整数、布尔及null,禁止拼接用户值。来源别名和字段标识符应独立正确引用;不能通过值绑定代替列名。

sources: {a: parcels, b: parcels} 已完成双别名注册,可直接 JOIN,不需要先复制两份表。普通表格结果须显式选择属性列:源空间列为 geom,SELECT * 会带几何,不能当普通表格输出。所有结果列须有唯一名称,连接时用 AS 避免重名。保留 NULL 与空字符串的区别。

空间成果用 result: {type: 'features', geometryColumn: 'shape', crs: 'EPSG:4326'},查询中直接选出 geom AS shape。CRS必须与原几何一致,仅作为断言;不改变坐标,也不支持SQL几何构造表达式。返回DatasetRef可直接接已有缓冲、聚合等接口。空几何不能生成空间成果。

直接字段保留源类型及空结果schema;表达式类型来自非空结果,没有列声明且空或全NULL时类型为string。布尔绑定按SQLite的0/1语义执行。查询结果为宿主持有的表格或数据集,仍通过既有分页读取;不要将完整结果搬入Agent上下文。

首期只支持本地SQLite受限方言,不连接远程PostGIS,不回退OGR。只允许SELECT及已验证的纯函数子集,禁止写入、PRAGMA、附加数据库、扩展加载、文件函数、内部元数据、复合SELECT和递归CTE。完整函数和资源边界见第13项契约。最多8个来源、累计一万行及4 MiB快照;输出最多一万行及4 MiB计费值,超限/取消失败,不返回部分成果。需要同步更新sjs运行库;旧库明确报告能力不可用,Windows实机验收待完成。

共同门面新增 map.sqs.flush({render,since}),返回实例身份、捕获水位及实际相机/帧回执。仅使用同一入口曾返回的水位;应用宿主请求序号不等同于底层 SDK/C 命令序号。旧 npm SDK 无确认能力时明确拒绝,二维原始相机与设备验收边界见命令与生命周期。

共同二维相机(06.3)

map.jumpTo/fitBounds/setCenter/setZoom/setBearing/setPitch/setPadding/resetNorth/zoomIn/zoomOut 返回地图,使用 await map.sqs.flush() 确认。getCenter/getZoom/getBearing/getPitch/getPadding/getBounds/getProjection/project/unproject/cameraForBounds 和 sqs.cameraState 返回真正的 Promise,查询等候此前共同相机写入。链式写入失败在省略确认时仍使脚本失败;已应用修改不会自动回滚。

完整代码、逻辑像素单位、二维范围、空白底图边界与已发布 npm 能力限制见生成门面参考。移动端未接通,不因共同声明存在就标注支持。

网页版指定图层定位已修复为所选矢量范围,不再定位全图。匹配 SDK 支持多层合并及留白/最大缩放;旧 npm SDK 只支持无定位选项的真实单层 focusLayer,其他组合明确拒绝。完整脚本和边界见官网指定图层定位。

共同样式设置(13.3)

// @gis-api 0.5-session
// @permissions ["project.read", "map.write"]
import { map } from 'sqsmap';
map.setStyle('https://tiles.openfreemap.org/styles/bright', { diff: false });
await map.sqs.flush();
export default await map.getProjection();

setStyle 返回地图,可与相机写入链式调用;权威查询等候此前共同写入。setStyle(null) 清空样式底图。当前仅接通 HTTP(S) 地址与完整替换,默认完整替换;diff:true、内联样式明确返回能力不可用,未知选项或无效地址返回参数错误,失败不修改已有底图。

桌面与带匹配 SDK 的网页宿主已实现;独立原生模块支持相同调用写法。桌面当前加载样式需要空白或 WebMercator 业务视图,其他 GIS 坐标系明确拒绝;移动脚本宿主继续接入,不能将其称为永久平台差异。下载与资源状态见原生资源和浏览器请求。网页旧 npm 包未含新入口时明确拒绝。命令确认不代表资源下载完成。

共同 GeoJSON 源见 图源指南。

共同circle/line/fill/raster、平面heatmap、无源background和点图片symbol的用法见 共享图层,网站提供中英文说明。

源查询的用法、分页和版本检查见网站 查询指南。

屏幕点/框查询与源查询的区别、孔洞、显示顺序和结果限额见 查询指南。

要素状态、选中/悬停与预算

标准相机 move 事件

共同二维相机变化可监听 map.on('move', event => { const state = event.cameraState; })。cameraState 与 await map.sqs.cameraState() 同一结构,包含 WGS84 中心、512 像素缩放、方向、边距、投影和 CSS 视口;它是不可改写的历史快照。事件确认实际应用,不确认 GPU 帧、网络资源、动画结束或 idle。连续命令分别通知,无变化和失败命令不通知;停止/取消监听后不继续回调。网页主线程、严格 Worker、桌面共同相机与原生持续入口接通,原生一次性监听仍明确拒绝。其余 movestart/moveend、zoom/rotate/pitch 生命周期与球面事件继续实施。详见 相机事件。

自定义比例尺与导航工具

普通地图操作沿用 map.zoomIn()/zoomOut()/resetNorth();上下限使用 await map.getMinZoom()/getMaxZoom()。用 await map.sqs.scaleAt({point:[x,y],maxWidth:80}) 取得水平 CSS 像素的局部地面比例尺,返回米数、建议条长与采样位置;监听 move 刷新自己的 UI。它采用球面局部近似,不是地形或工程测量;二维共同投影以外明确拒绝。见完整自定义工具指南和共同示例。

即时相机生命周期

共同二维相机提供 movestart/move/moveend、zoomstart/zoom/zoomend 和 rotatestart/rotate/rotateend。start 使用更新前的 event.cameraState,其余为更新后状态;失败和无变化不通知。异步宿主的回调不是同步写入前钩子,应使用事件快照;当前是每个即时命令的周期,不是动画或整个手势的起止。参见相机事件指南及完整共同生命周期脚本。

命令失败的原因与恢复

共同门面与原生入口保留 INVALID_ARGUMENT、CONFLICT、NOT_FOUND、STALE_HANDLE 等实际原因;后续 map.sqs.flush 不把这些原因统一改为 ENGINE_ERROR。确认失败包含 commandSequence/submittedSequence,用此前返回的 submittedSequence 作为同一入口的 since 排除已观察失败;这不清除历史,也不回滚已经应用的操作。取消错误码保留 CANCELLED,停止仍依照会话清理约定。完整可执行输入见 tools/command-lifecycle/portable-errors.js;中英文官网“命令确认与生命周期”指南同步,C 确认失败的 last_error 为带原错误码和水位的 JSON。

GeoJSON URL:map.addSource(id,{type:"geojson",data:absoluteHttpUrl})、source.setData(url)、map.sqs.getSourceInfo(id);加载通过 sourcedataloading/sourcedata/sourcedataabort/error 确认,详情见官网文档。

锚点导航(共同二维相机)

zoomTo/rotateTo/panTo/panBy/resetNorthPitch 已接通;zoomIn/zoomOut/resetNorth 支持 around 或 offset 选项。操作链式调用并用 await map.sqs.flush() 确认,坐标与屏幕单位分别为 WGS84 / 逻辑像素,角度按共同相机。缩放与回正可保留给定锚点;panBy 正偏移使内容反向移动。一次增减缩放在真实上下限停止,自定义步长用 zoomTo。getRoll 返回零,setRoll 目前只接受零。完整参数、立即应用和未接通动画边界见 锚点导航。

共同相机动画

easeTo/flyTo/stop 与持续动画状态已接入共同二维相机。flush 不代表动画结束;先注册 moveend,再检查 animation.status。详细选项、原生时钟/事件泵和减少动画约定见相机动画。

指针事件与图层委托已接通网页与原生动态库持续脚本;用 map.sqs.events() 检查真实宿主输入。详见 共同地图参考 与官网“宿主指针输入”中英文说明。桌面工作台已接通地图区域鼠标输入和共同图层委托;移动应用宿主及悬停事件仍待接入。桌面本机验收覆盖 RawInput 输入边界,外机与操作系统 HID 仍需实测。

原生脚本顶层 await 的参数错误保留已登记接口的安全说明与参数路径,不会被“未处理异步错误”覆盖;实际参数值与任意异常消息仍不回显。脱离顶层等待的未处理拒绝仍会结束会话。共同模块 sqsmap 的 map.setStyle 返回地图以便链式调用;兼容模块 gis 的同名方法返回 Operation<void>,须等待确认。

共同门面的 await map.sqs.getAttributions() 返回完整来源 text/items,超限明确失败;来源/实例/图层身份与平台范围见官网中英文“地图来源与署名”。署名变化使用下述事件订阅。

共同地图署名变化使用 map.on("sqs.attributionschange", event => ...) 的 event.attributions;先监听再查询初始化,通知在宿主泵/帧采样合并。超限error带context=attributions,恢复后重新通知;停止/销毁释放订阅。完整中英文指南及HTML/CSS示例见官网地图来源与署名页面。

共同默认导航使用 await map.dragPan.disable()、await map.scrollZoom.enable()、await map.doubleClickZoom.isEnabled()。三个开关不关闭用户指针监听或主动相机命令;查询/写入需await,选项和额外参数明确拒绝。键盘与双指手势已接通共同控制,详见键盘和触摸指南;框选/右键拖动旋转等剩余交互另列待办。

共同开关变化通过 map.on("sqs.gestureschange", event => ...) 发布,event.gestures 是事件发生时的完整开关与旋转选项不可修改快照。先订阅再查询初始化;只在有效状态变化时发送,不重放初始状态,失败和重复设置不发送。队列超限拒绝尚未提交的修改,停止/销毁释放订阅。它不表示手势正在进行;实际活动查询见下述说明。完整脚本及HTML/CSS示例见官网中英文手势指南。

共同 await map.dragPan.isActive() / scrollZoom.isActive() / doubleClickZoom.isActive() 读取宿主真实识别的输入活动,区别于已启用开关及相机动画。达到阈值后的按住拖动活动;释放、取消/丢失捕获、禁用后结束,重新启用不复活旧拖动。网页/桌面当前滚轮、双击为瞬时处理,结束后为false,不制造延时/惯性活动。C壳通过 sqsm_map_gesture_input_json 自行报告开始/结束,查询使用原 sqsm_map_gesture_json;它不会主动操作相机或产生政策变化事件。见官网中英文手势指南和同一活动状态脚本。

键盘默认导航

await map.keyboard.enable()/disable()/isEnabled()/isActive() 与独立keyboard政策同步;相机动画不是物理按键。点击二维地图取得焦点后方向键平移100逻辑像素,加号/等号/减号缩放一级,Shift缩放两级;编辑输入、Ctrl/Alt/Meta组合键及输入法不被地图接管。当前为瞬时操作,处理结束isActive为false。Shift左右方向旋转已接通,keyboardRotation独立开关控制;Shift上下倾角仍未接通。细节和完整HTML见指南。

共同 RGBA 图像(10.1b)

从 sqsmap 导入 map,使用 addImage/updateImage/removeImage/getImage/hasImage/listImages;样式 sprite 和运行时图像使用同组语义。查询 await,链式写入用 map.sqs.flush 确认。getImage 返回独立 Uint8Array 像素副本,updateImage 保持尺寸和 pixelRatio/sdf。map.sqs.getImageInfo 返回图像身份与字符串修订;持续会话用 sqs.imageschange 监听成功写入。用完取消监听,停止与销毁也会清理。完整网页按钮、署名、事件与 HTML/CSS 见网站中英文“图像资源”。可伸缩图片及字体仍待后续实施,未实现选项明确报错。

按需补全样式图像(10.2a)

使用 map.on("styleimagemissing", listener),在设置样式前订阅;持续脚本声明 export const sessionMode="persistent"。事件含 type、id、target 和不透明字符串 styleGeneration。同一可见缺失标识去重,补全后再移除、离开可见需求或更换样式代可以再次通知。停止、取消订阅和销毁释放监听;不会重放订阅前的通知。

检测使用当前平面视图中实际解码、可见且通过过滤的矢量要素,支持图标和已支持的固定/缩放级别填充图案,不要求 sprite URL。事件回调调用 addImage 并确认后,在下一帧绘制;这是跨线程共同通知语义,不提供当前帧同步解析器。排队事件保留历史代,异步资源完成前应重新核对地图当前需求,避免向新样式补入旧代图像。

网页 SDK 使用 view.on("styleimagemissing", listener),能力为 imageMissingEvents;C 轮询事件使用 SQSM_MAP_MISSING_IMAGES=2097152,通知的 imageEvent 含 id/styleGeneration。事件容量不足不会消费需求;释放容量后重试。当前缺失集合最多128项;超限明确 RESOURCE_LIMIT。地球仪/3D需求、伸缩/动态图像和完整字体仍在实施。

共同持续脚本 / 完整 HTML/CSS 和操作事件 / 使用指南。移动应用脚本接入、Windows/macOS、硬件和正式发行仍分别验收。

下载外部图片(10.2b)

await map.loadImage(url) 下载并解码 PNG、JPEG 或 WebP,返回 {data:{width,height,data:Uint8Array}}。可以直接将 result.data 传给 map.addImage。加载不会自动注册图片、改变样式或提交地图写入;返回的像素由调用方拥有,修改它不会改变已注册图片。名称和 {data} 使用 MapLibre 风格;这里统一返回 RGBA8 像素,避免三端依赖 DOM 图片对象。

interface MapImageLoadResult {
  readonly data: {readonly width:number; readonly height:number; readonly data:Uint8Array}
}
map.loadImage(url:string):Promise<MapImageLoadResult>

地址须为不含用户名密码的绝对 HTTP(S) URL,最多4096个 UTF-8 字节;浏览器需要图片服务允许跨域。根据实际文件字节识别格式;不支持 SVG/GIF,不隐式转换 EXIF 方向、色彩空间或动画帧。RGBA8 保留直通透明度,不预乘。

每张压缩图片最多4 MiB、边长最多512像素、解码像素最多1 MiB;最多8个并行加载。浏览器和动态库按地图限制,桌面后台下载还有进程级8任务限制。动态库完成但尚未领取的结果仍占名额;调用方领取后保存的像素不计入在途名额。解码器内部另有16 MiB分配限制。

错误包括 INVALID_ARGUMENT(URL)、IO_ERROR(HTTP/空响应/损坏文件)、CAPABILITY_UNAVAILABLE(格式)、RESOURCE_LIMIT(预算)和 CANCELLED(取消)。脚本停止和地图销毁会取消它们拥有的下载;迟到结果不能复活请求。独立网页 SDK 还提供 view.loadImage(url,{signal}),并经 transformRequest(url,ResourceType.Image);函数型请求钩子只能用于主线程宿主。普通跨端脚本只使用一个 URL 参数,不传 DOM AbortSignal。

// @gis-api 0.5-session
// @permissions ["project.read", "map.write"]
import {map} from "sqsmap";
const result=await map.loadImage("https://map.sqsh.com/sdk/sqsmap-core/load-image-fixtures/icon.png");
map.addImage("marker",result.data);
await map.sqs.flush();
export default {width:result.data.width,height:result.data.height};

以上公开 URL 需要部署配套附件后才能使用;本机验收使用本地服务。同一份四入口验收脚本使用明确标记的本地测试 URL;完整 HTML/CSS、下载/取消/移除/销毁及署名事件使用同目录附件,可复制整个 SDK 分发目录后运行。

动态库不内置 HTTP 客户端。sqsm_map_image_json 的 loadImage([url]) 返回 requestId;宿主轮询 sqsm_map_resource_requests_json,对 resourceType=Image 下载并调用现有 resource_response;传输失败以 error/errorCode 回传。loadImageResult([requestId]) 返回 pending 或独立 data,成功分配输出后才释放结果。失败输出不消费请求;错误结果需调用 cancelLoadImage([requestId]) 释放。能力位 SQSM_MAP_LOAD_IMAGE=4194304,ABI1及导出数保持不变。原生持续脚本会话等待该资源队列;原生一次性同步运行入口对外部图片加载明确报 CAPABILITY_UNAVAILABLE。桌面 ScriptService 自有后台传输,普通一次性脚本可以 await。

桌面、浏览器主线程/Worker 和 Linux 动态库持续 QuickJS 已接通。移动应用脚本接入、Windows/macOS实测、硬件后端及正式发行仍独立验收;动态图像、伸缩图像和完整字体继续实施。

已交付但尚未完成的下载取消后,动态库会输出 cancel:true 的 Image 描述符。宿主应按生成代中止其拥有的网络请求;取消通知在成功交付前继续占用一个名额,避免通知积压无界。

共同字形服务与标注字体

已解析样式提供 await map.getGlyphs() 与链式 map.setGlyphs(url|null|undefined);使用 await map.sqs.flush() 确认写入。切换保留图源、已加载瓦片和运行时图片,取消旧资源代数并重建文字图集。发行 WASM 与默认原生构建使用同一内置中文/拉丁字体回退;标注语言由样式 text-field 决定,不跟随控件 setLocale。字体文件注册和复杂文字塑形仍待实现。完整边界、中英文指南和可复制 HTML 见官网 /manual/glyph-services、/en/manual/glyph-services。

共同点聚合

匹配的网页、桌面和动态库脚本使用 addSource 的 cluster/clusterRadius/clusterMaxZoom/clusterMinPoints/clusterProperties,以及图源句柄 getClusterOptions/setClusterOptions/getClusterChildren/getClusterLeaves/getClusterExpansionZoom。查询和配置更新返回 Promise。生成点的 feature.id 为 sqs:cluster:<cluster_id>,成员查询传 properties.cluster_id;数据或配置重建后旧聚合 ID 失效。完整选项、预算、示例与差异见 共同地图参考 和官网中英文“点聚合”指南。

数字聚合支持 +、-、*、/、min、max 及 reduce/map 表达式,accumulated 仅用于归约,get 读取子节点统计。逐层合并、预算和失败保留原地图的共同约定见共同地图参考及官网中英文点聚合指南。容器统计仍未接通。

布尔和字符串统计现已接入共同聚合:all/any/concat 或自定义标量归约,字符串4096字节、映射/每工作层各8MiB。null/容器统计仍不支持;完整规则与数字文本转换见官网中英文点聚合指南。

共同实时源:addSource 的 sqsLive 扩展配置字段与 allowDelta;source.sqs.applyLiveUpdate 写入 gis-live-v1 批次,getLiveState 查询状态,freezeLiveSnapshot 返回独立副本。图源、协议和显示原子提交;普通 setData/updateData 对实时源返回 CONFLICT。完整中英文说明见官网实时图源批次页。网络接收器尚未接通。

HTTP实时图源接收器使用 source.sqs.connectLive/getLiveReceiver 和 receiver.getState/pause/resume/stop;地图/源持有,不随脚本退出自动停止。共同字段、事件、预算和完整代码见官网中英文 live-http。WebSocket、场景所有权、移动宿主仍待后续阶段。

共同地图图源的 source.sqs.connectLive 已支持 websocket 传输与 reconnectDelayMs(500..60000,默认2000);每连接第一帧须完整 snapshot,队列/取消/能力差异见网站中英文 WebSocket 实时接收器文档。HTTP 接口保持一致,WebSocket 不接受 intervalMs。scene 归属及移动实际宿主仍按任务表验证。

共同场景与接收器归属

用 map.sqs.scenes.create({id,name?}) 创建草稿;get(id) 返回当前句柄或 undefined,list() 返回不可变小快照。句柄包含 id/sceneInstanceId 与需要 await 的 getState/start/pause/resume/stop;remove(scene) 停止归属接收器、释放场景身份并保留图源数据。connectLive 选项可带 owner:scene(桥接提取身份),同名重建或跨地图身份会 STALE_HANDLE。

草稿不启动联网。场景 pause 与接收器主动 pause 分开保存,场景 resume 不复活主动暂停/停止的接收器;owner 未运行时 receiver.resume 为 CONFLICT。stop 是终态。地图持有场景和连接,脚本退出不会隐式停止。监听 sqs.scenechange(reason、不可变 scene 历史快照)和图源事件中的 owner/ownerState;控制完成不代表数据就绪。

await map.sqs.getCapabilities() 读取已实现能力:sceneLifecycle/sceneReceiverOwnership 为 true;sceneStaticResources/scenePlayback/sceneRoutePlayback 为 true;sceneLinePlayback/sceneTracks 仍 false。最多16场景、每图8活动/暂停接收器,草稿也计接收器配额;列表、事件和控制有界,控制失败不改变任何归属接收器。旧桌面 map.scenes 保留兼容范围。完整说明见共同场景。

15.2共同静态场景:scene.attachSource(source) / detachSource(source)均需await。草稿/停止隐藏、暂停保留画面、remove释放归属并恢复原layout;同源共同图层、渲染查询和署名使用相同有效显隐。getState.sources为冻结源身份列表,源和接收器分别计数。官网提供中英文static-scenes指南与完整HTML/C示例;playback/轨迹仍未接通。

共同轨迹播放、控制、完成等待与动态库差异见轨迹播放。公开类型包含 Playback、RoutePlaybackOptions、RoutePlaybackSnapshot 和 PlaybackChangeEvent;三个脚本宿主与网页 SDK 使用同一语义。

共同二维线动画:map.sqs.animations.line(options,{owner:scene});静态 GeoJSON 图源需 lineMetrics:true。控制器由地图持有,六效果及颜色/透明度/宽度曲线已接通;球面/三维线不支持。双语完整示例与生命周期说明见官网“共同线动画与样式曲线”。

共同球面相机(14.1)

map.setProjection({type:"globe"}) 与 jumpTo、中心/缩放/方向/倾角查询及地表投影使用同一球面模型;写入后用 await map.sqs.flush() 确认。持续会话增加 pitchstart、pitch、pitchend 历史事件。球面动画、范围拟合、roll 和共同 GeoJSON 圆点/线/面已接通;持久留白已接通,见球面持久留白。完整脚本、单位、模式切换及平台差异见中文地球仪指南和English Globe API。独立原生一次性入口支持相机操作;事件监听使用持续入口。

共同 CSS 颜色输入:样式常量、颜色表达式输入与共同光照使用同一自研解析器,支持148个标准名称、hex及逗号/空格形式RGB/HSL、百分比透明度和色相单位;光照仍要求不透明。具体范围、裁剪和未接通写法见官网中英文“颜色输入”。cssNamedColors/cssModernRgbHsl能力已开放;原生状态/持久事件lightingState子状态为深度冻结快照。

共同地球仪动画

map.setProjection({type: "globe"}) 后,easeTo/flyTo 和缩放、旋转、回正导航使用共享球面相机时间线;支持 around/offset。监听 moveend 判断完成,map.sqs.flush() 只确认命令应用。中英文官网指南为 /docs/manual/globe-motion 和 /en/docs/manual/globe-motion;移动宿主仍待接通,球面范围拟合与持久留白已接通。

标准矢量瓦片样式源

map.setStyle(url, {diff:false}) 所加载的样式可使用vector内联tiles、TMS、bounds与级别覆盖。与共同GeoJSON源登记区分,源详情见官网中英文tiled-vector-sources指南。共同脚本能力和署名查询使用map.sqs.getCapabilities()与map.sqs.getAttributions();原始SDK署名使用view.getAttributions()。

标准样式raster源已接通平面加载、透明度、颜色与绘制顺序;完整raster、球面/倾斜/渐变及共同影像源生命周期仍继续实施。官网中英文说明见 /docs/manual/raster-style-sources 与 /en/docs/manual/raster-style-sources。

共同 CameraPose.pitch 已改为 number。匹配开发动态库与网页主线程/Worker 支持 mercator 非零倾角 0–65;桌面调试板同形倾斜门面仍须后续接通,不能把可编译声明视为所有宿主均已支持。平台能力以 sqs.getCapabilities 与中英文官网倾斜指南为准。

球面共同圆点图层

共同MapLibre风格圆点已接通球面绘制与直接屏幕查询;先检查globeGeoJsonCircleLayers/globeGeoJsonCircleQueries能力。setProjection保留圆点身份,addLayer/setPaintProperty/filter/visibility与平面同名;project与queryRenderedFeatures使用逻辑像素和原始经纬度,包括极点和世界副本。flush({render:true})等待实际当前球面帧,不把旧平面帧或已应用命令当作完成;无用户样式时的背景独立于用户图源/图层/署名。球面线/面屏幕查询、完整三维遮挡、地形/点云和图层作用域输入事件仍须继续接通,不由圆点验收推断完成。完整例子及平台范围见官网中英文球面圆点指南。

球面共同 circle 的指针事件也使用 map.on/off/once:event.cameraState 为球面历史相机;event.lngLat 在天空为 null,地表为 {lng,lat},读取前必须判空。未命中图层不等于天空。球面共同line/fill查询亦已实现;完整3D遮挡查询仍未接通,详见宿主指针输入。

球面图层使用 map.addSource/addLayer/moveLayer/setPaintProperty/setFilter/queryRenderedFeatures 等共同语法,circle/line/fill采用原始经纬度和统一命中;当前范围、完整脚本和HTML见球面线与面。

共同图层悬停:map.on("mouseenter", "trees", callback) / map.on("mouseleave", "trees", callback) 由mouse/pen命中转换触发;touch不生成悬停,leave的features为空。取消、once、停止与销毁清理状态。详情和低层边界输入限制见官网中英文hover-events指南。

生命周期读取:await map.sqs.lifecycleState() 与 await map.loaded() 不绘制或采样动画。修改前注册render/idle,实际帧用await map.sqs.flush({render:true})确认。桌面当前通知限显式读回屏障,普通呈现与完整初始化/销毁生命周期仍在接入;中英文map-lifecycle指南同步说明。

首次完整绘制与load状态见官网地图实际帧与空闲;晚附着不重放load,先监听再读取firstLoadCompleted。

共同配准媒体使用 sqsmap 的 map.addSource(id, {type: "image" 或 "video", coordinates}) 与 raster 图层,以及媒体句柄 setCoordinates/play/pause;帧由宿主解码后提交。参数、预算、状态、实际显示和当前待实现范围见配准媒体指南。图像/视频URL与球面已接通,地形与自定义渲染扩展仍待实现,不代表完整MapLibre媒体兼容。

配准图像源已接通HTTP(S) url与句柄updateImage;确认表示登记请求,sourcedata/isSourceLoaded表示下载解码就绪。显式帧提交取消旧图像下载,更新失败保留旧配准和像素;视频URL已在16.4接通。

共同配准媒体已接通球面显示,使用setProjection({type:"globe"})且保留媒体句柄、帧和图层语义;mediaRasterGlobe=true;地形媒体及Canvas已接通,分别见terrain-quad和共同Canvas指南。详见共同媒体指南16.3。

在线视频使用共同type:video和urls地址数组,共享纯Rust普通MP4/H.264解码器、地图持有时钟、play/pause及循环;状态duration/currentTime单位秒。1..8地址依次回退,首帧成功后才通知sourcedata/isSourceLoaded。完整格式、内存预算、跨端边界和网页例子见共同媒体指南16.4;不能以注册确认替代加载完成。

Canvas 命名画面

共同脚本支持 map.addSource(id,{type:"canvas",canvas:"drawing",coordinates,animate:false})、配套 raster 图层及 play/pause/setCoordinates。宿主通过 source.sqs.submitFrame 提供 RGBA 字节数组,首帧成功才就绪;source.sqs.fail 报告供给错误。DOM画布自动捕获/getCanvas只属于浏览器SDK,不进入跨端脚本。详见官网中英文媒体接口与完整Canvas示例。

共同瓦片元数据源

vector/raster支持登记、TileJSON及setTiles/setUrl;sqs.getTileMetadata读取有效元数据。共同瓦片绘制图层、DEM和瓦片要素查询仍待实施;addLayer引用此源明确拒绝。详情见官网共同瓦片图源元数据。

点图片symbol支持默认false的icon-allow-overlap/icon-ignore-placement及默认2的icon-padding,symbol-sort-key和symbol-z-order已接通,图片先addImage登记;icon-image支持属性表达式,尺寸/旋转/九个锚点为常量,icon-opacity支持共同paint表达式。图片更新/删除同步刷新显示与查询。SDF图片已接通icon-color染色,共同点符号也发出styleimagemissing供监听器addImage补图;普通点文字、共同点符号碰撞及基础文字排版已接通;跨URL底图标注域统一碰撞、图文混排/沿线/复杂整形和三维符号仍未接通。完整中英文示例见官网图层API。

共同symbol已接通内置HarmonyOS Sans SC点文字:text-field/size/font/anchor/offset/rotate及text-color/opacity和共同碰撞/查询。实际使用内置字体回退,外部PBF字形请求与同层图文已接通;沿线/三维组合仍待接通,详见官网中英文点文字说明。

共同高程瓦片支持mapbox/terrarium/custom PNG;hillshade默认standard/viewport可用,支持五种单光源算法与map/viewport锚点,详细范围见网站高程手册与生成共同图层指南。

共同color-relief接通elevation线性/阶梯颜色带和opacity;共同样式颜色复用命名/RGB/HSL解析器,具体范围见网站高程设色手册。

共同map.addSource高程源的setTerrain/getTerrain/queryTerrainElevation已接通真实墨卡托表面,查询返回显示夸张后的number/null;桌面本地DEM的TerrainState/TerrainElevation扩展保留,详见网站地形手册。

共同DEM地形开启时,map.project/map.unproject使用实际显示网格三角面;缺少已加载表面明确拒绝,不退回零高程平面。关闭后恢复原相机坐标,详见官网地形坐标手册。

已支持的普通数值/颜色paint表达式增加interpolate/cubic-bezier,数值支持超调、颜色通道钳制;精确停止点保持原值,非法控制点拒绝并保留旧样式。详细范围和完整示例见官网三次贝塞尔样式插值手册。

共同样式增加标准标量数学函数、常量、一元负号、幂/余数和负数舍入;定义域/非有限值沿用明确错误或绘制默认值/告警规则。完整操作与跨端示例见官网标量数学手册。

共同地形已接通raster瓦片及hillshade/color-relief贴地、按层次绘制与一次透明混合;有效凸四角媒体也已贴地,跨日期线/非凸区域仍限制。网页reset先解除地形/层源/倾角再切投影。完整范围和来源呈现见官网地形影像手册。

共同地形增加image/video/canvas有效凸四角贴地,沿用Mercator双线性映射、层次、透明度和供帧生命周期;旋转/梯形在实际地形片元反求UV。范围与完整四按钮见官网配准媒体地形手册。

双指触摸控制

共同touchZoomRotate/touchPitch有enable/disable/isEnabled/isActive,touchZoomRotate另有enableRotation/disableRotation,均需await。网页主线程/Worker与Android开发宿主接通默认双指缩放/旋转/倾斜、逻辑DPR坐标、取消和点击;原生C壳仍自行提供物理输入。类型/契约/网页WASM同步,支持范围及完整代码见触摸导航。地区速率/阈值选项、一指双击拖动/惯性、桌面触屏/手机硬件、移动GIS/iOS仍待验收/实施。

球面范围定位

map.cameraForBounds(bounds, options) 与 map.fitBounds(bounds, options) 已共享球面计算。范围接受两个 WGS84 点或 [west,south,east,north],支持日期变更线、当前倾角、方向、缩放限制以及只约束目标的留白/偏移。fitBounds 使用共同相机动画。经度跨度达到180度或范围无法容纳时明确失败并保持旧相机。持久球面 padding 已接通;球面 roll 已接通,见官网 globe-roll 指南。详见官网中英文 globe-bounds 文档。

共同地形建筑

标准 fill-extrusion 可与共同 setTerrain 组合;Polygon在已显示地形三角面上按外框中心高度刚性抬升,缺少地面数据时不显示。楼高/base保留真实米制,夸张只影响地形。显示与屏幕查询使用同一网格/地面高程。坡面地基适配、球面及完整遮挡过滤仍待实现。详见官网中英文 terrain-buildings 指南。

共同点图文联合

同一symbol图层可同时指定icon-image/text-field。图文共同避让外部碰撞、避免自身碰撞,各自透明度/旋转/锚点独立;查询同一要素一次。空文字/缺图片/透明组件不参与,剩余组件可独立显示。icon-optional=true允许图标被挡时保留可放置文字,text-optional=true反向保留图片;默认false。格式化混排及沿线仍待实现。详见官网中英文joint-symbols。

共同影像材料

共同raster图层已支持brightness-min/max、saturation、contrast、hue-rotate及linear/nearest;影像瓦片和image/video/canvas使用同一材料。平面、倾斜、球面和地形保留一致参数、身份及源修订。数字支持既有zoom表达式;要素字段/状态不可用于影像材料。详见官网中英文raster-material。

共同外部字形

setGlyphs服务已用于共同symbol点文字,text-font完整字体栈及真实字形尺寸共用PBF请求、解码和图集;空地图可设置服务。实际请求及字形到达刷新绘制/查询,服务更换隔离旧响应,未就绪/缺字继续声明的内置回退。复杂整形/沿线尚未完成。详见官网中英文external-glyphs。

球面比例尺

map.sqs.scaleAt现支持globe,返回相同字段的真实球面局部距离,projection声明包含globe。逻辑像素/DPR/1-2-5刻度一致,两极可用,天空/切线无法取地面时明确失败。详见官网中英文globe-scale。

共同类型转换候选

to-number/to-color支持按顺序候选回退与成功短路;数字支持null/布尔值、空字符串、十进制/指数及无符号进制前缀;颜色支持CSS与RGB(A)数值数组。非有限数字不进入样式,颜色仍为CSS字符串。参见官网中英文type-conversions。

共同圆点描边

circle-stroke-opacity默认1,独立于填充透明度;平面/倾斜/球面统一向外描边。查询包括可见描边外半径,全部透明不命中,空心内部按要素包络仍可命中。参见官网中英文circle-stroke。

共同单词换行

text-max-width按真实字形尺寸优先整词换行,超宽词/CJK回退字形断行,0关闭自动换行并保留显式换行。URL样式/共同symbol复用同规则;完整Unicode断行、复杂整形/双向仍待实施。详见官网text-labels。

球面可见范围

getBounds在球面也返回连续日期线/极点可见地面保守包络,纯读无事件。纬向0.25度余量与随纬度放大的经向余量,不代替精确裁剪。参见官网中英文globe-viewport。

动态线宽与虚线

line-width数字表达式可与1~16项line-dasharray常量或共同表达式组合,段长/间隔按实际线宽缩放;各项动态倍率×24≤100px预检,总周期须为正。属性、要素/全局状态、词法变量和分支更新保留身份,dash zoom按整数;奇数数组首尾实段在周期边界相连。commonLineDashArrays报告共同平面子集,查询仍按整条线包络;完整三维/球面虚线与虚线端帽/连接待后续;二维实线显式拓扑见官网line-topology。见官网dynamic-dash及完整portable-multi-dash.js。

空间within表达式

within边界支持Polygon/MultiPolygon/Feature/FeatureCollection,在共同filter/源查询/渲染查询/paint使用真实WGS84点/线几何,边界与孔洞不算内部。线要求全段属于同一个面;日期线窄范围支持,完整组合及distance继续待办。详见官网中英文spatial-within。

共同distance表达式

distance返回米,点/线采用6371008.8米球短弧/大圆最小,面内部与孔洞沿用within平面拓扑,非完整椭球测量。支持GeoJSON多类目标和混合集合,预算/对跖歧义明确拒绝。参见官网中英文spatial-distance。

共同全局状态使用map.setGlobalStateProperty(name,value)与异步map.getGlobalState();global-state表达式及内联state默认值见官网全局状态指南。null恢复默认值或删除,替换样式重置状态;聚合与legacy CPU绘制不支持。

共同表达式semiliteral对数组元素逐项求值,支持属性/变量/状态穿透;literal保留数组不求值。规则及可复制示例见官网数组表达式指南。

map.sqs.viewModeState()区分2d/3d、投影、倾角和地形;按钮使用现有setPitch/easeTo和相机事件,显式45/0目标、flush确认。完整规则见官网自定义2D/3D切换。

共同symbol的icon-size/icon-rotate支持数值表达式,大小/旋转/碰撞与命中共用结果;layout不允许feature-state,动态零大小不显示。见官网图标布局表达式。

text-offset支持x,y常量或返回两个数值的数组表达式,em单位±256,绘制/碰撞/查询同步。见官网文字偏移指南。

13.6b:共同map.sqs.resources.plan支持合法层次化自定义协议;vector/raster/raster-dem瓦片模板与setTiles同样支持。原生QuickJS没有addProtocol回调注册,C宿主交付编码字节;网页Worker须自行注册处理器。详见中英文协议规划。

13.6c:GeoJSON data URL、TileJSON url、配准image/video及对应更新接受已验证自定义URI,宿主提供字节并继续使用原代次/解码/加载事件;Style/glyph/loadImage入口、原生JS回调另行实施。详见图源协议。

独立loadImage现在支持宿主提供的自定义层次URI;核心能力不代表桌面内置HTTP下载器已经注册自定义处理器。见图片协议入口。

共同setStyle接受合法自定义层次URI;处理器、相对资源和宿主条件见自定义样式协议。

共同setGlyphs可使用宿主提供的自定义层次模板;字形到达与重绘仍异步。见字形协议。

使用同步map.listens(type)查询本门面的普通/once/图层委托监听;门面之间独立,见事件监听查询。

共同join已修复嵌套数组/对象转换,保留split和预算;见join值转换。

球面 roll

setRoll/getRoll、jumpTo/easeTo/flyTo 已共享真实球面光轴旋转;持续事件增加 rollstart/roll/rollend。详见球面 roll。

桌面与网页共同脚本的自定义协议

从 sqsmap 具名导入 addProtocol / removeProtocol,登记后再加载对应协议的资源,结果仅支持 {data: ArrayBuffer | Uint8Array}。回调接收只读的 url / resourceType / maxBytes / method 和取消信号;响应按真实请求预算限制,最多8MiB,并复制精确子视图。桌面资源下载器与网页主线程/渲染Worker已接通;移动GIS应用仍未接通。详情和可复制示例见官网中英文“脚本自定义协议”手册。

桌面脚本声明 export const sessionMode='persistent' 可让处理器持续服务;一次性脚本结束会释放自己的登记。注册不会覆盖其它脚本拥有的协议;替换、注销和停止只取消受影响的请求,已加载地图数据保留。

format分段文字

共同点标签的 text-field 支持 ['format', text, {'font-scale': scale, 'text-color': color}, ...],段选项可省略;case、coalesce 可返回格式值。各段保留真实字号与颜色,共用换行、整体锚点、碰撞与查询。段颜色覆盖根颜色并乘根text-opacity;能力commonFormattedText表示此文本子集。top/center/bottom逐行垂直对齐已接通。段内text-font通过返回字体名称数组的共同表达式选择现有PBF字体栈,省略时继承根字体;没有字形服务/缺字时使用内置回退。已注册RGBA图片段通过image表达式进入真实混排;图片段缺失返回null,可coalesce回退,实际缺失名称走styleimagemissing。其它未实现格式类型仍明确报错。中英文官网“分段富文本标注”提供范围与可复制示例。

富文本还可经 let / var / match 返回,各段不会丢失字号和颜色;普通变量与格式变量共用原词法捕获和惰性求值,必须嵌套let引用此前绑定。coalesce 按真实null回退,空格式值不回退。作用域、控制流和段参数共用8192步预算;格式变量进入普通字号/字符串运算会明确拒绝。

format段内PBF字体栈

段选项支持 text-font: ['literal', ['Fixture Font', 'Fallback']] 或返回数组的get/let/var表达式;1至8个非空名称,每名称不超过256字节。需求、图集、advance和实际bitmap使用完整栈键,不仅保存配置。能力commonFormattedTextFonts;可复制脚本及完整HTML见中英文formatted-font指南。RGBA图片段已接通,SDF图片段/字体文件加载/复杂整形/沿线/三维组合仍未完成。

format中的RGBA图片

['format', 'A', {'text-color': 'red'}, ['image', 'marker']] 在文字中显示已注册的RGBA图片。图片显示尺寸为width/height除以pixelRatio,不受text-size、font-scale、text-color或text-font影响,只乘根text-opacity;vertical-align仍按行对齐。image可经过let/var和分支/coalesce保留真实图片类型,缺失返回null并允许回退。纯图片标签同样有绘制、碰撞和查询;顶级text-field直接返回image不属于当前文字/格式返回类型,明确拒绝。

共同注册/更新/移除在候选阶段检查标签;被实际引用的SDF图片段明确失败且不改变图集/旧画面,未引用的SDF仍可用于普通icon。能力commonFormattedTextImages;双语formatted-image提供完整脚本和HTML。

icon-image的可用性回退

共同symbol的icon-image支持['coalesce', ['image', 'primary'], ['image', 'fallback']]及let/var/分支。image同步检查当前图片表,缺失返回null;只记录实际尝试的缺失名称,primary可用时不误报fallback。旧字符串/空串行为、所有既有图标参数和普通RGBA/SDF保持。图片/源/图层候选使用同一原生与WASM预检,失败保留原状态。能力commonIconImageExpressions;中英文icon-image指南提供完整脚本/HTML。fill-pattern使用独立图案能力,见后面的共同二维填充图案;更多image扩展仍待实现。

共同二维填充图案

fill-pattern 已支持统一及逐要素的 RGBA / SDF 图案:字符串或 image / coalesce / let / var / 分支表达式,名称可由整数缩放级别和 global-state 选择。统一选择用 commonFillPatternsUniform,属性/get 与 feature-state 的逐要素选择用 commonFillPatternsPerFeature 判断。同层不同面可选不同图片,缺图只隐藏对应要素;未设置状态时使用 image(coalesce(feature-state,get)) 的名称回退,image(null)仍非法。RGBA图案颜色不受 fill-color 影响,纹理透明度乘 fill-opacity;周期按图片尺寸除以 pixelRatio 计算,并随地图世界位置和旋转保持相位。缺失图案不绘制、不命中查询,并通过 styleimagemissing 通知实际缺失名称。将属性设为 null 恢复纯色及轮廓。

当前每边限定为 2 至 512 的二次幂,这是项目边界;不支持图案过渡、线图案和三维/球面材质。查询保留面洞,不做纹理透明像素拾取。官网中英文“填充图案”指南提供完整共同脚本和运行附件。

共同数字格式

number-format返回普通字符串,支持locale/currency/unit/min-fraction-digits/max-fraction-digits及选项表达式。共同范围为五语言en-US/zh-CN/de-DE/fr-FR/ja-JP,默认固定en-US;其他语言或扩展明确不可用。货币代码三ASCII字母,单位45单项及-per-组合,小数位0..100,currency/unit互斥。固定CLDR48.2数据和同一Rust算法处理符号、间隔、精度、负零、舍入、分组和复数,许可/来源随SDK提供。网站中英文数字格式指南提供共同脚本及实际标签示例;不代表完整Intl/其它语言、复杂整形、设备和正式发行已完成。

共同语言感知比较

collator是内部typed搜索排序器,支持locale/case-sensitive/diacritic-sensitive、六比较第三参数、typeof和resolved-locale。共同范围为五语言en-US/zh-CN/de-DE/fr-FR/ja-JP,缺省en-US;使用真实Unicode搜索数据,公开语言解析分别en-US/zh-CN/de/fr/ja。词法变量、分支、动态选项、预算与候选失败原子性共享,普通JSON不能冒充或输出为字符串。动态非字符串相等/不等保留普通比较;原两参数行为不变。网站中英文语言感知比较指南含共同脚本与许可来源,未实现其他语言和完整样式/设备仍在清单中。

自定义事件和父事件链

从sqsmap导入Evented,使用map.fire/setEventedParent和普通/单次/解绑事件组织自编UI;父链支持Map和Evented,listens上行查询。事件留在本地VM,不发RPC也不修改地图。停止、remove终结与Evented.destroy释放监听和等待,循环及预算超限先拒绝再改动。详见官网evented和完整portable-evented.js;设备和正式发行另行验收。

SDF填充图案能力为commonFillPatternsSdf。addImage的sdf:true使用图片alpha距离,.5为边界,较大值为前景;fill-color作为前景色,前景alpha乘fill-opacity。按属性/feature-state动态着色严格预检,失败保留旧状态;透明前景和零opacity不进入几何查询,仍不逐纹理透明像素拾取。原RGBA、洞/顺序/世界相位保持。官网填充图案指南提供24条共同脚本及完整网页,MapLibre规范参考不等于其运行库像素兼容。

共同二维实线拓扑能力commonLineTopologySolid:显式line-cap(butt/square/round)、line-join(miter/bevel/round)、line-miter-limit和line-round-limit启用实际端帽与连接;四项已支持布局表达式(见下文),限值有限0..16为项目预算。完全未指定保留旧快线,不宣称旧dash/animation已具标准连接。新拓扑不支持dash/gradient/animation/3D/globe/media组合,明确拒绝;保守query不等于精确像素拾取。官网中英文实线端帽与连接指南提供23条共同脚本和完整HTML。

四项线拓扑布局表达式能力commonLineTopologyLayoutExpressions已接通逐要素属性/global-state/整数zoom和既有类型/词法/惰性系统;layout拒绝feature-state,zoom须顶层step或数值interpolate(可let包裹)。候选每表达式1024节点/8192求值步、累计200万节点估算,feed/query使用同一要素选项。既有几何与组合边界保留;实际读取的非法枚举/类型/限值整体失败,旧身份/状态保持。官网实线端帽与连接指南提供同层三端帽24条表达式共同脚本和完整网页。

共同面与线的要素绘制排序(08.55)

commonLayerSortKeys 提供共同二维 fill-sort-key / line-sort-key:筛选后对实际显示要素按有限数字键稳定升序绘制,大值覆盖小值,同值和 ±0 保留源序;queryRenderedFeatures 同层按实际顶层优先,原 ID、属性、筛选索引及 MVT 去重保持。键支持属性/global-state/类型/词法/惰性表达式,排序键布局拒绝 feature-state 和 interpolate;zoom 仅允许顶层 step(可 let 包裹),取 floor(zoom),须明确 Web Mercator 平面。每表达式 32 层/1024 节点/8192 步,候选累计 10 万显示要素/200 万节点估算。

纯色、RGBA/SDF 填充、普通线/虚线和显式实线拓扑已支持;显式拓扑加虚线及动画/渐变/3D/球面/媒体组合仍明确拒绝。失败保留旧源、全局值、相机、画面及身份。完整示例、24 项共同脚本和 HTML 见要素绘制排序。设备与正式发行仍待验收。

无地表坐标的平面快照

视口内的合法平面输入也可能没有可用地表:例如换算后的经纬度落在世界范围外,或倾斜 Web Mercator 的指针射线没有有效地表交点。此时 lngLat 返回 null,事件仍成功并继续执行 queryRenderedFeatures;features 不因缺少地表坐标而整体失败。球面天空和 mouseleave 同样可返回 null。读取经纬度前先检查 event.lngLat === null,并按需独立读取 event.features,不要把 null 当作整个事件失败。

共同二维solid line-offset:commonLineOffsetSolid,CSS像素默认0,线正右负左/面正内缩负外扩含洞;数值、属性/state/global/词法惰性/连续zoom,abs128/实际挤出2048预算。实际非零dash/gradient/animation/pitch3D/globe/media组合拒绝,zero保留旧路径与原限制;候选失败保留source/state/global/camera/identities,保守query依据实际挤出,不逐像素。详见网站实线偏移指南与30条共同脚本。

共同二维实线平移

paint的line-translate用CSS向量整体移动实线,默认[0,0];line-translate-anchor为map或viewport。例如map.setPaintProperty('route','line-translate',[0,12])配合viewport锚点向下12像素,map锚点则随地图bearing旋转。两个属性均支持uniform global/连续zoom及词法惰性,不读取feature属性或state;显式对象get/has仍可用于全局对象。原向量每分量最多128 CSSpx,实际组合挤出最多2048;能力查询commonLineTranslateSolid。查询使用反平移后的保守几何,MVT未知邻片覆盖与64块预算在候选提交前统一检查。详见中英文网站实线平移指南。

共同二维实线内槽

line-gap-width默认0,正值产生真正透明的CSS空隙,外部总宽gap+2×line-width,每侧厚度line-width;width0无壳。支持属性/state/global/连续zoom及类型词法惰性。保留排序与原ID,GeometryCollection按原feature统一样本mask,避免叶片重复混色。能力commonLineGapSolid;width24/gap128、两网格合计100万、综合挤出2048、物理目标512MiB和MVT64块预算,失败候选原子保留。query仍是保守命中,透明槽可命中原线,详见中英文内槽指南。

共同二维uniform RGBA line-pattern已接通核心限定范围:每层选图支持global/显式uniform对象/词法惰性/整数zoom,width/opacity支持属性/state/连续zoom;整幅图像高度映射到实际线宽、沿程周期width×imageW/imageH,透明显示下层,line-color不染色,width0不绘制。只接默认butt及稳定miter≤2,非零offset/translate/gap与SDF/显式拓扑/自交/反折/dash/gradient/animation/pitch3D/globe/media拒绝。完整范围与合计资源预算见网站中英文线图案指南,按匹配SDK能力及验收记录使用,不代表全部样式/设备/正式发布完成。

共同二维实线 line-blur 距离软边核心已实现并推送,能力为 commonLineBlurSolid。默认 0 保留旧路径与原预算,有限非负 CSS 值最多 16,线宽仍最多 24;支持属性/state/global、类型、词法惰性及连续 zoom。真实轮廓向内衰减,原要素覆盖并集后一次合成颜色/透明度;butt/square 横切端只裁切,square 延伸侧边继续软化,round 径向软化。保留原 ID/filter/sort 与同层 0/非零软边交错次序,稳定 cap/join/offset/translate 组合已复用真实拓扑。查询保持实际外包络的保守命中。

软边通道的未替换驻留与候选累计最多 256 个可绘制记录,包含混合层 0 软边;每正软边原要素组最多 256 条真实轮廓边。ROI 物理像素 × 软边数累计最多 1 亿,CPU 扫描/拆边/稳定性累计 200 万;实际顶点含 ROI 最多 100 万,综合挤出含 AA 最多 2048 CSS 像素。物理目标与几何/轮廓/uniform 合计最多 512 MiB,全图 MVT 最多 64 块。非邻重叠、自交、不稳定几何及正内槽/line-pattern/dash/gradient/animation/pitch3D/globe/media 组合明确拒绝。源、状态、全局、paint、相机/视口/DPR/投影候选失败保留旧数据、画面、队列和实例身份,未选未来分支保持惰性。核心 5 CPU/1 GPU 及 WASM 定向检查已通过;同一共同脚本 27 项与真实像素已通过 native/main/Worker;匹配开发 SDK 0.3.0-dev.3da09ace 已通过逐文件长度/SHA、Linux/Android/JNI 与 22 份近期共同脚本核对;正式发行、设备和其它组合仍待完成。完整范围见网站中英文距离软边指南。

共同逐要素RGBA线图案

commonLinePatternsPerFeature 扩展同层 line-pattern:按实际过滤/稳定排序后的属性/get/match、typed image/coalesce、类型/词法惰性、global 与整数zoom选择图片,保留原source/ID/属性、真实线宽比例周期及opacity。paint feature-state选图为SqsMap共同扩展,不声称MapLibre规范已声明该组合。单层A/B/A材质仍按A/B/A次序绘制,不跨其它材质重排。缺图或全透明图片只隐藏受影响记录;透明条纹继续保守几何命中,实际尝试的缺图才通知。

每层输入material/有序record各最多4096,W/H/RGBA完全相同材质去重;原静态/动画共32层、4096路径、10万实际生成顶点、256MiB和每路径CSS长度1千万保持。每去重纹理按64KiB页上取整,加48B uniform/256B绑定;共享sampler64B、每有序record64B及所有顶点计入资源预检。候选累计10万显示要素/200万节点估算及原表达式限值保持。非零offset/translate/gap/blur、显式拓扑、SDF/dash/gradient/animation、倾斜/球面/媒体组合仍拒绝;MVT逐decoded path相位0,跨片拼接未实现。

核心3CPU/同一最终实际GPU与WASM检查通过,公共33项和真实蓝/绿/透明像素在native/main/Worker通过。baked缺省global的literal-null numeric coalesce已实质修复,旧合法惰性fallback保持;首次日志保留。匹配开发交付版本见SDK指南;移动GIS/iOS/设备/外机、完整样式与正式发行/部署未完成。详见逐要素线图案。

共同GeoJSON线渐变

commonLineGradients 为非cluster、显式 lineMetrics:true 的GeoJSON LineString/MultiLineString提供共同二维 line-gradient。line-progress 按原Mercator部件距离0..1,闭合首0末1保留色缝,裁剪/相机/DPR/offset/translate不重新归一。支持step/interpolate/LAB/HCL的直接progress输入(合法let别名可展开)、既有曲线及uniform颜色/类型/词法惰性/global;拒绝gradient属性/state/zoom/空间输入与其它progress算术或条件硬切。width/opacity仍支持属性/state/global/连续zoom,三cap/join和稳定offset/translate已接通;line-color及其alpha不染色或隐藏gradient。

每层最多32step切点/33bands,每非零区间257个RGBA8颜色样本,区间内以sRGB重建后decode成linear输出,alpha不转换;step切点选右band,不跨切点采样。量化与曲线/LAB/HCL重建误差明确存在,非线性误差不能统一声称≤1/255或MapLibre像素相同。候选色带累计200万节点估算;原pattern/gradient/animation共32层/4096路径/10万实际顶点/256MiB和每路径CSS长度1千万保持。24B顶点、RGBA32Float颜色与metadata纹理各64KiB上取整、48B uniform/256B绑定与每path draw64B全部计入。每path原节点5000,同原feature全部parts三角pair检查最多200万/候选层。

同原feature真实拓扑及跨part重叠、自交、反折或不稳定几何拒绝;不同feature保留排序叠加。query为真实包络保守命中,局部透明仍可命中,全透明色带/width或opacity0不命中。gap/blur、dash/pattern/animation、MVT/media、3D/globe组合未接;候选source/state/global/paint/camera/viewport/DPR/输出和资源失败保留旧状态/帧/队列/身份。旧原生effects梯度API独立保留。

核心3CPU、同一最终实际GPU和WASM检查通过;同一完整32项及真实平滑/step/原位置裁剪/部件进度/单次alpha像素在native/main/Worker通过,原WGSL局部保留字错误日志保留。匹配开发版本见SDK验收指南,移动GIS/iOS/设备/外机、完整样式与正式发行/部署仍未完成。详见线进度与渐变。

共同圆点静态样式

能力 commonCircleStyles 接通 circle-blur、circle-translate/anchor、circle-sort-key、circle-pitch-scale/alignment,与既有填充和独立外描边一起使用。blur为可表示的有限f32,相对径向向内smoothstep;负值无额外衰减,保留AA,不使用卷积。blur支持属性/feature-state/global/连续zoom;translate与枚举为uniform求值,平移分量最多±128 CSS像素。默认blur0、translate0,0/anchor map、scale map、alignment viewport。

map alignment随地图平面或球面切平面,viewport面向屏幕;map scale随相机距离缩放,viewport保持屏幕尺寸。四组合采用同一真实projective足迹绘制/裁剪/查询,保持近远裁剪、球面背面中心拒绝和业务图层顺序;不写depth。查询保留原source/ID和可见外描边范围,空心内部仍可命中,非逐像素alpha拾取。circle-sort-key按有限数字稳定升序,相同键保留源顺序;仍拒绝layout state/interpolate,顶层step(可let包裹)按floor(zoom),同次支持倾斜Mercator/globe的实际zoom,旧fill/line限制保持。

全部圆点候选最多10万记录/200万新参数节点估算;可见图层filter后的Point/MultiPoint原始点另累计10万,包括视口外/透明/零半径;drawable glyph10万。每glyph CPU84+GPU六顶点240字节,每连续layer range64字节,与未替换驻留及完整候选合计256MiB。source/state/global/paint/layout/camera/viewport/DPR和瓦片覆盖先完整预检,失败保留旧状态/画面/队列/身份。新圆点CSS sRGB颜色恒decode到linear一次合成,alpha不转换;原生SRGB/网页UNORM的RGB存储编码不同,验收保留raw后只规范化RGB,不宣称任意旧底色逐像素相同。完整过渡/地形贴地、移动GIS/iOS/设备与正式发行仍待完成。

共同样式增量更新(SQSAPI-08.66)

共同 sqsmap 模块的 map.setStyle(style, options) 省略 diff 或传 true 时尝试增量更新,传 false 时完整替换,null 清空地图。兼容源保留实例、显式要素状态、缓存及在途请求;兼容 GeoJSON 数据更新沿用 setData 的状态规则。类型或结构选项变化替换源,旧句柄失效;glyphs/sprite 资源根变化回退完整替换。候选验证失败保留现有地图。URL 响应到达时比较实时状态。该默认行为从此前的完整替换改为增量,需保持旧行为的脚本应明确传 {diff:false}。

flush 只确认写入,资源与淡入完成仍查看加载状态。本节对应开发实现,实际交付验收以官网 style-diff 指南及 SDK 清单为准。