Portal、GA和REST API简介
Portal for ArcGIS是一个门户网站,可用户与组织内的其他人便捷地分享地图、场景、应用和其他地理信息。
GeoAnalytics Server是ArcGIS产品体系中针对空间大数据做高级分析的软件产品,可通过ArcGIS Pro或者Portal for ArcGIS执行大数据分析,也可以通过REST的方式进行远程调用。
ArcGIS REST API方便开发者将ArcGIS服务和功能集成到应用程序中,可实现访问ArcGIS服务(如地理编码和路由),也可以构建与ArcGIS Online和ArcGIS Enterprise深度集成的应用程序。
本篇博客一个GA的Overlay工具为例,介绍如何通过REST API访问Portal中的GA工具。通过访问REST API中的Overlay工具描述,可以了解到输入参数和响应结果信息。
叠加图层的选择
在实际应用中,常常使用发布的大数据的服务地址作为叠加工具的输入图层。叠加工具的叠加要素的选择基本上是有两种选择:一种是服务地址,一种是Feature Collection。经过对比测试,前者要比后者更稳定一些。因此,本篇博客使用服务地址作为叠加工具的叠加图层参数。
考虑到用户的实际需求(比如:上传一个SHP文件或者手绘一个范围并以此作为叠加要素,即:叠加要素是经常变的),因此建议发布一个要素服务,设置其为可编辑状态(如下图所示),然后将其作为叠加工具的叠加要素。
在前端页面实现上诉思路时,在绘制叠加范围或者上传SHP文件之前需要将这个要素服务清空,然后将绘制的范围或SHP文件内容添加到这个要素服务中。
下面的代码先对要素图层进行要素检索,如果有要素,则将其删除,然后将新的要素添加到该服务中;如果没有要素,则直接将新的要素添加该服务中。
overlayLayer.queryFeatures().then(function(results) {
if (results.features.length > 0) {
overlayLayer
.applyEdits({
deleteFeatures: results.features
})
.then(function(_) {
overlayLayer
.applyEdits({
addFeatures: overlayLayerAddingGraphics
})
.then(function(editsResult) {
overlayLayer.refresh();
// do overlay
})
.catch(function(error) {
console.log(error);
});
});
} else {
overlayLayer
.applyEdits({
addFeatures: overlayLayerAddingGraphics
})
.then(function(editsResult) {
overlayLayer.refresh();
// do overlay
})
.catch(function(error) {
console.log(error);
});
}
});
叠加范围的选择
GA的分析工具的环境设置中默认将输入图层的图层范围作为工具的分析范围。因此,如果你的输入图层范围过大时,建议将工具的分析范围设置为叠加图层的范围,这样可以加快工具的执行时间。
叠加结果的存储方式
GA的分析工具的分析结果存储方式有两种,一种是存储在时空大数据库中,一种是存储到关系型数据中,默认是存储在时空大数据库中。经过测试,如果选择存储到时空大数据库中,无论是否设置输出结果的坐标系,输出结果都是WGS84坐标系;而存储到关系数据库中,如果未指定输出结果的坐标系,输出结果的坐标系和输入要素的坐标系相同,反之为指定的坐标系。因此,这里建议将处理结果输出到关系型数据库中。
整个Overlay分析工具的参数如下如下:
let restData = {
overlayLayer:
'{"url": "' + Vue.prototype["featureServerUrl"] + '"}',
inputLayer:
'{"url": "' +
Vue.prototype["overlayFeatureServerUrl"] +
'"}',
overlayType: "Intersect",
includeOverlaps: "false",
outputName: that.gaOutputName,
context: "",
f: "json",
token: portalToken
};
let context = {
extent: getOverlayLayerExtent(
that.esriView,
quickClipSettingParams.selectedClipInputLayer
),
processSR: overlayLayer.spatialReference,
dataStore: "relational"
};
restData.context = JSON.stringify(context);
执行叠加工具
叠加工具的参数配置完成后,可以使用ajax或axios方式发送POST请求,请求执行叠加分析,实现代码如下:
export const postRequestOfAxios = (
requestUrl,
requestData,
successfulCallback,
failCallback
) => {
axios
.post(requestUrl, requestData, {
timeout: 3600000,
cache: false,
async: false,
dataType: "jsonp"
})
.then(function(requestResultInfo) {
successfulCallback(requestResultInfo);
})
.catch(function(requestErrorInfo) {
failCallback(requestErrorInfo);
});
}
postRequestOfAxios(
postRequestUrl,
qs.stringify(restData),
function(requestResultInfo) {
let jobId = requestResultInfo.data.jobId;
// Check Job Status
},
function(requestErrorInfo) {
console.log(requestErrorInfo);
}
);
检查叠加分析任务的状态,获取叠加分析结果图层地址
正如上述代码所示,叠加分析的POST请求会返回一个对应的JOB ID,并不会直接返回叠加结果的图层地址。这是因为叠加分析需要一定的时间,因此我们需要使用这个JOB ID访问叠加分析任务的状态,直到分析成功或者分析失败。
这里使用setInterval方法,每个2s查询一次叠加分析任务的状态。
that.overlayWindowsInterval = window.setInterval(
function() {
checkGAToolStatus(
overlayToolsUrl,
jobId,
Vue.prototype["portalDomainName"],
portalToken,
that.overlayWindowsInterval,
that.esriView,
successCallBack,
failCallBack
);
},
2000
);
function checkGAToolStatus(
gaToolUrl,
gaToolJobId,
portalDomainName,
portalToken,
overlayWindowsInterval,
esriView,
successCallBack,
failCallBack
) {
let jobUrl = gaToolUrl + "/jobs/" + gaToolJobId;
let data = {
f: "pjson",
token: portalToken
};
postRequestOfAxios(
jobUrl,
qs.stringify(data),
function(requestResultInfo) {
let jobStatus = requestResultInfo.data.jobStatus;
if (
jobStatus === "esriJobSubmitted" ||
jobStatus === "esriJobWaiting" ||
jobStatus === "esriJobExecuting"
) {
console.log(jobStatus);
} else if (
jobStatus === "esriJobFailed" ||
jobStatus === "esriJobTimedOut" ||
jobStatus === "esriJobCancelling" ||
jobStatus === "esriJobCancelled"
) {
window.clearInterval(overlayWindowsInterval);
failCallBack();
console.log(jobStatus);
} else if (jobStatus === "esriJobSucceeded") {
window.clearInterval(overlayWindowsInterval);
let jobOutputRequestUrl = jobUrl + "/results/output";
postRequestOfAxios(
jobOutputRequestUrl,
qs.stringify(data),
function(requestResultInfo) {
esriLoader
.loadModules(["esri/layers/FeatureLayer"], gisConfig.arcgisApi)
.then(([EsriFeatureLayer]) => {
let gaResultFeatureLayer = findLayerById(
esriView,
gisConfig.overlayResultLayerId
);
if (gaResultFeatureLayer) {
esriView.map.remove(gaResultFeatureLayer);
}
gaResultFeatureLayer = new EsriFeatureLayer({
url: requestResultInfo.data.value.url,
id: gisConfig.overlayResultLayerId,
title: "裁剪结果"
});
esriView.map.add(gaResultFeatureLayer);
successCallBack();
});
},
function(requestErrorInfo) {
console.log(requestErrorInfo);
failCallBack();
}
);
}
},
function(requestErrorInfo) {
console.log(requestErrorInfo);
failCallBack();
}
);
}
至此,我们已经完成了通过REST调用GA的Overlay工具并将结果显示在当前地图中的整个流程。