GP服务的使用详解
2022/3/27 23:23:06
本文主要是介绍GP服务的使用详解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
最近公司需要开发在线的WebGIS工具实现插值等功能,经过我的一番瞎几把研究,我发现目前只有ArcGIS Server发布GP工具可以实现这点(ps:应该是有其他的在线js可以用,只是我没发现)。于是乎就盯着GP服务去了,我为了完成这个功能,我在网上翻遍了博客和论坛,找到的有用的信息实在是太少太少,只能自己琢磨。上一篇已经把插值的代码贴出来了,这次我想把个人心得和另一个GP工具也分享一下。
废话不多说,开始正题:
GP工具:它是由ArcMap等桌面的GIS应用生成的,生成的方式是使用模型构建器将需要的工具和参数拖进去,然后把工具和参数进行关联,最后生成一个流程图。将流程图进行验证,如果成功了就可以进行发布,发布后就是GP工具了。
GP工具的具体制作过程就不赘述了,网上有着相关的教程。
GP工具流程截图
在制作GP工具的时候有几个细节要注意,如果使用插值等工具,需要将插值范围给限定出来--右击IDW选择属性--选择处理范围
--选择你的矢量边界,这样他处理就以边界形状执行;还有要说的就是栅格计算器,在使用时需要注意值的选择,以及公式的使用(我发现数的次方和float类型的数不能相乘,会报错),GP工具在ArcGIS中能正常执行的话,基本上就没有什么问题,最后将需要的参数选为P就行。我这里的点数据是shp格式。
GP工具发布成功也就是成功了一半,剩下最难的就是如何在客户端调用GP工具进行值的传入和结果的返回。
开始上代码:
头文件的引用:
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" /> <script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script> <script src="https://unpkg.com/esri-leaflet@2.2.1/dist/esri-leaflet.js" ></script> <script src="js/JZGEOJson.js"></script>//边界数据 <script SRC="js/leaflet.ChineseTmsProviders.js"></script>//地图数据 <link rel="stylesheet" href="https://js.arcgis.com/3.17/esri/css/esri.css"> <script src="https://js.arcgis.com/3.17/"></script> <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
我使用的是lealeaflet的开源js加上arcgis api for js,刚开始以为两个不通用,后来发现竟然是一家的东西,好吧果然是相爱一家亲。
地图加载部分js:
/** * 智图地图内容 */ var normalm1 = L.tileLayer.chinaProvider('Geoq.Normal.Map', { maxZoom: 18, minZoom: 5 }); var normalm2 = L.tileLayer.chinaProvider('Geoq.Normal.Color', { maxZoom: 18, minZoom: 5 }); var normalm3 = L.tileLayer.chinaProvider('Geoq.Normal.PurplishBlue', { maxZoom: 18, minZoom: 5 }); var normalm4 = L.tileLayer.chinaProvider('Geoq.Normal.Gray', { maxZoom: 18, minZoom: 5 }); var normalm5 = L.tileLayer.chinaProvider('Geoq.Normal.Warm', { maxZoom: 18, minZoom: 5 }); var normalm6 = L.tileLayer.chinaProvider('Geoq.Normal.Cold', { maxZoom: 18, minZoom: 5 }); /** * 天地图内容 */ var normalm = L.tileLayer.chinaProvider('TianDiTu.Normal.Map', { maxZoom: 18, minZoom: 5 }), normala = L.tileLayer.chinaProvider('TianDiTu.Normal.Annotion', { maxZoom: 18, minZoom: 5 }), imgm = L.tileLayer.chinaProvider('TianDiTu.Satellite.Map', { maxZoom: 18, minZoom: 5 }), imga = L.tileLayer.chinaProvider('TianDiTu.Satellite.Annotion', { maxZoom: 18, minZoom: 5 }); var normal = L.layerGroup([normalm, normala]), image = L.layerGroup([imgm, imga]); /** * 谷歌 */ var normalMap = L.tileLayer.chinaProvider('Google.Normal.Map', { maxZoom: 18, minZoom: 5 }), satelliteMap = L.tileLayer.chinaProvider('Google.Satellite.Map', { maxZoom: 18, minZoom: 5 }); /** * 高德地图 */ var Gaode = L.tileLayer.chinaProvider('GaoDe.Normal.Map', { maxZoom: 18, minZoom: 5 }); var Gaodimgem = L.tileLayer.chinaProvider('GaoDe.Satellite.Map', { maxZoom: 18, minZoom: 5 }); var Gaodimga = L.tileLayer.chinaProvider('GaoDe.Satellite.Annotion', { maxZoom: 18, minZoom: 5 }); var Gaodimage = L.layerGroup([Gaodimgem, Gaodimga]); var baseLayers = { "智图地图": normalm1, "智图多彩": normalm2, "智图午夜蓝": normalm3, "智图灰色": normalm4, "智图暖色": normalm5, "智图冷色": normalm6, "天地图": normal, "天地图影像": image, "谷歌地图": normalMap, "谷歌影像": satelliteMap, "高德地图": Gaode, "高德影像": Gaodimage, } var map = L.map("map", { center: [31.5, 115.9], zoom: 11, layers: [image], zoomControl: false }) L.control.layers(baseLayers, null).addTo(map); L.control.zoom({ zoomInTitle: '放大', zoomOutTitle: '缩小' }).addTo(map); //加载镇级地图 var JZmap= L.geoJson(statesData, { style: function (feature) { switch (feature.properties.name) { //case '关庙乡': return { color: "#0000ff" }; default: return { color: "#ff0000" }; } } }).addTo(map);
这里实现了可更换地图的功能
接下来是重头戏:实现GP工具的代码
/** * 调用GP服务 */ var gpUrl = "http://localhost:6080/arcgis/rest/services/JZtext/CZTR/GPServer/CZTR";//定义GP工具的url var mapServer="http://localhost:6080/arcgis/rest/services/JZtext/CZTR/MapServer";//该URL需要在ArcGIS server中使用异步的执行模式开启含查看地图服务的结果,位置在该服务的参数中 map.on("click", function (e) { var query = new esri.tasks.Query();//定义查询对象 //采样点查询地址 var queryTask = new esri.tasks.QueryTask("http://localhost:6080/arcgis/rest/services/JZtext/30points/MapServer/0"); //返回几何对象 query.returnGeometry = true; //判断条件,必须,一般选择FID >-1即可 query.where = "FID >-1"; //查询出来的字段,用于插值的,要保证是数字类型 query.outFields = ["有效磷"]; //查询出来的时候空间参考定义 query.outSpatialReference = { "wkid": 4326 }; //执行采样点查询方法,query是参数,function是成功后调用的方法 //alert(query); queryTask.execute(query, function (fs) { //将返回的几何点数据传输给featureSet //将数据的格式转换为json var featureSet = JSON.stringify(fs); //创建GP服务的参数 var params = { points: featureSet, //Points是GP的输入参数名称,要和GP服务一直 pointvalue: 10,//插值的字段,名称要和GP一致 }; submitJob1(params);//改函数为异步执行函数,用于执行长时间的服务 }) }) //GP服务调用 function submitJob1(params) { //使用post的方法向GP服务送请求,并将数据传入进去 /** * async. 默认是true,即为异步方式,如果是false这个ajax请求为同步请求,success之后打印日志。 * cache:true 如果当前请求有缓存的话,直接使用缓存。如果该属性设置为 false,则每次都会向服务器请求 */ //由该GP工具每次请求生成的结果都有一个新的文件,所以不使用缓存,以下是ajax的常用请求结果 $.ajax({ type: 'POST', cache: false, url: gpUrl+'/submitJob?f=json',//异步请求的样式 dataType: 'json', async: true, data: params, success: function (result) { var jobId = result.jobId; //alert(jobId); if (jobId) {//jobId是ArcGIS给添加上去的工作编号,每次向服务器发送请求的时候就会生成 Getresult1(jobId);//获取结果 } } }); } //获取结果 function Getresult1(jobId) {//将jobId传入方法 //alert(22); $.ajax({ type: "POST", cache: false, url: gpUrl + "/jobs/" + jobId + "?f=json",//判断是否生成结果 async: true, success: function (result1) { result1 = eval("(" + result1 + ")"); if (result1.jobStatus === "esriJobSucceeded") {//如果发送请求后的返回值的状态为esriJobSucceeded,说明已经完成操作并生成了结果 showResult1(jobId);//展示结果 } else { Getresult1(jobId); } } }); } //展示地图结果 function showResult1(jobId) { alert("运算成功!进行渲染"); var mapurl = mapServer + "/jobs/" + jobId;//这里是结果所放置的位置 var envLayer = new L.esri.dynamicMapLayer({ url: mapurl, opacity: 0.75, useCors: false });//新建动态图层 map.addLayer(envLayer);//加入地图 var lenUrl=mapurl+"/legend?f=pjson";//图例的URL GetLegend(lenUrl);//加载图例 } function GetLegend(LengendUrl) { $.ajax({ type: "POST", cache: false, url: LengendUrl, async: true, success: function (result1) { //字符串转换为数组 result1 = eval("(" + result1 + ")"); //使用拼接的方法,将图片和数值放入div中 var hmts = '<div class="Lenged" style="z-index: 1000; position: absolute; bottom: 2px; float: right; right: 2px; width: 120px; border: 1px solid #C0C0C0; font-size: 12px; font-weight: 600; border-radius: 3px; background-color: white; opacity: 1; margin-right: 20px; padding: 10px">'; //添加图片注释 for (var i = 0; i < result1.layers["0"].legend.length; i++) { //图片 var image ="data:image/png;base64," +result1.layers["0"].legend[i].imageData; //标注 var label = result1.layers["0"].legend[i].label hmts += "<div><img src=" + image + " height='20' width='20' /> " + label + "</div>" } hmts += '</div>'; //定义控件 var legend = L.control({ position: 'bottomright' });//将图例的位置放置在右下角 //对图例进行判断,如果已经存在,将先移除之前的图例,避免图上出现多个图例 if ($(".info_legend_div").length > 0) { $(".info_legend_div").remove(); } legend.onAdd = function (map) { var div = L.DomUtil.create('div', 'info_legend_div');//给div赋info_legend_div属性 div.innerHTML += hmts; return div; }; legend.addTo(map);//将legend添加进地图 } }) }
注释我已经写得非常详细了,就不多解释。
我想说一下关于GP传值的问题,我们虽然生成好了GP工具,但我们还需要去知道需要给GP工具传什么参数才是有效值,我使用的json和post的方法。想要验证GP的输入值是否有效可以使用GP工具自带的submitJob来进行测试,将你的数据格式放入其中然后验证其是否正确,如果正确的话会有返回值的。
如果你取到的数据在这里可以正常得到结果,那就是没有问题的,你可以放心大胆的在web端使用。
在进行web端的传值调试时,我走了不少弯路,最后在前辈的帮助下完成了该功能,我得好好去学会ajax和json。
最后奉上几个大佬博客传送门,我在其中学到了不少。
动态插值分析:基于ArcGIS API For JavaScript调用GP服务实现动态插值分析实现_特夜歌的博客-CSDN博客_arcgis js 调用gp服务
插值分析结果按指定多边形输出:ARCGIS10.1 插值分析结果按指定多边形输出_symoriaty的博客-CSDN博客
欢迎大家来讨论学习!!!
本文转自 https://jackie-sun.blog.csdn.net/article/details/81501684?spm=1001.2014.3001.5502,如有侵权,请联系删除。
这篇关于GP服务的使用详解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南