ArcGIS Engine开发之旅10--空间参考及坐标转换

原文:ArcGIS Engine开发之旅10--空间参考及坐标转换

空间参考(Spatial Reference)是 GIS 数据的骨骼框架,能够将我们的数据定位到相应的位置,为地图中的每一点提供准确的坐标。 在同一个地图上显示的地图数据的空间参考必须是一致的,如果两个图层的空间参考不一致,往往会导致两幅地图无法正确拼合,因此开发一个 GIS 系统时,为数据选择正确的空间参考非常重要。

1 相关知识 

1.1大地水准面 

大地水准面是由静止海水面并向大陆延伸所形成的不规则的封闭曲面。

1.2地球椭球体 

由定义可以知大地水准面的形状也是不规则的,仍不能用简单的数学公式表示,为了测量成果的 计算和制图的需要,人们选用一个同大地水准面相近的可以用数学方法来表达的椭球体来代替, 简称地球椭球体,它是一个规则的曲面,是测量和制图的基础,因地球椭球体是人们选定的跟大 地水准面很接近的规则的曲面,所以地球椭球体就可以有多个,地球椭球体是用长半轴、短半轴 和扁率来表示的。

1.3基准面 

基准面是在特定区域内与地球表面极为吻合的椭球体。椭球体表面上的点与地球表面上的特定位 置相匹配,也就是对椭球体进行定位,该点也被称作基准面的原点。原点的坐标是固定的,所有其他点由其计算获得

基准面的坐标系原点往往距地心有一定偏移(有的也在地心,如 WGS1984),如西安 80 的基准面和北京 54的基准面.因为椭球体通过定位以便能更好的拟合不同的地区,所以同一个椭球体可以拟合好几个基准面.因为原点不同,所以不同的基准面上,同一个点的坐标是不相同的,这点我们应该清楚.下面以华盛顿州贝灵厄姆市为例来说明。使用 NAD27、NAD83 和 WGS84 以十进制为单位比较贝灵厄姆的坐标。显而易见,NAD83 和 WGS84 表示的坐标几乎相同,但 NAD27 表示的坐标则大不相同,这是因为所使用的基准面和旋转椭球体对地球基本形状的表示方式不同。

1.4 地图投影 

简单的说地图投影就是把地球表面的任意点,利用一定数学法则,转换到地图平面上的理论和方法.2.

 

 2. 两种坐标系 

2.1 地理坐标系 

地理坐标系也可称为真实世界的坐标系,是用于确定地物在地球上位置的坐标系,它用经纬度来表示地物的位置,经度和纬度是从地心到地球表面上某点的测量角,通常以度或百分度为单位来测量该角度。

2.2投影坐标系 

投影坐标系是基于地理坐标系的,它使用基于 X,Y 值的坐标系统来描述地球上某个点所处的位置,可以这样认为投影坐标系=地理坐标系(如:北京 54、西安 80、WGS84)+投影方法(如:高斯-克吕格、Lambert 影、Mercator 投影)+线性单位。

2.3ArcGIS Engine 对空间参考的支持 

ArcGIS Engine 提供了一系列对象供开发者管理 GIS 系统的坐标系统。对大部分开发者而言了解ProjectedCoordinateSystem, GeographicCoordinateSystem, SpatialReference Environment 这三个组件类是非常有必要的,对于高级开发者而言,可能需要自定义坐标系统可以使用这些对象Projection,Datum,AngularUnit,Spheriod,PrimeMeridian 和 GeoTransformation 等。在 ArcGIS 中除了我们上面介绍的两种坐标系,还有一种称之为 Unknown 的坐标系,这种坐标系是当我们的数据没有坐标(jpg等文件)或者坐标文件丢失的时候 ArcMap 不能识别数据的投影信息而赋予的,在 ArcGIS Engine 中下面三个类分别对应了三个坐标系: 

 

利用 ArcGIS Engine 创 建 一 个 坐 标 系 或 者 基准面用的是SpatialReferenceEnvironmentClass 类,该类实现了 ISpatialReferenceFactory 接口,该接口 定义了创建坐标系,基准面等方法和属性,如下图:   

在利用 ISpatialReferenceFactory 创建坐标系的时候往往需要一个 int 类型的参数,这个int 其实就是这些坐标系的代号,如我们熟悉的 4326 就是 WGS1984,下面为部分截图: 

2.4 同一基准面的坐标转换 

对于同一基准面,我们可以肯定一点就是同一位置经纬度坐标是一样的,而不同的就是计算成平面坐标的时候可能有所不同,因为算法不一样,在这里我只是将经纬度坐标转成平面的坐标。

 private IPoint GetpProjectPoint(IPoint pPoint, bool pBool)
 {
     ISpatialReferenceFactory pSpatialReferenceEnvironemnt = new SpatialReferenceEnvironment();
     ISpatialReference pFromSpatialReference = pSpatialReferenceEnvironemnt.CreateGeographicCoordinateSystem((int)esriSRGeoCS3Type .esriSRGeoCS_Xian1980);//西安80
     ISpatialReference pToSpatialReference = pSpatialReferenceEnvironemnt.CreateProjectedCoordinateSystem((int)esriSRProjCS4Type .esriSRProjCS_Xian1980_3_Degree_GK_Zone_34);//西安80
     if (pBool == true)//球面转平面
        {
            Geometry pGeo = (IGeometry)pPoint;
            pGeo.SpatialReference = pFromSpatialReference;
            pGeo.Project(pToSpatialReference);
            return pPoint;
        }
        else //平面转球面
        {
        IGeometry pGeo = (IGeometry)pPoint;
        pGeo.SpatialReference = pToSpatialReference;
        pGeo.Project(pFromSpatialReference);
        return pPoint;
        }
} 

View Code

2.5不同基准面的坐标转换 

通过前面的介绍,我们知道地球上同一位置的坐标在不同的基准面上是不一样的,而基准面是构成坐标系的一个部分,因为基准面在定位的时候牵扯到了相对地心的平移或旋转等,所以对于这样的转换我们无法直接进行,需要一个转换参数,而这些参数也是基于不同的模型的,常用的有三参数和 7 参数,三参数是比较简单的也是比较容易理解的,三参数是在两个基准面之间进行了 X,Y,Z 轴的平移,通过下面的图我们很清楚的看到三参数之间两个基准面的关系:

而 7 参数的模型比较复杂,这种复杂的同时让精度大为提高,7参数不仅仅考虑了两个基准面之间的平移,还考虑了旋转外加一个比例因子(椭球体的大小可能不一样).

对于不同基准面之间的转换,ArcGIS Engine 提供了一个用来控制转换参数的接口 IGeoTransformation,该接口被以下类实现 

着每一个接口对应了一种转换方法,比如 GeocentricTranslationClass类就实现了三参数,而CoordinateFrameTransformationClass 类实现了7 参数,要实现 3 参数或者 7 参数需要 IGeometry2 或更新接口的ProjectEx 方法,下面我们用代码实现一个不同基准面之间的坐标转换。  

public void ProjectExExample()
 {
            ISpatialReferenceFactory pSpatialReferenceFactory = new SpatialReferenceEnvironmentClass();  // ISpatialReference pFromCustom = pSpatialReferenceFactory.CreateESRISpatialReferenceFromPRJFile(@"E:\arcgis\Engine\z idingyi.prj");
            IPoint pFromPoint = new PointClass();
            pFromPoint.X = 518950.788;
            pFromPoint.Y = 4335923.97;
            IZAware pZAware = pFromPoint as IZAware;
            pZAware.ZAware = true;
            pFromPoint.Z = 958.4791;
           // ((IGeometry)pFromPoint).SpatialReference = pFromCustom;
           //自定义投影WGS84下的北京6度19带。             ((IGeometry)pFromPoint).SpatialReference = CreateCustomProjectedCoordinateSystem();             //目标投影             IProjectedCoordinateSystem projectedCoordinateSystem = pSpatialReferenceFactory.CreateProjectedCoordinateSystem((int)esriSRProjCS4Type.esr iSRProjCS_Xian1980_GK_Zone_19);             //因为目标基准面和原始基准面不在同一个上,所以牵扯到参数转换,我用7参数 转换             ICoordinateFrameTransformation   pCoordinateFrameTransformation = new CoordinateFrameTransformationClass();
            pCoordinateFrameTransformation.PutParameters(-112.117, 4.530, 21.89, -0.00058702, -0.00476421, 0.00009358, 0.99998006411);
            pCoordinateFrameTransformation.PutSpatialReferences(CreateCustomProjectedCoordinate System(), projectedCoordinateSystem as ISpatialReference);
            //投影转换             IGeometry2 pGeometry = pFromPoint as IGeometry2;
            pGeometry.ProjectEx(projectedCoordinateSystem as ISpatialReference, esriTransformDirection.esriTransformForward, pCoordinateFrameTransformation, false, 0, 0);
                }
private IProjectedCoordinateSystem CreateCustomProjectedCoordinateSystem()
{
            ISpatialReferenceFactory2 pSpatialReferenceFactory = new SpatialReferenceEnvironmentClass();
            IProjectionGEN pProjection = pSpatialReferenceFactory.CreateProjection((int) esriSRProjectionType.esriSRProjection_GaussKruger) as IProjectionGEN;IGeographicCoordinateSystem pGeographicCoordinateSystem = pSpatialReferenceFactory.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984);
            ILinearUnit pUnit = pSpatialReferenceFactory.CreateUnit((int)esriSRUnitType.esriSRUnit_Meter) as ILinearUnit;
            IParameter[] pParameters = pProjection.GetDefaultParameters();
            IProjectedCoordinateSystemEdit pProjectedCoordinateSystemEdit = new ProjectedCoordinateSystemClass();
            object pName = "WGS-BeiJing1954";
            object pAlias = "WGS-BeiJing1954";
            object pAbbreviation = "WGS-BeiJing1954";
            object pRemarks = "WGS-BeiJing1954";
            object pUsage = "Calculate Meter From lat and lon";
            object pGeographicCoordinateSystemObject = pGeographicCoordinateSystem as object;
            object pUnitObject = pUnit as object;
            object pProjectionObject = pProjection as object;
            object pParametersObject = pParameters as object;
            pProjectedCoordinateSystemEdit.Define(ref pName, ref pAlias, ref pAbbreviation, ref  pRemarks, ref pUsage, ref pGeographicCoordinateSystemObject, ref pUnitObject,ref pProjectionObject, ref pParametersObject);
            IProjectedCoordinateSystem5 pProjectedCoordinateSystem = pProjectedCoordinateSystemEdit as IProjectedCoordinateSystem5;
            pProjectedCoordinateSystem.FalseEasting = 500000;
            pProjectedCoordinateSystem.LatitudeOfOrigin = 0;
            pProjectedCoordinateSystem.set_CentralMeridian(true,111);
            pProjectedCoordinateSystem.ScaleFactor=1;
            pProjectedCoordinateSystem.FalseNorthing=0;
            return pProjectedCoordinateSystem;
} 

View Code

 

时间: 2025-01-30 14:20:44

ArcGIS Engine开发之旅10--空间参考及坐标转换的相关文章

ArcGIS Engine开发之旅09--几何对象和空间参考

原文:ArcGIS Engine开发之旅09--几何对象和空间参考 1.Geometry  Geometry 是 GIS 中使用最为广泛的对象集之一,用户在创建.删除.编辑和进行地理分析的时候,就是处理一个包含几何形体的矢量对象:除了显示要素意外,控件对象选择,要素符号化,标注要素,编辑要素都需要 Geometry 参与.在 ArcGIS Engine 中,几个对象都有严格的定义,比如我们所说的直线,多断线等,于此同时 ArcGIS Engine 提供了而一个几何对象的模型图,如下: 2.Geo

ArcGIS Engine开发之旅04---ARCGIS接口详细说明

原文:ArcGIS Engine开发之旅04---ARCGIS接口详细说明 ArcGIS接口详细说明... 1 1.      IField接口(esriGeoDatabase)... 2 2.      IFieldEdit接口(esriGeoDatabase)... 2 3.      IFields接口(esriGeoDatabase)... 2 4. IRow接口(esriGeoDatabase)... 3 5. ITable接口(esriGeoDatabase)... 3 6. IAr

ArcGIS Engine开发之旅05---空间数据库

原文:ArcGIS Engine开发之旅05---空间数据库 1  Geodatabase概念 Geodatabase是ArcInfo8引入的一种全新的面向对象的空间数据模型,是建立在DBMS之上的统一的.智能的空间数据模型."统一"是指,Geodatabase之前的多个空间数据模型都不能在一个统一的模型框架下对地理空间要素信息进行统一的描述,而Geodatabase做到了这一点:"智能化"是指,在Geodatabase模型中,对空间要素的描述和表达较之前的空间数据

ArcGIS Engine开发之旅02--ArcGIS Engine中的类库

原文:ArcGIS Engine开发之旅02--ArcGIS Engine中的类库 System类库 System类库是ArcGIS体系结构中最底层的类库.System类库包含给构成ArcGIS的其他类库提供服务的组件.System类库中定义了大量开发者可以实现的接口.AoInitializer对象就是在System类库中定义的,所有的开发者必须使用这个对象来初始化ArcGISEngine和解除ArcGIS Engine的初始化.开发者不能扩展这个类库,但可以通过实现这个类库中包含的接口来扩展A

ArcGIS Engine开发之旅01---产品组成、逻辑体系结构

原文:ArcGIS Engine开发之旅01---产品组成.逻辑体系结构   ArcGIS Engine 由两个产品组成:  面向开发人员的软件开发包(ArcGIS Engine Developer kit) 面向最终用户的运行时(ArcGIS Engine Runtime)ArcGIS Engine 开发工具包是一个基于组件的软件开发产品,可用于构建自定义GIS 和制图应用软件.它并不是一个终端用户产品,而是软件开发人员的工具包,支持四种开发环境(C++, COM, .NET,以及Java

ArcGIS Engine开发之旅08--和查询相关的对象和接口

原文:ArcGIS Engine开发之旅08--和查询相关的对象和接口 查询在GIS领域应该是一个很频繁的操作,在GIS中除了具有属性查询(和其他关系型数据库的查询类似),还提供了空间查询.在介绍查询的时候,让我们先了解下面的对象. 1.Table 对象 Table 是不含有空间信息的一张二维表,它主要实现了 ITable 接口.在这张二维表中,每一行称之为 Row(IRow),ITable 接口 定义了对这张二维表行的插入,更新,查询,以及删除等操作. 独立表(standalone table

ArcGIS Engine开发之旅03--ArcGIS Engine中的控件

原文:ArcGIS Engine开发之旅03--ArcGIS Engine中的控件 制图控件,如MapControl.PageLayoutControl,其中MapControl控件主要用于地理数据的显示和分析,PageLayoutControl用于生成一幅成品地图.MapControl封装了Map对象,而PageLayoutControl则封装了PageLayout对象.这两个控件都实现了IMxContents接口,因此不仅可以读取ArcMap创建的地图文档,而且可以将自身的地图内容写到一个新

ArcGIS Engine开发之旅07---文件地理数据库、个人地理数据库和 ArcSDE 地理数据库中的栅格存储加以比较 、打开栅格数据

原文:ArcGIS Engine开发之旅07---文件地理数据库.个人地理数据库和 ArcSDE 地理数据库中的栅格存储加以比较 .打开栅格数据 对文件地理数据库.个人地理数据库和 ArcSDE 地理数据库中的栅格存储加以比较  1.打开栅格数据  要打开一个栅格数据,这个有点类似我们打开 FeatureClass 一样,先要获取工作空间,只不过我们过于要素类的时候需要 IFeatureWorkspace,而栅格数据则需要 IRasterWorkspace,示例如下: IRasterWorksp

Android 开发之旅:view的几种布局方式及实践

引言 通过前面两篇: Android 开发之旅:又见Hello World! Android 开发之旅:深入分析布局文件&又是"Hello World!" 我们对Android应用程序运行原理及布局文件可谓有了比较深刻的认识和理解,并且用"Hello World!"程序来实践证明了.在继续深入Android开发之旅之前,有必要解决前两篇中没有介绍的遗留问题:View的几种布局显示方法,以后就不会在针对布局方面做过多的介绍.View的布局显示方式有下面几种:线