ArcGIS JS 基础教程(27):DisplayFilter 显示过滤器
- 零、写在前面
- 一、功能介绍
- 二、功能实现
- 2.1 配置 DisplayFilterInfo
- 2.2 运行时切换过滤器
- 三、功能应用
- 四、核心代码
- 五、在线示例
- 六、关键 API 说明
- 七、系列导航
零、写在前面
📌本系列教程完整目录:ArcGIS JS 系列基础教程(100个项目常用热门功能)
💡在线示例:完整可运行的 HTML 示例,无需任何环境配置,可直接在浏览器中打开体验
🗂️专栏导航:收藏 + 关注,专栏文章第一时间送达
❤️一键三连:点赞 + 评论 + 收藏
一、功能介绍
DisplayFilter(显示过滤器)用于在图层级限制「哪些要素被渲染显示」,但保留全部要素用于查询与分析。这与definitionExpression(在数据源层面过滤、会影响查询)有本质区别。
- 显示过滤器比
definitionExpression更轻量:切换时不重新请求数据,仅控制渲染,适合海量要素的秒级筛选。 - 一个图层可配置多个过滤器,通过
DisplayFilterInfo的mode与activeFilterId控制激活哪一个。
参考:DisplayFilter API | DisplayFilterInfo API
⚠️5.0 正确用法:通过
featureLayer.displayFilterInfo(一个DisplayFilterInfo)配置,where是 SQL 子句属性(不是sqlWhere,也没有apply()方法)。
二、功能实现
2.1 配置 DisplayFilterInfo
constDisplayFilter=await$arcgis.import("@arcgis/core/layers/support/DisplayFilter.js");constDisplayFilterInfo=await$arcgis.import("@arcgis/core/layers/support/DisplayFilterInfo.js");buildingsLayer.displayFilterInfo=newDisplayFilterInfo({mode:"manual",// 手动切换filters:[newDisplayFilter({id:"all",title:"全部建筑",where:"1=1"}),newDisplayFilter({id:"tall",title:"高层(≥20层)",where:"floor >= 20"}),newDisplayFilter({id:"mid",title:"中层(10-19层)",where:"floor >= 10 AND floor < 20"})],activeFilterId:"all"// 当前激活的过滤器});buildingsLayer.displayFilterEnabled=true;// 开启图层显示过滤view.displayFilterEnabled=true;// 开启视图级显示过滤2.2 运行时切换过滤器
// mode 为 "manual" 时,直接改 activeFilterId 即可切换buildingsLayer.displayFilterInfo.activeFilterId="tall";
mode: "scale"时无需手动切换——系统会根据当前比例尺自动匹配minScale/maxScale范围内的过滤器。
三、功能应用
| 应用场景 | 说明 |
|---|---|
| 海量设施秒级筛选 | 千万级要素切换不重新请求,性能高 |
| 按时间段/区域过滤 | where写时间或行政区划条件 |
| 多方案对比 | 多个过滤器快速切换查看 |
| 仅看不查 | 显示过滤不影响queryFeatures结果 |
四、核心代码
📦完整代码已保存至
sample/lesson27_display_filter.html,可直接在浏览器打开。
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>第27课:DisplayFilter 显示过滤器</title><linkrel="stylesheet"href="https://js.arcgis.com/5.0/esri/themes/light/main.css"><scripttype="module"src="https://js.arcgis.com/5.0/"></script><style>*{margin:0;padding:0;box-sizing:border-box;}body{font-family:"Microsoft YaHei",sans-serif;}#mapContainer{width:100vw;height:100vh;}.page-title{position:absolute;top:20px;left:50%;transform:translateX(-50%);background:rgba(255,255,255,0.95);padding:10px 24px;border-radius:6px;font-size:18px;font-weight:bold;z-index:100;box-shadow:0 2px 8pxrgba(0,0,0,0.15);}.control-panel{position:absolute;top:80px;right:20px;background:rgba(255,255,255,0.95);padding:16px;border-radius:8px;box-shadow:0 2px 12pxrgba(0,0,0,0.15);z-index:100;min-width:300px;}.control-panel h3{margin:0 0 8px 0;font-size:14px;color:#333;}.section{margin-bottom:12px;padding-bottom:10px;border-bottom:1px solid #eee;}.section:last-child{border-bottom:none;margin-bottom:0;}.btn-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:6px;}.btn-row button{flex:1;min-width:60px;padding:6px 0;border:1px solid #d9d9d9;border-radius:4px;background:white;cursor:pointer;font-size:12px;}.btn-row button:hover{border-color:#1890ff;color:#1890ff;}.btn-row button.on{background:#1890ff;color:white;border-color:#1890ff;}.info-card{margin-top:10px;padding:10px 12px;background:#f0f5ff;border-radius:6px;border-left:3px solid #1890ff;font-size:12px;line-height:1.6;}.info-card .val{font-weight:bold;color:#1890ff;}.status-text{position:absolute;bottom:20px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,0.7);color:white;padding:8px 20px;border-radius:20px;font-size:13px;z-index:100;pointer-events:none;white-space:nowrap;}</style></head><body><h1class="page-title">第27课:DisplayFilter 显示过滤器</h1><divclass="control-panel"><divclass="section"><h3>🔎 显示过滤器(DisplayFilter)</h3><divclass="btn-row"><buttonid="btnAll"class="on">🏙️ 全部建筑</button><buttonid="btnTall">🏗️ 高层 ≥20层</button></div><divclass="btn-row"><buttonid="btnMid">🏢 中层 10-19层</button><buttonid="btnDisable">⏹️ 关闭过滤</button></div></div><divclass="info-card"><div>当前过滤:<spanclass="val"id="filterStatus">全部建筑</span></div><div>显示过滤不影响查询</div></div></div><divclass="status-text"id="statusText">DisplayFilter | 显示过滤 · 不重新请求数据 · 保留全部要素</div><divid="mapContainer"></div><scripttype="module">constMap=await$arcgis.import("@arcgis/core/Map.js");constSceneView=await$arcgis.import("@arcgis/core/views/SceneView.js");constFeatureLayer=await$arcgis.import("@arcgis/core/layers/FeatureLayer.js");constDisplayFilter=await$arcgis.import("@arcgis/core/layers/support/DisplayFilter.js");constDisplayFilterInfo=await$arcgis.import("@arcgis/core/layers/support/DisplayFilterInfo.js");constgetTianditu=await$arcgis.import("https://openlayers.vip/examples/resources/tianditu.js");constvecLayers=getTianditu.default({type:"vec_w"});constmap=newMap({basemap:{baseLayers:[vecLayers.base,vecLayers.anno]}});constview=newSceneView({container:"mapContainer",map:map,camera:{position:{longitude:121.435,latitude:31.245,z:4000},heading:30,tilt:60}});window.view=view;constbuildingsLayer=newFeatureLayer({url:"https://gs3d.geosceneonline.cn/server/rest/services/Hosted/ShangHaiBuilding/FeatureServer/0",elevationInfo:{mode:"on-the-ground"},outFields:["id","floor","year"],renderer:{type:"simple",symbol:{type:"polygon-3d",symbolLayers:[{type:"extrude",material:{color:"#D4B87C"},edges:{type:"solid",color:"#999999",size:0.5}}]},visualVariables:[{type:"size",field:"floor",axis:"height",valueUnit:"unknown"}]}});map.add(buildingsLayer);view.when(()=>{buildingsLayer.when(()=>{// 配置显示过滤器buildingsLayer.displayFilterInfo=newDisplayFilterInfo({mode:"manual",filters:[newDisplayFilter({id:"all",title:"全部建筑",where:"1=1"}),newDisplayFilter({id:"tall",title:"高层(≥20层)",where:"floor >= 20"}),newDisplayFilter({id:"mid",title:"中层(10-19层)",where:"floor >= 10 AND floor < 20"})],activeFilterId:"all"});buildingsLayer.displayFilterEnabled=true;view.displayFilterEnabled=true;view.goTo(buildingsLayer.fullExtent,{duration:2000,easing:"cubic-out"});});});functionsetActive(id,label,btn){buildingsLayer.displayFilterInfo.activeFilterId=id;document.querySelectorAll(".btn-row button").forEach(b=>b.classList.remove("on"));btn.classList.add("on");document.getElementById("filterStatus").textContent=label;document.getElementById("statusText").textContent="显示过滤:"+label;}document.getElementById("btnAll").addEventListener("click",function(){setActive("all","全部建筑",this);});document.getElementById("btnTall").addEventListener("click",function(){setActive("tall","高层 ≥20层",this);});document.getElementById("btnMid").addEventListener("click",function(){setActive("mid","中层 10-19层",this);});document.getElementById("btnDisable").addEventListener("click",function(){buildingsLayer.displayFilterEnabled=false;document.querySelectorAll(".btn-row button").forEach(b=>b.classList.remove("on"));this.classList.add("on");document.getElementById("filterStatus").textContent="已关闭";document.getElementById("statusText").textContent="显示过滤已关闭(显示全部)";});</script></body></html>五、在线示例
🔗在线体验:https://southjor.github.io/arcgis-examples/lessons/lesson27.html
操作说明:
- 场景加载上海建筑,配置 3 个显示过滤器(全部 / 高层 / 中层)。
- 点击「高层 ≥20层」「中层 10-19层」通过
activeFilterId即时切换显示,且不重新请求数据。- 点击「关闭过滤」将
displayFilterEnabled = false恢复显示全部。- 显示过滤只影响渲染,用
queryFeatures仍能查到全部要素。
六、关键 API 说明
| API | 说明 |
|---|---|
featureLayer.displayFilterInfo | DisplayFilterInfo:含filters、activeFilterId、mode |
new DisplayFilter({ id, title, where }) | 单个过滤器,where为 SQL 子句(非sqlWhere) |
DisplayFilterInfo.mode | "manual"(手动)/"scale"(按比例尺自动) |
featureLayer.displayFilterEnabled | 开启/关闭图层显示过滤 |
view.displayFilterEnabled | 开启/关闭视图级显示过滤 |
与definitionExpression区别 | 显示过滤不影响查询,切换不重新请求 |
参考链接:DisplayFilter API | DisplayFilterInfo API
七、系列导航
⬅️上一篇:ArcGIS JS 基础教程(26):图层可见性与透明度控制
➡️下一篇:ArcGIS JS 基础教程(28):图层渲染顺序管理
💡小贴士:显示过滤与
definitionExpression最大的不同是——显示过滤只改「看得到什么」,不改「数据有什么」。所以当你需要频繁切换显示条件、又不想影响查询统计时,首选DisplayFilter。