ArcGIS影像服务研究之影像下载

    技术2022-05-20  43

    影像服务( Image Service )是 ArcGIS Server 中非常重要的一种服务类型,通过影像服务能够将各类影像数据、栅格数据发布为服务,客户端可以通过 SOAP REST 接口进行访问,从而在更大范围内实现影像数据的共享访问和在线处理等。

    本文主要探讨 ArcGIS Server 10.0 新增的影像下载功能。

    1   准备服务

    ArcGIS Server 10.0 中,影像服务可以提供下载功能(要求数据源是镶嵌数据集),在服务能力中启用下载功能即可,如下图所示。

    启用影像服务的 Web 下载功能

    1   影像下载参数说明

    影像下载功能的参数可以在 REST SDK 中查询,如下所述:

    f :返回值(响应)的格式,可选值为htmljson ,其中html 是默认响应格式。

    rasterIds :由逗号分隔的raster IDs ,指定待下载的栅格数据,例如:rasterIds=37,462

    geometry 用于裁剪栅格数据的图形。如果指定了,则选择的栅格数据将在服务器端被裁剪。默认情况下认为该geometry 的空间参考与影像服务的空间参考一致。

    JSON 语法结构:geometryType=<geometryType>&geometry={geometry}

    Envelope 简单语法: geometryType=esriGeometryEnvelope&geometry=

    <xmin>,<ymin>,<xmax>,<ymax>

    示例:

    geometryType=esriGeometryEnvelope&geometry={xmin: -104, ymin: 35.6, xmax: -94.32, ymax: 41}

    geometryType=esriGeometryEnvelope&geometry=-104,35.6,-94.32,41

    geometryType 用于裁剪的图形类型,可选值为envelope polygon 默认值是envelope

    format返回的栅格数据格式,如果不指定,将返回数据本身的格式。本参数仅当裁剪时有效。可选的格式包括:TIFF, Imagine Image, JPEG, BIL, BSQ, BIP, ENVI, JP2, GIF, BMP,PNG 。例如:format=TIFF

    Json 格式返回值语法:

    { "rasterFiles" :  [ //the list of files that make up the rasters to be downloaded   { //info pertaining to a single file     //use this id to download the file using the Raster File resource     "id" : "<fileId1>",     "size" : <fileSize1>,     //an array of IDs of rasters that include this file     "rasterIds" : [ <rasterId11>, <rasterId12> ]   },   {     "id" : "<fileId2>",     "size" : <fileSize2>,     "rasterIds" : [ <rasterId21>, <rasterId22> ]   } ] }

    2   客户端访问

    ArcGIS Silverlight API 中,通过 HttpWebRequest 来请求下载,通过 HttpWebResponse 获取下载结果并进行处理。

    下面的代码演示了如何请求下载以及如何处理下载结果。

    public void BeginDownload(string rasterIds,string geometry,string geoType,string imgFormat)

    {

        string comma = "," ;// 逗号

        rasterIds = rasterIds.Replace("," , comma);

        geometry = geometry.Replace("," , comma);

     

        StringBuilder urlBuilder = new StringBuilder ();

        urlBuilder.Append(_ImageServiceUrl);

        urlBuilder.Append("/download?" );

        urlBuilder.Append("RasterIds=" );// 指定要下载的栅格数据 ObjectID

        urlBuilder.Append(rasterIds);

        urlBuilder.Append("&geometryType=" );// 指定范围类型

        urlBuilder.Append(geoType);

        urlBuilder.Append("&geometry=" );// 指定裁切范围

        urlBuilder.Append(geometry);

        urlBuilder.Append("&format=" );// 指定输出的栅格数据格式

        urlBuilder.Append(imgFormat);

        urlBuilder.Append("&f=json" );// 指定返回的结果格式

     

        // 开始请求下载

    HttpWebRequest request = (HttpWebRequest )HttpWebRequest .Create(

    urlBuilder.ToString());

        request.BeginGetResponse(new AsyncCallback (DownloadCallback), request);

    }

     

    private void DownloadCallback(IAsyncResult asynchronousResult)

    {

        HttpWebRequest request = (HttpWebRequest )asynchronousResult.AsyncState;

    HttpWebResponse response = (HttpWebResponse )request.EndGetResponse(

    asynchronousResult);

        long length = response.ContentLength;

        Stream stream = response.GetResponseStream();

        StreamReader reader = new StreamReader (stream);

     

        string result = reader.ReadToEnd();// 读取返回的 json 字符串

     

        // 处理错误结果

        if (result.Contains("/"error/":" ))

        {

            result = result.Substring(10);// 去掉开头的 {"error":{

            result = result.Substring(0, result.Length - 4);// 去掉末尾的 "]}}

     

            int codeIndex = result.IndexOf("/"code/":" );

            int msgIndex = result.IndexOf(",/"message/":/"" );

            int detailsIndex = result.IndexOf("/",/"details/":[/"" );

     

            int codeLength = 7;// "code":"

            int msgLength = 12;// ,"message":"

             int detailsLength = 14;// ","details":["

     

            DownloadError error = new DownloadError ();

            error.ErrorCode = result.Substring(codeIndex + codeLength,

      msgIndex - codeIndex - codeLength);

            error.Message = result.Substring(msgIndex + msgLength,

    detailsIndex - msgIndex - msgLength);

            error.Detail = result.Substring(detailsIndex + detailsLength);

     

            if (DownloadFailed != null )

            {

                DownloadFailed(error);// 触发下载失败事件

            }

        }

        else // 获取数据成功

        {

            IList <DownloadResult > lstResultObjects = new List <DownloadResult >();

     

            if (result.Contains("id" ))// 有下载结果

            {

                result = result.Substring(17);// 去掉开头的 {"rasterFiles":[{               

                result=result.Substring(0,result.Length-3);// 去掉末尾的 }]}

     

                string [] files = result.Split(new string [] { "},{" },

                StringSplitOptions .RemoveEmptyEntries);

                foreach (string jsonResult in files)

                {

                    int nameIndex = jsonResult.IndexOf("/"id/":/"" );

                     int sizeIndex = jsonResult.IndexOf("/",/"size/":" );

                    int rasterIdIndex = jsonResult.IndexOf(",/"rasterIds/":" );

     

                    int idLength = 6;// "id":"

                    int sizeLength = 9;// ","size":

                    int rasteridLength = 13;// ,"rasterIds":

     

                    // 创建下载结果对象

                    DownloadResult resultObject = new DownloadResult ();

                    resultObject.FileSize = Convert .ToInt64(

    jsonResult.Substring(sizeIndex + sizeLength,

    rasterIdIndex - sizeIndex - sizeLength));

                    resultObject.RasterIds = jsonResult.Substring(

    rasterIdIndex + rasteridLength);

     

                    string fileName = jsonResult.Substring(nameIndex +

                    idLength, sizeIndex - nameIndex - idLength);

                    string fileUrl = fileName;

                    if (fileUrl.StartsWith("http:" ))

                    {

                        fileName = fileName.Substring(

    fileName.LastIndexOf('/' ) + 1);

                    }

                    else // 下载结果指向原始文件路径

                    {

                         fileUrl = _ImageServiceUrl + "//file?id=" + fileName;

                        fileName = fileName.Substring(

    fileName.LastIndexOf('//' ) + 1);

                    }

     

                    resultObject.FileName = fileName;

                    resultObject.Url = fileUrl;// 结果文件 URL

     

                    lstResultObjects.Add(resultObject);

                }

            }

     

            if (DownloadCompleted != null )

            {

                if (lstResultObjects.Count > 0)

                {

                    DownloadCompleted(lstResultObjects);// 触发下载完成事件

                }

                else

                {

                    DownloadError error = new DownloadError ();

                    error.Message = " 结果为 0" ;

                    error.Detail = " 未能在指定范围内获取到数据 " ;

     

                    if (DownloadFailed != null )

                     {

                        DownloadFailed(error);// 触发下载失败事件

                    }

                }

            }

        }

    }

    }

    辅助类:

    public class DownloadResult

    {

        public string Url = "" ;

        public string FileName = "" ;

        public string RasterIds = "" ;

        public long FileSize = 0;

    }

     

    public class DownloadError

    {

        public string ErrorCode = "0" ;

        public string Message = "" ;

        public string Detail = "" ;

    }

    3   总结

    ArcGIS Server 10.0 中,通过 REST 接口能够方便地实现影像服务的访问,如果影像服务启用了 Web 下载功能,则在 ArcGIS API for Silverlight 中,通过简单编码即可获取待下载的数据 URL ,从而供用户点击下载。

      影像数据的下载,既可以下载原始文件,也可以下载裁剪结果(可指定数据格式),可以通过 raster id 过滤要下载的影像数据。

    影像数据支持 Web 下载的前提是,影像服务的数据源是镶嵌数据集。


    最新回复(0)