码迷,mamicode.com
首页 > 其他好文 > 详细

通过栅格类型扩展使ArcGIS 支持更多传感器类型

时间:2016-03-26 07:38:35      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:

1  WHAT:什么是栅格类型?

ArcGIS海量影像管理解决方案推出已经有一年时间了,相信很多朋友已经对ArcGIS中如何管理海量影像数据有了大致了解。ArcGIS 10.0中推出了适用于海量影像管理的镶嵌数据集模型(Mosaic Dataset),单个镶嵌数据集就可以管理数百万景,不同时相、不同分辨率、不同坐标系、不同空间位置的影像。

为了将各种来源,形式各异的影像数据导入镶嵌数据集中,我们需要为影像指定“栅格类型(Raster Type)”。简单说,栅格类型就是对各种影像数据的分门别类,而这种分类,基本上是按照卫星传感器类型、航摄相机类型进行划分的。下图是ArcGIS内置支持的一些栅格类型:

技术分享

这里需要将栅格类型和栅格数据格式进行区分:栅格数据格式用于定义栅格像素如何存储,例如行列数、波段数、像素值等。而栅格类型则定义了如何识别影像关联的元数据,以及为影像定义的处理函数,如波段组合、全色融合等。

为了更好地理解栅格类型,我们可以打个比方:你要去电影院看电影,除了人要进去,还需要电影票,如果是3D电影,还需要带上3D眼镜。栅格影像数据入库,就相当于去看电影的过程:除了栅格影像数据本身要进去,还需要元数据信息(电影票),如果是多波段影像,可能还需要进行波段组合(看3D需要3D眼镜)。

2  WHEN:什么时候需要栅格类型扩展?

那么既然ArcGIS已经默认支持这么多的栅格类型,我们还有必要进行栅格类型扩展吗?当然需要了,在下面几个常见的场景中,栅格类型扩展是必须的:

1)       需要管理处理过的成果影像:很多单位会对影像数据进行各种处理,例如几何纠正、大气校正、影像拼接等等。经过这些处理的影像,就可能产生了自定义格式的元数据,这样就需要进行栅格类型扩展。

2)       需要管理国产卫星影像:很多单位都有国产卫星影像数据,例如风云系列、北京系列、环境星系列等等。这些卫星的元数据格式,也都形式各异,由于并不是国际通用的商业卫星,因此也需要进行栅格类型扩展。

3)       需要管理军用卫星影像:这类影像元数据格式可能就更加神秘了,如果读者有幸参与相关项目,则必须要通过栅格类型扩展才能管理这类影像。

4)       需要管理航飞拍摄的影像:航片也是影像数据的最大来源之一,比如无人机拍摄等。根据搭载的相机不同,生成的元数据也不尽相同,因此进行栅格类型扩展也是必要的。

那么有哪些影像是不需要进行栅格类型扩展就可以入库的呢?读者可以参考ArcGIS帮助中的介绍:

卫星传感器栅格类型:http://resources.arcgis.com/en/help/#/Satellite_sensor_raster_types/009t000001z6000000/

航空影像栅格类型:http://resources.arcgis.com/en/help/#/Aerial_imagery_raster_types/009t000001zp000000/

3  HOW:如何进行栅格类型扩展

OK,到这里,你已经了解了什么是栅格类型,以及在什么情况下需要进行栅格类型扩展,现在是时候学习如何进行栅格类型扩展了。

栅格类型扩展,实际上是通过ArcObjects开发来完成的。读者不必担心开发的难度,因为ArcGIS提供了非常完善的示例,而开发人员需要做的事情,其实就是给栅格类型扩展起个名字,然后去解析一下元数据文件,再根据需要定义一些预处理函数。

3.1 程序结构

在ArcObjects安装目录下,可以找到栅格类型扩展的示例程序,例如:C:\ArcGIS\DeveloperKit10.1\Samples\ArcObjectsNet\CustomRasterType\CSharp\ThumbnailBuilder,打开示例程序,可以看到ThumbnailBuilder.cs文件,其中包含了一个接口和两个类,如下图所示:

技术分享

其中IThumbnailBuilder只包含一个属性,InnerRasterBuilder,表示栅格类型内置的构造器。

ThumbnailFactory则实现了IRasterTypeFactory接口,主要包含COM注册/反注册函数,栅格类型的名称,以及调用栅格类型构造器的流程。

ThumbnailBuilder则是具体的栅格类型构造器,其中包含了栅格类型扩展的具体处理算法。

3.2 实战案例

本例中,我们参考示例程序,但考虑到实际应用,加入了其他的功能,例如:记录操作日志,解析元数据文件等。程序结构如下图所示:

技术分享

上述文件分别为:

1)       CgcImageryBuilder:栅格类型构造器,执行具体的栅格类型构造操作;

2)       CgcRasterTypeFactory:栅格类型工厂,定义栅格类型名称,提供COM注册函数,提供栅格类型构造器调用流程;

3)       BuilderHelper:一些通用的处理函数,比如获取镶嵌数据集默认字段、自定义字段,或者添加字段等;

4)       LogHelper:记录操作日志,写日志文件;

MetaReader:包含元数据解析函数,将指定格式的元数据文件,读取为标注的键值对。

3.3 主要代码

3.3.1 IAppendedBuilder

[csharp] view plain copy
  1. interface IAppendedBuilder : IRasterBuilder  
  2.     {  
  3.         ///<summary>  
  4.         /// 附加的内置目标Raster Builder对象  
  5.         ///</summary>  
  6.         IRasterBuilder InnerRasterBuilder  
  7.         {  
  8.             get;  
  9.             set;  
  10.         }  
  11.     }  

3.3.2 CgcRasterTypeFactory

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Runtime.InteropServices;  
  6. using ESRI.ArcGIS.esriSystem;  
  7. using ESRI.ArcGIS.DataSourcesRaster;  
  8. using esricd.demos.cgc.imagery.util;  
  9.   
  10. namespace esricd.demos.cgc.imagery.ext  
  11. {  
  12.     /// <summary>  
  13.     /// 重庆地理信息中心影像数据栅格类型工厂  
  14.     /// </summary>  
  15.     [Guid("AE299550-610F-44B6-9069-5C6E5CDC2F80")]  
  16.     [ClassInterface(ClassInterfaceType.None)]  
  17.     [ProgId("RasterTypeExtension.CgcRasterTypeFactory")]  
  18.     [ComVisible(true)]  
  19.     public class CgcRasterTypeFactory : IRasterTypeFactory  
  20.     {  
  21.         #region 私有成员  
  22.   
  23.         public const string CGC_IMAGERY = "重庆地理信息中心影像类型";  
  24.         private IStringArray myRasterTypeNames;  
  25.         private UID myUID;  
  26.   
  27.         public CgcRasterTypeFactory()  
  28.         {  
  29.             //指定栅格类型的名称,这些类型可以与扩展的栅格构造器关联  
  30.             myRasterTypeNames = new StrArrayClass();  
  31.             myRasterTypeNames.Add(CGC_IMAGERY);  
  32.   
  33.             myUID = new UIDClass();  
  34.             myUID.Value = "{AE299550-610F-44B6-9069-5C6E5CDC2F80}";  
  35.         }  
  36.  
  37.         #endregion  
  38.  
  39.         #region IRasterTypeFactory 成员  
  40.   
  41.         public ESRI.ArcGIS.esriSystem.UID CLSID  
  42.         {  
  43.             get { return myUID; }  
  44.         }  
  45.   
  46.         public IRasterType CreateRasterType(string RasterTypeName)  
  47.         {  
  48.             try  
  49.             {  
  50.                 // 1-首先获取内置栅格类型(Raster Dataset)  
  51.                 IRasterTypeName theRasterTypeName = new RasterTypeNameClass();  
  52.                 theRasterTypeName.Name = "Raster Dataset";//接受指向.art文件的路径,或内置栅格类型的名称  
  53.                 IRasterType theRasterType = (IRasterType)(((IName)theRasterTypeName).Open());  
  54.                 if (theRasterType == null)  
  55.                 {  
  56.                     LogHelper.AddMessage("错误:未找到栅格类型 " + theRasterTypeName.Name);  
  57.                     return null;  
  58.                 }  
  59.   
  60.                 // 2-在内置栅格类型(Raster Dataset)的栅格构造器上附加自定义的栅格构造器  
  61.                 IAppendedBuilder pAppendedBuilder = new CgcImageryBuilder();  
  62.                 pAppendedBuilder.InnerRasterBuilder = theRasterType.RasterBuilder;  
  63.                 theRasterType.RasterBuilder = pAppendedBuilder as IRasterBuilder;  
  64.   
  65.                 // 3-将内置栅格类型(Raster Dataset)的名称改为自定义栅格类型的名称  
  66.                 IName theName = theRasterType.FullName;  
  67.                 ((IRasterTypeName)theName).Name = RasterTypeName;  
  68.   
  69.                 return theRasterType;  
  70.             }  
  71.             catch (Exception ex)  
  72.             {  
  73.                 LogHelper.AddMessage("创建栅格类型 " + RasterTypeName + " 失败:" + ex.Message);  
  74.                 return null;  
  75.             }  
  76.         }  
  77.   
  78.         public string Name  
  79.         {  
  80.             get { return "Cgc Raster Type Factory"; }  
  81.         }  
  82.   
  83.         public ESRI.ArcGIS.esriSystem.IStringArray RasterTypeNames  
  84.         {  
  85.             get { return myRasterTypeNames; }  
  86.         }  
  87.  
  88.         #endregion  
  89.  
  90.         #region COM 注册函数  
  91.   
  92.         [ComRegisterFunction()]  
  93.         static void Reg(string regKey)  
  94.         {  
  95.             ESRI.ArcGIS.ADF.CATIDs.RasterTypeFactory.Register(regKey);  
  96.         }  
  97.   
  98.         [ComUnregisterFunction()]  
  99.         static void Unreg(string regKey)  
  100.         {  
  101.             ESRI.ArcGIS.ADF.CATIDs.RasterTypeFactory.Unregister(regKey);  
  102.         }  
  103.         #endregion  
  104.     }  
  105. }  

3.3.3 CgcImageryBuilder

[csharp] view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Runtime.InteropServices;  
  6. using ESRI.ArcGIS.DataSourcesRaster;  
  7. using ESRI.ArcGIS.esriSystem;  
  8. using ESRI.ArcGIS.Geodatabase;  
  9. using esricd.demos.cgc.imagery.util;  
  10. using ESRI.ArcGIS.Geometry;  
  11.       
  12. namespace esricd.demos.cgc.imagery.ext  
  13. {  
  14.     [Guid("A1AE3CF4-2C9E-4A9C-9287-C8D9BF182F64")]  
  15.     [ClassInterface(ClassInterfaceType.None)]  
  16.     [ProgId("RasterTypeExtension.CgcImageryBuilder")]  
  17.     [ComVisible(true)]  
  18.     public class CgcImageryBuilder : IAppendedBuilder, IPersistVariant, IRasterBuilderInit  
  19.     {  
  20.         #region 私有成员  
  21.   
  22.         public IRasterBuilder innerRasterBuilder; // Inner Raster Builder   
  23.         private UID myUID; // UID for the Builder.  
  24.         
  25.         #endregion  
  26.  
  27.         #region 附加构造器成员  
  28.   
  29.         /// <summary>  
  30.         /// 构造函数不能含参数,否则报内存访问错误  
  31.         /// </summary>  
  32.         public CgcImageryBuilder()  
  33.         {  
  34.             innerRasterBuilder = null;  
  35.   
  36.             myUID = new UIDClass();  
  37.             myUID.Value = "{A1AE3CF4-2C9E-4A9C-9287-C8D9BF182F64}";  
  38.         }  
  39.   
  40.         public IRasterBuilder InnerRasterBuilder  
  41.         {  
  42.             get  
  43.             {  
  44.                 return innerRasterBuilder;  
  45.             }  
  46.             set  
  47.             {  
  48.                 innerRasterBuilder = value;  
  49.             }  
  50.         }  
  51.  
  52.         #endregion  
  53.  
  54.         #region IRasterBuilder 成员  
  55.   
  56.         /// <summary>  
  57.         /// AuxiliaryFieldAlias property gets and sets the Auxiliary(辅助、备用) fields Alias  
  58.         /// present in the raster builder  
  59.         /// </summary>  
  60.         public ESRI.ArcGIS.esriSystem.IPropertySet AuxiliaryFieldAlias  
  61.         {  
  62.             get  
  63.             {  
  64.                 return innerRasterBuilder.AuxiliaryFieldAlias;  
  65.             }  
  66.             set  
  67.             {  
  68.                 innerRasterBuilder.AuxiliaryFieldAlias = value;  
  69.             }  
  70.         }  
  71.   
  72.         /// <summary>  
  73.         /// Flag to specify whether the Raster Builder can build items in place.  
  74.         /// </summary>  
  75.         public bool CanBuildInPlace  
  76.         {  
  77.             get { return innerRasterBuilder.CanBuildInPlace; }  
  78.         }  
  79.   
  80.         /// <summary>  
  81.         /// Prepare the Raster Type for generating Crawler items  
  82.         /// </summary>  
  83.         /// <param name="pCrawler">Crawler to use to generate the crawler items</param>  
  84.         public void BeginConstruction(IDataSourceCrawler pCrawler)  
  85.         {  
  86.             innerRasterBuilder.BeginConstruction(pCrawler);  
  87.         }  
  88.   
  89.         /// <summary>  
  90.         /// Construct a Unique Resource Identifier (URI)  
  91.         /// for each crawler item  
  92.         /// </summary>  
  93.         /// <param name="crawlerItem">Crawled Item from which the URI is generated</param>  
  94.         public void ConstructURIs(object crawlerItem)  
  95.         {  
  96.             innerRasterBuilder.ConstructURIs(crawlerItem);  
  97.         }  
  98.   
  99.         /// <summary>  
  100.         /// Finish Construction of the URI‘s  
  101.         /// </summary>  
  102.         /// <returns></returns>  
  103.         public IItemURIArray EndConstruction()  
  104.         {  
  105.             return innerRasterBuilder.EndConstruction();  
  106.         }  
  107.   
  108.         /// <summary>  
  109.         /// Generate the next URI.  
  110.         /// </summary>  
  111.         /// <returns>The URI generated.</returns>  
  112.         public IItemURI GetNextURI()  
  113.         {  
  114.             return innerRasterBuilder.GetNextURI();  
  115.         }  
  116.   
  117.         /// <summary>  
  118.         /// Get the recommended data crawler for the Raster Type based on   
  119.         /// properties provided by the user.  
  120.         /// </summary>  
  121.         /// <param name="pDataSourceProperties">List of properties provided by the user</param>  
  122.         /// <returns></returns>  
  123.         public IDataSourceCrawler GetRecommendedCrawler(IPropertySet pDataSourceProperties)  
  124.         {  
  125.             return innerRasterBuilder.GetRecommendedCrawler(pDataSourceProperties);  
  126.         }  
  127.   
  128.         /// <summary>  
  129.         /// Check if the item provided is "stale不新鲜的,过时的" or not valid  
  130.         /// </summary>  
  131.         /// <param name="pItemURI">URI for the item to be checked</param>  
  132.         /// <returns></returns>  
  133.         public bool IsStale(IItemURI pItemURI)  
  134.         {  
  135.             return innerRasterBuilder.IsStale(pItemURI);  
  136.         }  
  137.   
  138.         /// <summary>  
  139.         /// Properties associated with the Raster Type  
  140.         /// </summary>  
  141.         public IPropertySet Properties  
  142.         {  
  143.             get  
  144.             {  
  145.                 return innerRasterBuilder.Properties;  
  146.             }  
  147.             set  
  148.             {  
  149.                 innerRasterBuilder.Properties = value;  
  150.             }  
  151.         }  
  152.   
  153.         /// <summary>  
  154.         /// 添加辅助字段,所有非镶嵌数据集默认字段均可视为辅助字段  
  155.         /// </summary>  
  156.         public IFields AuxiliaryFields  
  157.         {  
  158.             get  
  159.             {  
  160.                 ESRI.ArcGIS.DataSourcesRaster.IRasterBuilder pRasterBuilder = innerRasterBuilder;  
  161.                 IFields myFields = pRasterBuilder.AuxiliaryFields;  
  162.                 try  
  163.                 {  
  164.                     IMosaicDataset pMosaicDataset = ((IRasterBuilderInit)innerRasterBuilder).MosaicDataset;  
  165.                     IFields pAllFields = BuilderHelper.GetMosaicDatasetFields(pMosaicDataset);  
  166.                     Dictionary<string, esriFieldType> lstCustomFields = BuilderHelper.GetMosaicDatasetCustomFields(pAllFields);  
  167.   
  168.                     foreach (KeyValuePair<string,esriFieldType> fieldItem in lstCustomFields)  
  169.                     {  
  170.                         int count = myFields.FindField(fieldItem.Key);  
  171.                         if (count == -1)  
  172.                         {  
  173.                             BuilderHelper.AddNewField(myFields, fieldItem.Key, fieldItem.Value);  
  174.                             pRasterBuilder.AuxiliaryFields = myFields;  
  175.                         }  
  176.                     }  
  177.                 }  
  178.                 catch (Exception ex)  
  179.                 {  
  180.                     LogHelper.AddMessage("添加辅助字段失败:" + ex.ToString());  
  181.                 }  
  182.   
  183.                 return innerRasterBuilder.AuxiliaryFields;  
  184.             }  
  185.             set  
  186.             {  
  187.                 innerRasterBuilder.AuxiliaryFields = value;  
  188.             }  
  189.         }  
  190.   
  191.         /// <summary>  
  192.         /// 构建栅格数据项,可在此对每一项执行附加的构建操作.  
  193.         /// </summary>  
  194.         /// <param name="pItemURI"></param>  
  195.         /// <returns></returns>  
  196.         public IBuilderItem Build(IItemURI pItemURI)  
  197.         {  
  198.             try  
  199.             {  
  200.                 // 执行内置的构建操作(参数为待构建项的URI)  
  201.                 LogHelper.AddMessage("正在读取栅格数据:" + pItemURI.Key);  
  202.                 IBuilderItem pBuilderItem = innerRasterBuilder.Build(pItemURI);  
  203.   
  204.                 //获取镶嵌数据集字段列表,以便根据字段别名提取元数据项  
  205.                 IMosaicDataset md = ((IRasterBuilderInit)innerRasterBuilder).MosaicDataset;  
  206.                 IFields pFields = BuilderHelper.GetMosaicDatasetFields(md);  
  207.                 //获取栅格数据的属性,以便将元数据项写入属性表中  
  208.                 IPropertySet pPropSet = pBuilderItem.Dataset.Properties;  
  209.                 //读写元数据  
  210.                 MetaReader.ReadCgcImageryMeta(pItemURI.Key, pFields, pPropSet);  
  211.   
  212.                 LogHelper.AddMessage("已完成栅格数据添加。");  
  213.                 LogHelper.WriteToLogFile();  
  214.   
  215.                 return pBuilderItem;  
  216.             }  
  217.             catch (Exception ex)  
  218.             {  
  219.                 LogHelper.AddMessage("构建栅格数据失败:" + ex.ToString());  
  220.                 LogHelper.WriteToLogFile();  
  221.   
  222.                 return null;  
  223.             }  
  224.         }  
  225.  
  226.         #endregion  
  227.  
  228.         #region IPersistVariant 成员  
  229.   
  230.         /// <summary>  
  231.         /// UID for the object implementing the Persist Variant  
  232.         /// </summary>  
  233.         UID IPersistVariant.ID  
  234.         {  
  235.             get { return myUID; }  
  236.         }  
  237.   
  238.         /// <summary>  
  239.         /// Load the object from the stream provided  
  240.         /// </summary>  
  241.         /// <param name="Stream">Stream that represents the serialized Raster Type</param>  
  242.         void IPersistVariant.Load(IVariantStream Stream)  
  243.         {  
  244.             string name = (string)Stream.Read();  
  245.             innerRasterBuilder = (IRasterBuilder)Stream.Read(); // Load the innerRasterBuilder from the stream.  
  246.         }  
  247.   
  248.         /// <summary>  
  249.         /// Same the Raster Type to the stream provided  
  250.         /// </summary>  
  251.         /// <param name="Stream">Stream to serialize the Raster Type into</param>  
  252.         void IPersistVariant.Save(IVariantStream Stream)  
  253.         {  
  254.             Stream.Write("CgcImageryBuilder");  
  255.             Stream.Write(innerRasterBuilder); // Save the innerRasterBuilder into the stream.  
  256.         }  
  257.  
  258.         #endregion  
  259.  
  260.         #region IRasterBuilderInit 成员  
  261.   
  262.         /// <summary>  
  263.         /// Default spatial reference for the MD.  
  264.         /// </summary>  
  265.         ISpatialReference IRasterBuilderInit.DefaultSpatialReference  
  266.         {  
  267.             get  
  268.             {  
  269.                 return ((IRasterBuilderInit)innerRasterBuilder).DefaultSpatialReference;  
  270.             }  
  271.             set  
  272.             {  
  273.                 ((IRasterBuilderInit)innerRasterBuilder).DefaultSpatialReference = value;  
  274.             }  
  275.         }  
  276.   
  277.         /// <summary>  
  278.         /// Parent mosaic dataset for the Raster Builder.  
  279.         /// </summary>  
  280.         IMosaicDataset IRasterBuilderInit.MosaicDataset  
  281.         {  
  282.             get  
  283.             {  
  284.                 return ((IRasterBuilderInit)innerRasterBuilder).MosaicDataset;  
  285.             }  
  286.             set  
  287.             {  
  288.                 ((IRasterBuilderInit)innerRasterBuilder).MosaicDataset = value;  
  289.             }  
  290.         }  
  291.   
  292.         /// <summary>  
  293.         /// The raster type operation helper object associated with this raster type.  
  294.         /// </summary>  
  295.         IRasterTypeOperation IRasterBuilderInit.RasterTypeOperation  
  296.         {  
  297.             get  
  298.             {  
  299.                 return ((IRasterBuilderInit)innerRasterBuilder).RasterTypeOperation;  
  300.             }  
  301.             set  
  302.             {  
  303.                 ((IRasterBuilderInit)innerRasterBuilder).RasterTypeOperation = value;  
  304.             }  
  305.         }  
  306.   
  307.         /// <summary>  
  308.         /// Tracker for when cancel is pressed.  
  309.         /// </summary>  
  310.         ITrackCancel IRasterBuilderInit.TrackCancel  
  311.         {  
  312.             get  
  313.             {  
  314.                 return ((IRasterBuilderInit)innerRasterBuilder).TrackCancel;  
  315.             }  
  316.             set  
  317.             {  
  318.                 ((IRasterBuilderInit)innerRasterBuilder).TrackCancel = value;  
  319.             }  
  320.         }  
  321.  
  322.         #endregion  
  323.     }  
  324. }  
扩展开发完成、注册之后,可以在栅格类型中看到自定义的栅格类型,如下图最后一个:
技术分享

这样在影像数据导入镶嵌数据集的时候,就可以选择扩展的栅格类型,保证元数据信息正确入库管理,为下一步影像管理、应用打下坚实的基础。

本文仅介绍栅格类型扩展的技术路线和关键代码,日志记录和其他辅助函数则没有上传,如需完整代码,请在评论中留下邮箱地址。如有疑问,也请在评论中留言探讨。

转自http://blog.csdn.net/esrichinacd/article/details/7844494

通过栅格类型扩展使ArcGIS 支持更多传感器类型

标签:

原文地址:http://blog.csdn.net/kone0611/article/details/50978375

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!