除了地图基本的放大缩小等功能,在webgis上的二次开发中,查询功能 通常作为需求的一部分需要我们去实现,今天就给大家详细的分析实例代码中的查询功能:Query features from a FeatureLayer
话不多说,进入今天的实例代码的分析
网址:https://developers.arcgis.com/javascript/latest/sample-code/featurelayer-query/index.html
界面:
然后我们来看代码:
第一段还是引用,这里我没标注释,希望和我一样基础一般的读者可以去api上查这些引用,印象会比较深。
第二段:这里是定义一些变量,方便引用。还有一些地图的设置,这些不详细介绍了,有不懂的读者请留言,我会解答。
第三段开始比较重要:
从大框架上看:当视图(view)加载好以后,进行一些操作,之后进行getvalues,getuniquevalues,addtoselect以及createbuffer等操作
中间这些操作是这样的:1.建立一个查询createQuery,API reference的截图在下面. 2.执行查询,返回一个FeatureSet
第四段:
第五段:
最后附上所有代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Query features from a FeatureLayer - 4.10</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.10/esri/css/main.css">
<script src="https://js.arcgis.com/4.10/"></script>
<style>
html,
body,
#viewDiv {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#infoDiv {
background-color: white;
color: black;
padding: 6px;
width: 400px;
}
#results {
font-weight: bolder;
}
</style>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/layers/GraphicsLayer",
"esri/geometry/geometryEngine",
"esri/Graphic"
],
function (
Map, MapView,
FeatureLayer,
GraphicsLayer,
geometryEngine,
Graphic
) {
var quakesUrl =
"https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/ks_earthquakes_since_2000/FeatureServer/0";
var wellBuffer, wellsGeometries, magnitude;//定义缓冲区,图形,和震级
var wellTypeSelect = document.getElementById("well-type");//选择井的类型
var magSlider = document.getElementById("mag");//slider滑动器,选择震级
var distanceSlider = document.getElementById("distance");//选择距离
var queryQuakes = document.getElementById("query-quakes");//查询地震按钮
// 井图层
var wellsLayer = new FeatureLayer({
portalItem: { // autocasts as new PortalItem()
id: "8af8dc98e75049bda6811b0cdf9450ee"
},
outFields: ["*"],
visible: false
});
// 地震图层
var quakesLayer = new FeatureLayer({
url: quakesUrl,
outFields: ["*"],
visible: false
});
// 用于显示结果的图形图层
var resultsLayer = new GraphicsLayer();
//定义一个地图
var map = new Map({
basemap: "dark-gray",
layers: [wellsLayer, quakesLayer, resultsLayer]
});
//定义一个视图
var view = new MapView({
container: "viewDiv",
map: map,
center: [-97.75188, 37.23308],
zoom: 10
});
view.ui.add("infoDiv", "top-right");
// 从井的图层中查询元素
view.when(function () {//当视图加载完view.when()
return wellsLayer.when(function () {
var query = wellsLayer.createQuery();//创建可用于获取满足层的当前筛选器的特性的查询参数和定义。
return wellsLayer.queryFeatures(query); //对feature服务执行查询,并返回一个FeatureSet,一旦promise解析,就可以使用then()方法访问该FeatureSet。
//FeatureSet包含一个图形特性数组,可以将其添加到视图的图形中。如果没有发现任何结果,则不会填充此数组。
});
})
.then(getValues)
.then(getUniqueValues)
.then(addToSelect)
.then(createBuffer);
function getValues(response) {//上面对featurelayer执行了查询,返回了了一个featureset(集合),getValues方法是获取集合里面某个属性所有的值
var features = response.features;//featureset的features属性是从任务返回的图形数组
var values = features.map(function (feature) {//对于查询出来的的feature,获取STATUS2这个字段的属性值
return feature.attributes.STATUS2;
});
return values;//返回所有值
}
function getUniqueValues(values) {//对所有值进行筛选,得到唯一值的集合,
var uniqueValues = [];//定义一个唯一值的集合
values.forEach(function (item, i) {//进行循环判断,这里参数i不是很明白,作者感觉有点多余
if ((uniqueValues.length < 1 || uniqueValues.indexOf(item) === -1) && //详细讲一下这里的判断,首先||为逻辑运算符
//a || b只要ab有一个为true就为true,ab都为false才为false,a(第一个)为true则不用判断b,直接为true,这样减少了不必要的运算
// &&就是并运算,整个判断是说:如果集合uniqueValues集合为空,且循环的item不为空,则将item加到uniqueValues集合里,
//当集合里面有元素之后,判断能否在集合里找到循环的item,如果能找到且不为空,则添加item到集合
(item !== "")) {
uniqueValues.push(item);
}
});
return uniqueValues;
}
// 向井的类型添加惟一值选择元素。这将允许用户按类型筛选井。
function addToSelect(values) {//根据井的类型筛选
values.sort();//进行排序
values.forEach(function (value) {
var option = document.createElement("option");//创建一个"option"元素
option.text = value;
wellTypeSelect.add(option);//将option添加到井的类型选择器中,比如一共3种井,ABC,就会将ABC依次添加到wellTypeSelete中
});
return setWellsDefinitionExpression(wellTypeSelect.value);
}
// 在井的图层上设置定义表达式,以反映用户的选择
function setWellsDefinitionExpression(newValue) {
wellsLayer.definitionExpression = "STATUS2 = '" + newValue + "'";
if (!wellsLayer.visible) {//设置井的图层的可见属性为true
wellsLayer.visible = true;
}
return queryForWellGeometries();
}
// 获取wells层的所有几何图形,这些几何对象是由createQuery()方法创建一个查询对象,该对象遵循该层的definition表达式
function queryForWellGeometries() {
var wellsQuery = wellsLayer.createQuery();//建立一个查询对象
return wellsLayer.queryFeatures(wellsQuery)//执行查询,返回一个featureset
.then(function (response) {
wellsGeometries = response.features.map(function (feature) {//查询完,井的图形设置为feature的图形
return feature.geometry;
});
return wellsGeometries;//返回井的图形
});
}
// 建立缓冲区
function createBuffer(wellPoints) {
var bufferDistance = parseInt(distanceSlider.value);//获取缓冲区的距离
var wellBuffers = geometryEngine.geodesicBuffer(wellPoints, [bufferDistance], "meters",
true);
wellBuffer = wellBuffers[0];
// 将缓冲去作为图形添加到视图中
var bufferGraphic = new Graphic({
geometry: wellBuffer,
symbol: {
type: "simple-fill", // autocasts as new SimpleFillSymbol()
outline: {
width: 1.5,
color: [255, 128, 0, 0.5]
},
style: "none"
}
});
view.graphics.removeAll();
view.graphics.add(bufferGraphic);
}
// 获取由用户设置的地震级别
magSlider.addEventListener("input", function () {
magnitude = magSlider.value;
document.getElementById("mag-value").innerText = magnitude;
});
// 获取由用户设置的距离
distanceSlider.addEventListener("input", function () {
document.getElementById("distance-value").innerText = distanceSlider.value;
});
// 在查询的图形周边创建缓冲区
distanceSlider.addEventListener("change", function () {
createBuffer(wellsGeometries);
});
// 在wells层上设置一个新的定义表达式,并围绕新wells创建一个新的缓冲区
wellTypeSelect.addEventListener("change", function () {
var type = event.target.value;
setWellsDefinitionExpression(type)
.then(createBuffer);
});
//对queryQuakes按钮添加click时间的监听
queryQuakes.addEventListener("click", function () {
queryEarthquakes()
.then(displayResults);
});
function queryEarthquakes() {
var query = quakesLayer.createQuery();//创建查询
query.where = "mag >= " + magSlider.value;//定义查询条件:震级大于等于用户输入的数值
query.geometry = wellBuffer;//定于查询的图形为井的缓冲区
query.spatialRelationship = "intersects";//定义空间关系为"intersects"相交
return quakesLayer.queryFeatures(query);返回符合条件的集合
}
// 在视图中显示查询结果并输出结果
function displayResults(results) {
resultsLayer.removeAll();//清除结果图层
var features = results.features.map(function (graphic) {
graphic.symbol = {
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
style: "diamond",
size: 6.5,
color: "darkorange"
};
return graphic;
});
var numQuakes = features.length;
document.getElementById("results").innerHTML = numQuakes + " earthquakes found";
resultsLayer.addMany(features);
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="infoDiv">
Select well type:
<select id="well-type"></select>
<br> Well buffer distance:
<input id="distance" type="range" min="10" max="10000" step="10" value="10000">
<span id="distance-value">10000</span> meters
<br> Earthquake magnitude:
<input id="mag" type="range" min="0.0" max="5.0" step="0.1" value="2.0">
<span id="mag-value">2.0</span>
<button id="query-quakes">Query Earthquakes</button>
<br>
<div id="results"></div>
</div>
</body>
</html>