要素状态 API
当匹配SDK的commonPlanarLayerComposition为true时,墨卡托零pitch/roll、无terrain/extrusion的共同二维画面允许影像、背景、图文、热力及既有静态线面效果按完整图层顺序组合。本文旧阶段关于“媒体组合拒绝”的限制在此共同二维范围内由该能力取代;自定义线动画、倾斜/球面/地形及其它未实现材料组合仍保持各自限制。重排和兼容diff保留身份/缓存/在途请求/淡入时钟;所有素材、联合几何和纹理预算均先验证再发布。参见二维图层合成。
要素状态与选中/悬停显示
setFeatureState(target, state)、await getFeatureState(target)、removeFeatureState(target, key?) 参考 MapLibre Map 的公开语法,使用 SqsMap 自研共享实现。当前支持共同GeoJSON及MVT circle/line/fill;状态不写入业务属性。用户自行绘制工具 UI,通过点/框查询取得要素,再设置 selected/hover 等自定义状态键。
import { map } from 'sqsmap';
map.addSource('trees', {type:'geojson', data:{
type:'Feature', id:'oak', properties:{name:'Oak'},
geometry:{type:'Point', coordinates:[116.4,39.9]}
}});
map.addLayer({id:'trees',type:'circle',source:'trees',paint:{
'circle-radius':['case',['coalesce',['feature-state','hover'],false],12,6],
'circle-color':['case',['coalesce',['feature-state','selected'],false],'#ff8800','#008800']
}});
await map.sqs.flush();
const pixel = await map.project([116.4,39.9]);
const hits = await map.queryRenderedFeatures(pixel,{layers:['trees']});
if (hits[0]) {
map.setFeatureState(hits[0],{selected:true,hover:true});
await map.sqs.flush();
console.log(await map.getFeatureState(hits[0]));
map.removeFeatureState({source:'trees',id:'oak'},'hover');
await map.sqs.flush();
}
目标为 {source,id,sourceLayer?}。源须存在;GeoJSON 的 sourceLayer 报 CAPABILITY_UNAVAILABLE。数字和字符串 ID 不混同,支持与图源一致的安全有限数字与字符串。允许给尚不存在的 ID 设置状态;有效 ID 可来自原数据、promoteId 或 generateId。相同 ID 的要素及集合子几何共享状态。
设置合并顶层键,null 保留为值。读取独立快照,未设置为 {};修改返回对象不影响地图。removeFeatureState(target,key) 删除单键;只有 source/id 时清空该要素;只有 source 时清空整个源,指定 key 必须含 id。未知业务键可存任意受限 JSON,包括数组/对象。feature-state 缺失返回 null,示例通过 coalesce 设默认值;仅用于 paint,筛选或 layout 不使用状态表达式。动态类型/尺寸无效时采用既有样式回退并记录 warningCount。
状态修订 stateRevision 与 dataRevision 分离,getData 和业务属性不改变。显式稳定 ID/promoteId 状态在同源 setData/updateData 后保留;generateId 的整体数据替换会清空状态,须按新索引重新应用。删除图源清空状态,同名重建不继承。查询 Feature 可直接作目标,但 sqs.sourceInstanceId/dataRevision 若存在会检查,旧实例/数据修订报 CONFLICT;直接 source/id 目标使用当前源。
渲染查询返回 state 快照及 sqs.stateRevision;source/layer/sqs/state 是保留查询字段,原始同名成员仍通过 getData 读取。状态实际影响绘制和查询半径/宽度/求值 paint。只有含状态表达式的样式缓存需要刷新,状态不自动更改既有 GIS 的属性或选择记录。每次成功状态写入沿用有界 sqs.sourceschange 通知;通知代表修改提交,帧呈现另走生命周期接口。
限额:单要素状态最多 16 KiB、256 个顶层键、4096 节点、32 层;目标对象最多 64 KiB、4096 节点、32 层。全图最多 10000 个非空状态目标和保守驻留估算 4 MiB,空状态不占目标。输入、合并结果、缓存/GPU 预备、输出分配或事件预算失败时整次修改拒绝。完整渲染查询结果的 1000 项/8 MiB 限额包含状态和求值图层描述。
SDK、C 的 sqsm_map_source_json、独立一次性/持续 QuickJS 和共同应用/网页脚本使用同名方法。需要匹配开发版 SDK,npm 0.2.0 不自动具备能力。Linux RTX 实际像素、C11 独立示例、应用 QuickJS、SDK 主线程/Worker 与网站宿主路由分别验证;真实浏览器 GPU、移动设备和 Windows/macOS 外机验收单独记录。标准鼠标/按层订阅由事件阶段继续接通,示例不假定它们已经存在。
MVT 子层状态
矢量瓦片目标须为{source,sourceLayer,id}。同ID在不同sourceLayer中互不影响,数字/字符串ID也区分;可以提前设置未下载的ID。状态随同源瓦片刷新和视图移动保留,删除并重建图源后清空。来源/数据修订的可选sqs校验沿用GeoJSON规则,状态不改变dataRevision或业务属性。
map.setFeatureState({source:'roads',sourceLayer:'transportation',id:1},{selected:true});
await map.sqs.flush({render:true});
console.log(await map.getFeatureState({source:'roads',sourceLayer:'transportation',id:1}));
map.removeFeatureState({source:'roads',sourceLayer:'transportation'}); // 清除此子层
map.removeFeatureState({source:'roads'}); // 清除整个源
共同渲染查询返回对应子层的state快照,feature-state驱动真实paint。ID会共享同子层的跨瓦片/世界副本状态;不自动合并查询几何。没有要素的影像/媒体源明确拒绝状态API。预算与原有GeoJSON状态一致。
完整HTML状态示例展示选中按钮、查询、视图切换、来源和销毁;共同脚本在原生和实际WASM主线程/严格Worker验证隔离、清除和实际像素。倾斜画面沿用距离雾效果。移动宿主和外机仍需后续验收。