本程序实现了在鼠标点击区域范围内搜索800米范围内的那些带有附件的要素,并把附件图片显示出来。有个别地方我没有看懂,加了一些注释放在下面供参考和以后研究。
我没有看懂的主要是在:含有Object.keys(attachmentsByFeatureId) 的代码段,确切的说还不是特别懂 Object.keys()的用法。
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
<title>Query Attachments | Sample | ArcGIS API for JavaScript 4.19</title>
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#attachmentsDiv {
height: 100%;
width: 30%;
float: left;
padding: 20px;
overflow: auto;
min-width: 240px;
}
#viewDiv {
height: 100%;
max-width: 70%;
}
.queryImg {
width: 175px;
padding-right: 5px;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.19/esri/themes/dark/main.css" />
<script src="https://js.arcgis.com/4.19/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer"
], function(
Map, MapView, FeatureLayer
) {
// get layer from online portal
const layer = new FeatureLayer({
portalItem: {
id: "d532e04739cd45e4964291a2a8875ef6"
},
outFields: ["*"]
});
// setup the map
const map = new Map({
basemap: "dark-gray-vector",
layers: [layer]
});
const view = new MapView({
container: "viewDiv",
map: map,
center: [-118.41, 34.08],
zoom: 13,
popup: {
autoOpenEnabled: false
}
});
let highlight;//定义highlight,高亮
view.on("click", function(event) {
clearMap();//清理地图
queryFeatures(event);//查询入口,从这里开始查询
});
function queryFeatures(screenPoint) {//参数屏幕点,就是距离左上角的像素值
const point = view.toMap(screenPoint);//该函数接收屏幕点为参数,转换为地图上的点。
// Query the for the object ids within 800m from where the user clicked
//查询用户点击处的800米范围内的对象
layer.queryObjectIds({//该函数的返回是一个符合条件的要素的ObjectIDs数组
geometry: point,
spatialRelationship: "intersects",
distance: 800,
units: "meters",
returnGeometry: false,
outFields: ["*"]
})
.then(function(objectIds) {//根据返回的这些objectIds,继续做处理
if (!objectIds.length) {//如果这个数组为空,那么if()就为真,就调用showMessage();showMessage();就是显示了一段话:There are no tree image/jpeg attachments located in your query area
showMessage();
return;
}
// Highlight the query-area on the map
//高亮这个地图上的查询区域(query-area)
view.whenLayerView(layer).then(function(layerView){
if (highlight) {//如果highlight有值,那么就调用remove 意思是如果有高亮的区域,那么就删除掉,为新的高亮做准备
highlight.remove();
}
//下面这句是高亮给定的objectIds的那些要素,返回一个handler给highlight变量。
highlight = layerView.highlight(objectIds);//为highlight赋值,layerView.highlight(objectIds)这个函数的作用:高亮给定的要素{Highlights the given feature(s)},
//接收的参数是objectIds的单个值或者是个数组, 返回:一个handler,这个handler可以继续调用remvoe()来移除高亮
//{Returns a highlight handler with a remove() method that can be called to remove the highlight.}
});
// Query the for the attachments from the object ids found
//从找到的要素的ids中继续查询attachments,附件
return layer.queryAttachments({
attachmentTypes: ["image/jpeg"],
objectIds: objectIds
});
})
.then(function(attachmentsByFeatureId) {
if (!attachmentsByFeatureId) {//如果这个id为空,那么就返回去了,return;
return;
}
//Object.keys(obj):返回值:一个表示给定对象的所有可枚举属性的字符串数组,就是对一个xxx对象调用Object.key(xxx),那么我们得到了一个字符串数组,是这个对象的可枚举属性
if (Object.keys(attachmentsByFeatureId).length === 0){//如果属性的长度为0,那说明啥也没有查到啊
const infoP = document.createElement("p");//创建一个p元素,
infoP.innerHTML = "<b>There are no tree image/jpeg attachments located in your query area.</b>";//p里面是一段文本:你查询的面积里面就没有jpeg附件。
document.getElementById("queryResults").appendChild(infoP);//在结果div中,吧infop给加上,就是上面的那段话。
}
// Display the attachments 显示这个附件
console.log("I am the Id you want:"+attachmentsByFeatureId);
Object.keys(attachmentsByFeatureId)
.forEach(function(objectId) {
const attachments = attachmentsByFeatureId[objectId];
attachments.forEach(function (attachment) {
const image = document.createElement("img");//创建img,
image.src = attachment.url;
image.className = "queryImg";//分配css class为queryImg
document.getElementById("queryResults").appendChild(image);
});
});
})
.catch(function(error) {
showMessage();
})
}
function showMessage(){
clearMap();
const infoP = document.createElement("p");
infoP.innerHTML = "<b>There are no tree image/jpeg attachments located in your query area. Please click within the feature layer to get results.</b>";
document.getElementById("queryResults").appendChild(infoP);
}
// Clear attachments from div
function clearMap(){
if (highlight) {
highlight.remove();
}
const att = document.getElementById("queryResults");
while(att.firstChild){
att.removeChild(att.firstChild);
}
}
});
//下面一段是一个queryAttachments函数的说明,来自于帮助文档。作为帮助理解的补充材料
//featurelayer.queryAttachments(attachmentQuery, options){Promise<Object>}该函数查询与要素相关联的附件,
//返回的是一个promoise,When resolved, returns an object containing AttachmentInfos grouped by the source feature objectIds.
// ,当解析后,返回一个含有 AttachmentInfos 的对象,根据源要素的objectIds进行分组。
/* 不懂的就看下面的例子代码,我也还没有搞懂。
featureLayer.when(function () {
// queryObjectIds for all features within the layer
featureLayer.queryObjectIds().then(function (objectIds) {
// Define parameters for querying attachments,定义参数
// query features where objectIds are less than 735,查询那些id小于735的要素
// and only query jpeg attachments for these features.只查询jpeg的图片
let attachmentQuery = {
objectIds: objectIds,
definitionExpression: "OBJECTID < 735",
attachmentTypes: ["image/jpeg"]
};
// Only pass in one objectId for attachmentQuery.objectIds: 对于attachmentQuery.objectIds只传入一个objectId
// if the layer's capabilities.operations.supportsQueryAttachments is false 如果能力.操作.支持附件查询为假,那就是不支持呗
//featureLayer.queryAttachments(attachmentQuery).then(function (attachments)这句是做了附件查询,输入的是一个query。
featureLayer.queryAttachments(attachmentQuery).then(function (attachments) {
// Print out all returned attachment infos to the console.打印所有返回的附件信息到控制台。
attachmentQuery.objectIds.forEach(function (objectId) {
if (attachments[objectId]) {
let attachment = attachments[objectId];
console.group("attachment for", objectId);
attachment.forEach(function (item) {
console.log("attachment id", item.id);
console.log("content type", item.contentType);
console.log("name", item.name);
console.log("size", item.size);
console.log("url", item.url);
console.groupEnd();
});
}
});
})
.catch(function (error) {
console.log("attachment query error", error);
})
});
});
*/
</script>
</head>
<body>
<div id="attachmentsDiv" class="esri-widget">
<h2>Trees Returned from Query</h2>
<p>Click somewhere in the map to query for images of trees located on a block within 800m of your desired location.</p>
<div id="queryResults"></div>
</div>
<div id="viewDiv"></div>
</body>
</html>