SceneLayer 过滤和查询
此示演示了如何过滤和查询网格 SceneLayer 。过滤是通过在图层的 definitionExpression 属性中设置一个 SQL 查询来完成的:
sceneLayer.definitionExpression = "BUILDINGNAME = 'Main Building'";
在设置 definitionExpression 属性之后,视图会立刻更新。
查询图层时,可以从头开始构建新查询,也可以创建一个已经满足设置的 definitionExpression 的查询。通过使用 createQuery(),结果将只返回过滤的要素。
var query = sceneLayer.createQuery();
query.outFields = ['SPACETYPE'];
sceneLayer.queryFeatures(query)
.then(function(result){
console.log(result.features);
});
程序完整源代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>SceneLayer filter and query - 4.5</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#optionsDiv {
width: 250px;
padding: 0 12px 0 12px;
background-color: white;
padding: 10px;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.5/esri/css/main.css">
<script src="https://js.arcgis.com/4.5/"></script>
<script>
require([
"esri/WebScene",
"esri/views/SceneView",
"esri/widgets/Legend",
"esri/widgets/LayerList",
"dojo/on",
"dojo/dom",
"dojo/domReady!"
], function(
WebScene, SceneView, Legend, LayerList,
on, dom
) {
// 加载 ArcGIS Online 的场景
var webScene = new WebScene({
portalItem: {
id: "b1f8fb3b2fd14cc2a78728de108776b0"
}
});
var view = new SceneView({
container: "viewDiv",
map: webScene,
environment: {
lighting: {
directShadowsEnabled: false
}
}
});
webScene.then(function() {
// 定义 web 场景中每个图层对应的查询
var buildingQuery = {
"Building Wireframe": "BUILDINGID = 'Q'",
"Interior Space": "BUILDING = 'Q'",
"Walls": "BUILDINGKEY = 'Q'",
"Doors": "BUILDINGKEY = 'Q'"
};
// 筛选出包含 建筑 Q 的图层
webScene.layers.forEach(function(layer) {
layer.definitionExpression = buildingQuery[layer.title];
});
// 我们需要多次使用 "Interior Space" 图层,所以将其保存在一个变量中
var officeLayer = webScene.layers.find(function(l) {
return l.title === "Interior Space";
});
// 下列是我们想显示的办公室类型
var officeTypes = [
"Office-Executive",
"Conference Room",
"Office-Single",
"Office-Manager",
"Office Cubicle"
];
// 计算当前显示的办公室类型数量,并显示在图例中
function displayOfficeTypes() {
// 在 办公室图层 上创建查询,使其遵循 definitionExpression
var query = officeLayer.createQuery();
query.outFields = ["SPACETYPE"];
// 查询并计算每种类型的数量
officeLayer.queryFeatures(query)
.then(function(results) {
var typesCounter = {}; // 用于统计每种类型的数量
var othersCounter = 0; // 用于统计其他类型的数量
results.features.forEach(function(feature) {
var spaceType = feature.attributes.SPACETYPE;
if (typesCounter[spaceType]) {
typesCounter[spaceType]++;
} else {
typesCounter[spaceType] = 1;
}
if (officeTypes.indexOf(spaceType) === -1) {
othersCounter++;
}
});
// 把统计结果显示到图例
var newRenderer = officeLayer.renderer.clone();
officeTypes.forEach(function(value, i) {
newRenderer.uniqueValueInfos[i].label = value +
": " + (typesCounter[value] || 0) + " rooms";
});
newRenderer.defaultLabel = "Other types: " +
othersCounter + " rooms";
officeLayer.renderer = newRenderer;
});
}
displayOfficeTypes();
function showFloors(evt) {
var floorQuery = evt.target.value;
// 更新 definitionExpression
webScene.layers.forEach(function(layer) {
if (layer.title !== "Building Wireframe") {
layer.definitionExpression = buildingQuery[layer.title] +
" AND " + floorQuery;
}
});
// 重新统计
displayOfficeTypes();
}
on(dom.byId("floorSelect"), "change", showFloors);
var legend = new Legend({
view: view,
layerInfos: [{
layer: officeLayer,
title: " "
}]
});
view.ui.add(legend, "bottom-right");
// 添加 LayerList 小部件
var layerList = new LayerList({
view: view
});
view.ui.add(layerList, {
position: "top-right"
});
});
view.ui.add(dom.byId("optionsDiv"), {
position: "top-left",
index: 0
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="optionsDiv">
<div><b>Filter building by floor:</b>
<select id="floorSelect">
<option value="1=1">All</option>
<option value="FLOOR = '1'">1</option>
<option value="FLOOR = '2'">2</option>
<option value="FLOOR = '3'">3</option>
</select>
</div>
</div>
</body>
</html>
程序运行效果: