ArcGIS 服務對象擴展(SOE)新手自學筆記(5):注冊與調試


  上一篇到現在過去好幾天了,本來打算用ESRI官方自帶的例子呢,后來覺得還是應該實踐一下。這幾天都在忙着寫這個例子,其中也出現了好多問題,從一開始思考解決問題的方法,到找代碼,再調試成功,費了不少事,好在問題都已經解決了。不喜歡說廢話,還是忍不住說了這么多,下面正式進入主題。

  首先說說我們要解決的問題。gp服務廣泛使用的一個原因是他可以做柵格數據的分析,那好我們就用SOE來解決一個插值問題。在gp服務中,我們可以通過設置輸入輸出類型來保客戶端成功加載分析結果,大部分分析結果是以圖片形式傳到客戶端。在SOE中理論上是可以設置輸出圖片形式,但幫助中只是簡單地說了幾句,很不詳細,所以我用的方法是將柵格分類后轉換成矢量數據,再將矢量數據序列化成json格式,傳給客戶端。流圖如下:

  獲取要素類---》插值---》重分類---》柵格轉面---》序列化成json---》客戶端

1.編寫代碼

新建一個工程,命名為Saturation  

首先加入以下引用:

代碼:

View Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 
  6 using System.Collections.Specialized;
  7 
  8 using System.Runtime.InteropServices;
  9 using System.EnterpriseServices;
 10 
 11 using ESRI.ArcGIS.esriSystem;
 12 using ESRI.ArcGIS.Server;
 13 using ESRI.ArcGIS.Geometry;
 14 using ESRI.ArcGIS.Geodatabase;
 15 using ESRI.ArcGIS.Carto;
 16 using ESRI.ArcGIS.SOESupport;
 17 using ESRI.ArcGIS.GeoAnalyst;
 18 using ESRI.ArcGIS.DataSourcesRaster;
 19 
 20 
 21 //TODO: sign the project (project properties > signing tab > sign the assembly)
 22 //      this is strongly suggested if the dll will be registered using regasm.exe <your>.dll /codebase
 23 
 24 
 25 namespace Saturation
 26 {
 27     [ComVisible(true)]
 28     [Guid("f8cb9f88-1dc9-4f34-a0a9-fa931afb8730")]
 29     [ClassInterface(ClassInterfaceType.None)]
 30     public class Saturation : ServicedComponent, IServerObjectExtension, IObjectConstruct, IRESTRequestHandler
 31     {
 32         private string soe_name;
 33 
 34         private IPropertySet configProps;
 35         private IServerObjectHelper serverObjectHelper;
 36         private ServerLogger logger;
 37         private IRESTRequestHandler reqHandler;
 38 
 39         //Member variables
 40         private string m_layerNameToAnalyst = null;
 41         private IFeatureClass m_fcToAnalyst = null;//進行插值的要素類
 42 
 43         public Saturation()
 44         {
 45             soe_name = this.GetType().Name;
 46             logger = new ServerLogger();
 47             reqHandler = new SoeRestImpl(soe_name, CreateRestSchema()) as IRESTRequestHandler;
 48         }
 49 
 50         #region IServerObjectExtension Members
 51 
 52         public void Init(IServerObjectHelper pSOH)
 53         {
 54             serverObjectHelper = pSOH;
 55         }
 56 
 57         public void Shutdown()
 58         {
 59             logger.LogMessage(ServerLogger.msgType.infoStandard, "Shutdown", 8000, "Custom error message: Shutting down the SOE");
 60             soe_name = null;
 61             m_fcToAnalyst = null;
 62             serverObjectHelper = null;
 63             m_layerNameToAnalyst = null;
 64             logger = null;
 65         }
 66 
 67         #endregion
 68 
 69         #region IObjectConstruct Members
 70 
 71         public void Construct(IPropertySet props)
 72         {
 73             logger.LogMessage(ServerLogger.msgType.error, "Construct", 8000, "SOE Construct:start");
 74             configProps = props;
 75             m_layerNameToAnalyst = "testPoint";
 76             //獲得所要分析的FeatureClass
 77             try
 78             {
 79                 IMapServer3 mapServer = serverObjectHelper.ServerObject as IMapServer3;
 80 
 81                 string mapName = mapServer.DefaultMapName;
 82                 IMapLayerInfos layerInfos = mapServer.GetServerInfo(mapName).MapLayerInfos;
 83                 IMapLayerInfo layerInfo = null;
 84 
 85                 //獲得所要分析圖層的index
 86                 int c = layerInfos.Count;
 87                 int layerIndex = 0;
 88                 for (int i = 0; i < c; i++)
 89                 {
 90                     layerInfo = layerInfos.get_Element(i);
 91                     if (layerInfo.Name == m_layerNameToAnalyst)
 92                     {
 93                         layerIndex = i;
 94                         break;
 95                     }
 96                 }
 97 
 98                 //使用IMapServerDataAccess獲取數據
 99                 IMapServerDataAccess dataAccess = mapServer as IMapServerDataAccess;
100                 m_fcToAnalyst = dataAccess.GetDataSource(mapName, layerIndex) as IFeatureClass;
101 
102                 if (m_fcToAnalyst == null)
103                 {
104                     logger.LogMessage(ServerLogger.msgType.error, "Construct", 8000, "SOE custom error: Layer name not found.");
105                     return;
106                 }
107             }
108             catch (Exception es)
109             {
110                 logger.LogMessage(ServerLogger.msgType.error, "Construct", 8000, "SOE custom error: Could not get the feature layer.");
111             }
112         }
113 
114         #endregion
115 
116         #region IRESTRequestHandler Members
117 
118         public string GetSchema()
119         {
120             return reqHandler.GetSchema();
121         }
122 
123         public byte[] HandleRESTRequest(string Capabilities, string resourceName, string operationName, string operationInput, string outputFormat, string requestProperties, out string responseProperties)
124         {
125             return reqHandler.HandleRESTRequest(Capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, out responseProperties);
126         }
127 
128         #endregion
129 
130         private RestResource CreateRestSchema()
131         {
132             RestResource rootRes = new RestResource(soe_name, false, RootResHandler);
133 
134             RestOperation sampleOper = new RestOperation("sampleOperation",
135                                                       new string[] { "field" },
136                                                       new string[] { "json" },
137                                                       SaturationAnalystOpeartionHandler);
138 
139             rootRes.operations.Add(sampleOper);
140 
141             return rootRes;
142         }
143 
144         private byte[] RootResHandler(NameValueCollection boundVariables, string outputFormat, string requestProperties, out string responseProperties)
145         {
146             responseProperties = null;
147 
148             JsonObject result = new JsonObject();
149             //result.AddString("hello", "world");
150 
151             return Encoding.UTF8.GetBytes(result.ToJson());
152         }
153 
154         private byte[] SaturationAnalystOpeartionHandler(NameValueCollection boundVariables,
155                                                   JsonObject operationInput,
156                                                       string outputFormat,
157                                                       string requestProperties,
158                                                   out string responseProperties)
159         {
160             responseProperties = null;
161             //反序列化參數
162             string strField;
163             bool found = operationInput.TryGetString("field", out strField);
164             if (!found || string.IsNullOrEmpty(strField))
165                 throw new ArgumentNullException("field");
166 
167             byte[] result = SaturationAnalyst(strField);
168 
169             return result;
170         }
171 
172         private byte[] SaturationAnalyst(string field)
173         {
174             if (field.Length <= 0)
175             {
176                 throw new ArgumentOutOfRangeException("field");
177             }
178 
179             //插值
180             IRaster krigeRaster = BuildKrigeRaster(m_fcToAnalyst, field);
181             //重分類
182             IRaster reclassRastr = BuildReclassRaster(krigeRaster, 4);
183             //柵格轉面,字段名作為生成的要素名稱
184             IFeatureClass ConPolygon = RasterToPolygon(reclassRastr, field);
185             //將要素類序列化成json格式
186             JsonObject resultJsonObject = FclassToJsonObj(ConPolygon);
187 
188             byte[] result = Encoding.UTF8.GetBytes(resultJsonObject.ToJson());
189             return result;
190 
191         }
192 
193         #region Helper 函數
194         /// <summary>
195         /// 克里金插值
196         /// </summary>
197         /// <param name="inputFclass">插值數據</param>
198         /// <param name="inputField">字段</param>
199         /// <returns></returns>
200         private IRaster BuildKrigeRaster(IFeatureClass inputFclass, string inputField)
201         {
202             if (inputFclass == null)
203             {
204                 logger.LogMessage(ServerLogger.msgType.error, "BuildKrigeRaster", 8000, "SOE custom error: inputFclass is null.");
205                 return null;
206             }
207             if (inputField.Length == 0)
208             {
209                 logger.LogMessage(ServerLogger.msgType.error, "BuildKrigeRaster", 8000, "SOE custom error: inputField is null.");
210                 return null;
211             }
212             
213             //生成IFeatureClassDescriptor
214             IFeatureClassDescriptor pFcDescriptor = new FeatureClassDescriptorClass();
215             pFcDescriptor.Create(inputFclass, null, inputField);
216             //設置分析環境
217             IInterpolationOp pInterpolationOp = new RasterInterpolationOpClass();
218             IRasterAnalysisEnvironment pEnv = pInterpolationOp as IRasterAnalysisEnvironment;
219             object cellSize = 5.80481468000016E-04;
220             pEnv.Reset();//柵格單元大小
221             pEnv.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref cellSize);
222 
223             IRasterRadius pRadius = new RasterRadius();
224             object obj = Type.Missing;//可變搜索半徑
225             pRadius.SetVariable(12, ref obj);
226 
227             IGeoDataset pGeodataset = inputFclass as IGeoDataset;
228             IEnvelope pRasterExt = new EnvelopeClass();
229             pRasterExt.XMin = 117.178625;
230             pRasterExt.XMax = 117.376715;
231             pRasterExt.YMax = 31.922649;
232             pRasterExt.YMin = 31.777529;
233             object extentPro = pRasterExt;//分析范圍
234             pEnv.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref extentPro, ref obj);
235             pEnv.OutSpatialReference = pGeodataset.SpatialReference;
236             //執行差值
237             IGeoDataset pGeoDataset = pInterpolationOp.Krige((IGeoDataset)pFcDescriptor, esriGeoAnalysisSemiVariogramEnum.esriGeoAnalysisLinearSemiVariogram,
238                 pRadius, false, ref obj);
239 
240             return pGeoDataset as IRaster;
241         }
242 
243         /// <summary>
244         /// 對柵格進行等間距重分類
245         /// </summary>
246         /// <param name="inputRaster">待分類柵格</param>
247         /// <param name="pClassNo">分類數</param>
248         /// <returns></returns>
249         private IRaster BuildReclassRaster(IRaster inputRaster, int pClassNo)
250         {
251             if (inputRaster == null)
252             {
253                 logger.LogMessage(ServerLogger.msgType.error, "BuildReclassRaster", 8000, "SOE custom error: inputRaster is null.");
254                 return null;
255             }
256             if (pClassNo <= 0)
257             {
258                 logger.LogMessage(ServerLogger.msgType.error, "BuildReclassRaster", 8000, "SOE custom error: pClassNo is null.");
259                 return null;
260             }
261 
262             //獲取柵格分類數組和頻度數組
263             object dataValues = null, dataCounts = null;
264             GetRasterClass(inputRaster, out dataValues, out dataCounts);
265 
266             //獲取柵格分類間隔數組
267             IClassifyGEN pEqualIntervalClass = new EqualIntervalClass();
268             pEqualIntervalClass.Classify(dataValues, dataCounts, ref pClassNo);
269             double[] breaks = pEqualIntervalClass.ClassBreaks as double[];
270 
271             //設置新分類值
272             INumberRemap pNemRemap = new NumberRemapClass();
273             for (int i = 0; i < breaks.Length - 1; i++)
274             {
275                 pNemRemap.MapRange(breaks[i], breaks[i + 1], i+1);
276             }
277             IRemap pRemap = pNemRemap as IRemap;
278             
279             //設置環境
280             IReclassOp pReclassOp = new RasterReclassOpClass();
281             IGeoDataset pGeodataset = inputRaster as IGeoDataset;
282             IRasterAnalysisEnvironment pEnv = pReclassOp as IRasterAnalysisEnvironment;
283             object obj = Type.Missing;
284 
285             IEnvelope pRasterExt = new EnvelopeClass();
286             pRasterExt.XMin = 117.178625;
287             pRasterExt.XMax = 117.376715;
288             pRasterExt.YMax = 31.922649;
289             pRasterExt.YMin = 31.777529;
290             object extentPro = pRasterExt;//分析范圍
291             pEnv.SetExtent(esriRasterEnvSettingEnum.esriRasterEnvValue, ref extentPro, ref obj);
292             pEnv.OutSpatialReference = pGeodataset.SpatialReference;
293 
294             //重分類
295             IRaster pRaster = pReclassOp.ReclassByRemap(pGeodataset, pRemap, false) as IRaster;
296             return pRaster;
297         }
298 
299         /// <summary>
300         /// 獲取柵格分類數組和頻度數組
301         /// </summary>
302         /// <param name="inputRaster">輸入柵格</param>
303         /// <param name="dataValues"></param>
304         /// <param name="dataCounts"></param>
305         private void GetRasterClass(IRaster inputRaster, out object dataValues, out object dataCounts)
306         {
307             IRasterBandCollection pRasBandCol = inputRaster as IRasterBandCollection;
308             IRasterBand pRsBand = pRasBandCol.Item(0);
309             pRsBand.ComputeStatsAndHist();//IRasterBand中本無統計直方圖,必須先進行ComputeStatsAndHist()
310             IRasterStatistics pRasterStatistic = pRsBand.Statistics;
311 
312             double mMean = pRasterStatistic.Mean;
313             double mStandsrdDeviation = pRasterStatistic.StandardDeviation;
314 
315             IRasterHistogram pRasterHistogram = pRsBand.Histogram;
316             double[] dblValues;
317             dblValues = pRasterHistogram.Counts as double[];
318             int intValueCount = dblValues.GetUpperBound(0) + 1;
319             double[] vValues = new double[intValueCount];
320 
321             double dMaxValue = pRasterStatistic.Maximum;
322             double dMinValue = pRasterStatistic.Minimum;
323             double BinInterval = Convert.ToDouble((dMaxValue - dMinValue) / intValueCount);
324             for (int i = 0; i < intValueCount; i++)
325             {
326                 vValues[i] = i * BinInterval + pRasterStatistic.Minimum;
327             }
328 
329             dataValues = vValues as object;
330             dataCounts = dblValues as object;
331         }
332 
333         /// <summary>
334         /// 柵格轉面
335         /// </summary>
336         /// <param name="inputRaster">待轉換柵格</param>
337         /// <param name="fcName">生成要素類名稱</param>
338         /// <returns></returns>
339         private IFeatureClass RasterToPolygon(IRaster inputRaster, string fcName)
340         {
341             //獲得testPoint所在工作空間
342             IWorkspace pWorkspace = (m_fcToAnalyst as IDataset).Workspace;
343             IRasterBandCollection pRasBandCol = inputRaster as IRasterBandCollection;
344             IRasterBand pRsBand = pRasBandCol.Item(0);
345             IRasterDataset pRasterDataset = pRsBand as IRasterDataset;
346             IGeoDataset pRasterGeoDataset = pRasterDataset as IGeoDataset;
347 
348             //柵格轉面
349             IConversionOp pConversionOp = new RasterConversionOpClass();
350             ISpatialReference pSpatialReference = pRasterGeoDataset.SpatialReference;
351 
352             IGeoDataset pGeoDataset = pConversionOp.RasterDataToPolygonFeatureData(pRasterGeoDataset, pWorkspace, fcName, true);
353             return pGeoDataset as IFeatureClass;
354         }
355 
356         /// <summary>
357         /// 將要素類序列化成json格式對象
358         /// </summary>
359         /// <param name="inputFeaClass">輸入要素類</param>
360         /// <returns></returns>
361         private JsonObject FclassToJsonObj(IFeatureClass inputFeaClass)
362         {
363             //獲取要素數目
364             IQueryFilter pQueryFilter = new QueryFilterClass();
365             pQueryFilter.WhereClause = null;
366             int count = inputFeaClass.FeatureCount(pQueryFilter);
367 
368             //將每一個要素序列化成json數據
369             IFeature pFeature = null;
370             List<JsonObject> jsonGeometries = new List<JsonObject>();
371             for (int i = 1; i < count; i++)//OBJECTID從1開始
372             {
373                 pFeature = inputFeaClass.GetFeature(i);
374                 IGeometry pGeometry = pFeature.Shape;
375                 JsonObject featureJson = new JsonObject();
376                 JsonObject feaGeoJson = null;//幾何對象
377                 if (pGeometry != null)
378                 {
379                     feaGeoJson = Conversion.ToJsonObject(pGeometry);
380                     featureJson.AddJsonObject("geometry", feaGeoJson);//加入幾何對象
381                 }
382 
383                  
384                 double grid_Code = (double)pFeature.get_Value(pFeature.Fields.FindField("GRIDCODE"));
385                 featureJson.AddLong("id", i);//id
386                 featureJson.AddDouble("gridCode", grid_Code);//等級
387 
388                 jsonGeometries.Add(featureJson);
389             }
390 
391             JsonObject resultJson = new JsonObject();
392             resultJson.AddArray("geometries", jsonGeometries.ToArray());
393             return resultJson;
394         }
395         #endregion
396     }
397 }

增加一個控制台應用程序,命名為RegisterSaturation

加入以下引用

代碼:

View Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using ESRI.ArcGIS.esriSystem;
  6 using ESRI.ArcGIS.Server;
  7 using ESRI.ArcGIS;
  8 using ESRI.ArcGIS.ADF.Connection.AGS;
  9 
 10 namespace RegisterSaturation
 11 {
 12     class Program
 13     {
 14         static void Main(string[] args)
 15         {
 16             // Must run as an user in the agsadmin group on the SOM
 17             ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsServerConnection =
 18                 new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection();
 19             agsServerConnection.Host = "localhost";
 20             agsServerConnection.Connect();
 21             ESRI.ArcGIS.Server.IServerObjectAdmin2 serverObjectAdmin =
 22                 agsServerConnection.ServerObjectAdmin as ESRI.ArcGIS.Server.IServerObjectAdmin2;
 23 
 24             // This name must match those defined for property pages 
 25             string extensionName = "Saturation";
 26 
 27             // Check command line arguments to see if SOE is to be unregistered
 28             if (args.Length == 1 && args[0] == "/unregister")
 29             {
 30                 // Check whether the SOE is registered
 31                 if (ExtensionRegistered(serverObjectAdmin, extensionName))
 32                 {
 33                     // Delete the SOE
 34                     serverObjectAdmin.DeleteExtensionType("MapServer", extensionName);
 35                     Console.WriteLine(extensionName + " successfully unregistered");
 36                 }
 37                 else
 38                     Console.WriteLine(extensionName + " is not registered with ArcGIS Server");
 39             }
 40             else
 41             {
 42                 // Check whether the SOE is registered
 43                 if (!ExtensionRegistered(serverObjectAdmin, extensionName))
 44                 {
 45                     // Use IServerObjectExtensionType3 to get access to info properties
 46                     ESRI.ArcGIS.Server.IServerObjectExtensionType3 serverObjectExtensionType =
 47                         serverObjectAdmin.CreateExtensionType() as ESRI.ArcGIS.Server.IServerObjectExtensionType3;
 48 
 49                     // Must match the namespace and class name of the class implementing IServerObjectExtension
 50                     serverObjectExtensionType.CLSID = "Saturation.Saturation";
 51                     //serverObjectExtensionType.CLSID = "{C41E8674-F186-4a0c-8FC9-AAB7885EFD00}";
 52                     serverObjectExtensionType.Description = "the shops saturation";
 53                     serverObjectExtensionType.Name = extensionName;
 54 
 55                     // Name that will be shown in the capabilities list on property pages
 56                     serverObjectExtensionType.DisplayName = "Saturation REST";
 57 
 58                     // Use info properties to define capabilities and msd support
 59                     serverObjectExtensionType.Info.SetProperty("DefaultWebCapabilities", "GetInfo");
 60                     serverObjectExtensionType.Info.SetProperty("AllWebCapabilities", "GetInfo,Saturation");
 61                     serverObjectExtensionType.Info.SetProperty("SupportsMSD", "true");
 62 
 63                     // Required to enable exposure of SOE with ArcGIS Server REST endpoint
 64                     serverObjectExtensionType.Info.SetProperty("SupportsREST", "true");
 65 
 66                     // Register the SOE with the server
 67                     serverObjectAdmin.AddExtensionType("MapServer", serverObjectExtensionType);
 68 
 69                     Console.WriteLine(extensionName + " successfully registered with ArcGIS Server");
 70                 }
 71                 else
 72                     Console.WriteLine(extensionName + " is already registered with ArcGIS Server");
 73             }
 74 
 75             Console.ReadLine();
 76         }
 77 
 78         // Checks whether an extension with the passed-in name is already registered with the passed-in server
 79         static private bool ExtensionRegistered(ESRI.ArcGIS.Server.IServerObjectAdmin2 serverObjectAdmin, string extensionName)
 80         {
 81             // Get the extensions that extend MapServer server objects
 82             ESRI.ArcGIS.Server.IEnumServerObjectExtensionType extensionTypes = serverObjectAdmin.GetExtensionTypes("MapServer");
 83             extensionTypes.Reset();
 84 
 85             // If an extension with a name matching that passed-in is found, return true
 86             ESRI.ArcGIS.Server.IServerObjectExtensionType extensionType = extensionTypes.Next();
 87             while (extensionType != null)
 88             {
 89                 if (extensionType.Name == extensionName)
 90                 {
 91                     //serverObjectAdmin.DeleteExtensionType("MapServer", extensionName);
 92                     return true;
 93                 }
 94                     
 95 
 96                 extensionType = extensionTypes.Next();
 97             }
 98 
 99             // No matching extension was found, so return false
100             return false;
101         }
102     }
103 }

在代碼中有個地方需要注意:

serverObjectExtensionType.CLSID = "Saturation.Saturation";

CLSID的值必須與你的命名空間的類名相一致

 

2.注冊

  (1)注冊COM組件

  SOE其實是運行在服務器端的COM組件,並且你需要在每台運行SOC的機器上都為其注冊COM組件

  * 右擊Saturation工程--》屬性--》生成,將目標平台選為“x86”,因為ArcServer是運行在32位機器上

  *在屬性中選擇“簽名”選項卡,為程序集生成一個簽名

  *在開始菜單-》visual studio 20110-》visual studio tools-》命令提示,打開命令提示工具

  *在命令提示工具中輸入命令:regasm <path to DLL> /codebase,在本例中輸入如下命令:

  regasm “C:\Users\LZZ\Documents\Visual Studio 2010\Projects\Saturation\Saturation\bin\Debug\Saturation.dll” /codebase

  (2)ArcServer服務器注冊

  現在程序集已經注冊號,接下來要在ArcServer服務器上注冊,這里要用到RegisterSaturation工程,右擊工程-》屬性-》調試-》啟動新實例,如果注冊成功,你會看到一個提示成功的信息。

   注意:在注冊的時候一定要保證讓運行在這台機器上的soc用戶能夠訪問到你上面注冊的dll,否則會提示你無法注冊(給soc用戶能夠讀取你注冊的dll的權限)

3.調試

  如果沒有調試的話,那豈不是太痛苦了,不過還有說回來,SOE這個東西有調試也很痛苦。他需要附加到SOC進程中去,而你的機器上往往會有多個SOC進程,這時候如果你附加錯誤的話,你是無法進行調試的,我常用的方法是把其他的服務全部刪除,是刪除不是停止;這里還會碰到一個古怪的問題,就是第一次你可以調試,當你停止調后,再一次附加到進城后卻無法調試,我的方法是停止服務,將該工程重新生成,然后啟動服務,在附加到進程中去。這是我的這幾天捉摸出來的經驗。在調試之前我們首先需要使服務支持SOE,貌似在ArcGIS10中只支持MapServer的SOE。

  這里我建議你用Manager來發布服務,發布服務的方法跟發布普通mapServer的方法一樣,如果你的SOE在服務器上注冊成功的話,你會看到以下內容:

 

  在這里你不需要選中,我碰到過注冊成功后這在里面卻不顯示的問題,這時候你只要重啟一下計算機即可。發布服務成功后,點擊編輯服務:

 

在這里選中Saturation REST,在下方選中兩個check框,點擊右邊按鈕保存並重啟,現在我們的mapServer已經有了SOE能力。接下來我們進行調試:

在VS中點擊調試-》附加到進程:

如果你看到你附加到進城后,斷點依然顯示的話,說明可以正常調試,否則你就需要看一下前文提到的解決方法啦。

當點擊按鈕時,后進入VS中的斷點處:

運行成功后,你會看到返回的結果為json類型對象

現在我們已經介紹完SOE的內容了,如果你還有什么不了解的可以直接看幫助:

http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#/Extending_ArcGIS_Server/0001000000mv000000/

  這里補充幾句:官網中有三個例子,其中空間查詢的那個我沒運行成功,是跟里面設置屬性也有關,因為我沒用過里面的WebControl對他不太了解,而且我們的東西不需要使用屬性頁,所以暫時還無法解決他。希望有哪位大神看了這篇文章后能給小人指點一下,感激不盡。

 

  這個教程到這里就暫時告一段落了,如果以后還碰到關於這種技術的問題話,我會繼續發博文的。

  在這里順便感謝一下群哥多年來的幫助,這個技術也是從他那聽說的。可以說沒有群哥,也就沒有這系列教程。呵呵,祝大家好運!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM