ArcGIS SOE开发

2023-11-06 00:30
文章标签 arcgis 开发 soe

本文主要是介绍ArcGIS SOE开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一般情况下,一个ArcGIS Engine 工程师转向Web端开发,如果没有相关的web思想,很难转换这个角色,但是如果你有ArcGIS Engine的开发经验,势必会对Web API的开发有很大的帮助,至少今天的主题需要你有ArcGIS Engine开发的经验。


Web API 已经提供了足够多个功能供开发者去完善相关的业务功能,特别是GP Service的加入,让Web API在分析方面如虎添翼,但是不可否认,Web技术由于受到网络的限制,浏览器的限制,一些大数据量的分析可能让Web开发者比较挠头,而且如果想实现目前WebAPI还没有提供的功能,基本上无路可走,但是幸好,我们可以使用ArcObject的资源来完善我们的Web应用,也就是ArcGIS for Server的SOE的扩展。

------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

建议看到转载,请直接访问正版链接获得最新的ArcGIS技术文章

Blog:               http://blog.csdn.net/linghe301 

------------------------------------------------------------------


参考文档

ArcGIS for Server的SOE扩展:http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/#/What_is_a_server_object_extension/0001000000zv000000/


关于GP和SOE 的对比问题

这方面不是本博客的主题,但是有必要简单给大家进行说明一下:

  • GP适合复杂业务流程,较低并发下的应用 
  • SOE适合单一功能的模块,较高并发下的应用


SOE开发环境

ArcObject10.1、VS2010(AO支持的版本)、ArcGIS10.1 for Server、ArcSDE10.1、ArcGIS for JS 3.9


开发目的

一个地图服务,该地图服务包含一个subway的点图层,该图层有一个name字段,存储相关的地铁站名称,比如东直门站、北京站,使用一个查询条件获得某一个点要素,然后再进行缓冲区(半径1000),然后进行叠加分析,获得该缓冲区下所有的地铁站要素信息,在web端进行渲染。

当然该需求不管通过ArcGIS for JS基础API或者GP Service都可以实现,但是本次主题的目的就是通过这个例子来了解一下ArcGIS for Server的SOE扩展的开发流程。


开发思路

1:首先我们需要进行核心需求的ArcObject代码编程实现,也就是获得要素类对象,然后根据用户提供的属性条件过滤,获得相关要素,然后进行buffer,然后再对该要素类进行空间查询获得符合条件的数据,其实这个熟悉AO开发的是一个非常简单的功能,但是如果希望进行SOE扩展就需要了解SOE开发的相关问题


2:在VS上创建SOE程序,系统会自动生成一个相关模板,我们以开放REST为例



生成完毕之后,我们就可以看到相关的模板代码。


为了便于用户了解SOE的生命周期和对应接口,我觉得先给大家介绍SOE的部署和调试,如果我们会使用调试,那么我们就可以根据相关模板代码,一步步的进行了解SOE是怎样一个相关原理。

------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

建议看到转载,请直接访问正版链接获得最新的ArcGIS技术文章

Blog:               http://blog.csdn.net/linghe301 

------------------------------------------------------------------


SOE部署

我们生成了相关的SOE版本,在ArcGIS 10.2版本,支持了影像服务的扩展,所以在我们需要在模板里面输入支持地图服务还是影像服务。如下所示“MapServer”。

 [ServerObjectExtension("MapServer",AllCapabilities = "",DefaultCapabilities = "",Description = "",DisplayName = "RestSOE2",Properties = "",SupportsREST = true,SupportsSOAP = false)]

我们需要在初始化函数Init里面添加如下代码,才能进入调试状态

 public void Init(IServerObjectHelper pSOH){//生命周期开始时调试System.Diagnostics.Debugger.Launch();serverObjectHelper = pSOH;}

生成解决方案,在bin目录下可以看到以.soe后缀名的文件。

PS:该.soe后缀的文件可以将.soe名称修改为.zip,那么用户可以看到相关dll以及元数据xml文件信息。


打开Manger,点击site选项,在GIS Server页选择Extensions



然后再Services选项中,选择某个服务比如JS 地图服务,在该服务的Capablities选择新的RestSOE2扩展,然后保存和重新启动服务即可。


------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

建议看到转载,请直接访问正版链接获得最新的ArcGIS技术文章

Blog:               http://blog.csdn.net/linghe301 

------------------------------------------------------------------


SOE调试

如果前面在init函数中已经添加了调试代码,那么在该服务重启过程中就会弹出如下对话框


选择相应的SOE 程序点击是,那么系统就会进入调试状态



掌握了SOE的调试,用户可以跟踪相关的调试顺序,了解SOE的具体执行步骤。


注意:

1:我的VS、AO、ArcGIS  Server都在同一个环境下,相关调试没有问题,但是如果VS和Server不再一台机器上,调用调试可能会有问题,咨询相关人员回答在不同环境下是可以调试的,但是我并没有解决。

2:因为64Bit的关系,代码不能像C#+ArcGIS Engine 开发可以实时修改代码进行调试

3:SOE的代码如果需要修改,停止调试,然后修改代码,然后重新生成SOE,然后删除manager的扩展项,然后添加新修改的soe文件,然后再针对某个服务添加扩展重新启动服务,这个就比较麻烦,建议现在纯AO环境下进行调试,这样会减少比较多的麻烦。

------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

建议看到转载,请直接访问正版链接获得最新的ArcGIS技术文章

Blog:               http://blog.csdn.net/linghe301 

------------------------------------------------------------------


SOE生命周期

通过跟踪代码,我们可以了解SOE的生命周期,建议用户还需要提前查看相关帮助

===========在添加扩展SOE服务的重启过程============

1:MapServer初始化

2:SOE初始化

 public void Init(IServerObjectHelper pSOH){System.Diagnostics.Debugger.Launch();serverObjectHelper = pSOH;}

3:MapServer启动

4:SOE构造

public void Construct(IPropertySet props){configProps = props;}

===============生成相关的SOE服务连接,点击该连接=====


5:SOE活动——REST/SOAP处理请求——SOE停止活动

这是一个相关循环的过程。

在点击链接时会创建Schema

 public string GetSchema(){return reqHandler.GetSchema();}


然后进行REST/SOAP处理请求

 public byte[] HandleRESTRequest(string Capabilities, string resourceName, string operationName, string operationInput, string outputFormat, string requestProperties, out string responseProperties){return reqHandler.HandleRESTRequest(Capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, out responseProperties);}

请求完毕之后,创建Root资源,也就是可以看到的SOE介绍信息

  private byte[] RootResHandler(NameValueCollection boundVariables, string outputFormat, string requestProperties, out string responseProperties){responseProperties = null;JsonObject result = new JsonObject();result.AddString("hello", "world");return Encoding.UTF8.GetBytes(result.ToJson());}

点击相关的sampleOperation函数,我们输入相关参数值,点击GET请求


我们可以看到系统还会进行REST/SOAP请求,然后进入相关的主体函数中,核心的代码应该在该函数中编写即可

 private byte[] SampleOperHandler(NameValueCollection boundVariables,JsonObject operationInput,string outputFormat,string requestProperties,out string responseProperties){responseProperties = null;string parm1Value;bool found = operationInput.TryGetString("parm1", out parm1Value);if (!found || string.IsNullOrEmpty(parm1Value))throw new ArgumentNullException("parm1");string parm2Value;found = operationInput.TryGetString("parm2", out parm2Value);if (!found || string.IsNullOrEmpty(parm2Value))throw new ArgumentNullException("parm2");JsonObject result = new JsonObject();result.AddString("parm1", parm1Value);result.AddString("parm2", parm2Value);return Encoding.UTF8.GetBytes(result.ToJson());}

6:MapServer停止

7:SOE关闭

  public void Shutdown(){}
关闭之后需要用户释放相关的对象资源。

------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

建议看到转载,请直接访问正版链接获得最新的ArcGIS技术文章

Blog:               http://blog.csdn.net/linghe301 

------------------------------------------------------------------


关于Schema

一般情况下,我们实现一个功能都会需要输入相关参数,和参与该功能的图层或者字段等,那么我们将Schema称之为SOE中的资源和操作的层次结构,资源(resource)就是从服务器端返回的信息块,比如图层列表、缓存服务的比例尺级别,如果这次实验用的的图层名称subway,字段名称name,操作(operations)就是让服务器资源做的一些事情,比如我们设置的where条件以及缓冲区bufferRedius等

 private RestResource CreateRestSchema(){RestResource rootRes = new RestResource(soe_name, false, RootResHandler);RestOperation sampleOper = new RestOperation("QueryBuffer",new string[] { "WhereClause", "BufferRadius" },new string[] { "json" },DoQueryBuffer);rootRes.operations.Add(sampleOper);RestResource propertiesResource = new RestResource("properties", false, PropertiesResHandler);rootRes.resources.Add(propertiesResource);return rootRes;}


关于SOE的处理流程

1:客户端请求参数,请求参数反序列化


2:SOE业务逻辑实现处理

3:结果序列化


关于参数的序列化或者反序列化,都使用了ESRI.ArcGIS.SOESupport;

序列化             反序列化

我个人觉得一句话总结,一切皆JSON。最终返回的结果都是JSON格式即可。

比如本次主题的目的就是查询出来符合条件和缓冲区面积的点要素几何,那么我们需要获得这些相关Geometry对象的JSON格式的集合即可。

 private byte[] GetResultJson(List<IFeature> pList){List<JsonObject> pJoList = null;if (pList!=null){IFeature pfea = null;pJoList = new List<JsonObject>();for (int i = 1; i < pList.Count; i++){pfea = pList[i];pJoList.Add(Conversion.ToJsonObject(pfea.ShapeCopy));}}JsonObject resultJson = new JsonObject();resultJson.AddArray("geometries", pJoList.ToArray());byte[] result = Encoding.UTF8.GetBytes(resultJson.ToJson());return result;}

关于获取数据源信息

SOE开发与AO开发不一样的地方,AO可以直接获得SDE连接对象,然后打开获得相关的IFeatureClass对象等,那么SOE跟这个不太一样,它需要通过服务来获得对象,主要关注IMapServerDataAccess获得相关的MSD数据,有两个功能可以使用



一般情况下使用GetDataSource,那么如果有关联关系的可以使用GetDisplayDataSouce。

 //获取数据              IMapServer3 mapServer = (IMapServer3)serverObjectHelper.ServerObject;IMapLayerInfo layerInfo;IMapLayerInfos layerInfos = mapServer.GetServerInfo(mapServer.DefaultMapName).MapLayerInfos;// 获取查询图层idint layercount = layerInfos.Count;int layerIndex = 0;string sName = "";for (int i = 0; i < layercount; i++){layerInfo = layerInfos.get_Element(i);//默认的oracle数据库的sde用户,查询出来的layerInfo.Name为sde.subway所以需要去掉sde.信息sName=layerInfo.Name;if (sName != ""){sName= sName.Substring(sName.IndexOf(".") + 1, (sName.Length - sName.IndexOf(".")) - 1).Trim();}if (sName == m_LayerName){layerIndex = i;break;}}IMapServerDataAccess dataAccess = (IMapServerDataAccess)mapServer;this.m_FeatureClass = (IFeatureClass)dataAccess.GetDataSource(mapServer.DefaultMapName, layerIndex);

------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

建议看到转载,请直接访问正版链接获得最新的ArcGIS技术文章

Blog:               http://blog.csdn.net/linghe301 

------------------------------------------------------------------


相关SOE源代码


<pre code_snippet_="" snippet_file_name="blog_20140813_13_1641120" name="code" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; padding: 9.5px; margin-top: 0px; margin-bottom: 10px; line-height: 1.42857; word-break: break-all; word-wrap: break-word; border: 1px solid rgb(204, 204, 204); border-radius: 4px; background-color: rgb(245, 245, 245);">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;using System.Collections.Specialized;using System.Runtime.InteropServices;using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Server;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.SOESupport;//TODO: sign the project (project properties > signing tab > sign the assembly)
//      this is strongly suggested if the dll will be registered using regasm.exe <your>.dll /codebasenamespace RestSOE1
{[ComVisible(true)][Guid("99611947-9d7d-4f6f-a4c4-d835ce4a7fa5")][ClassInterface(ClassInterfaceType.None)][ServerObjectExtension("MapServer",//use "MapServer" if SOE extends a Map service and "ImageServer" if it extends an Image service.AllCapabilities = "",DefaultCapabilities = "",Description = "Query Buffer SOE",DisplayName = "RestSOE1",Properties = "Field_Name=name;Layer_Name=subway",SupportsREST = true,SupportsSOAP = false)]public class RestSOE1 : IServerObjectExtension, IObjectConstruct, IRESTRequestHandler{private string soe_name;private IPropertySet configProps;private IServerObjectHelper serverObjectHelper;private ServerLogger logger;private IRESTRequestHandler reqHandler;private IFeatureClass m_FeatureClass = null;//查询图层名称private string m_LayerName = "";//查询字段名称private string m_FieldName = "";public RestSOE1(){soe_name = this.GetType().Name;logger = new ServerLogger();reqHandler = new SoeRestImpl(soe_name, CreateRestSchema()) as IRESTRequestHandler;}#region IServerObjectExtension Memberspublic void Init(IServerObjectHelper pSOH){//生命周期开始时调试System.Diagnostics.Debugger.Launch();serverObjectHelper = pSOH;}public void Shutdown(){this.soe_name = null;this.m_FeatureClass = null;this.logger = null;this.m_FieldName = null;this.m_LayerName = null;this.serverObjectHelper = null;this.configProps = null;this.reqHandler = null;}#endregion#region IObjectConstruct Memberspublic void Construct(IPropertySet props){configProps = props;if (props.GetProperty("Field_Name") != null){this.m_FieldName = props.GetProperty("Field_Name") as string;}else {throw new ArgumentNullException();}if (props.GetProperty("Layer_Name") != null){this.m_LayerName = props.GetProperty("Layer_Name") as string;}else{throw new ArgumentNullException();}try{//获取数据              IMapServer3 mapServer = (IMapServer3)serverObjectHelper.ServerObject;IMapLayerInfo layerInfo;IMapLayerInfos layerInfos = mapServer.GetServerInfo(mapServer.DefaultMapName).MapLayerInfos;// 获取查询图层idint layercount = layerInfos.Count;int layerIndex = 0;string sName = "";for (int i = 0; i < layercount; i++){layerInfo = layerInfos.get_Element(i);//默认的oracle数据库的sde用户,查询出来的layerInfo.Name为sde.subway所以需要去掉sde.信息sName=layerInfo.Name;if (sName != ""){sName= sName.Substring(sName.IndexOf(".") + 1, (sName.Length - sName.IndexOf(".")) - 1).Trim();}if (sName == m_LayerName){layerIndex = i;break;}}IMapServerDataAccess dataAccess = (IMapServerDataAccess)mapServer;this.m_FeatureClass = (IFeatureClass)dataAccess.GetDataSource(mapServer.DefaultMapName, layerIndex);if (this.m_FeatureClass == null){logger.LogMessage(ServerLogger.msgType.error, "Construct", 8000, "SOE custom error: Layer name not found.");return;}if (this.m_FeatureClass.FindField(this.m_FieldName) == -1){logger.LogMessage(ServerLogger.msgType.error, "Construct", 8000, "SOE custom error: Field not found in layer.");}}catch (Exception e){ }}#endregion#region IRESTRequestHandler Memberspublic string GetSchema(){return reqHandler.GetSchema();}public byte[] HandleRESTRequest(string Capabilities, string resourceName, string operationName, string operationInput, string outputFormat, string requestProperties, out string responseProperties){return reqHandler.HandleRESTRequest(Capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, out responseProperties);}#endregionprivate RestResource CreateRestSchema(){RestResource rootRes = new RestResource(soe_name, false, RootResHandler);RestOperation sampleOper = new RestOperation("QueryBuffer",new string[] { "WhereClause", "BufferRadius" },new string[] { "json" },DoQueryBuffer);rootRes.operations.Add(sampleOper);RestResource propertiesResource = new RestResource("properties", false, PropertiesResHandler);rootRes.resources.Add(propertiesResource);return rootRes;}private byte[] PropertiesResHandler(NameValueCollection boundVariables, string outputFormat, string requestProperties, out string responseProperties){responseProperties = "{\"Content-Type\" : \"application/json\"}";JsonObject result = new JsonObject();result.AddString("Field_Name", this.m_FieldName);result.AddString("Layer_Name", this.m_LayerName);return Encoding.UTF8.GetBytes(result.ToJson());}private byte[] RootResHandler(NameValueCollection boundVariables, string outputFormat, string requestProperties, out string responseProperties){responseProperties = null;JsonObject result = new JsonObject();result.AddString("名称", "查询缓冲Soe");result.AddString("描述", "通过属性查询条件,获得一个点要素,然后再做缓冲区");result.AddString("方法", "条件过滤加上缓冲区");return Encoding.UTF8.GetBytes(result.ToJson());}private byte[] DoQueryBuffer(NameValueCollection boundVariables,JsonObject operationInput,string outputFormat,string requestProperties,out string responseProperties){responseProperties = null;string WhereClause;bool found = operationInput.TryGetString("WhereClause", out WhereClause);if (!found || string.IsNullOrEmpty(WhereClause))throw new ArgumentNullException("WhereClause");double? BufferRadius;found = operationInput.TryGetAsDouble("BufferRadius", out BufferRadius);if (!found || !BufferRadius.HasValue)throw new ArgumentNullException("BufferRadius");List<IFeature> pList = GetQueryBufferGeometryList(this.m_FieldName, WhereClause, BufferRadius);return GetResultJson(pList);}private IGeometry GetQueryBufferGeometry(string sFieldName, IFeatureClass pfc,string sWhereClause, object sBufferRadius){IGeometry pGeo = null;IQueryFilter qf = new QueryFilterClass();//这里只测试字符串查询,其他类型不再进行逻辑检查和编写string sWhere=sFieldName+"='"+sWhereClause+"'";qf.WhereClause = sWhere;IFeatureCursor pCur= pfc.Search(qf, true);IFeature pFea = pCur.NextFeature();ITopologicalOperator pTO = null; while (pFea != null){pTO = pFea.ShapeCopy as ITopologicalOperator;pGeo = pTO.Buffer(Convert.ToDouble(sBufferRadius));pFea = pCur.NextFeature();}return pGeo;}private List<IFeature> GetQueryBufferGeometryList(string sFieldName, string sWhereClause, object sBufferRadius){List<IFeature> pFeatureList = new List<IFeature>();IQueryFilter qf = new QueryFilterClass();//这里只测试字符串查询,其他类型不再进行逻辑检查和编写string sWhere = sFieldName + "='" + sWhereClause + "'";qf.WhereClause = sWhere;IFeatureCursor pCur = this.m_FeatureClass.Search(qf, false);IFeature pFea = pCur.NextFeature();ITopologicalOperator pTO = null;IGeometry pBufferGeo = null;while (pFea != null){pTO = pFea.ShapeCopy as ITopologicalOperator;pBufferGeo = pTO.Buffer(Convert.ToDouble(sBufferRadius));pFea = pCur.NextFeature();}ISpatialFilter sf = new SpatialFilterClass();sf.Geometry = pBufferGeo;sf.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;sf.GeometryField = this.m_FeatureClass.ShapeFieldName;ISpatialReference sr=(this.m_FeatureClass as IGeoDataset).SpatialReference;sf.set_OutputSpatialReference(this.m_FeatureClass.ShapeFieldName, sr);IFeatureCursor pFCur = this.m_FeatureClass.Search(sf, false);while ((pFea = pFCur.NextFeature()) != null){pFeatureList.Add(pFea);}return pFeatureList;}private byte[] GetResultJson(List<IFeature> pList){List<JsonObject> pJoList = null;if (pList!=null){IFeature pfea = null;pJoList = new List<JsonObject>();for (int i = 1; i < pList.Count; i++){pfea = pList[i];pJoList.Add(Conversion.ToJsonObject(pfea.ShapeCopy));}}JsonObject resultJson = new JsonObject();resultJson.AddArray("geometries", pJoList.ToArray());byte[] result = Encoding.UTF8.GetBytes(resultJson.ToJson());return result;}}
}

 

很久不写Engine代码了,连很简单的东西都忘记的差不多了。我们可以通过前面介绍的调试方法,测试是否可以获得正确的结果?


------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

建议看到转载,请直接访问正版链接获得最新的ArcGIS技术文章

Blog:               http://blog.csdn.net/linghe301 

------------------------------------------------------------------


ArcGIS for JS 调用SOE服务


关于ArcGIS for JS调用SOE 服务主要使用了如下代码:

  var WhereClause = dom.byId("WhereClause").value;var BufferRadius = dom.byId("BufferRadius").value;var content = {'WhereClause': WhereClause,'BufferRadius': BufferRadius,'f': "json"};var Request = esriRequest({url: soeUrl,content: content,handleAs: "json",callbackParamName: "callback"});Request.then(function (responses) {...........});

使用esriRequest,传入soe的REST,然后将属性参数传入(content),然后对请求进行枚举查询,由于我们SOE获得的结果是查询的IGeometry的Array,那么执行对返回结果进行循环获得,然后将相关结果作为一个graphic添加到map即可。


ArcGIS for JS调用SOE 源代码如下

<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>Simple Map</title><link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_v39_api/arcgis_js_api/library/3.9/3.9/js/dojo/dijit/themes/tundra/tundra.css" /><link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_v39_api/arcgis_js_api/library/3.9/3.9/js/esri/css/esri.css" /><script type="text/javascript" src="http://localhost/arcgis_js_v39_api/arcgis_js_api/library/3.9/3.9"> </script><script type="text/javascript" src="jsapi_vsdoc_v32_2012.js"></script><style>html, body, #mapDiv {padding: 0;margin: 0;height: 100%;}#messages {background-color: #fff;box-shadow: 0 0 5px #888;;top: 300px;z-index: 40;}</style><script>var map;require(["esri/map", "esri/layers/FeatureLayer","esri/layers/ArcGISDynamicMapServiceLayer","esri/request","esri/graphic", "esri/symbols/SimpleMarkerSymbol","esri/geometry/Point","esri/SpatialReference","esri/config", "esri/Color", "dojo/_base/array", "dojo/on", "dojo/dom", "dojo/domReady!"], function (Map, FeatureLayer, ArcGISDynamicMapServiceLayer,esriRequest,Graphic, SimpleMarkerSymbol,Point,SpatialReference,esriConfig, Color,arrayUtils,on, dom) {// use a proxy page if a URL generated by this page is greater than 2000 characters//// this should not be needed as nearly all query & select functions are performed on the clientesriConfig.defaults.io.proxyUrl = "/proxy";map = new Map("mapDiv", {});var mapUrl = "http://192.168.220.125:6080/arcgis/rest/services/JS/MapServer";var soeUrl = "http://192.168.220.125:6080/arcgis/rest/services/JS/MapServer/exts/RestSOE1/QueryBuffer";//Takes a URL to a non cached map service.var dynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer(mapUrl);map.addLayer(dynamicMapServiceLayer);on(dom.byId("execute"), "click", function () {var WhereClause = dom.byId("WhereClause").value;var BufferRadius = dom.byId("BufferRadius").value;var content = {'WhereClause': WhereClause,'BufferRadius': BufferRadius,'f': "json"};var Request = esriRequest({url: soeUrl,content: content,handleAs: "json",callbackParamName: "callback"});Request.then(function (responses) {map.graphics.clear();var markerSymbol = new SimpleMarkerSymbol();markerSymbol.setPath("M16,4.938c-7.732,0-14,4.701-14,10.5c0,1.981,0.741,3.833,2.016,5.414L2,25.272l5.613-1.44c2.339,1.316,5.237,2.106,8.387,2.106c7.732,0,14-4.701,14-10.5S23.732,4.938,16,4.938zM16.868,21.375h-1.969v-1.889h1.969V21.375zM16.772,18.094h-1.777l-0.176-8.083h2.113L16.772,18.094z");markerSymbol.setColor(new Color("#00FFFF"));markerSymbol.setSize(30);markerSymbol.setOffset(20, 10);var wgs = new SpatialReference({"wkid": 102100});for (var i = 0; i < responses.geometries.length; i++) {var pt = new Point(responses.geometries[i].x, responses.geometries[i].y, wgs);var graphic = new Graphic(pt, markerSymbol);map.graphics.add(graphic);}});});});</script></head><body>查询条件<input type="text" id="WhereClause" value="北京站">缓冲区半径<input type="text" id="BufferRadius" value="1500"><input id="execute" type="button" value="执行查询"><div id="mapDiv"></div></body>
</html>

获得的查询页面和结果如下

ArcGIS for Server的SOE开发思路解析

------------------------------------------------------------------

版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!

建议看到转载,请直接访问正版链接获得最新的ArcGIS技术文章

Blog:               http://blog.csdn.net/linghe301 

------------------------------------------------------------------


感谢@JMB同学的资料支持

这篇关于ArcGIS SOE开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/353428

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

v0.dev快速开发

探索v0.dev:次世代开发者之利器 今之技艺日新月异,开发者之工具亦随之进步不辍。v0.dev者,新兴之开发者利器也,迅速引起众多开发者之瞩目。本文将引汝探究v0.dev之基本功能与优势,助汝速速上手,提升开发之效率。 何谓v0.dev? v0.dev者,现代化之开发者工具也,旨在简化并加速软件开发之过程。其集多种功能于一体,助开发者高效编写、测试及部署代码。无论汝为前端开发者、后端开发者

pico2 开发环境搭建-基于ubuntu

pico2 开发环境搭建-基于ubuntu 安装编译工具链下载sdk 和example编译example 安装编译工具链 sudo apt install cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib 注意cmake的版本,需要在3.17 以上 下载sdk 和ex