GIS坐标系

        最近GIS开发中遇到两个图层坐标系的对比是否相同。在GIS开发中总会接触到坐标系,如:地理坐标系、投影坐标系等,既然用到了,那就在这里记下一笔。那么当然先要了解一下坐标系的基本概念了。

基本概念

1、坐标系用来表达和确定空间位置。没有坐标系,坐标值就无从谈起,也就无法描述空间位置。   
2、在GIS中,我们遇到的坐标系一般有两种:地理坐标系(GCS) 和投影坐标系(PCS)。地理坐标系是球面坐标,参考面是椭球面,坐标单位为经纬度;投影坐标系是平面坐标系,参考平面是水平面,坐标单位为米、千米等。
3、地理坐标系经过投影后变成投影坐标系,投影坐标系因此由地理坐标系和投影组成,投影坐标系必然包括有一个地理坐标系。(投影坐标系=地理坐标系+投影)

4、坐标系是数据或地图的属性,而投影是坐标系的属性。一个数据或一张地图一定有坐标系,而一个坐标系可以有投影也可以没投影。

EPSG:EPSG的英文全称是European Petroleum Survey Group,中文名称为欧洲石油调查组织。这个组织成立于1986年,2005年并入IOGP(International Association of Oil & Gas Producers),中文名称为国际油气生产者协会。EPSG是一个组织,现在改名叫做OGP,它维护了坐标参考系统。在国际上,每个坐标系统都会被分配一个 EPSG 代码,EPSG:4326 就是 WGS84。这个数字代码就叫WKID。
OGC:OGC全称Open Geospatial Consortium,自称是一个非盈利的、国际化的、自愿协商的标准化组织,它的主要目的就是制定与空间信息、基于位置服务相关的标准。这些标准就是OGC的“产品”,而这些标准的用处就在于使不同厂商、不同产品之间可以通过统一的接口进行互操作。
SRID:全称Spatial Reference System Identifier,是指坐标系在OGC标准中的唯一ID,跟EPSG中的code是一致的。是与特定坐标系、容差和分辨率关联的唯一标识符。

常见坐标系:

EPSG:4490是基于CGCS2000椭球的经纬度坐标系(地理坐标系)。
EPSG:4326 (WGS84) 地理坐标系,WGS84 是目前最流行的地理坐标系统。特点:利于存储,可读性高。缺点:会导致页面变形。

EPSG:3857 (Pseudo-Mercator) 伪墨卡托投影,也被称为球体墨卡托,Web Mercator。它是基于墨卡托投影的,把 WGS84坐标系投影到平面上。范围为纬度85度以下,由于google地图最先使用而成为事实标准。至今,大多互联网地图都使用EPSG3857,主要是因为该投影是等角投影,适合地图定向及导航,但是纬度越高,面积变形越大。特点:用于分析,显示数据。缺点:数据的可读性差和数值大存储比较占用内存。

地理坐标系的WKID介绍:Geographic Coordinate Systems

投影坐标系的WKID介绍:Projected Coordinate Systems

一、初识坐标系

例如ArcGIS中某图层有如下坐标系,其全部参数拷贝在下面。

CGCS2000_3_Degree_GK_Zone_38
WKID: 4526 权限: EPSG

Projection: Gauss_Kruger
False_Easting: 38500000.0
False_Northing: 0.0
Central_Meridian: 114.0
Scale_Factor: 1.0
Latitude_Of_Origin: 0.0
Linear Unit: Meter (1.0)

Geographic Coordinate System: GCS_China_Geodetic_Coordinate_System_2000
Angular Unit: Degree (0.0174532925199433)
Prime Meridian: Greenwich (0.0)
Datum: D_China_2000
  Spheroid: CGCS2000
    Semimajor Axis: 6378137.0
    Semiminor Axis: 6356752.314140356
    Inverse Flattening: 298.257222101

       地理坐标系由三个参数来定义:角度单位(Angular Unit)、本初子午线(Prime Meridian)和大地测量系统(Datum)。地理坐标系“GCS_China_Geodetic_Coordinate_System_2000”使用的角度单位为“度(Degree)”,0.0174532925199433这个数字等于“π/180”,使用的本初子午线为0.0度经线,即格林威治皇家天文台(Greenwich)所在位置的经线,使用的大地测量系统则为“D_China_2000”。

       地理坐标系的最重要的参数是“大地测量系统(Datum)”,而大地测量系统的最重要的参数是“椭球(Spheroid)”。椭球相同,大地测量系统不一定相同,因为原点(origin)和方位(orientation)可以不同。想象一下,同一个椭球,首先可以固定在三维空间中的任意一个点,并且在固定于某点后还能以三个自由度任意地旋转其方位(朝向)。当然,具体国家或地区在选择大地测量系统时,总是选择与这一国家或地区的地面最吻合的大地测量系统,而不是拍脑袋随便选的。“D_China_2000”大地测量系统使用的椭球为“CGCS2000”,而“CGCS2000”椭球的“长半轴(Semimajor Axis)”和“短半轴(Semiminor Axis)”分别为6378137.0和6356752.314140356,其“反扁率(Inverse Flattening)”为298.257222101,等于Semimajor Axis/( Semimajor Axis - Semiminor Axis)。

       投影的参数对不同的投影方法有一定差别。投影坐标系“CGCS2000_3_Degree_GK_Zone_38”中“GK_Zone_38”这个名称指出,其投影方法是“高斯-克吕格(Gauss-Kruger,GK)”。投影的另一个重要参数是“东偏(False Easting)”为38500000.0,其中38为投影带号,而有些投影会在X坐标值前没有投影带号如:“Xian_1980_GK_CM_117E”的“false_easting”参数为500000.0。

获取坐标系信息:

/// <summary>
/// 获取空间参考信息
/// </summary>
/// <param name="pSpatialReference">ISpatialReference继承ISpatialReferenceInfo接口</param>
public static void GetMsgFromSpatialReference(ISpatialReference pSpatialReference)
{
    #region ISpatialReferenceInfo接口信息
    string spName = pSpatialReference.Name;  //该空间参考组件的名称   CGCS2000_3_Degree_GK_Zone_38
    string spAlias = pSpatialReference.Alias; //空间参考别名   ""   
    string sAbbreviation = pSpatialReference.Abbreviation; //该空间参考组件的缩写名称  ""
    string Remarks = pSpatialReference.Remarks; //此空间参考组件的注释字符串  ""
    int wkid = pSpatialReference.FactoryCode; //空间参考的工厂代码(WKID)    4526
    #endregion

    bool pXY = pSpatialReference.HasXYPrecision();  //是否定义了(x,y)精度信息  true
    bool pZ = pSpatialReference.HasZPrecision();  //是否定义了Z值精度信息   true
    bool pM = pSpatialReference.HasMPrecision();  //是否定义了M值精度信息   true
    //int spImpl = pSpatialReference.SpatialReferenceImpl; //空间参考接口  106285480
    //int preImpl = pSpatialReference.PrecisionExImpl;//精度接口   92924964
    //int preExImpl = pSpatialReference.PrecisionExImpl; //精度扩展接口 92924964

    ILinearUnit pZCoordinateUnit = pSpatialReference.ZCoordinateUnit; //Z坐标系(ILinearUnit接口提供对控制线性单元属性的成员的访问)
    if (pZCoordinateUnit != null)
    {   //ILinearUnit继承IUnit接口继承ISpatialReferenceInfo接口
        string zName = pZCoordinateUnit.Name;  //名称
        string zAlias = pZCoordinateUnit.Alias; //别名
        string zAbbreviation = pZCoordinateUnit.Abbreviation; //缩写
        string zRemarks = pZCoordinateUnit.Remarks;  //注释字符串
        int zFactoryCode = pZCoordinateUnit.FactoryCode; //WKID
        double zConversionFactor = pZCoordinateUnit.ConversionFactor; //单位转换系数,转换到米
        double zMetersPerUnit = pZCoordinateUnit.MetersPerUnit;  //坐标系单位
    }

    if (pSpatialReference is IProjectedCoordinateSystem tProCoordSys) //是否为平面坐标系(投影坐标系是地理坐标系的在平面上的投影)
    {   //IProjectedCoordinateSystem接口继承ISpatialReference接口
        string proName = tProCoordSys.Name;        //投影(平面)坐标系名称      CGCS2000_3_Degree_GK_Zone_38
        string proAlias = tProCoordSys.Alias; //空间参考别名   ""   
        string proAbbreviation = tProCoordSys.Abbreviation; //空间参考缩写   ""
        string proRemarks = tProCoordSys.Remarks; //注释字符串  ""
        int proFactoryCode = tProCoordSys.FactoryCode; //空间参考的工厂代码(WKID)  4526

        bool proXY = tProCoordSys.HasXYPrecision();  //是否定义了(x,y)精度信息 true
        bool proZ = tProCoordSys.HasZPrecision();  //是否定义了z精度信息 true
        bool proM = tProCoordSys.HasMPrecision();  //是否定义了m精度信息 true

        double proCentralMeridian = tProCoordSys.CentralMeridian[false];  //投影坐标系的中央子午线  114
        double proFalseEasting = tProCoordSys.FalseEasting;  //投影坐标系的东偏  38500000
        double proFalseNorthing = tProCoordSys.FalseNorthing; //投影坐标系的北偏    0
        string proUsage = tProCoordSys.Usage; //投影坐标系的使用说明   ""
        int proHorizonCount = tProCoordSys.HorizonCount; //描述ProjCS限制的形状数量  1
        double proScaleFactor = tProCoordSys.ScaleFactor; //投影坐标系的比例因子(K0)  1
        //double proAzimuth = tProCoordSys.Azimuth; //投影坐标系的方位角  没有方位角并且报异常
        //double proParallel = tProCoordSys.CentralParallel;  //投影坐标系的中心平行线  没有中心线并且报异常
        //double proLatitudeOf1st = tProCoordSys.LatitudeOf1st; //投影坐标系的第一个点(Phi 1)的纬度  没有
        //double proLatitudeOf2nd = tProCoordSys.LatitudeOf2nd; //投影坐标系的第二点(Phi 2)的纬度      没有
        //double proLongitudeOf1st = tProCoordSys.LongitudeOf1st; //投影坐标系第一个点(Lambda 1)的经度  没有
        //double proLongitudeOf2nd = tProCoordSys.LongitudeOf2nd; //投影坐标系第二点(Lambda 2)的经度。  没有
        //double proLongitudeOfOrigin = tProCoordSys.LongitudeOfOrigin; //投影坐标系的原点经度(Lambda0) 没有
        //double proStandardParallel1 = tProCoordSys.StandardParallel1; //投影坐标系的第一个平行线(Phi 1) 没有
        //double proStandardParallel2 = tProCoordSys.StandardParallel2;  //投影坐标系的第二个平行线(Phi 2) 没有

        //IGeographicCoordinateSystem继承ISpatialReference接口
        IGeographicCoordinateSystem pGeographic = tProCoordSys.GeographicCoordinateSystem; //投影坐标系的地理坐标系  

        ILinearUnit proLinearUnit = tProCoordSys.CoordinateUnit; //投影坐标系的线性单位   ILinearUnit继承IUnit接口继承ISpatialReferenceInfo接口
        string proLName = proLinearUnit.Name;  //该空间参考组件的名称  Meter
        string proLAlias = proLinearUnit.Alias; //此空间参考组件的别名  null
        string proLAbbreviation = proLinearUnit.Abbreviation; //该空间参考组件的缩写名称  null
        string proLRemarks = proLinearUnit.Remarks;  //此空间参考组件的注释字符串  null
        int proLFactoryCode = proLinearUnit.FactoryCode; //空间参考的工厂代码(WKID) 9001
        double proLConversionFactor = proLinearUnit.ConversionFactor; //单位的换算系数(单位为米)1
        double proLMetersPerUnit = proLinearUnit.MetersPerUnit;  //坐标系的单位米  1

        ILinearUnit proZCoordinateUnit = tProCoordSys.ZCoordinateUnit; //Z坐标系 ILinearUnit继承IUnit接口继承ISpatialReferenceInfo接口
        if (proZCoordinateUnit != null)
        {
            string zName = proLinearUnit.Name;  //名称
            string zAlias = proLinearUnit.Alias; //别名
            string zAbbreviation = proLinearUnit.Abbreviation; //缩写
            string zRemarks = proLinearUnit.Remarks;  //注释字符串
            int zFactoryCode = proLinearUnit.FactoryCode; //WKID
            double zConversionFactor = proLinearUnit.ConversionFactor; //单位的换算系数(单位为米)
            double zMetersPerUnit = proLinearUnit.MetersPerUnit;  //坐标系的单位米
        }


        IProjection pPro = tProCoordSys.Projection; //投影坐标系的地图投影   IProjection继承ISpatialReferenceInfo接口
        string pProName = pPro.Name;       //该空间参考组件的名称    Gauss_Kruger
        string pProAlias = pPro.Alias;  //此空间参考组件的别名  null
        string pProAbbreviation = pPro.Abbreviation; //该空间参考组件的缩写名称  null
        string pProRemarks = pPro.Remarks; //此空间参考组件的注释字符串   null
        int pProFactoryCode = pPro.FactoryCode; //空间参考的工厂代码(WKID)   43005
        string pProUsage = pPro.Usage; //地图投影的使用说明  null
        string pProClassification = pPro.Classification; //地图投影的分类  null
        IParameter pParameter = null;
        pPro.GetDefaultParameters(ref pParameter);  //返回此投影所需的默认参数集  IParameter继承ISpatialReferenceInfo接口
        string pParName = pParameter.Name; //该空间参考组件的名称   False_Easting
        string pParAlias = pParameter.Alias; //此空间参考组件的别名  null
        string pParAbbreviatio = pParameter.Abbreviation; //该空间参考组件的缩写名称  null
        string pParRemarks = pParameter.Remarks;  //此空间参考组件的注释字符串  null
        int pParFactoryCode = pParameter.FactoryCode; //空间参考的工厂代码(WKID) 100001
        double pParValue = pParameter.Value; //投影参数的数值      0     
        int pParIndex = pParameter.Index; //投影坐标系的参数数组中的投影参数的索引 0
    }
    else if (pSpatialReference is IGeographicCoordinateSystem pGeographic)  //是否为地理坐标系
    {
        string gName = pGeographic.Name;   //该空间参考组件的名称 GCS_China_Geodetic_Coordinate_System_2000
        string gAlias = pGeographic.Alias; //此空间参考组件的别名  ""
        string gAbbreviation = pGeographic.Abbreviation; //该空间参考组件的缩写名称  ""
        string gRemarks = pGeographic.Remarks;  //此空间参考组件的注释字符串  ""
        int gFactoryCode = pGeographic.FactoryCode; //空间参考的工厂代码(WKID) 4490
        bool gXY = pGeographic.HasXYPrecision();  //是否定义了(x,y)精度信息 true
        bool gZ = pGeographic.HasZPrecision();  //是否定义了z精度信息   true
        bool gM = pGeographic.HasMPrecision();  //是否定义了m精度信息   true
        string goUsage = pGeographic.Usage; //使用注意事项 ""
        ILinearUnit gZCoordinateUnit = pGeographic.ZCoordinateUnit; //Z坐标系 null
        if (gZCoordinateUnit != null)
        {
            string gzName = gZCoordinateUnit.Name;  //名称
            string gzAlias = gZCoordinateUnit.Alias; //别名
            string gzAbbreviation = gZCoordinateUnit.Abbreviation; //缩写
            string gzRemarks = gZCoordinateUnit.Remarks;  //注释字符串
            int gzFactoryCode = gZCoordinateUnit.FactoryCode; //WKID
            double gzConversionFactor = gZCoordinateUnit.ConversionFactor; //单位转换系数,转换到米
            double gzMetersPerUnit = gZCoordinateUnit.MetersPerUnit;  //坐标系单位
        }

        //地理坐标系由三个参数来定义:角度单位(Angular Unit)、本初子午线(Prime Meridian)和大地测量系统(Datum)
        IDatum gDatum = pGeographic.Datum; //这个地理坐标系的水平基准  IDatum继承ISpatialReferenceInfo接口
        string gdName = gDatum.Name;  //名称  D_China_2000
        string gdAlias = gDatum.Alias; //别名 null
        string gdAbbreviation = gDatum.Abbreviation; //缩写 null
        string gdRemarks = gDatum.Remarks;  //注释字符串 null
        int gdFactoryCode = gDatum.FactoryCode; //WKID 1043
        ISpheroid gdSpheroid = gDatum.Spheroid; //这个水平基准面的球体  ISpheroid继承ISpatialReferenceInfo接口
        string gdspName = gdSpheroid.Name;  //名称  CGCS2000
        string gdspAlias = gdSpheroid.Alias; //别名  null
        string gdspAbbreviation = gdSpheroid.Abbreviation; //缩写 null
        string gdspRemarks = gdSpheroid.Remarks;  //注释字符串  null
        int gdspFactoryCode = gdSpheroid.FactoryCode; //WKID  1024
        double gdspSemiMajorAxis = gdSpheroid.SemiMajorAxis;  //球体的半长轴长度  6378137
        double gdspSemiMinorAxis = gdSpheroid.SemiMinorAxis;  //该球体的半短轴长度  6356752.3141403561
        double GDSPFlattening = gdSpheroid.Flattening;  //这个球体的扁率   0.0033528106811823188

        IPrimeMeridian gPrimeMeridian = pGeographic.PrimeMeridian; //这个地理坐标系的本初子午线  IPrimeMeridian继承ISpatialReferenceInfo接口
        string gpmName = gPrimeMeridian.Name;   //名称   Greenwich
        string gpmAlias = gPrimeMeridian.Alias; //别名   null
        string gpmAbbreviation = gPrimeMeridian.Abbreviation; //缩写  null
        string gpmRemarks = gPrimeMeridian.Remarks;  //注释字符串  null
        int gpmFactoryCode = gPrimeMeridian.FactoryCode; //WKID   8901
        double gpmLongitude = gPrimeMeridian.Longitude;  //本初子午线的经度值 0

        IAngularUnit gAngularUnit = pGeographic.CoordinateUnit; //这个地理坐标系的角度单位。  IAngularUnit继承IUnit接口继承ISpatialReferenceInfo接口
        string gAgulardw = gAngularUnit.Name;   //该空间参考组件的名称 Degree
        string gAAlias = gAngularUnit.Alias; //此空间参考组件的别名  null
        string gAAbbreviation = gAngularUnit.Abbreviation; //该空间参考组件的缩写名称 null
        string gARemarks = gAngularUnit.Remarks;  //此空间参考组件的注释字符串 null
        int gAFactoryCode = gAngularUnit.FactoryCode; //空间参考的工厂代码(WKID)  9102
        double gAConversionFactor = gAngularUnit.ConversionFactor; //单位的换算系数(单位为米) 0.017453292519943295
        double gARadiansPerUnit = gAngularUnit.RadiansPerUnit; //每角度单位的弧度  0.017453292519943295
    }
}

若要获取分度带信息:如果带号和中央经线分别用N和L0表示,3分度:L0=3*N,6度分度:L0=6*N-3,在中国境内3度分度带号25-45,6度分度带号13-23,带号大于24是3度分带,小于24是6度分带。

二、获取坐标系

   1、从要素类中获取:

public void GetCoordinateSystem(IFeatureClass targetFClass)
{
    IGeoDataset tgeoDataset = targetFClass as IGeoDataset; //通过IGeoDataset接口获取FeatureClass坐标系统
    ISpatialReference tSpatialRef = tgeoDataset.SpatialReference;
}

2、从几何字段获取

/// <summary>
/// 由自几何字段获取空间参考信息
/// </summary>
/// <param name="geofield">几何字段</param>
public void GetCoordinateSystemByField(IField geofield)
{
    IGeometryDef geoDef = geofield.GeometryDef;
    ISpatialReference tSpatialRef = geoDef.SpatialReference;
}

3、重要素集中获取 

三、创建坐标系

1、从文件获取创建

/// <summary>
/// 从文件获取坐标系
/// </summary>
/// <returns></returns>
public ISpatialReference GetSpatialReferenceByFile()
{
    ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
    ISpatialReference spatialReference = spatialReferenceFactory.CreateESRISpatialReferenceFromPRJFile("D:\\CGCS 2000.prj");
    return spatialReference;
}

2、创建预定义空坐标系

/// <summary>
/// 空坐标系
/// </summary>
/// <returns></returns>
public ISpatialReference EmptySpatialReference()
{
    ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();

    ISpatialReference spatialReference = new UnknownCoordinateSystemClass();
    ISpatialReferenceResolution spatialReferenceResolution = (ISpatialReferenceResolution)spatialReference;
    spatialReferenceResolution.ConstructFromHorizon();
    ISpatialReferenceTolerance spatialReferenceTolerance = (ISpatialReferenceTolerance)spatialReference;
    spatialReferenceTolerance.SetDefaultXYTolerance();
    return spatialReference;
}

3、创建预定义的地理坐标系

/// <summary>
/// 创建预定义的地理坐标系 使用esriSRGeoCSType,esriSRGeoCS2Type或esriSRGeoCS3Type枚举中的元素作为gcsType来创建特定的预定义地理坐标系。
/// </summary>
/// <returns></returns>
public ISpatialReference GetGeographicCoordinateSystems()
{
    ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();

    esriSRGeoCS3Type geoSystem = esriSRGeoCS3Type.esriSRGeoCS_Xian1980;
    ISpatialReferenceResolution spatialReferenceResolution = spatialReferenceFactory.CreateGeographicCoordinateSystem(Convert.ToInt32(geoSystem)) as ISpatialReferenceResolution;
    spatialReferenceResolution.ConstructFromHorizon();
    ISpatialReferenceTolerance spatialReferenceTolerance = spatialReferenceResolution as ISpatialReferenceTolerance;
    spatialReferenceTolerance.SetDefaultXYTolerance();
    ISpatialReference spatialReference = spatialReferenceResolution as ISpatialReference;

    return spatialReference;
}

4、创建预定义的投影坐标系

/// <summary>
/// 创建预定义的投影坐标系 使用esriSRProjCSType,esriSRProjCS2Type,esriSRProjCS3Type或esriSRProjCS4Type枚举中的元素作为pcsType来创建特定的预定义投影坐标系
/// </summary>
/// <returns></returns>
public ISpatialReference GetProjectedCoordinateSystems()
{
    ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();

    esriSRProjCS4Type proSystem = esriSRProjCS4Type.esriSRProjCS_Xian1980_3_Degree_GK_Zone_35;
    ISpatialReferenceResolution spatialReferenceResolution = spatialReferenceFactory.CreateProjectedCoordinateSystem(Convert.ToInt32(proSystem)) as ISpatialReferenceResolution;
    spatialReferenceResolution.ConstructFromHorizon();
    ISpatialReferenceTolerance spatialReferenceTolerance = spatialReferenceResolution as ISpatialReferenceTolerance;
    spatialReferenceTolerance.SetDefaultXYTolerance();
    ISpatialReference spatialReference = spatialReferenceResolution as ISpatialReference;

    return spatialReference;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值