加载中…
个人资料
在路上
在路上
  • 博客等级:
  • 博客积分:0
  • 博客访问:2,340
  • 关注人气:42
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

AE基于C# 示例代码【转】

(2013-02-20 15:19:12)
分类: AE
矢量转栅格
             IMap pMap = axMapControl1.Map;
            IFeatureLayer pFlyr = pMap.get_Layer(0) as IFeatureLayer;
            IFeatureClass pFCls = pFlyr.FeatureClass;
            IFeatureClassDescriptor pFClsDp = new FeatureClassDescriptorClass();
            pFClsDp.Create(pFCls, null, "landuse");

            IWorkspaceFactory pWsf = new RasterWorkspaceFactoryClass();
            IWorkspace pWs = pWsf.OpenFromFile(@"C:\Data", 0);
            IConversionOp pConOp = new RasterConversionOpClass();
            IRasterAnalysisEnvironment pEment = pConOp as IRasterAnalysisEnvironment;
            object oo = 200;
            pEment.SetCellSize(esriRasterEnvSettingEnum.esriRasterEnvValue, ref oo);


            IRasterDataset pRDataset = pConOp.ToRasterDataset(pFClsDp as IGeoDataset, "GRID", pWs, "raster");

            IRasterLayer pRlyr = new RasterLayerClass();
            pRlyr.CreateFromDataset(pRDataset);
            pMap.AddLayer(pRlyr as ILayer);

浏览属性表
 栅格图层和矢量图层的属性表浏览
if (pLyr is IFeatureLayer)
            {
                DataTable pTable = new DataTable();
                IFeatureLayer pFealyr = pLyr as IFeatureLayer;
                IFeatureClass pFCls = pFealyr.FeatureClass;
                string shape = "";
                if (pFCls.ShapeType == esriGeometryType.esriGeometryPoint)
                    shape = "Point";
                else if (pFCls.ShapeType == esriGeometryType.esriGeometryPolyline)
                    shape = "Polyline";
                else if (pFCls.ShapeType == esriGeometryType.esriGeometryPolygon)
                    shape = "Polygon";

                for (int i = 0; i < pFCls.Fields.FieldCount; i++)
                {
                    pTable.Columns.Add(pFCls.Fields.get_Field(i).Name);
                }
                IFeatureCursor pCursor = pFCls.Search(null, false);
                int ishape = pFCls.Fields.FindField("Shape");
                IFeature pFea = pCursor.NextFeature();
                while (pFea != null)
                {
                    DataRow pRow = pTable.NewRow();
                    for (int i = 0; i < pFCls.Fields.FieldCount; i++)
                    {
                        if (i == ishape)
                        {
                            pRow[i] = shape;
                            continue;
                        }
                        pRow[i] = pFea.get_Value(i).ToString();
                    }
                    pTable.Rows.Add(pRow);
                    pFea = pCursor.NextFeature();
                }
                dataGridView1.DataSource = pTable;
            }
            else if (pLyr is IRasterLayer)
            {
                IRasterLayer pRlyr = pLyr as IRasterLayer;
                IRaster pRaster = pRlyr.Raster;
                IRasterProps pProp = pRaster as IRasterProps;
                pProp.PixelType = rstPixelType.PT_LONG;
                if (pProp.PixelType == rstPixelType.PT_LONG)
                {
                    IRasterBandCollection pBcol = pRaster as IRasterBandCollection;
                    IRasterBand pBand =  pBcol.Item(0);
                    ITable pRTable =  pBand.AttributeTable;              

                    DataTable pTable = new DataTable();
                    for (int i = 0; i < pRTable.Fields.FieldCount; i++)
                        pTable.Columns.Add(pRTable.Fields.get_Field(i).Name);

                   
                     ICursor pCursor=    pRTable.Search(null, false);
                     IRow pRrow=   pCursor.NextRow();
                     while (pRrow != null)
                     {
                         DataRow pRow = pTable.NewRow();
                         for (int i =0 ;i
                         {
                             pRow[i] =  pRrow.get_Value(i).ToString ()   ;
                         }
                         pTable.Rows.Add(pRow);
                         pRrow = pCursor.NextRow();
                     }
                     dataGridView1.DataSource = pTable;
                }              

            }

IIdentify属性查询
           IPoint ppoint = pActView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);    
           IIdentify pIdentify = plyr as IIdentify;
           IEnvelope pEnv = ppoint.Envelope;
           IDisplayTransformation pDT = pActView.ScreenDisplay.DisplayTransformation;
           pEnv.Expand(pDT.VisibleBounds.Width / 100, pDT.VisibleBounds.Height / 100, false);
           IArray pArray = pIdentify.Identify(pEnv   as IGeometry);
           IIdentifyObj pIdentifyObj = pArray.get_Element(0) as IIdentifyObj;               
           pIdentifyObj.Flash(pActView.ScreenDisplay);

           TreeNode pNode = new TreeNode(plyr.Name);
           pFrm.treeView1.Nodes.Clear();
           pFrm.treeView1.Nodes.Add(pNode);
           pNode.Nodes.Add(pIdentifyObj.Name);
           pFrm.treeView1.ExpandAll();
           if (plyr is IRasterLayer)
           {
               int i = 0;
               IRasterIdentifyObj2 pRObj = pIdentifyObj as IRasterIdentifyObj2;
               string pField = "";
               string pValue = "";
               do
               {
                   pFrm.MxFelx.Rows = 2+i;                      
                   pRObj.GetPropAndValues(i, out pField, out pValue);
                   pFrm.MxFelx.set_TextMatrix(i + 1, 0, pField);
                   pFrm .MxFelx .set_TextMatrix (i+1,1,pValue ) ;                   
                   i++;
               }
               while (pField != "");          
               
           }
           else if (plyr is IFeatureLayer ) 
           {
               IRowIdentifyObject pRowObj = pIdentifyObj as IRowIdentifyObject;
               IRow pRow = pRowObj.Row;
               IFields pFields = pRow.Fields;

               pFrm.MxFelx.Rows = pFields.FieldCount + 1;
               for (int i = 0; i < pFields.FieldCount; i++)
               {
                   IField pField = pFields.get_Field(i);
                   pFrm.MxFelx.set_TextMatrix(i + 1, 0, pField.Name);
                   switch (pField.Type)
                   {
                       case esriFieldType.esriFieldTypeOID:
                           pFrm.MxFelx.set_TextMatrix(i + 1, 1, pRow.OID.ToString());
                           break;
                       case esriFieldType.esriFieldTypeGeometry:
                           pFrm.MxFelx.set_TextMatrix(i + 1, 1, QueryShapeType(pField.GeometryDef.GeometryType));
                           break;
                       default:
                           pFrm.MxFelx.set_TextMatrix(i + 1, 1, pRow.get_Value(i).ToString());
                           break;
                   }
               }

           }

Geodatabase中的QueryDef对象
QueryDef 对象代表了数据库中基于一个或多个表、要素类的进行的属性查询。通过这个对象,用户可以在多个表间建立连接,并且保证在这个连接基础上的查询可以实现。

QueryDef 中的表必须放在一个工作空间内,而QueryDef 对象也是用IFeatureWorkspace::CreateQueryDef 方法来产生,它并不是一个组件类。需要注意的是,它并不能在Shapefile 和Coverage 数据中使用,而仅仅可以使用在GeoDatabase数据库中。

QueryDef 的查询的结果是Cursor 对象返回的,系统可以依据返回的Cursor 来获得基于查询的要素集合。但是使用这种方式获得的Cursor 对象,仅仅是只读的,Cursor 指向的行对象并没有和它们的父表相关联,因而如果试图对这些被选择出来的数据使用store 方法会出现错误。

IQueryDef 是QueryDef 对象实现的主要接口,它定义了在多个表中定义连接需要使用的属性和方法。SubFields 属性是产生一个QueryDef 对象时的可选项,默认情况下它为“*”,它表示返回所有的字段。下面的例子用于显示如何产生一个QueryDef 对象,并使用它在两个表中产生一个连接,

 ' 产生一个QueryDef 对象 
Dim pQueryDef As IQueryDef 
pQueryDef = pFeatureWorkspace.CreateQueryDef 
' 基于连接的两个表必须是在一个工作空间内,设置它的各种属性 
pQueryDef.Tables = "Counties, States" 
pQueryDef.SubFields = "COUNTIES.Shape, COUNTIES.NAME, STATES.STATE_ABBR" 
pQueryDef.WhereClause = "COUNTIES.STATE_FIPS = STATES.STATE_FIPS"

IFeatureWorkspace::OpenFeatureQuery 方法会产生一个基于QueryDef 对象的要素类,这个要素类可以被作为一个要素图层被添加到一个Map 对象中去,它和ArcSDE 中的“视图”概念很类似。下面的例子就是基于一个上面产生的QueryDef 对象来新建一个要素类的例子,注意IQueryDed::SubFields 中必须设置一个字段,以保证新建的要素类有最少拥有一个属性字段: 
' 新建一个要素类 
Dim pFeatureClass As IFeatureClass 
Dim pFeatureClassContainer As IFeatureClassContainer 
pFeatureClassContainer = pFeatureWorkspace.OpenFeatureQuery ("My counties join", pQueryDef) 
' 判断IFeatureClassContainer 对象中是否有要素类存在 
If (pFeatureClassContainer.ClassCount <> 1) Then 
MsgBox "Failed to create feature class by query" 
Else pFeatureClass = pFeatureClassContainer.Class(0) 
End If 
' 添加要素类到Map 对象 
Dim pFeatureLayer As IFeatureLayer 
pFeatureLayer = New FeatureLayerClass 
pFeatureLayer.FeatureClass = pFeatureClass 
pFeatureLayer.Name = pFeatureClass.AliasName 
pMap.AddLayer (pFeatureLayer)

QueryDef 对象使用的SQL 语法和关系数据库中使用的SQL 语法是一样的,程序可以使用工作空间对象的ISqlSyntax 接口来获得这个数据库中的SQL 语法信息。

QueryDef 代表了一个查询的子集,在数据库中,用户也可以使用SELECT 语句来得到同样的结果。但是QueryDef 并不能完整地支持SQL 语句。在ArcObjects 中的SQL 语句不能使用SQL 语句的order by,如果需要对选择的结果结果进行排序,可以使用ITablesort 接口进行操作。


ArcEngine中获取图层唯一值的方法
    
    这是在ArcEngine9.2中,获取图层指定字段唯一值的方法。鉴于ArcEngine众多的接口、函数,选择

合适的接口、方法来进行操作是很关键的,而且对它的学习也相对困难一些,需要一定的时间积累才能渡

过初期的困难时刻,这里与大家共勉,希望能早日成为AE高手。获取图层唯一值,一般通过

IDataStatistics和IQueryDef接口,IDataStatistics代码如下:

        ///
        /// 通过IDataStatistics获取图层指定字段唯一值
        ///
        ///
        ///
        /// 指定字段所有唯一值
        private ArrayList GetLayerUniqueFieldValueByDataStatistics(IFeatureLayer 

pFeatureLayer, string fieldName)
        {
            ArrayList arrValues = new ArrayList();
            IQueryFilter pQueryFilter = new QueryFilterClass();
            IFeatureCursor pFeatureCursor = null;

            pQueryFilter.SubFields = fieldName;
            pFeatureCursor = pFeatureLayer.FeatureClass.Search(pQueryFilter, true);

            IDataStatistics pDataStati = new DataStatisticsClass();
            pDataStati.Field = fieldName;
            pDataStati.Cursor = (ICursor)pFeatureCursor;

            IEnumerator pEnumerator = pDataStati.UniqueValues;
            pEnumerator.Reset();
            while (pEnumerator.MoveNext())
            {
                object pObj = pEnumerator.Current;
                arrValues.Add(pObj.ToString());
            }

            arrValues.Sort();
            return arrValues;
        }


      据网上资料介绍,当图层的数据量很大时,以上这种方法执行起来速度较慢,性能影响比较明显,

得考虑使用另外一种方法。通过IQueryDef接口使用类似SQL的查询语句来获取图层字段的唯一值集合,执

行速度等同于执行SQL查询语句。
        ///
        /// 通过IQueryDef获取图层指定字段唯一值
        ///
        ///
        ///
        /// 指定字段所有唯一值
        private ArrayList GetLayerUniqueFieldValueByQueryDef(IFeatureLayer pFeatureLayer, 

string fieldName)
        {
            ArrayList arrValues = new ArrayList();

            IQueryDef pQueryDef = null;
            IRow pRow = null;
            ICursor pCursor = null;
            IFeatureWorkspace pFeatWrok = null;
            IDataset pDataset = null;

            pDataset = (IDataset)pFeatureLayer.FeatureClass;
            pFeatWrok = (IFeatureWorkspace)pDataset.Workspace;
            pQueryDef = pFeatWrok.CreateQueryDef();
            pQueryDef.Tables = pDataset.Name;
            pQueryDef.SubFields = "DISTINCT(" + fieldName + ")";
            pCursor = pQueryDef.Evaluate();

            pRow = pCursor.NextRow();
            while (pRow != null)
            {
                object pObj = pRow.get_Value(0);
                arrValues.Add(pObj.ToString());

                pRow = pCursor.NextRow();
            }

            arrValues.Sort();
            return arrValues;
        }
      经过的我的实际测试,在C#中,用IQueryDef方法没有成功,运行到这句pCursor = 

pQueryDef.Evaluate();就出错了,并没有得到结果集,估计是workspace的原因,查看ArcEngine的帮助

例子,确定应该是这个原因。因此后面的这个函数,在使用时需要注意,在同一个workspace下进行。 

ArcGIS中的投影和坐标转换
                                  --   转载

南京凯图科技有限责任公司 郭胜涛   1  ArcGIS中坐标系统的定义

一般情况下地理数据库(如Personal GeoDatabase的 Feature DataSet 、Shape File等)在创建时都具有空间参考的属性,空间参考定义了该数据集的地理坐标系统或投影坐标系统,没有坐标系统的地理数据在生产应用过程中是毫无意义的,但由于在数据格式转换、转库过程中可能造成坐标系统信息丢失,或创建数据库时忽略了坐标系统的定义,因此需要对没有坐标系统信息的数据集进行坐标系统定义。

坐标系统的定义是在不改变当前数据集中特征X Y值的情况下对该数据集指定坐标系统信息。

操作方法:运行ArcGIS9中的ArcMap,打开ArcToolBox,打开 Data Management Tools ->Projections and Transformations->Define Projection 项打开坐标定义对话框。介下来在Input DataSet or Feature Class栏中输入或点击旁边的按钮选择相应的DataSet或Feature Class;在Coordinate System栏中输入或点击旁边的按钮选择需要为上述DataSet或Feature定义的坐标系统。最后点OK键即可。

例如 某点状shape文件中 某点P的坐标为  X 112.2  Y 43.3 ,且该shape文件没有带有相应的Prj文件,即没有空间参考信息,也不知道X Y 的单位。通过坐标系统定义的操作定义其为Beijing1954坐标,那么点P的信息是东经112.2度 北纬43.3度。

2  ArcGIS中的投影方法
投影的方法可以使带某种坐标信息数据源进行向另一坐标系统做转换,并对源数据中的X和Y值进行修改。我们生产实践中一个典型的例子是利用该方法修正某些旧地图数据中X,Y值前加了带数和分带方法的数值。

操作方法:运行ArcGIS9中的ArcMap,打开ArcToolBox,打开 Data Management Tools ->Projections and Transformations->Feature->Project 项打开投影对话框。在Input DataSet or Feature Class栏中输入或点击旁边的按钮选择相应的DataSet或Feature Class(带有空间参考),Output DataSet or Feature Class栏中输入或点击旁边的按钮选择目标DataSet或Feature Class,在Output Coordinate System 栏中输入或点击旁边的按钮选择目标数据的坐标系统。最后点OK键即可。

例如 某点状shape文件中 某点P的坐标为  X 40705012  Y 3478021 ,且该shape文件坐标系统为中央为东经120度的高斯克吕格投影,在数据使用过程中为了将点P的值改为真实值X 705012  Y478021,首先将源数据的投影参数中False_Easting和False_Northing值分别加上40000000和3000000作为源坐标系统,修改参数前的坐标系统作为投影操作的目标坐标系统,然后通过投影操作后生成一新的Shape文件,且与源文件中点P对应的点的坐标为X 705012  Y478021。

3  编程实现坐标转换和投影
3.1 矢量数据投影和坐标转换
相关接口

3.1.1 IGeometry.Project方法
该方法声明如下: (C#语法)

public void Project (    ISpatialReference newReferenceSystem);

该方法对实现Igeoemtry的对象进行投影操作, 参数为目标空间参考.以下代码中实现了对Point对象从一个空间参考到另一个空间参考的投影操作:

//Create Spatial Reference Factory
            ISpatialReferenceFactory srFactory = new SpatialReferenceEnvironmentClass();

            ISpatialReference sr1;

            //GCS to project from

            IGeographicCoordinateSystem gcs = srFactory.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_NAD1983);

            sr1 = gcs;

            sr1.SetFalseOriginAndUnits(-180, -90, 1000000);

            //Projected Coordinate System to project into

            IProjectedCoordinateSystem pcs = srFactory.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_NAD1983N_AmericaLambert);

            pcs.SetFalseOriginAndUnits(0, 0, 1000);

            ISpatialReference sr2;

            sr2 = pcs;

            //Point to project

            IPoint point = new PointClass() as IPoint;

            point.PutCoords(-117.17, 34.06);

            //Geometry Interface to do actual project

            IGeometry geometry;

            geometry = point;

            geometry.SpatialReference = sr1;

            geometry.Project(sr2);

            point = geometry as IPoint;

            double x;

            double y;

            point.QueryCoords(out x, out y);

            Debug.Print("X: " + x.ToString());

            Debug.Print("Y: " + y.ToString());

IGeometry接口的Project方法提供的投影操作实现了最基本的坐标转换功能. 实际数据处理过程中, 比较明确数据转换前后空间参考信息情况下一般用此方法作坐标转换,不同投影带之间的坐标转换就是一个典型.

3.1.2 ITransform2D接口
ITransform2D接口不仅提供了图形平移, 旋转和缩放,还提供了更加强大的坐标转换方法Transform. 其定义如下:(C#语法)

public void Transform (
    esriTransformDirection direction,
    ITransformation transformation
);

在该方法中, 参数direction是转换方向, transformation是一个Itransformation接口, 而Itransformation接口由很多类实现,这意味着不同的实现类,所包含的坐标转换数学公式是不一的, 这里面包括二次多项式转换(AffineTransformation2D), AbridgedMolodensky转换(AbridgedMolodenskyTransformation)等。每一种实现类的转换方法这里不再赘述,可参照ArcObjects联机帮助获得更详细的信息,下面举例来说明该方法的使用:(Delphi 代码)

procedure Transform_(FromPtColl, ToPtColl: IPointCollection; pGeo as IGeometry);
var
  pAffineTransformation2D: IAffineTransformation2D;
  ControlPtCnt: integer;
  FormPtArray: array of IPoint;
  ToPtArray: array of IPoint;
  i: integer;  
  pTransform2D: ITransform2D; 
begin
  //判断给定的控制点是否合法
  if FromPtColl.PointCount <> ToPtColl.PointCount then
    begin
      //控制点不成对错误
      exit;
    end;
  if FromPtColl.PointCount < 4 then
    begin
      //控制点不能少于4个
      exit;
    end;
  ControlPtCnt := FromPtColl.PointCount;
  SetLength(FormPtArray, ControlPtCnt);
  SetLength(ToPtArray, ControlPtCnt);
  for i := 0 to ControlPtCnt -1 do
    begin
      FormPtArray[i] := CoPoint.Create as IPoint;
      FormPtArray[i].PutCoords(FromPtColl.Point[i].X,  FromPtColl.Point[i].Y);
      ToPtArray[i] := CoPoint.Create as IPoint;
      ToPtArray[i].PutCoords(ToPtColl.Point[i].X,  ToPtColl.Point[i].Y);
    end;
  //创建  AffineTransformation2D 对象
  pAffineTransformation2D := CoAffineTransformation2D.Create as IAffineTransformation2D;  
  //设置控制点信息
  pAffineTransformation2D.DefineFromControlPoints(ControlPtCnt, FormPtArray[0], ToPtArray[0]);  
  //转到ITransform2D接口
  pTransform2D := pGeo as ITransform2D;
  //坐标转换
  pTransform2d.Transform(esriTransformForward, pAffineTransformation2D);
end;
 
ITransform接口较Igeoemtry提供了更加丰富的坐标转换方法。

3.2 影像数据纠正。
影像数据纠正可以通过IrasterGeometryProc接口实现。该接口提供了影像Clip, Filp, Merge, Mirror以及Mosaic等操作。如果通过控制点的方式对影像进行纠正处理可以通过该接口的wrap方法。该方法声明如下:(C#语法)

public void Warp (
    IPointCollection sourceControlPoints,
    IPointCollection targetControlPoints,
    esriGeoTransTypeEnum transformType,
    IRaster ipRaster
);

参数 sourceControlPoints和targetControlPoint定义了控制点信息, transformType定义了坐标转换方法, ipRaster是需要转换的Raster对象. 以下代码是该接口使用的例子:

public static void GeoreferenceRaster(IRasterDataset2 rasterDataset, IPointCollection sourcePoints, IPointCollection targetPoints)
{
  //this sample show how to georeference a raster using control points
  // sourcePoints: represents source control points
  // targetPoints: represents target control points  IRasterGeometryProc rasterPropc = new RasterGeometryProcClass();
  IRaster raster = rasterDataset.CreateDefaultRaster();  //set the transformatin
  rasterPropc.Warp(sourcePoints, targetPoints, esriGeoTransTypeEnum.esriGeoTransPolyOrder1, raster);  //There are two ways to get the georeferenced result: to save the transformation with the input raster dataset
  rasterPropc.Register(raster);  //or save to another new raster dataset
  rasterPropc.Rectify(@"c:\temp\georeferencing_output.img", "IMAGINE Image", raster);
}
需要注意的是当选择不同的转换类型时(参数transformType取值不同时), 对控制点的对数也有不同的要求. 这个可以参照联机帮助中的详细说明.

此外, 使用IrasterGeometryProc.Wrap方法, 会略微改变影像图的色彩值, 当对一幅影像图前后转换作对比时会发现这种色彩的变化情况.

个人认为,ArcGIS对影像图的处理功能较其他一些专业影像处理软件来讲,还是稍显逊色了些.

矢量图层叠加求交
            IMap pMap = axMapControl1.Map;
            ITable pInTable = ((IFeatureLayer)pMap.get_Layer(0)).FeatureClass as ITable;
            ITable pTempTable = ((IFeatureLayer)pMap.get_Layer(1)).FeatureClass as ITable;

            IFeatureClassName pName = new FeatureClassNameClass();
            pName.FeatureType = esriFeatureType.esriFTSimple;
            pName.ShapeFieldName = "shape";
            pName.ShapeType = esriGeometryType.esriGeometryPolygon;

 


            IWorkspaceName pWsName = new WorkspaceNameClass();
            pWsName.WorkspaceFactoryProgID = "esriDataSourcesFile.ShapefileWorkspaceFactory";
            pWsName.PathName = @"C:\Data";
            IDatasetName pDatasetName = pName as IDatasetName;
            pDatasetName.Name = "Interset_resultaa";
            pDatasetName.WorkspaceName = pWsName;

            IBasicGeoprocessor pBGeoOr = new BasicGeoprocessorClass();
            IFeatureClass pFeaCls = pBGeoOr.Intersect(pInTable, false, pTempTable, false, 0, pName);

            IFeatureLayer pFeaLyr = new FeatureLayerClass();
            pFeaLyr.FeatureClass = pFeaCls;
            pFeaLyr.Name = pFeaCls.AliasName;
            pMap.AddLayer(pFeaLyr as ILayer);

矢量图层合并
本程序实现了对具有同类型数据结构的shapefile的图层合并,并在MapControl中显示.

            ILayer pLayer;
            IFeatureLayer pFeatureLayer;
            IFeatureClass pFeatureClass;
            IWorkspaceName pNewWSName;
            IBasicGeoprocessor pBasicGeop;
            IFeatureClassName pFeatureClassName;
            IDatasetName pDatasetName;
            IFeatureClass pOutputFeatClass;
            IFeatureLayer pOutputFeatLayer;
            IArray pArray;
            ITable pTable;
            //合并图层的集合
            pArray = new ArrayClass();
            for (int i = 0; i < this.MapC_main.LayerCount;i++ )
            {
                pLayer = this.MapC_main.get_Layer(i);
                pArray.Add(pLayer);
            }
            //定义输出图层的fields表
            pLayer = this.MapC_main.get_Layer(0);
            pTable = (ITable)pLayer;

            pFeatureLayer=(IFeatureLayer)pLayer;
            pFeatureClass = pFeatureLayer.FeatureClass;
            //判断图层是否大于2个
            if(this.MapC_main.LayerCount< 2){
                MessageBox.Show("Table QI failed");
                return;
            }
            //输出文件类型
            pFeatureClassName = new FeatureClassNameClass();
            pFeatureClassName.FeatureType = esriFeatureType.esriFTSimple;
            pFeatureClassName.ShapeFieldName = "Shape";
            pFeatureClassName.ShapeType = pFeatureClass.ShapeType;
            //输出shapefile的名称和位置
            pNewWSName = new WorkspaceNameClass();
            pNewWSName.WorkspaceFactoryProgID="esriDataSourcesFile.ShapefileWorkspaceFactory";
            pNewWSName.PathName = "E:\\Cshape";
            pDatasetName = (IDatasetName)pFeatureClassName;
            pDatasetName.Name = "Union_result_1";
            pDatasetName.WorkspaceName = pNewWSName;
            
            //合并图层
            pBasicGeop = new BasicGeoprocessorClass();
            pOutputFeatClass=pBasicGeop.Merge(pArray,pTable,pFeatureClassName);
            //Add the output layer to the map
            pOutputFeatLayer = new FeatureLayerClass();
            pOutputFeatLayer.FeatureClass = pOutputFeatClass;
            pOutputFeatLayer.Name = pOutputFeatClass.AliasName;
            this.MapC_main.AddLayer(pOutputFeatLayer as ILayer, 0);

Geodatabase中的QueryDef对象
07-12-19 00:00:00 作者:浩淼的天空 出处:浩淼的天空
QueryDef 对象代表了数据库中基于一个或多个表、要素类的进行的属性查询。通过这个对象,用户可以在多个表间建立连接,并且保证在这个连接基础上的查询可以实现。

QueryDef 中的表必须放在一个工作空间内,而QueryDef 对象也是用IFeatureWorkspace::CreateQueryDef 方法来产生,它并不是一个组件类。需要注意的是,它并不能在Shapefile 和Coverage 数据中使用,而仅仅可以使用在GeoDatabase数据库中。

QueryDef 的查询的结果是Cursor 对象返回的,系统可以依据返回的Cursor 来获得基于查询的要素集合。但是使用这种方式获得的Cursor 对象,仅仅是只读的,Cursor 指向的行对象并没有和它们的父表相关联,因而如果试图对这些被选择出来的数据使用store 方法会出现错误。

IQueryDef 是QueryDef 对象实现的主要接口,它定义了在多个表中定义连接需要使用的属性和方法。SubFields 属性是产生一个QueryDef 对象时的可选项,默认情况下它为“*”,它表示返回所有的字段。下面的例子用于显示如何产生一个QueryDef 对象,并使用它在两个表中产生一个连接,

 ' 产生一个QueryDef 对象 
Dim pQueryDef As IQueryDef 
pQueryDef = pFeatureWorkspace.CreateQueryDef 
' 基于连接的两个表必须是在一个工作空间内,设置它的各种属性 
pQueryDef.Tables = "Counties, States" 
pQueryDef.SubFields = "COUNTIES.Shape, COUNTIES.NAME, STATES.STATE_ABBR" 
pQueryDef.WhereClause = "COUNTIES.STATE_FIPS = STATES.STATE_FIPS"

IFeatureWorkspace::OpenFeatureQuery 方法会产生一个基于QueryDef 对象的要素类,这个要素类可以被作为一个要素图层被添加到一个Map 对象中去,它和ArcSDE 中的“视图”概念很类似。下面的例子就是基于一个上面产生的QueryDef 对象来新建一个要素类的例子,注意IQueryDed::SubFields 中必须设置一个字段,以保证新建的要素类有最少拥有一个属性字段: 
' 新建一个要素类 
Dim pFeatureClass As IFeatureClass 
Dim pFeatureClassContainer As IFeatureClassContainer 
pFeatureClassContainer = pFeatureWorkspace.OpenFeatureQuery ("My counties join", pQueryDef) 
' 判断IFeatureClassContainer 对象中是否有要素类存在 
If (pFeatureClassContainer.ClassCount <> 1) Then 
MsgBox "Failed to create feature class by query" 
Else pFeatureClass = pFeatureClassContainer.Class(0) 
End If 
' 添加要素类到Map 对象 
Dim pFeatureLayer As IFeatureLayer 
pFeatureLayer = New FeatureLayerClass 
pFeatureLayer.FeatureClass = pFeatureClass 
pFeatureLayer.Name = pFeatureClass.AliasName 
pMap.AddLayer (pFeatureLayer)

QueryDef 对象使用的SQL 语法和关系数据库中使用的SQL 语法是一样的,程序可以使用工作空间对象的ISqlSyntax 接口来获得这个数据库中的SQL 语法信息。

QueryDef 代表了一个查询的子集,在数据库中,用户也可以使用SELECT 语句来得到同样的结果。但是QueryDef 并不能完整地支持SQL 语句。在ArcObjects 中的SQL 语句不能使用SQL 语句的order by,如果需要对选择的结果结果进行排序,可以使用ITablesort 接口进行操作。


如何使用Name对象
如何使用Name对象,包括WorkspaceNames和DatasetNames
                                                                                                            ----转载

一、Name对象
    Name对象是一个代表性对象。通过使用Name对象,可以访问它所代表的对象的一些基本属性,而不用将整个对象调入内存,如果需要用到Name对象所代表的对象本身,可以通过Name来获取它。
    Name对象可以应用于Tables,FeatureClasses和Workspaces。

Name:
       1、WorkspaceName
       2、DatasetName
             1>RelationshipClassName
             2>FeatureDatasetName
             3>RasterDatasetName
             4>TinName
             5>TableName    
                        △--FeatureClassName
        使用Name对象最重要的一点是通过Name来获取所代表的对象,要访问Name子类里的任何对象,使用IName接口的Open方法。
示例:查找某个数据集并打开它
public void OpenCities()
{
    IWorkspaceFactory pWSFactory;
    IWorkspace pWS;
    IEnumDatasetName pEnumDSNames;
    IDatasetName pDSName;
    IFeatureClass pCities;

    pWSFactory = new ShapefileWorkspaceFactoryClass();
    pWS = pWSFactory.OpenFromFile("C:\\Data\\Africa", 0);
    pEnumDSNames = pWS.DatasetNames(esriDatasetType.esriDTFeatureClass);//feature class
    pDSName = pEnumDSNames.Next();
    while (pDSName != null)
    {
       if (pDSName.Name == "AfricanCities")
       {
          IName pName = pDSName as IName;
          pCities = pName.Open() as IFeatureClass;
          return;
        }
    pDSName = pEnumDSNames.Next();
}

二、使用DataSetNames
    Name对象的一个常用用法是用来在磁盘中新建数据集时指定名字。例如,在数据转换过程中的输入输出参数中,使用DatasetName对象即可,而不必用dataset对象。DatasetName的所有子类都是可以用New关键字新建的CoClass,一旦创建好就可以设置Name属性来代表数据集。
示例:在C:\Data下创建一个新表PositianFroys.dbf。
IWorkspaceFactory pShapeWSFactory;
IWorkspaceName pWorkName;
IDatasetName pTableName;

pShapeWSFactory = new ShapefileWorkspaceFactoryClass();
pWorkName = pShapeWSFactory.Create("C:\", "Data", null, 0);
pTableName = new TableNameClass();
pTableName.WorkspaceName = pWorkName;
pTable.Name = "PositianFroys.dbf";

三、数据的转换、输出和装载
    FeatureDataConverter是一个能将要素类、要素集或表转换成其它数据集的CoClass,它不仅可以转换单个的要素类或表,也可以转换整个数据集(如ArcInfo Coverage)。FeatureDataConverter对象能够使数据在geodatabase,shapefile和coverages之间转换支持大多数的数据类型(除了标注)。在把数据引入geodatabase时,可以指定数据的区别;对ArcSDE Geodatabase还可以通过配置ArcSDE的某些关键字来指定存储参数。
    ExportOperation是一个用于输出要素类或表的CoClass。它提供的功能与要素数据转换器大体相似,但是形式更简单。在ArcMap的目录表中右击一个图层时就是调用了这个数据输出函数。
    ObjectLoader用于向表(或要素类)中追加一个表(或要素类)。IObjectLoader只包含一个方法--LoadObjects。

四、验证字段和记录
    FieldChecker对象可以用来验证一个字段集,这对于在不同格式间转换数据时很有用,因为不同格式的数据集字段名可能不通用。FieldChecker遇到非法字段名时能够根据一定的标准(如加底线UID)来纠正错误从而产生一个合法的字段集。在把数据转换成Geodatabase格式时,FieldChecker将为Geometry字段和OID字段生成标准的名字(Shape和OBJECTID)。
    在用ObjectLoader或FeatureDataConverter装载或者转换要素时,非法对象将以枚举的形式被返回(IEnumInvalidObject),通过查看这个枚举,很容易知道哪些对象不能被装载或转换。

五、使用Feature Data Converter
    IFeatureDataConverter接口有3个方法用于转换数据:
1、ConvertFeatureClass
2、ConvertFeatureDataset
3、ConvertTable

public IEnumInvalidObject ConvertFeatureClass (
    IFeatureClassName InputDatasetName,
    IQueryFilter InputQueryFilter,
    IFeatureDatasetName outputFDatasetName,
    IFeatureClassName outputFClassName,
    IGeometryDef OutputGeometryDef,
    IFields OutputFields,
    string configKey,
    int FlushInterval,
    int parentHWND
);
InputDatasetName--IFeatureClassName用于指定转换的要素类的一个Name对象;
InputQueryFilter--IQueryFilter用于过滤要转换的要素的QueryFilter对象;
outputFDatasetName--IFeatureDatasetName要素类输出的新数据集成现存数据集的Name对象;
outputFClassName--IFeatureClassName新输出的要素类的Name对象;
OutputGeometryDef--用于指定输出要素类的空间参考信息的GeometryDef对象。如果知道为null就使用输出的要素集成输入的要素类的空间参考信息。
OutputFields--IFields用于指定输出要素类的字段集。如果把要素类简单的输出为同样的格式,可以使用输入的要素类的字段集。如果格式有变化,建议使用FieldChecker以确保输出的格式有效;
configKey--string用于指定ArcSDE配置关键字的字符串;
FlushInterval--在输出到Geodatabase时用于指定把要素转换到新的要素类时的区间整数值;
parentHWND--指定应用程序的窗口句柄;

示例://IFeatureDataConverter ConvertFeatureClass Example(From .NET Help)

    //e.g., nameOfSourceFeatureClass = "ctgFeatureshp.shp"
    //      nameOfTargetFeatureClass = "ctgFeature"
    public void IFeatureDataConverter_ConvertFeatureClass_Example(IWorkspace sourceWorkspace, IWorkspace targetWorkspace, string nameOfSourceFeatureClass, string nameOfTargetFeatureClass)
    {
        //create source workspace name
        IDataset sourceWorkspaceDataset = (IDataset)sourceWorkspace;
        IWorkspaceName sourceWorkspaceName = (IWorkspaceName)sourceWorkspaceDataset.FullName;

        //create source dataset name
        IFeatureClassName sourceFeatureClassName = new FeatureClassNameClass();
        IDatasetName sourceDatasetName = (IDatasetName)sourceFeatureClassName;
        sourceDatasetName.WorkspaceName = sourceWorkspaceName;
        sourceDatasetName.Name = nameOfSourceFeatureClass;

        //create target workspace name
        IDataset targetWorkspaceDataset = (IDataset)targetWorkspace;
        IWorkspaceName targetWorkspaceName = (IWorkspaceName)targetWorkspaceDataset.FullName;

        //create target dataset name
        IFeatureClassName targetFeatureClassName = new FeatureClassNameClass();
        IDatasetName targetDatasetName = (IDatasetName)targetFeatureClassName;
        targetDatasetName.WorkspaceName = targetWorkspaceName;
        targetDatasetName.Name = nameOfTargetFeatureClass;

        //Open input Featureclass to get field definitions.
        ESRI.ArcGIS.esriSystem.IName sourceName = (ESRI.ArcGIS.esriSystem.IName)sourceFeatureClassName;
        IFeatureClass sourceFeatureClass = (IFeatureClass)sourceName.Open();

        //Validate the field names because you are converting between different workspace types.
        IFieldChecker fieldChecker = new FieldCheckerClass();
        IFields targetFeatureClassFields;
        IFields sourceFeatureClassFields = sourceFeatureClass.Fields;
        IEnumFieldError enumFieldError;

        // Most importantly set the input and validate workspaces!
        fieldChecker.InputWorkspace = sourceWorkspace;
        fieldChecker.ValidateWorkspace = targetWorkspace;
        fieldChecker.Validate(sourceFeatureClassFields, out enumFieldError, out targetFeatureClassFields);

        // Loop through the output fields to find the geomerty field
        IField geometryField;
        for (int i = 0; i < targetFeatureClassFields.FieldCount; i++)
        {
            if (targetFeatureClassFields.get_Field(i).Type == esriFieldType.esriFieldTypeGeometry)
            {
                geometryField = targetFeatureClassFields.get_Field(i);
                // Get the geometry field's geometry defenition
                IGeometryDef geometryDef = geometryField.GeometryDef;

                //Give the geometry definition a spatial index grid count and grid size
                IGeometryDefEdit targetFCGeoDefEdit = (IGeometryDefEdit)geometryDef;

                targetFCGeoDefEdit.GridCount_2 = 1;
                targetFCGeoDefEdit.set_GridSize(0, 0); //Allow ArcGIS to determine a valid grid size for the data loaded
                targetFCGeoDefEdit.SpatialReference_2 = geometryField.GeometryDef.SpatialReference;

                // we want to convert all of the features
                IQueryFilter queryFilter = new QueryFilterClass();
                queryFilter.WhereClause = "";

                // Load the feature class
                IFeatureDataConverter fctofc = new FeatureDataConverterClass();
                IEnumInvalidObject enumErrors = fctofc.ConvertFeatureClass(sourceFeatureClassName, queryFilter, null, targetFeatureClassName, geometryDef, targetFeatureClassFields, "", 1000, 0);
                break;
            }
        }
    }

关于Raster的理解
关于Raster的理解
 作者:3s4d 出处:http://www.gissky.net/blog/user1/yumao/15896.html
raster 是在重投影、重采样后内存中存在的短暂的数据表达。对raster的修改并不能够影响现有的数据源。虽然是存储在内存中,但是我们可以通过方法来永久保存这个raster对象。
如我们可以使用:ISaveAs 接口 或者 IRasterBandCollection  接口 来进行保存 raster对象;
创建raster对象的方法:
1,从现有的RasterLayer 中派生出raster对象IRasterLayer::Raster;
2,从rasterdataset对象中创建raster对象;
   IRasterDataset::CreateDefaultRaster 方法;--本方法是创建默认的raster,最多具有3个rasterdataset
   中的波段band。
   IRasterDataset2::CreateRaster 方法;--本方法是创建空raster对象的方法,所创建的raster属性都是空值0。
   IRasterDataset2::CreateFullRaster方法;--本方法创建的raster对象,会包含所有的波段band。

当创建完空的raster对象后,就需要对raster对象设置长、宽 extent 等属性,使用IRasterProps(设置)接口;
使用获取Raster对象的raster属性信息 使用IRasterDefaultProps(只读)接口来查看;
使用IRasterAnalysisProps接口来设置raster分析时的属性;

名词解释:
PixelBlock :字面上理解为“像素块”。顾名思义PixelBlock 是多个像素点组成的块,它的大小可以是整个raster, 当然也可以是raster中的某一个区域(要随定义块的大小而定行数、列数而确定);利用这个PixelBlock 我们可以读取PixelBlock上的所有像素点值(通过SafeArray来获取)。我们也可以理解使用PixelBlock可以从原有的raster或rasterband中截取一个区域,组成新的raster或者rasterband。
Planes :    可以把它理解为是波段。如一个raster有3个波段,那么Planes的数量就是3;
SafeArray:  返回某一波段中pixelBlock的所有像素数组;
GetVal:   而GetVal是可以返回特点波段上,特定行、列上的数值;

测量面积的简单实现
  public override void OnMouseDown(int Button, int Shift, int X, int Y)
        {
            IActiveView pActView = m_hookHelper.ActiveView;
            IScreenDisplay pScreen = pActView.ScreenDisplay;
            IRubberBand pRubber = new RubberPolygonClass();
            IPolygon pPolygon = pRubber.TrackNew(pScreen, null) as IPolygon ;
            IArea pArea = pPolygon as IArea;
            double dArea =  pArea.Area;
            MessageBox.Show("面积为:" + dArea);
             
        }
关于Raster的理解
 作者:3s4d 出处:http://www.gissky.net/blog/user1/yumao/15896.html
raster 是在重投影、重采样后内存中存在的短暂的数据表达。对raster的修改并不能够影响现有的数据源。虽然是存储在内存中,但是我们可以通过方法来永久保存这个raster对象。
如我们可以使用:ISaveAs 接口 或者 IRasterBandCollection  接口 来进行保存 raster对象;
创建raster对象的方法:
1,从现有的RasterLayer 中派生出raster对象IRasterLayer::Raster;
2,从rasterdataset对象中创建raster对象;
   IRasterDataset::CreateDefaultRaster 方法;--本方法是创建默认的raster,最多具有3个rasterdataset
   中的波段band。
   IRasterDataset2::CreateRaster 方法;--本方法是创建空raster对象的方法,所创建的raster属性都是空值0。
   IRasterDataset2::CreateFullRaster方法;--本方法创建的raster对象,会包含所有的波段band。

当创建完空的raster对象后,就需要对raster对象设置长、宽 extent 等属性,使用IRasterProps(设置)接口;
使用获取Raster对象的raster属性信息 使用IRasterDefaultProps(只读)接口来查看;
使用IRasterAnalysisProps接口来设置raster分析时的属性;

名词解释:
PixelBlock :字面上理解为“像素块”。顾名思义PixelBlock 是多个像素点组成的块,它的大小可以是整个raster, 当然也可以是raster中的某一个区域(要随定义块的大小而定行数、列数而确定);利用这个PixelBlock 我们可以读取PixelBlock上的所有像素点值(通过SafeArray来获取)。我们也可以理解使用PixelBlock可以从原有的raster或rasterband中截取一个区域,组成新的raster或者rasterband。
Planes :    可以把它理解为是波段。如一个raster有3个波段,那么Planes的数量就是3;
SafeArray:  返回某一波段中pixelBlock的所有像素数组;
GetVal:   而GetVal是可以返回特点波段上,特定行、列上的数值;


关于Raster的理解
 作者:3s4d 出处:http://www.gissky.net/blog/user1/yumao/15896.html
raster 是在重投影、重采样后内存中存在的短暂的数据表达。对raster的修改并不能够影响现有的数据源。虽然是存储在内存中,但是我们可以通过方法来永久保存这个raster对象。
如我们可以使用:ISaveAs 接口 或者 IRasterBandCollection  接口 来进行保存 raster对象;
创建raster对象的方法:
1,从现有的RasterLayer 中派生出raster对象IRasterLayer::Raster;
2,从rasterdataset对象中创建raster对象;
   IRasterDataset::CreateDefaultRaster 方法;--本方法是创建默认的raster,最多具有3个rasterdataset
   中的波段band。
   IRasterDataset2::CreateRaster 方法;--本方法是创建空raster对象的方法,所创建的raster属性都是空值0。
   IRasterDataset2::CreateFullRaster方法;--本方法创建的raster对象,会包含所有的波段band。

当创建完空的raster对象后,就需要对raster对象设置长、宽 extent 等属性,使用IRasterProps(设置)接口;
使用获取Raster对象的raster属性信息 使用IRasterDefaultProps(只读)接口来查看;
使用IRasterAnalysisProps接口来设置raster分析时的属性;

名词解释:
PixelBlock :字面上理解为“像素块”。顾名思义PixelBlock 是多个像素点组成的块,它的大小可以是整个raster, 当然也可以是raster中的某一个区域(要随定义块的大小而定行数、列数而确定);利用这个PixelBlock 我们可以读取PixelBlock上的所有像素点值(通过SafeArray来获取)。我们也可以理解使用PixelBlock可以从原有的raster或rasterband中截取一个区域,组成新的raster或者rasterband。
Planes :    可以把它理解为是波段。如一个raster有3个波段,那么Planes的数量就是3;
SafeArray:  返回某一波段中pixelBlock的所有像素数组;
GetVal:   而GetVal是可以返回特点波段上,特定行、列上的数值;


Geodatabase中的QueryDef对象
07-12-19 00:00:00 作者:浩淼的天空 出处:浩淼的天空
QueryDef 对象代表了数据库中基于一个或多个表、要素类的进行的属性查询。通过这个对象,用户可以在多个表间建立连接,并且保证在这个连接基础上的查询可以实现。

QueryDef 中的表必须放在一个工作空间内,而QueryDef 对象也是用IFeatureWorkspace::CreateQueryDef 方法来产生,它并不是一个组件类。需要注意的是,它并不能在Shapefile 和Coverage 数据中使用,而仅仅可以使用在GeoDatabase数据库中。

QueryDef 的查询的结果是Cursor 对象返回的,系统可以依据返回的Cursor 来获得基于查询的要素集合。但是使用这种方式获得的Cursor 对象,仅仅是只读的,Cursor 指向的行对象并没有和它们的父表相关联,因而如果试图对这些被选择出来的数据使用store 方法会出现错误。

IQueryDef 是QueryDef 对象实现的主要接口,它定义了在多个表中定义连接需要使用的属性和方法。SubFields 属性是产生一个QueryDef 对象时的可选项,默认情况下它为“*”,它表示返回所有的字段。下面的例子用于显示如何产生一个QueryDef 对象,并使用它在两个表中产生一个连接,

 ' 产生一个QueryDef 对象 
Dim pQueryDef As IQueryDef 
pQueryDef = pFeatureWorkspace.CreateQueryDef 
' 基于连接的两个表必须是在一个工作空间内,设置它的各种属性 
pQueryDef.Tables = "Counties, States" 
pQueryDef.SubFields = "COUNTIES.Shape, COUNTIES.NAME, STATES.STATE_ABBR" 
pQueryDef.WhereClause = "COUNTIES.STATE_FIPS = STATES.STATE_FIPS"

IFeatureWorkspace::OpenFeatureQuery 方法会产生一个基于QueryDef 对象的要素类,这个要素类可以被作为一个要素图层被添加到一个Map 对象中去,它和ArcSDE 中的“视图”概念很类似。下面的例子就是基于一个上面产生的QueryDef 对象来新建一个要素类的例子,注意IQueryDed::SubFields 中必须设置一个字段,以保证新建的要素类有最少拥有一个属性字段: 
' 新建一个要素类 
Dim pFeatureClass As IFeatureClass 
Dim pFeatureClassContainer As IFeatureClassContainer 
pFeatureClassContainer = pFeatureWorkspace.OpenFeatureQuery ("My counties join", pQueryDef) 
' 判断IFeatureClassContainer 对象中是否有要素类存在 
If (pFeatureClassContainer.ClassCount <> 1) Then 
MsgBox "Failed to create feature class by query" 
Else pFeatureClass = pFeatureClassContainer.Class(0) 
End If 
' 添加要素类到Map 对象 
Dim pFeatureLayer As IFeatureLayer 
pFeatureLayer = New FeatureLayerClass 
pFeatureLayer.FeatureClass = pFeatureClass 
pFeatureLayer.Name = pFeatureClass.AliasName 
pMap.AddLayer (pFeatureLayer)

QueryDef 对象使用的SQL 语法和关系数据库中使用的SQL 语法是一样的,程序可以使用工作空间对象的ISqlSyntax 接口来获得这个数据库中的SQL 语法信息。

QueryDef 代表了一个查询的子集,在数据库中,用户也可以使用SELECT 语句来得到同样的结果。但是QueryDef 并不能完整地支持SQL 语句。在ArcObjects 中的SQL 语句不能使用SQL 语句的order by,如果需要对选择的结果结果进行排序,可以使用ITablesort 接口进行操作。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有