1.代码
<!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.9</title>
<link rel="stylesheet" href="http://localhost:8080/arcgis_js_api/library/4.9/esri/css/main.css">
<script src="http://localhost:8080/arcgis_js_api/library/4.9/init.js"></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 =
"http://localhost:6080/arcgis/rest/services/hotel/FeatureServer/0";
var wellBuffer, wellsGeometries;
var wellTypeSelect = document.getElementById("well-type");
var magSlider = document.getElementById("mag");
var distanceSlider = document.getElementById("distance");
var wellsLayer = new FeatureLayer({
url: quakesUrl,
outFields: ["*"],
visible: false
})
// GraphicsLayer for displaying results
var resultsLayer = new GraphicsLayer();
var map = new Map({
basemap: "gray",
layers: [wellsLayer]
});
var view = new MapView({
container: "viewDiv",
map: map,
center:[123.5,41.8],
spatialReference:{ wkid: 3857},
zoom: 11
});
view.ui.add("infoDiv", "top-right")
/*then的含义就是,等then前面的操作在服务器上做完后,再执行then里面的内容。因为js是单线程的解释型语言,不会编译,只会从头到尾一次读下来,所以执行到then前面的代码时,是不可能停在那里的。
then前面的代码执行完肯定有一个类似回执的东西(可以理解为返回值),但是浏览器不能一直等待这个回执啊?所以就在then里面写一个回调函数,丢给服务器,在服务器端等待then前的操作完成后,
再把“返回值”返还给回调函数做,即可。then()里的东西不会立刻在本地执行,在本地等待前一步的操作结果只会让浏览器卡死。*/
/*
* 在wellsLayer中,使用createQuery()方法就能返回一个query对象,query对象包含了所有用于空间查询(搜索)用的信息,
通过它,才能使用queryFeatures等方法对需要进行空间查询(搜索)的图层进行空间查询(搜索)。
*/
/*实现的步骤 1.view加载后,执行when(),when返回wellslayer的空间搜索结果(queryFeatures),这个结果是Featureset类型的,名为response;
2.通过getValues获取其内所有features的所有HOTELSTAR字段的值,名为valuesl,类型为数组;
3.values把值传递给getUniqueValues方法,通过forEach()方法过滤重复值;
4.通过创建option元素将唯一值添加到select标签下,于是select标签下出现的是酒店类型(hotelstar)
5.针对查询出的点进行空间缓冲区*/
view.when(function () {
return wellsLayer.when(function () {
var query = wellsLayer.createQuery();
console.log(wellsLayer.queryFeatures(query))
return wellsLayer.queryFeatures(query);
});
})
.then(getValues)
.then(getUniqueValues)
.then(addToSelect)
.then(createBuffer);
// return an array of all the values in the
// STATUS2 field of the wells layer
function getValues(response) {
var features = response.features;
var values = features.map(function (feature) {
return feature.attributes.HOTELSTAR;
});
console.log(values)
console.log(values.length)
return values;
}
//返回wellsLayer图层的HOTELSTAR属性字段的数组中的唯一值
function getUniqueValues(values) {
var uniqueValues = [];
values.forEach(function (item, i) {
// uniqueValues.indexOf(item) === -1 代表如果uniqueValues数组中不存在item则向数组中插入,否则不插入
if ((uniqueValues.length < 1 || uniqueValues.indexOf(item) === -1) &&
(item !== "")) {
uniqueValues.push(item);
}
});
console.log(uniqueValues)
return uniqueValues;
}
function addToSelect(values) {
var a=values.sort();
console.log(a)
values.forEach(function (value) {
var option = document.createElement("option");
option.text = value;
wellTypeSelect.add(option);
});
console.log(wellTypeSelect.value)
return setWellsDefinitionExpression(wellTypeSelect.value);
}
// 设置wells的定义表达式
function setWellsDefinitionExpression(newValue) {
wellsLayer.definitionExpression = "HOTELSTAR = '" + newValue + "'";
if (!wellsLayer.visible) {
wellsLayer.visible = true;
}
return queryForWellGeometries();
}
function queryForWellGeometries() {
var wellsQuery = wellsLayer.createQuery();
return wellsLayer.queryFeatures(wellsQuery)
.then(function (response) {
wellsGeometries = response.features.map(function (feature) {
return feature.geometry;
});
return wellsGeometries;
});
}
/*创建单个的缓冲区(geometryEngine.geodesicBuffer(geometry, distance, unit, unionResults)
unionResults: Determines whether the output geometries should be unioned into a single polygon.*/
function createBuffer(wellPoints) {
console.log(wellPoints)
var bufferDistance = parseInt(distanceSlider.value);
var wellBuffers = geometryEngine.geodesicBuffer(wellPoints, [bufferDistance], "meters",
true);
console.log(wellBuffers)
//因为unionResults为true,返回的是缓冲区合并后的单个的面的数组。
wellBuffer = wellBuffers[0];
// add the buffer to the view as a graphic
var bufferGraphic = new Graphic({
geometry: wellBuffer,
symbol: {
type: "simple-fill", // autocasts as new SimpleFillSymbol()
outline: {
width: 1.5,
color: [0, 2, 255, 0.5]
},
style: "none"
}
});
view.graphics.removeAll();
view.graphics.add(bufferGraphic);
}
//distanceSlider绑定input事件
distanceSlider.addEventListener("input", function () {
document.getElementById("distance-value").innerText = distanceSlider.value;
});
// 对查询的几何创建缓冲区
distanceSlider.addEventListener("change", function () {
createBuffer(wellsGeometries);
});
// set a new definitionExpression on the wells layer
// and create a new buffer around the new wells
wellTypeSelect.addEventListener("change", function () {
var type = event.target.value;
setWellsDefinitionExpression(type)
.then(createBuffer);
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="infoDiv">
选择酒店类型:
<select id="well-type"></select>
<br> 酒店缓冲区距离:
<input id="distance" type="range" min="10" max="10000" step="10" value="10000">
<span id="distance-value">10000</span> 米
</div>
</body>
</html>
2.结果