AE实现批量修改SHP文件坐标系

因老板提到了一个需求,要求写一个小程序,能够批量修改shp文件的坐标系,自己思考了一下,可能关键的问题在于更改坐标系时对应shp文件中各个要素的坐标要跟着转换。关于使用AE里面哪些接口开始也是一头雾水,于是咨询了一下esri的小醉老师,感谢他提供的几种思路。自己研究了好几天,最后终于算是实现了,又学到了不少东西,拿出来分享一下。

先总结一下实现的方法思路:

1、使用IGeoDatasetSchemaEdit方法:只是更改prj文件,要素坐标并没有跟着转换过来,参见ESRI帮助文档解释:

Note that the AlterSpatialReference method does not project or otherwise modify the existing data in the dataset-this method merely rewrites the spatial reference associated with the dataset. The caller is responsible for ensuring the correctness and appropriateness of the supplied spatial reference. Its most common use is to supply a spatial reference for a dataset whose spatial reference is currently tagged as Unknown.

注:ArcCatalog也可更改已有shp文件的坐标系,但只是修改prj文件,要素坐标并没有跟着改变;

2、使用Project方法:Project只是获取数据,需要新创建shp文件,把几何数据写入,可行;

注:通过打开要素类编辑会话,然后依次pFeature.Shape.project(**)和pFeature.Store()的方法貌似不行,所以需要获取project后的坐标,写入新创建的FeatureClass中;

3、使用IFeatureDataConverter.ConvertFeatureClass方法:重新定义空间参考,可行;

4、使用GP工具:可行;

 

最后将使用ConvertFeatureClass和GP工具的代码分享一下:

(1)使用ConvertFeatureClass方法(红色部分是关键):

 public void ConvertFeatureClass(IWorkspaceFactory _pSWorkspaceFactory, String _pSWs, string _pSName, IWorkspaceFactory _pTWorkspaceFactory, String _pTWs, string _pTName)

        {

            try

            {

                // 打开工作空间

                IWorkspace pSWorkspace = _pSWorkspaceFactory.OpenFromFile(_pSWs, 0);

                IWorkspace pTWorkspace = _pTWorkspaceFactory.OpenFromFile(_pTWs, 0);

                IFeatureWorkspace pFtWs = pSWorkspace as IFeatureWorkspace;

                IFeatureClass pSourceFeatureClass = pFtWs.OpenFeatureClass(_pSName);

                IDataset pSDataset = pSourceFeatureClass as IDataset;

                IFeatureClassName pSourceFeatureClassName = pSDataset.FullName as IFeatureClassName;

                IDataset pTDataset = (IDataset)pTWorkspace;

                IName pTDatasetName = pTDataset.FullName;

                IWorkspaceName pTargetWorkspaceName = (IWorkspaceName)pTDatasetName;

                IFeatureClassName pTargetFeatureClassName = new FeatureClassNameClass();

                IDatasetName pTargetDatasetName = (IDatasetName)pTargetFeatureClassName;

                pTargetDatasetName.Name = _pTName;

                pTargetDatasetName.WorkspaceName = pTargetWorkspaceName;

                // 创建字段检查对象

                IFieldChecker pFieldChecker = new FieldCheckerClass();

                IFields sourceFields = pSourceFeatureClass.Fields;

                IFields pTargetFields = null;

                IEnumFieldError pEnumFieldError = null;

                pFieldChecker.InputWorkspace = pSWorkspace;

                pFieldChecker.ValidateWorkspace = pTWorkspace;

                // 验证字段

                pFieldChecker.Validate(sourceFields, out pEnumFieldError, out pTargetFields);

                if (pEnumFieldError != null)

                {

                    Console.WriteLine(“Errors were encountered during field validation.”);

                }

                // 获取源要素类的空间参考,可以通过获取源要素类中Shape字段的GeometryDef字段获得

                // 这里应该也可以自定义GeometryDef,实现源要素类的投影变换?

                String pShapeFieldName = pSourceFeatureClass.ShapeFieldName;

                int pFieldIndex = pSourceFeatureClass.FindField(pShapeFieldName);

                IField pShapeField = sourceFields.get_Field(pFieldIndex);

                IGeometryDef geometryDef = new GeometryDefClass();

                IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;

                geometryDefEdit.GeometryType_2 = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint;

                // 定义新的空间参考

                ISpatialReferenceFactory pSpatialReferFac = new SpatialReferenceEnvironmentClass();

                ISpatialReference pSpatialRefer = pSpatialReferFac.CreateGeographicCoordinateSystem((int)4214);

                if (pSpatialRefer != null)

                {

                    geometryDefEdit.SpatialReference_2 = pSpatialRefer;

                }

                //IGeometryDef pTargetGeometryDef = pShapeField.GeometryDef;

                IGeometryDef pTargetGeometryDef = geometryDef;

                // 创建要素转换对象

                IFeatureDataConverter pFDConverter = new FeatureDataConverterClass();

                IEnumInvalidObject pEnumInvalidObject = pFDConverter.ConvertFeatureClass

                    (pSourceFeatureClassName, null, null, pTargetFeatureClassName,

                    pTargetGeometryDef, pTargetFields, “”, 1000, 0);

                IInvalidObjectInfo pInvalidInfo = null;

                pEnumInvalidObject.Reset();

                while ((pInvalidInfo = pEnumInvalidObject.Next()) != null)

                {

                    Console.WriteLine(“Errors occurred for the following feature: {0}”,

                        pInvalidInfo.InvalidObjectID);

                }

                

                // 执行成功

                MessageBox.Show(“转换成功!”);

            }

            catch (System.Exception ex)

            {

                MessageBox.Show(ex.Message);

            

转载自:https://blog.csdn.net/liupeng_qwert/article/details/45556869

You may also like...