使用JavaScript在ArcGIS要素过滤时显示结果计数点标注
ArcGIS JS 多图层按年过滤+匹配数标注实现及1936年图层异常修复
基础配置结构参考
首先确认你的年份维度图层配置结构符合规范,参考如下:
// 按年份分组的图层配置数组 const layersByYears = [ { year: 1936, layerList: [ { layerID: "对应1936年点位图层的服务子ID", opacity: 0.8, name: "1936年点位图层", featureLayer: null // FeatureLayer实例初始化占位 } // 同年份其他图层可追加在此 ] } // 其他年份节点按相同结构追加 ]
一、createFL 图层初始化+进度条实现
- 初始化
FeatureLayer实例时必须显式声明标注相关配置,避免后续动态改标注不生效 - 进度条统计要覆盖所有图层加载流程,不要提前把未加载完成的图层实例挂载到配置节点,避免后续过滤时拿到null实例报错
- 可直接复用的实现代码:
async function createFL() { // 统计所有待加载图层总数 const total = layersByYears.reduce((sum, node) => sum + node.layerList.length, 0) let loaded = 0 const progressBar = document.querySelector("#load-progress") for (const yearNode of layersByYears) { for (const conf of yearNode.layerList) { const featureLayer = new FeatureLayer({ url: `你的ArcGIS服务根地址/${conf.layerID}`, opacity: conf.opacity, title: conf.name, outFields: ["*"], labelsVisible: true, // 全局开启图层标注,1936年图层优先检查该配置是否开启 labelingInfo: [ new LabelClass({ labelExpressionInfo: { expression: "''" }, // 初始化时标注为空 symbol: { type: "text", color: [220, 20, 60, 1], haloColor: [255,255,255,1], haloSize: 1.2, font: { size: 12, weight: "bold" } } }) ] }) // 等图层加载完成再挂载实例、更新进度 await featureLayer.when(() => { conf.featureLayer = featureLayer map.add(featureLayer) loaded++ progressBar.style.width = `${Math.round(loaded / total * 100)}%` }) } } }
注意:必须显式配置outFields: ["*"],老版本ArcGIS服务(比如1936年对应的早期测绘图层)默认不会返回全量字段,容易导致后续查询、标注逻辑失效
二、doQuery 过滤+匹配数标注实现
- 拼接过滤表达式时要区分字段类型,字符串类型的值必须包裹单引号,否则会报SQL语法错误
- 设置
definitionExpression后要等待过滤生效,再统计匹配要素数、更新标注,不要同步执行导致计数不准 - 可直接复用的实现代码:
async function doQuery() { // 读取页面筛选控件参数 const filterField = document.querySelector("#select-field").value const operator = document.querySelector("#select-operator").value const filterValue = document.querySelector("#input-value").value.trim() // 拼接合法的where表达式 const isNumber = !isNaN(Number(filterValue)) const whereExpr = isNumber ? `${filterField} ${operator} ${filterValue}` : `${filterField} ${operator} '${filterValue.replace(/'/g, "''")}'` // 转义单引号避免SQL语法错误 for (const yearNode of layersByYears) { for (const conf of yearNode.layerList) { const fl = conf.featureLayer if (!fl) continue // 跳过未加载完成的图层,避免1936年图层因为加载慢导致空指针报错 // 校验当前图层是否存在筛选字段,解决不同年份图层字段结构不一致问题 const hasField = fl.fields.some(item => item.name === filterField) if (!hasField) { fl.definitionExpression = "1=0" fl.labelingInfo[0].labelExpressionInfo.expression = "''" fl.refresh() continue } // 应用过滤规则 fl.definitionExpression = whereExpr // 统计当前图层匹配的要素总数 const matchCount = await fl.queryFeatureCount(new Query({ where: whereExpr })) // 更新点位标注内容 fl.labelingInfo[0].labelExpressionInfo.expression = `'匹配:${matchCount}个'` fl.refresh() } } }
三、1936年图层异常专项排查点
- 检查1936年图层配置的
layerID是否和服务后台一致,确认该图层服务已开启查询、标注权限,没有跨域访问限制 - 对比1936年图层和其他年份图层的字段结构,确认筛选字段名、字段类型一致,避免表达式拼接错误
- 检查1936年图层是否配置了
minScale/maxScale显示范围限制,过滤后如果当前地图缩放级别不在范围内,会看不到要素和标注 - 调整图层加载顺序,把1936年图层放到图层栈最上层,避免被其他年份的面、线图层挡住标注
内容的提问来源于stack exchange,提问作者jenik2205
相关产品推荐
相关产品推荐

