前端转计算之SuperMap GPA 算子开发-手把手入门教程
一、GPA 了解与使用
1、相关资料
公开资料:
iServer GPA模型在实际场景中的使用——实现导入shp数据并切瓦片存储到MongoDB数据库发布服务_shp切割瓦片-CSDN博客
超图FAQ:基于iServer 11.1.1版本开发的GPA扩展算子,放到到11.3.0版本的iserver报错。该如何解决? - SuperMap技术问答社区
SuperMap iServer 扩展开发领域服务简单示例教程 - 可修改接口参数名称_supermap 示例-CSDN博客
SuperMap iDesktopX 11i GPA 扩展开发之对现有算子的调用实践_supermap idesktop11i-CSDN博客
2、了解
GPA 英文全称为 Geoprocessing Automaition,简称 GPA,对应中文名称为 处理自动化。
所谓处理自动化,就是 指将一系列的地理数据处理工具,通过一定的逻辑关系进行连接,构建成可自动化进行处理的模型。处理自动化模型是一系列地理数据处理工具串联在一起的流程图,其中前一个工具的输出是后一个工具的输入。
类似于UE游戏引擎中的蓝图。蓝图:一种可视化脚本工具,允许开发者通过图形化界面创建游戏逻辑,而无需深入了解复杂的编程语言。
类似于 ArcGIS 中的 ModelBuilder。
类似于 dify 的工作流搭建:
类似于后端的流程表单的搭建。
在 SuperMap 中 GPA 存在于 iServer 和 iDesktopX 中。即:在 iServer 数据服务中以服务接口的形式提供,在 iDesktopX 中以桌面端工具的形式提供。
对于 Web 应用的开发来说,就是使用 iServer 中的 GPA。当 GPA 工具中的算子不满足业务应用的需求时,就需要基于 iServer 的 GPA 进行算子的定制开发。之后进行自动化流程的建模,最后以服务接口的形式提供给使用者。
3、使用
① 在 SuperMap 官网下载最新版本的 iserver
② 启动 iserver 进入 GPA 页面
点击 startup.bat 启动本地 iserver
启动后,进入 http://localhost:8090/iserver 页面,没有用户的需要先创建用户、获取许可等。登录之后,即可进入 GPA 模型搭建、使用页面:处理自动化 http://localhost:8090/iserver/apps/gpmodeler/index.html
③ 使用处理自动化工具进行计算(示例):统计面图层所有地块面积及地块个数
这里以 统计面图层所有地块面积及地块个数 为例。
找到 数据处理-》矢量-》计算总面积,拖拽到中间。
在右侧面板中,选择参数,点击设置,设置数据源。
在设置连接信息中,支持多种数据源、数据库、数据文件类型。
这里以本地文件 udb 超图数据为例。(选中具体的 udb 数据,如果无法选择,可以点击上传数据,将 udb 上传至目录后即可选择)。
设置文件地址后,数据集列表将自动解析数据中的图层,这里选中 WaterPoly 面图层。
然后点击执行,在 下方可以看到,在参数一栏中,输出了总面积。
类似,可以多加几个处理自动化的工具,从而实现一个模型(流程)多个计算工具的顺序执行。比如下面这里还拖拽了计算个数。
如下图所示,拖拽 计算个数 到中间,并且设置源数据集,这里跟 计算总面积 一样 选择了同样的数据和图层。
然后将 计算总面积 与 计算个数 相连接。这意味着,将先执行计算总面积然后再执行计算个数。
点击执行后,如下:
将会先计算总面积,然后再计算地块个数。
通过 SuperMap 桌面端打开数据进行验证:
可以看到参与 GPA 计算的 WaterPoly 面图层确实有 216 个地块(记录)。
行内变量替换
行内变量替换能够替换输入参数的部分内容。在模型构建时灵活使用行内变量替换,能够大大减轻我们的工作量,达到数据处理规范化、型复用率更高的目的。
使用规则:
- 在文本框内输入’%,即可自动显示可引用的参数列表。
- 选择对应的行内变量替换后,也可输入"#,即能自动显示出可用的具体属性。
④ 导出模型:用于后续复用
创建的自动化处理流程的模型支持在 iServer 中导入、导出。
比如这里点击导出后,将以 xml 文件的形式导出。导出后可以在其他项目现场或产品的 iServer 中再导入。以达到模型复用的目的。
⑤ 发布模型
创建好的自动化处理的流程 的模型可以点击发布。可以通过模型分组和模型名称来指定相应分组和名称。
模型发布成功后,可以在 模型 菜单栏 查看到刚才分组、创建的指定名称的模型。同事 iServer 本身也提供了一些创建好的业务模型,可以直接复用。
在单个模型上右键,可以修改编辑当前模型,修改相应参数,以用于适配项目上具体的图层、数据等,满足项目的不同数据源等的情况。
模型还支持 计划执行,点击 计划执行-》添加。
可以选择定时、按分循环等,按计划执行模型。比如数据可能随时更新,则可以根据定时任务进行按计划的重复计算。确保最新的数据得到最新的计算结果等。
⑥ GPA 计算模型的 HTTP 请求、Web 调用
在模型上右键,点击打开资源页。
则会打开如下网址的 计算模型的 访问、请求地址,会有具体的计算模型说明,传参、返回参数等具体信息。
http://localhost:8090/iserver/services/geoprocessing/restjsr/gp/v2/sps.WorkflowProcessFactory.models.模型测试:计算总面积和个数的自动化处理模型/
上面这个地址以及输入参数、输出结果就是前端业务应用发送 HTTP POST 请求时的 API 地址及传参、返回结果等。
在 iserver 中 生成令牌/token。
前端发送HTTP请求 计算模型的步骤如下:
第一步,要发送POST请求,开启计算模型任务。
第二步,开启计算模型任务执行后会产生一个任务 ID,根据当前 ID 可以获取执行的计算任务的状态以及计算结果,有时计算任务可能比较耗时,发送 GET 可能计算任务还在执行。因此需要判断计算任务是否执行完毕。执行完毕后才能获取计算结果。
第三步,拿到计算结果后,将结果展示到前端页面中即可。
第一步 POST 请求发起的计算任务 在 处理自动化页面的 任务菜单中可以看到对应的 任务ID。
在资源页中的 可用操作-》当前工具任务列表中 也可以看到相同任务 ID 的任务。
当任务为 FINISHED 状态后,即可执行 GET 请求,获取计算结果。
当然也可以遍历已有的任务列表中的其中一个,获取计算结果。但获取结果的本质都一样,通过任务ID获取已经计算完成的任务的结果。
test.html 完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>测试用</title>
<style>
html,
body {
height: 100vh;
width: 100vw;
overflow: hidden;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
.sendBtn {
width: 10rem;
height: 2rem;
margin-left: 2rem;
margin-top: 2rem;
margin-bottom: 2rem;
}
.resultItem {
display: flex;
margin-left: 2rem;
}
</style>
</head>
<body>
<div class="container">
<button type="submit" id="submit" class="sendBtn">
<i class="fas fa-paper-plane"></i> 发送POST请求
</button>
<div class="resultItem">
<div>面积为:</div>
<div id="responseArea"></div>
</div>
<div class="resultItem">
<div>个数为:</div>
<div id="responseNum"></div>
</div>
</div>
<script>
function fetchPromise(url, options) {
return new Promise((resolve, reject) => {
fetch(url, options)
.then((response) => {
if (!response.ok) {
console.error(
"Network response was not ok " + response.statusText
);
reject(response.statusText);
}
return response.json(); // 解析JSON数据
}) // 解析JSON响应体内容
.then((result) => {
if (!result) {
console.error("结果为空");
reject("结果为空");
}
resolve(result);
}) // 打印结果或进行其他操作
.catch((error) => {
console.error(error);
reject(error);
});
});
}
document
.getElementById("submit")
.addEventListener("click", async function (event) {
const token =
"4nazxe-K_bUlswLjdBQ2-RA8DE35AX9zjjR9W9WGmWBzKcs7seOmtQTfLHq_9yPuXhdu-8rcJCd_fJtqPKRtyzBm";
const gpaModelURL =
"http://localhost:8090/iserver/services/geoprocessing/restjsr/gp/v2/sps.WorkflowProcessFactory.models.模型测试:计算总面积和个数的自动化处理模型";
const startJobURL = `${gpaModelURL}/jobs?token=${token}`;
const options = {
method: "POST", // *GET, POST, PUT, DELETE, etc.
};
const result = await fetchPromise(startJobURL, options);
if (result && result.jobID) {
const finishJobURL = `${gpaModelURL}/jobs/${result.jobID}.json?token=${token}`;
const options2 = {
method: "GET", // *GET, POST, PUT, DELETE, etc.
};
let result2 = await fetchPromise(finishJobURL, options2);
while (result2.state.runState !== "FINISHED") {
setTimeout(async () => {
result2 = await fetchPromise(finishJobURL, options2);
}, 500);
}
const jsonRes = JSON.parse(result2.messages.result);
document.getElementById("responseArea").textContent =
jsonRes["computegeodesicarea-totalArea"];
document.getElementById("responseNum").textContent =
jsonRes["computegeodesicarea-totalArea"];
}
});
</script>
</body>
</html>