C#調用ArcGIS REST服務


ArcGIS REST API提供了簡單、開放的接口來訪問和使用ArcGIS Server發布的服務。使用ArcGIS REST API通過URL可以獲取和操作每一個服務中的所有資源和操作。

1、使用步驟

    1)構建請求網址

  A、確定端點:每個GIS服務都有一個端點。例如,ArcGIS Server上Demographics文件夾下名為ESRI_Census_USA的一個地圖服務sampleserver1.arcgisonline.com的端點為:http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer.

  B、確定操作:不同地理信息系統服務支持不同的操作。不同的操作會返回不同的結果。地圖服務可以地圖輸出,點擊查看,查找和生成KML。輸出地圖可以生成地圖,同時可以點擊產看是否給出地圖服務圖層的屬性表。

  C、確定參數:不同的操作需要不同的參數。例如,如果請求地圖圖片,需要提供地圖范圍的四周角點坐標參數,也就是地圖覆蓋范圍。

  D、確定輸出格式:REST API支持很多輸出格式,例如JSON,KMZ,圖片和HTML。確定輸出格式的重要參數是f。在URL請求的查詢字符串后面加上”f=<你的格式>”來確定輸出格式。例如:f=html返回的數據格式為html;f=json返回的數據格式為json;f=image返回的格式為image等等。

我們就以上面的4個步驟來構建自己需要的URL。一般來說,格式如下:

  http://{ArcGIS Server name}/ArcGIS/rest/services/{foldername}/{service name}/{service type}/{operation}?{{parameter1}={somevalues}&{parameter2}={some values}&…&{parameter}={some values}}

  可以看到,整個URL請求分為兩個部分,第一部分是服務的端點和操作類型,也就是“?”前面的部分;第二部分是查詢字符串,即請求參數,“?”后面的部分。

  2)發送請求到ArcGIS Server

  提交URL請求到ArcGIS Server Sending,可以不通過編程發送URL請求。例如,只需在網頁瀏覽器的地址欄輸入網址,如IE或Firefox。每種編程語言都用不同的提出請求方式。

  3)接受服務器的響應

  接受ArcGISServer的響應,ArcGIS Server處理請求並返回響應到客戶端。對於一個同步的工作,客戶端一直等待收到服務器的響應。對於一部工作,服務器發送一份工作編號來定期跟蹤客戶端的工作狀態。

  4)解析服務器響應

  ArcGIS Server REST Web服務的響應可以是多種格式,例如JSON,KML,圖片和HTML。客戶端可判斷響應時成功還是失敗。如果失敗了,客戶端可以判斷錯誤信息。如果響應是成功的,客戶端可以解析響應所需的信息,並恰當地利用這些信息。


2、編程使用

代碼以ArcGIS API for WPF為例,操作為addFeatures,這里只是add一個要素點,參考ArcGIS官方文檔說明:http://sampleserver3.arcgisonline.com/ArcGIS/SDK/REST/index.html?fsadd.html

參考代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Geometry;
using ESRI.ArcGIS.Client.Tasks;
using System.Net;
using System.IO;

namespace ArcGISDemo
{
    //自定義的Feature
    class FeatureItem
    {
        public Geometry Geometry { set; get; }
        public IDictionary<string, object> Attributes { set; get; }
    };

    class Program
    {
        static bool AddFeature(string layerUrl, FeatureItem featureItem)
        {
            string url = layerUrl+"/addFeatures";
            string data = "f=json"; //以json格式返回結果

            ESRI.ArcGIS.Client.Graphic g = new ESRI.ArcGIS.Client.Graphic()
            {
                //Graphic的Attributes在ArcGIS API for WPF 中是只讀的
                //如果是可寫的,就可以直接使用Graphic的Attributes,而不需要拼接json
                //Attributes = featureItem.Attributes, 
                Geometry = featureItem.Geometry
            };
            FeatureSet fs = new FeatureSet();
            fs.Features.Add(g);
            //使用FeatureSet自帶的ToJson函數轉換,可以幫助轉換Feature的Geometry對象
            //ArcGIS的Geometry對象序列化為json字符串時和標准的json不太一樣
            string json = fs.ToJson();
            int begin = json.IndexOf("[");
            int end = json.IndexOf("]", begin);
            string featuresJson = json.Substring(begin, end - begin + 1);
            string features = string.Format("&features={0}", featuresJson);
            data += features;

            //使用fastJson轉換Attributes
            //fastJSON.JSON.Instance.Parameters.UseEscapedUnicode = false;
            //string attr = fastJSON.JSON.Instance.ToJSON(featureItem.Attributes);
            string attr = Newtonsoft.Json.JsonConvert.SerializeObject(featureItem.Attributes);
            //int attrPos = data.IndexOf("attributes");
            //將原來空的Attributes替換掉,以自己轉換的json字符串實際情況為准
            string para = data.Replace("\"attributes\":{}","\"attributes\":"+attr);
            
            string res = PostData(url, para);

            //處理返回的結果
            if (res.Contains("error"))
                return false;
            Dictionary<string, List<Dictionary<string, object>>> resDic 
                = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, List<Dictionary<string, object>>>>(res);
            if (resDic.ContainsKey("addResults"))
            {
                List<Dictionary<string, object>> addRes = resDic["addResults"];
                foreach (Dictionary<string, object> dic in addRes)
                {
                    if (dic.ContainsKey("success"))
                    {
                        if (dic["success"].ToString().ToLower() == "true")
                            return true;
                        else return false;
                    }
                }
            }
            return false;
        }

        static string PostData(string url, string data)
        {
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            byte[] bs = Encoding.UTF8.GetBytes(data);
            Stream reqStream = request.GetRequestStream();
            reqStream.Write(bs, 0, bs.Length);
            reqStream.Close();

            string responseString = null;
            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                StreamReader reader = new StreamReader(response.GetResponseStream());
                responseString = reader.ReadToEnd();
                reader.Close();
            }
            return responseString;
        }

        static void Main(string[] args)
        {
            string url = "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Fire/Sheep/FeatureServer/0";
            MapPoint point = new MapPoint(105, 30);

            FeatureItem fi = new FeatureItem();
            fi.Geometry = point;
            fi.Attributes = new Dictionary<string, object>();
            fi.Attributes.Add("description", "測試點");
            bool res = AddFeature(url, fi);
            if (res)
            {
                Console.WriteLine("添加要素成功!");
            }
            else
            {
                Console.WriteLine("添加要素失敗!");
            }
            Console.ReadKey();
        }
    }
}

代碼只是簡單的在一個圖層上加了一個點,注意以下2點:

(1)確定參數的json格式
  ArcGIS API for WPF中FeatureSet有ToJson()可以把對象序列化json字符串,FromJson()將json字符串反序列化為一個對象,這里之所以使用FeatureSet的ToJson,然后拼接一個json字符串參數,是因為使用FeatureSet自帶的ToJson函數可以幫助轉換每個Feature的Geometry對象,如果全部使用Newtonsoft.Json來轉換,得到的json字符串中Geometry對象和ArcGIS規定的格式不一樣(對於Point是一樣的,但是對於Multipoint Polyline等不一樣),可以參考ArcGIS文檔中對Geometry對象json格式的說明:http://sampleserver3.arcgisonline.com/ArcGIS/SDK/REST/index.html?fsadd.html

(2)解析響應結果
  對於{"addResults":[{"objectId":6,"globalId" : null,"success":true}]}這樣的json字符串構造了一個Dictionary<string, List<Dictionary<string, object>>>復雜的對象來保存結果,如果是調用Query操作,返回的結果是一個FeatureSet,可以使用FeatureSet的FromJson來得到結果。

 

Newtonsoft.Json(Json.Net)下載:
http://json.codeplex.com/

參考:

1、基於 REST 的 Web 服務:基礎
http://www.ibm.com/developerworks/cn/webservices/ws-restful/

2、ArcGIS客戶端開發學習筆記(五)——ArcGIS REST API基礎
http://www.cnblogs.com/carlbiao/archive/2010/09/09/1822419.html

3、Java中調用ArcGIS Server REST API
http://www.cnblogs.com/esrichina/archive/2013/02/01/2889224.html

 

 


免責聲明!

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



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