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

相关文章

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

基于Python开发批量提取Excel图片的小工具

《基于Python开发批量提取Excel图片的小工具》这篇文章主要为大家详细介绍了如何使用Python中的openpyxl库开发一个小工具,可以实现批量提取Excel图片,有需要的小伙伴可以参考一下... 目前有一个需求,就是批量读取当前目录下所有文件夹里的Excel文件,去获取出Excel文件中的图片,并

基于Python开发PDF转PNG的可视化工具

《基于Python开发PDF转PNG的可视化工具》在数字文档处理领域,PDF到图像格式的转换是常见需求,本文介绍如何利用Python的PyMuPDF库和Tkinter框架开发一个带图形界面的PDF转P... 目录一、引言二、功能特性三、技术架构1. 技术栈组成2. 系统架构javascript设计3.效果图

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T