ArcEngine 栅格数据
1、ArcEngine中的栅格数据组织方式(详细信息见:http://resources.arcgis.com/zh-cn/help/main/10.1/index.html#/na/009t0000000n000000/)
1.1 栅格数据集(RasterDataset)
大多数影像和栅格数据(例如正射影像或 DEM)都以栅格数据集的形式提供。栅格数据集这个术语是指存储在磁盘或地理数据库中的任何栅格数据模型。它是构建其他数据的最基本的栅格数据存储模型 - 镶嵌数据集和栅格目录管理栅格数据集。栅格数据集是组织成一个或多个波段的任何有效的栅格格式。每个波段由一系列像素(单元)数组组成,每个像素都有一个值。栅格数据集至少有一个波段。可以采用许多格式存储栅格数据集,包括 TIFF、JPEG 2000、Esri Grid 和 MrSid。
1.2 镶嵌数据集(MosaicDataset)
镶嵌数据集是若干栅格数据集(影像)的集合,它以目录形式存储并以单个镶嵌影像或单独影像(栅格)的方式显示或访问。这些集合的总文件大小和栅格数据集数量都会非常大。镶嵌数据集中的栅格数据集可以采用本机格式保留在磁盘上,也可在需要时加载到地理数据库中。可通过栅格记录以及属性表中的属性来管理元数据。通过将元数据存储为属性,可以更方便地管理诸如传感器方向数据等参数,同时也可以提高对选择内容的查询速度。
镶嵌数据集中的栅格数据不必相邻或叠置,也可以以未连接的不连续数据集的形式存在。例如,您可以使用完全覆盖某个区域的影像,也可使用没有连接到一起形成连续影像的多条影像(例如,沿管线)。数据甚至可以完全或部分叠置,但需要在不同的日期进行捕获。镶嵌数据集是一种用于存储临时数据的理想数据集。您可以在镶嵌数据集中根据时间或日期查询所需的影像,也可以使用某种镶嵌方法来根据时间或日期属性显示镶嵌影像。
1.3 栅格目录(RasterCatalog)
栅格目录是以表格式定义的栅格数据集的集合,其中每个记录表示目录中的一个栅格数据集。栅格目录可以大到包含数千个影像。栅格目录通常用于显示相邻、完全重叠或部分重叠的栅格数据集,而无需将它们镶嵌为一个较大的栅格数据集。
2、ArcEngine操作栅格
2.1 读取栅格数据
ArcEngine中的栅格数据存储分为两类:以单独的文件形式存储,如:TIFF、JPEG 2000、Esri Grid 和 MrSid等;存储在地理数据库(SDE数据库、个人数据库、文件数据库等)中。
IRasterWorkspace 接口一般用于打开文件格式存储的栅格数据,IRasterWorkspaceEx 接口用于打开存储于地理数据库中的栅格数据。
打开文件格式存储的栅格数据:
// Libraries needed to run the code: // ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.DataSourcesRaster public IRasterDataset OpenRasterDataset(string directoryName, string fileName) { //Open the raster dataset with the given name. //directoryName is the directory where the file resides //fileName is the filename to be opened //Open the workspace IWorkspaceFactory workspaceFactory = new RasterWorkspaceFactoryClass(); // define the directory as a raster workspace IRasterWorkspace rasterWorkspace = workspaceFactory.OpenFromFile(directoryName, 0) as IRasterWorkspace; //Open the raster dataset IRasterDataset rasterDataset = null; rasterDataset = rasterWorkspace.OpenRasterDataset(fileName); // Return raster dataset return rasterDataset; }
打开地理数据库中的栅格数据(以个人数据库为例):
// Libraries needed to run this code: // ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.DataSourcesGDB public IRasterCatalog OpenPGDBRasterCatalog(string pathName, string rasterCatalogName) { // Open personal geodatabase raster catalog with the given name // pathName is the PGDB path (location of the personal geodatabase) // rasterCatalogName is the name of the raster catalog to be opened //Open the Access workspace IWorkspaceFactory2 workspaceFactory = new AccessWorkspaceFactoryClass(); IRasterWorkspaceEx rasterWorkspaceEx = workspaceFactory.OpenFromFile(pathName, 0) as IRasterWorkspaceEx; //Open the PGDB raster Catalog IRasterCatalog rasterCatalog = null; rasterCatalog = rasterWorkspaceEx.OpenRasterCatalog(rasterCatalogName); return rasterCatalog; }
2.2 创建栅格数据
创建以文件格式存储的栅格数据集:
// Libraries needed to run this code: // ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.DataSourcesRaster, ESRI.ArcGIS.Geometry public IRasterDataset createFileRasterDataset(string directoryName, string fileName) { // This function creates a new img file in the given workspace // and then assigns pixel values try { IRasterDataset rasterDataset = null; IPoint originPoint = new PointClass(); originPoint.PutCoords(0, 0); // Create the dataset IRasterWorkspace2 rasterWorkspace2 = null; rasterWorkspace2 = createRasterWorkspace(directoryName); rasterDataset = rasterWorkspace2.CreateRasterDataset(fileName, "IMAGINE Image", originPoint, 200, 100, 1, 1, 1, rstPixelType.PT_UCHAR, new UnknownCoordinateSystemClass(), true); IRawPixels rawPixels = null; IPixelBlock3 pixelBlock3 = null; IPnt pixelBlockOrigin = null; IPnt pixelBlockSize = null; IRasterBandCollection rasterBandCollection; IRasterProps rasterProps; // QI for IRawPixels and IRasterProps rasterBandCollection = (IRasterBandCollection) rasterDataset; rawPixels = (IRawPixels) rasterBandCollection.Item(0); rasterProps = (IRasterProps) rawPixels; // Create pixelblock pixelBlockOrigin = new DblPntClass(); pixelBlockOrigin.SetCoords(0, 0); pixelBlockSize = new DblPntClass(); pixelBlockSize.SetCoords(rasterProps.Width, rasterProps.Height); pixelBlock3 = (IPixelBlock3) rawPixels.CreatePixelBlock(pixelBlockSize); // Read pixelblock rawPixels.Read(pixelBlockOrigin, (IPixelBlock) pixelBlock3); // Get pixeldata array System.Object[,] pixelData; pixelData = (System.Object[,]) pixelBlock3.get_PixelDataByRef(0); // Loop through all the pixels and assign value for(int i = 0; i < rasterProps.Width; i++) for (int j = 0; j < rasterProps.Height; j++) pixelData[i,j] = (i * j) % 255; // Write the pixeldata back System.Object cachePointer; cachePointer = rawPixels.AcquireCache(); rawPixels.Write(pixelBlockOrigin, (IPixelBlock) pixelBlock3); rawPixels.ReturnCache(cachePointer); // Return raster dataset return rasterDataset; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return null; } } public IRasterWorkspace2 createRasterWorkspace(string pathName) { // Create RasterWorkspace IWorkspaceFactory workspaceFactory = new RasterWorkspaceFactoryClass(); return workspaceFactory.OpenFromFile(pathName, 0) as IRasterWorkspace2; }
创建存储在地理数据库中的栅格目录:
// Libraries needed to run this code: // ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.Geometry public IRasterCatalog createCatalog(IRasterWorkspaceEx rasterWorkspaceEx, string catalogName, string rasterFieldName, string shapeFieldName, ISpatialReference shapeSpatialReference, ISpatialReference rasterSpatialReference, bool isManaged, IFields fields, string keyword) { // Create a raster catalog in a geodatabase workspace // rasterWorkspaceEx == destination geodatabase workspace (personal or ArcSDE) // catalogName == name of the raster catalog // rasterFieldName == name of the raster column // shapeFieldName == name of the geometry column // shapeSpatialReference == spatial reference of the geometry column // rasterSpatialReference == spatial reference fo the raster column // isManaged == for personal geodatabase only, if true, the rasters are managed by the GDB // fields == fields of the raster catalog table // keyword == ArcSDE only, configuration keyword if (fields == null) fields = createFields(rasterFieldName, shapeFieldName, isManaged, shapeSpatialReference, rasterSpatialReference); if (keyword.Length == 0) keyword = "defaults"; // create raster catalog IRasterCatalog newRasterCatalog = null; newRasterCatalog = rasterWorkspaceEx.CreateRasterCatalog(catalogName, fields, shapeFieldName, rasterFieldName, keyword); return newRasterCatalog; } private IFields createFields(string rasterFieldName, string shapeFieldName, bool isManaged, ISpatialReference shapeSpatialReference, ISpatialReference rasterSpatialReference) { // create Fields // add OID field IFieldsEdit fieldsEdit = new FieldsClass(); fieldsEdit.AddField(createOIDField("ObjectID")); // add NAME field fieldsEdit.AddField(createNameField("name")); // add RASTER field fieldsEdit.AddField(createRasterField(rasterFieldName, isManaged, rasterSpatialReference)); // add SHAPE field fieldsEdit.AddField(createShapeField(shapeFieldName, shapeSpatialReference)); // add XML field for METADATA fieldsEdit.AddField(createXMLField()); return (IFields) fieldsEdit; } private IField createNameField(string fieldName) { // create Name field IFieldEdit fieldEdit = new FieldClass(); fieldEdit.Name_2 = fieldName; fieldEdit.Type_2 = esriFieldType.esriFieldTypeString; return (IField) fieldEdit; } private IField createOIDField(string oidFieldName) { // Create OID field IFieldEdit fieldEdit = new FieldClass(); fieldEdit.Name_2 = oidFieldName; fieldEdit.Type_2 = esriFieldType.esriFieldTypeOID; return (IField) fieldEdit; } private IField createRasterField(string rasterFieldName, bool isManaged, ISpatialReference spatialReference) { // create Raster field IFieldEdit2 rasterFieldEdit = new FieldClass() as IFieldEdit2; IRasterDef rasterDef = new RasterDefClass(); rasterDef.Description = "this is a raster catalog"; // only for PGDB rasterDef.IsManaged = isManaged; if (rasterFieldName.Length == 0) rasterFieldName = "RASTER"; rasterFieldEdit.Name_2 = rasterFieldName; rasterFieldEdit.Type_2 = esriFieldType.esriFieldTypeRaster; // Set unknown spatial reference if not set if (spatialReference == null) spatialReference = new UnknownCoordinateSystemClass(); rasterDef.SpatialReference = spatialReference; // Set rasterdef rasterFieldEdit.RasterDef = rasterDef; return (IField) rasterFieldEdit; } private IField createShapeField(string shapeFieldName, ISpatialReference spatialReference) { // Create Shape field IFieldEdit fieldEdit = new FieldClass(); if (shapeFieldName.Length == 0) shapeFieldName = "SHAPE"; fieldEdit.Name_2 = shapeFieldName; fieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry; fieldEdit.GeometryDef_2 = createGeometryDef(spatialReference); return (IField) fieldEdit; } private IField createXMLField() { // create METADATA field IFieldEdit fieldEdit = new FieldClass(); fieldEdit.Name_2 = "METADATA"; fieldEdit.Type_2 = esriFieldType.esriFieldTypeBlob; return (IField) fieldEdit; } private IGeometryDef createGeometryDef(ISpatialReference spatialReference) { // Create GeometryDef IGeometryDefEdit geometryDefEdit = new GeometryDefClass(); geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon; geometryDefEdit.AvgNumPoints_2 = 4; geometryDefEdit.GridCount_2 = 1; geometryDefEdit.set_GridSize(0,1000); // Set unknown spatial reference is not set if (spatialReference == null) spatialReference = new UnknownCoordinateSystemClass(); geometryDefEdit.SpatialReference_2 = spatialReference; return (IGeometryDef) geometryDefEdit; }
创建存储在地理数据库中的栅格数据集:
// Libraries needed to run this code: // ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.Geometry public IRasterDataset createSDERasterDs(IRasterWorkspaceEx rasterWorkspaceEx, string rasterDatasetName, int numberOfBands, rstPixelType pixelType, ISpatialReference spatialReference, IRasterStorageDef rasterStorageDef, IRasterDef rasterDef, string keyword) { // Create a raster dataset in a geodatabase workspace // rasterWorkspaceEx == destination geodatabase workspace (personal or ArcSDE) // rasterDatasetName == Name of raster dataset to create // numberOfBands == number of bands in the raster dataset that will be created // pixelType == type of pixel in target raster dataset // spatialReference == desired spatial reference in raster dataset // rasterStorageDef == RasterStorageDef object of Raster dataset -- defines pyramids, tiling, etc // rasterDef == definition for spatial reference // sKeyword == ArcSDE only, configuration keyword IRasterDataset rasterDataset = null; IGeometryDef geometryDef; // if rasterdef is missing, create one with specified/unknown spatialreference if (rasterDef == null) rasterDef = createRasterDef(false, spatialReference); // if rasterstoragedef is missing, use default parameters if (rasterStorageDef == null) rasterStorageDef = createRasterStorageDef(); // create geometry definition geometryDef = createGeometryDef(spatialReference); // if keyword is missing, use default if (keyword.Length == 0) keyword = "DEFAULTS"; rasterDataset = rasterWorkspaceEx.CreateRasterDataset(rasterDatasetName, numberOfBands, pixelType, rasterStorageDef, keyword, rasterDef, geometryDef); return rasterDataset; } private IRasterDef createRasterDef(bool isManaged, ISpatialReference spatialReference) { // Create rasterdef IRasterDef rasterDef = new RasterDefClass(); rasterDef.Description = "Raster Dataset"; if (spatialReference == null) spatialReference = new UnknownCoordinateSystemClass(); rasterDef.SpatialReference = spatialReference; return rasterDef; } private IRasterStorageDef createRasterStorageDef() { // Create rasterstoragedef IRasterStorageDef rasterStorageDef = new RasterStorageDefClass(); rasterStorageDef.CompressionType = esriRasterSdeCompressionTypeEnum.esriRasterSdeCompressionTypeRunLength; rasterStorageDef.PyramidLevel = 2; rasterStorageDef.PyramidResampleType = rstResamplingTypes.RSP_BilinearInterpolation; rasterStorageDef.TileHeight = 128; rasterStorageDef.TileWidth = 128; return rasterStorageDef; } private IGeometryDef createGeometryDef(ISpatialReference spatialReference) { // Create GeometryDef IGeometryDefEdit geometryDefEdit = new GeometryDefClass(); geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon; geometryDefEdit.AvgNumPoints_2 = 4; geometryDefEdit.GridCount_2 = 1; geometryDefEdit.set_GridSize(0,1000); // Set unknown spatial reference is not set if (spatialReference == null) spatialReference = new UnknownCoordinateSystemClass(); geometryDefEdit.SpatialReference_2 = spatialReference; return (IGeometryDef) geometryDefEdit; }
创建镶嵌数据集:
//Libraries needed to run this code: // ESRI.ArcGIS.DataManagementTools, ESRI.ArcGIS.Geoprocessor, ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.Geometry void CreateMosaicDataset(IWorkspace ws, string strMosaicDatasetName, ISpatialReference spr, int nBandNum, string strPixel_type) { if (ws == null) return; IWorkspace2 pWorkspace2 = ws as IWorkspace2; if (pWorkspace2.get_NameExists(esriDatasetType.esriDTMosaicDataset, txtDatasetName.Text)) { //Dataset Has Existed return; } //Create CreateMosaicDataset CreateMosaicDataset gpProcess = new CreateMosaicDataset(); //Set Paramers gpProcess.in_workspace = ws; gpProcess.in_mosaicdataset_name = strMosaicDatasetName; gpProcess.coordinate_system = spr; gpProcess.num_bands = nBandNum; gpProcess.pixel_type = strPixel_type; //Call the IGPProcess Interface IGPProcess pGPProcess = gpProcess; Geoprocessor geoprocessor = new Geoprocessor(); geoprocessor.OverwriteOutput = true; try { //Do Create geoprocessor.Execute(pGPProcess, null); } catch { //Failed } }
2.3 加载栅格数据
添加 IRasterDataset 到Map:
// Libraries needed to use this code: // ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.Carto, ESRI.ArcGIS.Display void AddRasterLayer(IMap map, IRasterDataset rasterDataset) { // rasterDataset represents a RasterDataset from raster workspace, access workspace or sde workspace. // map represents the Map to add the layer to once it is created // Create a raster layer. Use CreateFromRaster method when creating from a Raster. IRasterLayer rasterLayer = new RasterLayerClass(); rasterLayer.CreateFromDataset(rasterDataset); // Add the raster layer to Map map.AddLayer(rasterLayer); // QI for availabilty of the IActiveView interface for a screen update IActiveView activeView = map as IActiveView; if (activeView != null) activeView.Refresh(); }
创建 IGdbRasterCatalogLayer
// Libraries needed to run this code: // ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.Carto private IGdbRasterCatalogLayer createGeodatabaseRasterLayer(IRasterWorkspaceEx rasterWorkspaceEx, string catalogName) { // rasterWorkspaceEx represents the workspace wher the raster catalog resides // catalogName is the name of the raster catalog IGdbRasterCatalogLayer gdbRasterCatalogLayer = null; //Open the raster catalog IRasterCatalog rasterCatalog = null; rasterCatalog = rasterWorkspaceEx.OpenRasterCatalog(catalogName); //Create the GdbRasterCatalogLayer if (rasterCatalog != null) { gdbRasterCatalogLayer = new GdbRasterCatalogLayerClass(); if (gdbRasterCatalogLayer.Setup((ITable)rasterCatalog) == false) { gdbRasterCatalogLayer = null; return gdbRasterCatalogLayer; } } return gdbRasterCatalogLayer; }
创建 IRasterCatalogLayer
// Libraries needed to run this code: // ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.DataSourcesRaster, ESRI.ArcGIS.Carto public IRasterCatalogLayer createTableBasedRasterLayer(IFeatureWorkspace featureWorkspace, string name) { //featureWorkspace is the workspace where the table based raster catalog resides. //name is the name of the raster catalog that will be open try { //Open the raster catalog as a regular table ITable table; table = featureWorkspace.OpenTable(name); //Create raster catalog table IRasterCatalogTable catalogTable = new RasterCatalogTableClass(); catalogTable.Table = table; catalogTable.Update(); //Create raster catalog layer IRasterCatalogLayer rasterCatalogLayer = new RasterCatalogLayerClass(); rasterCatalogLayer.Create(catalogTable); return rasterCatalogLayer; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return null; } }
2.4 管理栅格数据
更改栅格数据空间参考:
// Libraries needed to run this code: // ESRI.ArcGIS.DataSourcesRaster, ESRI.ArcGIS.Geodatabase, ESRI.ArcGIS.Geometry public static IRaster reprojectRasterDataset(string rasterWorkspaceName, string inRasterDatasetName, int projectedCoordinateCode) { IWorkspaceFactory rasterWorkspaceFactory = new RasterWorkspaceFactoryClass(); IRasterWorkspace rasterWorkspace = rasterWorkspaceFactory.OpenFromFile(rasterWorkspaceName, 0) as IRasterWorkspace; IRasterDataset rasterDataset = rasterWorkspace.OpenRasterDataset(inRasterDatasetName); // open rasterdataset and get default raster IRaster raster = rasterDataset.CreateDefaultRaster(); System.Console.WriteLine("Created default raster: " + inRasterDatasetName); // define spatial reference SpatialReferenceEnvironment spatialReferenceEnvironment = new SpatialReferenceEnvironmentClass(); ISpatialReference projectedSpatialReference = spatialReferenceEnvironment.CreateProjectedCoordinateSystem(projectedCoordinateCode); IRasterProps rasterProps = raster as IRasterProps; System.Console.WriteLine("Orig Raster Coordinate System: ." + rasterProps.SpatialReference.Name.ToString()); rasterProps.SpatialReference = projectedSpatialReference; System.Console.WriteLine("New Raster Coordinate System: ." + rasterProps.SpatialReference.Name.ToString()); // set raster property rasterProps.Height = (rasterProps.Height / 2); rasterProps.Width = (rasterProps.Width / 2); return raster; }
添加影像到镶嵌数据集:
/// <summary> /// 导入镶嵌数据集 /// </summary> /// <param name="MDatasetName">镶嵌数据集名称</param> /// <param name="filePath">物理路径</param> /// <param name="pWorkspace">工作空间</param> /// <param name="error"></param> /// <returns></returns> public static bool InputRasterMoasicDataset(string MDatasetName, string filePath, IWorkspace pWorkspace, out Exception error) { //Open Dataset IMosaicWorkspaceExtensionHelper mosaicExtHelper = new MosaicWorkspaceExtensionHelperClass(); // Find the right extension from the workspace. IMosaicWorkspaceExtension mosaicExt = mosaicExtHelper.FindExtension(pWorkspace); // Use the extension to open the mosaic dataset. IMosaicDataset theMosaicDataset = mosaicExt.OpenMosaicDataset(MDatasetName); try { Geoprocessor geoprocessor = new Geoprocessor(); geoprocessor.OverwriteOutput=true; AddRastersToMosaicDataset addMosaicDataSet = new AddRastersToMosaicDataset(); addMosaicDataSet.in_mosaic_dataset = theMosaicDataset;//1 addMosaicDataSet.raster_type="Raster Dataset";//2 addMosaicDataSet.input_path=filePath;//待入库的文件目录 addMosaicDataSet.filter="*"+Path.GetExtension(filePath);//匹配入镶嵌数据集中的文件类型 addMosaicDataSet.update_overviews="true"; addMosaicDataSet.update_boundary = "true"; addMosaicDataSet.update_cellsize_ranges = "true"; addMosaicDataSet.maximum_cell_size = 0; addMosaicDataSet.minimum_dimension = 1500; /** ALLOW_DUPLICATES 全部添加 * EXCLUDE_DUPLICATES 只添加更新的 * OVERWRITE_DUPLICATES 重写以前添加的 * */ addMosaicDataSet.duplicate_items_action = "ALLOW_DUPLICATES"; IGPProcess pGPProcess = addMosaicDataSet; //执行 geoprocessor.Execute(pGPProcess, null); error = null; return true; } catch (Exception ee) { error = ee; return false; } }
添加影像到栅格目录:
/// <summary> /// 导入数据(栅格目录库) /// </summary> /// <param name="RCDatasetName">栅格目录名称</param> /// <param name="filepaths">源数据路径</param> /// <param name="pWorkspace">栅格目录工作空间</param> /// <param name="eError"></param> /// <returns></returns> private static bool InputRasterCatalogData(string RCDatasetName, string filepaths, IWorkspace pWorkspace, out Exception eError) { eError = null; try { IRasterCatalogLoader pRCLoader = new RasterCatalogLoaderClass(); pRCLoader.Workspace = pWorkspace; pRCLoader.LoadDatasets(RCDatasetName, filepaths, null);
return true; } catch (Exception eX) { eError = eX; return false; } }
移除镶嵌数据集中的数据:
/// <summary> /// 移除镶嵌数据集中的数据 /// </summary> /// <param name="mosaicDataset">镶嵌数据集</param> /// <param name="sql">删除命令 例如:name='005'</param> public void RemoveMosaicDataSet(object mosaicDataset, string sql) { Geoprocessor geoprocessor = null; try { geoprocessor = new Geoprocessor (); geoprocessor.OverwriteOutput=true; RemoveRastersFromMosaicDataset deleteFeatures = new RemoveRastersFromMosaicDataset(); deleteFeatures.in_mosaic_dataset=mosaicDataset; deleteFeatures.where_clause=sql; IGPProcess pGPProcess = deleteFeatures; geoprocessor.OverwriteOutput=true; //执行 geoprocessor.Execute(pGPProcess, null); } catch{} }
For more information,please visit http://www.cnblogs.com/chen-whutgis/ or write emial to chen_whutgis@163.com .Best Regards!