(三)GDAL开发&OGRSpatialReference的IsSame与AutoIdentifyEPSG

最近项目中需要用到空间参考中两个函数,分别是IsSame和AutoIdentifyEPSG两个函数。其中,前者是用于比较两个空间参考是否相同,而AutoIdentifyEPSG则是说明这个空间参考是否是EPSG编号。因为之前也提到过如果使用ArcGIS Desktop进行投影转为wkt是3857的参考后返回的字符串和GDAL自己申明wkt为3857的参考返回的字符串是不相同的,所有在自己编写的代码中运用到了AutoIdentifyEPSG来验证一下,现在我们来看这个函数的源代码实现。函数定义在OGR下面的ogr_fromepsg.cpp

首先该函数对参考参数进行判断,直接获取地理坐标代码,而如果是投影坐标则需要获取相应的代号信息。


OGRErr OGRSpatialReference::AutoIdentifyEPSG()

{
/* -------------------------------------------------------------------- */
/*      Do we have a GEOGCS node, but no authority?  If so, try         */
/*      guessing it.                                                    */
/* -------------------------------------------------------------------- */
    if( (IsProjected() || IsGeographic()) 
        && GetAuthorityCode( "GEOGCS" ) == NULL )
    {
        int nGCS = GetEPSGGeogCS();
        if( nGCS != -1 )
            SetAuthority( "GEOGCS", "EPSG", nGCS );
    }

/* -------------------------------------------------------------------- */
/*      Is this a UTM coordinate system with a common GEOGCS?           */
/* -------------------------------------------------------------------- */
    int nZone, bNorth;
    if( (nZone = GetUTMZone( &bNorth )) != 0 
        && GetAuthorityCode( "PROJCS") == NULL )
    {
        const char *pszAuthName, *pszAuthCode;

        pszAuthName = GetAuthorityName( "PROJCS|GEOGCS" );
        pszAuthCode = GetAuthorityCode( "PROJCS|GEOGCS" );

        if( pszAuthName == NULL ||  pszAuthCode == NULL )
        {
            /* don't exactly recognise datum */
        }
        else if( EQUAL(pszAuthName,"EPSG") && atoi(pszAuthCode) == 4326 )
        { // WGS84
            if( bNorth ) 
                SetAuthority( "PROJCS", "EPSG", 32600 + nZone );
            else
                SetAuthority( "PROJCS", "EPSG", 32700 + nZone );
        }
        else if( EQUAL(pszAuthName,"EPSG") && atoi(pszAuthCode) == 4267 
                 && nZone >= 3 && nZone <= 22 && bNorth )
            SetAuthority( "PROJCS", "EPSG", 26700 + nZone ); // NAD27
        else if( EQUAL(pszAuthName,"EPSG") && atoi(pszAuthCode) == 4269
                 && nZone >= 3 && nZone <= 23 && bNorth )
            SetAuthority( "PROJCS", "EPSG", 26900 + nZone ); // NAD83
        else if( EQUAL(pszAuthName,"EPSG") && atoi(pszAuthCode) == 4322 )
        { // WGS72
            if( bNorth ) 
                SetAuthority( "PROJCS", "EPSG", 32200 + nZone );
            else
                SetAuthority( "PROJCS", "EPSG", 32300 + nZone );
        }
    }

/* -------------------------------------------------------------------- */
/*      Return.                                                         */
/* -------------------------------------------------------------------- */
    if( IsProjected() && GetAuthorityCode("PROJCS") != NULL )
        return OGRERR_NONE;
    else if( IsGeographic() && GetAuthorityCode("GEOGCS") != NULL )
        return OGRERR_NONE;
    else
        return OGRERR_UNSUPPORTED_SRS;
}

而IsSame函数则是在ogrspatialreference.cpp中。


int OGRSpatialReference::IsSame( const OGRSpatialReference * poOtherSRS ) const

{
    if( GetRoot() == NULL && poOtherSRS->GetRoot() == NULL )
        return TRUE;
    else if( GetRoot() == NULL || poOtherSRS->GetRoot() == NULL )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Compare geographic coordinate system.                           */
/* -------------------------------------------------------------------- */
    if( !IsSameGeogCS( poOtherSRS ) )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Do the have the same root types?  Ie. is one PROJCS and one     */
/*      GEOGCS or perhaps LOCALCS?                                      */
/* -------------------------------------------------------------------- */
    if( !EQUAL(GetRoot()->GetValue(),poOtherSRS->GetRoot()->GetValue()) )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Compare projected coordinate system.                            */
/* -------------------------------------------------------------------- */
    if( IsProjected() )
    {
        const char *pszValue1, *pszValue2;
        const OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );

        pszValue1 = this->GetAttrValue( "PROJECTION" );
        pszValue2 = poOtherSRS->GetAttrValue( "PROJECTION" );
        if( pszValue1 == NULL || pszValue2 == NULL
            || !EQUAL(pszValue1,pszValue2) )
            return FALSE;

        for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
        {
            const OGR_SRSNode    *poNode;

            poNode = poPROJCS->GetChild( iChild );
            if( !EQUAL(poNode->GetValue(),"PARAMETER") 
                || poNode->GetChildCount() != 2 )
                continue;

            /* this this eventually test within some epsilon? */
            if( this->GetProjParm( poNode->GetChild(0)->GetValue() )
                != poOtherSRS->GetProjParm( poNode->GetChild(0)->GetValue() ) )
                return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      If they are LOCALCS/PROJCS, do they have the same units?        */
/* -------------------------------------------------------------------- */
    if( IsLocal() || IsProjected() )
    {
        if( GetLinearUnits() != 0.0 )
        {
            double      dfRatio;

            dfRatio = poOtherSRS->GetLinearUnits() / GetLinearUnits();
            if( dfRatio < 0.9999999999 || dfRatio > 1.000000001 )
                return FALSE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Compare vertical coordinate system.                             */
/* -------------------------------------------------------------------- */
    if( IsVertical() && !IsSameVertCS( poOtherSRS ) )
        return FALSE;

    return TRUE;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yGIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值