ogrct.cpp

来自「用于读取TAB、MIF、SHP文件的类」· C++ 代码 · 共 835 行 · 第 1/2 页

CPP
835
字号
/************************************************************************//*                   OCTNewCoordinateTransformation()                   *//************************************************************************/OGRCoordinateTransformationH CPL_STDCALL OCTNewCoordinateTransformation(    OGRSpatialReferenceH hSourceSRS, OGRSpatialReferenceH hTargetSRS ){    return (OGRCoordinateTransformationH)         OGRCreateCoordinateTransformation(             (OGRSpatialReference *) hSourceSRS,            (OGRSpatialReference *) hTargetSRS );}/************************************************************************//*                             OGRProj4CT()                             *//************************************************************************/OGRProj4CT::OGRProj4CT(){    poSRSSource = NULL;    poSRSTarget = NULL;    psPJSource = NULL;    psPJTarget = NULL;        nErrorCount = 0;}/************************************************************************//*                            ~OGRProj4CT()                             *//************************************************************************/OGRProj4CT::~OGRProj4CT(){    if( poSRSSource != NULL )    {        if( poSRSSource->Dereference() <= 0 )            delete poSRSSource;    }    if( poSRSTarget != NULL )    {        if( poSRSTarget->Dereference() <= 0 )            delete poSRSTarget;    }    CPLMutexHolderD( &hPROJMutex );    if( psPJSource != NULL )        pfn_pj_free( psPJSource );    if( psPJTarget != NULL )        pfn_pj_free( psPJTarget );}/************************************************************************//*                             Initialize()                             *//************************************************************************/int OGRProj4CT::Initialize( OGRSpatialReference * poSourceIn,                             OGRSpatialReference * poTargetIn ){    CPLMutexHolderD( &hPROJMutex );    if( poSourceIn == NULL || poTargetIn == NULL )        return FALSE;    poSRSSource = poSourceIn->Clone();    poSRSTarget = poTargetIn->Clone();    bSourceLatLong = poSRSSource->IsGeographic();    bTargetLatLong = poSRSTarget->IsGeographic();/* -------------------------------------------------------------------- *//*      Setup source and target translations to radians for lat/long    *//*      systems.                                                        *//* -------------------------------------------------------------------- */    dfSourceToRadians = DEG_TO_RAD;    dfSourceFromRadians = RAD_TO_DEG;    bSourceWrap = FALSE;    dfSourceWrapLong = 0.0;    if( bSourceLatLong )    {        OGR_SRSNode *poUNITS = poSRSSource->GetAttrNode( "GEOGCS|UNIT" );        if( poUNITS && poUNITS->GetChildCount() >= 2 )        {            dfSourceToRadians = atof(poUNITS->GetChild(1)->GetValue());            if( dfSourceToRadians == 0.0 )                dfSourceToRadians = DEG_TO_RAD;            else                dfSourceFromRadians = 1 / dfSourceToRadians;        }    }    dfTargetToRadians = DEG_TO_RAD;    dfTargetFromRadians = RAD_TO_DEG;    bTargetWrap = FALSE;    dfTargetWrapLong = 0.0;    if( bTargetLatLong )    {        OGR_SRSNode *poUNITS = poSRSTarget->GetAttrNode( "GEOGCS|UNIT" );        if( poUNITS && poUNITS->GetChildCount() >= 2 )        {            dfTargetToRadians = atof(poUNITS->GetChild(1)->GetValue());            if( dfTargetToRadians == 0.0 )                dfTargetToRadians = DEG_TO_RAD;            else                dfTargetFromRadians = 1 / dfTargetToRadians;        }    }/* -------------------------------------------------------------------- *//*      Preliminary logic to setup wrapping.                            *//* -------------------------------------------------------------------- */    const char *pszCENTER_LONG;    if( CPLGetConfigOption( "CENTER_LONG", NULL ) != NULL )    {        bSourceWrap = bTargetWrap = TRUE;        dfSourceWrapLong = dfTargetWrapLong =             atof(CPLGetConfigOption( "CENTER_LONG", "" ));        CPLDebug( "OGRCT", "Wrap at %g.", dfSourceWrapLong );    }    pszCENTER_LONG = poSRSSource->GetExtension( "GEOGCS", "CENTER_LONG" );    if( pszCENTER_LONG != NULL )    {        dfSourceWrapLong = atof(pszCENTER_LONG);        bSourceWrap = TRUE;        CPLDebug( "OGRCT", "Wrap source at %g.", dfSourceWrapLong );    }    pszCENTER_LONG = poSRSTarget->GetExtension( "GEOGCS", "CENTER_LONG" );    if( pszCENTER_LONG != NULL )    {        dfTargetWrapLong = atof(pszCENTER_LONG);        bTargetWrap = TRUE;        CPLDebug( "OGRCT", "Wrap target at %g.", dfTargetWrapLong );    }/* -------------------------------------------------------------------- *//*      Establish PROJ.4 handle for source if projection.               *//* -------------------------------------------------------------------- */    char        *pszProj4Defn;    if( poSRSSource->exportToProj4( &pszProj4Defn ) != OGRERR_NONE )        return FALSE;    if( strlen(pszProj4Defn) == 0 )    {        CPLError( CE_Failure, CPLE_AppDefined,                   "No PROJ.4 translation for source SRS, coordinate\n"                  "transformation initialization has failed." );        return FALSE;    }    psPJSource = pfn_pj_init_plus( pszProj4Defn );        if( psPJSource == NULL )    {        if( pfn_pj_get_errno_ref != NULL            && pfn_pj_strerrno != NULL )        {            int *p_pj_errno = pfn_pj_get_errno_ref();            CPLError( CE_Failure, CPLE_NotSupported,                       "Failed to initialize PROJ.4 with `%s'.\n%s",                       pszProj4Defn, pfn_pj_strerrno(*p_pj_errno) );        }        else        {            CPLError( CE_Failure, CPLE_NotSupported,                       "Failed to initialize PROJ.4 with `%s'.\n",                       pszProj4Defn );        }    }        CPLFree( pszProj4Defn );        if( psPJSource == NULL )        return FALSE;/* -------------------------------------------------------------------- *//*      Establish PROJ.4 handle for target if projection.               *//* -------------------------------------------------------------------- */    if( poSRSTarget->exportToProj4( &pszProj4Defn ) != OGRERR_NONE )        return FALSE;    if( strlen(pszProj4Defn) == 0 )    {        CPLError( CE_Failure, CPLE_AppDefined,                   "No PROJ.4 translation for destination SRS, coordinate\n"                  "transformation initialization has failed." );        return FALSE;    }    psPJTarget = pfn_pj_init_plus( pszProj4Defn );        if( psPJTarget == NULL )        CPLError( CE_Failure, CPLE_NotSupported,                   "Failed to initialize PROJ.4 with `%s'.",                   pszProj4Defn );        CPLFree( pszProj4Defn );        if( psPJTarget == NULL )        return FALSE;    return TRUE;}/************************************************************************//*                            GetSourceCS()                             *//************************************************************************/OGRSpatialReference *OGRProj4CT::GetSourceCS(){    return poSRSSource;}/************************************************************************//*                            GetTargetCS()                             *//************************************************************************/OGRSpatialReference *OGRProj4CT::GetTargetCS(){    return poSRSTarget;}/************************************************************************//*                             Transform()                              *//*                                                                      *//*      This is a small wrapper for the extended transform version.     *//************************************************************************/int OGRProj4CT::Transform( int nCount, double *x, double *y, double *z ){    int *pabSuccess = (int *) CPLMalloc(sizeof(int) * nCount );    int bOverallSuccess, i;    bOverallSuccess = TransformEx( nCount, x, y, z, pabSuccess );    for( i = 0; i < nCount; i++ )    {        if( !pabSuccess[i] )        {            bOverallSuccess = FALSE;            break;        }    }    CPLFree( pabSuccess );    return bOverallSuccess;}/************************************************************************//*                            OCTTransform()                            *//************************************************************************/int CPL_STDCALL OCTTransform( OGRCoordinateTransformationH hTransform,                              int nCount, double *x, double *y, double *z ){    return ((OGRCoordinateTransformation*) hTransform)->        Transform( nCount, x, y,z );}/************************************************************************//*                            TransformEx()                             *//************************************************************************/int OGRProj4CT::TransformEx( int nCount, double *x, double *y, double *z,                             int *pabSuccess ){    int   err, i;/* -------------------------------------------------------------------- *//*      Potentially transform to radians.                               *//* -------------------------------------------------------------------- */    if( bSourceLatLong )    {        if( bSourceWrap )        {            for( i = 0; i < nCount; i++ )            {                if( x[i] != HUGE_VAL && y[i] != HUGE_VAL )                {                    if( x[i] < dfSourceWrapLong - 180.0 )                        x[i] += 360.0;                    else if( x[i] > dfSourceWrapLong + 180 )                        x[i] -= 360.0;                }            }        }        for( i = 0; i < nCount; i++ )        {            if( x[i] != HUGE_VAL )            {                x[i] *= dfSourceToRadians;                y[i] *= dfSourceToRadians;            }        }    }/* -------------------------------------------------------------------- *//*      Do the transformation using PROJ.4.                             *//* -------------------------------------------------------------------- */    CPLMutexHolderD( &hPROJMutex );    err = pfn_pj_transform( psPJSource, psPJTarget, nCount, 1, x, y, z );/* -------------------------------------------------------------------- *//*      Try to report an error through CPL.  Get proj.4 error string    *//*      if possible.  Try to avoid reporting thousands of error         *//*      ... supress further error reporting on this OGRProj4CT if we    *//*      have already reported 20 errors.                                *//* -------------------------------------------------------------------- */    if( err != 0 )    {        if( pabSuccess )            memset( pabSuccess, 0, sizeof(int) * nCount );        if( ++nErrorCount < 20 )        {            const char *pszError = NULL;            if( pfn_pj_strerrno != NULL )                pszError = pfn_pj_strerrno( err );                        if( pszError == NULL )                CPLError( CE_Failure, CPLE_AppDefined,                           "Reprojection failed, err = %d",                           err );            else                CPLError( CE_Failure, CPLE_AppDefined, "%s", pszError );        }        else if( nErrorCount == 20 )        {            CPLError( CE_Failure, CPLE_AppDefined,                       "Reprojection failed, err = %d, further errors will be supressed on the transform object.",                       err );        }        return FALSE;    }/* -------------------------------------------------------------------- *//*      Potentially transform back to degrees.                          *//* -------------------------------------------------------------------- */    if( bTargetLatLong )    {        for( i = 0; i < nCount; i++ )        {            if( x[i] != HUGE_VAL && y[i] != HUGE_VAL )            {                x[i] *= dfTargetFromRadians;                y[i] *= dfTargetFromRadians;            }        }        if( bTargetWrap )        {            for( i = 0; i < nCount; i++ )            {                if( x[i] != HUGE_VAL && y[i] != HUGE_VAL )                {                    if( x[i] < dfTargetWrapLong - 180.0 )                        x[i] += 360.0;                    else if( x[i] > dfTargetWrapLong + 180 )                        x[i] -= 360.0;                }            }        }    }/* -------------------------------------------------------------------- *//*      Establish error information if pabSuccess provided.             *//* -------------------------------------------------------------------- */    if( pabSuccess )    {        for( i = 0; i < nCount; i++ )        {            if( x[i] == HUGE_VAL || y[i] == HUGE_VAL )                pabSuccess[i] = FALSE;            else                pabSuccess[i] = TRUE;        }    }    return TRUE;}/************************************************************************//*                           OCTTransformEx()                           *//************************************************************************/int CPL_STDCALL OCTTransformEx( OGRCoordinateTransformationH hTransform,                                int nCount, double *x, double *y, double *z,                                int *pabSuccess ){    return ((OGRCoordinateTransformation*) hTransform)->        TransformEx( nCount, x, y, z, pabSuccess );}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?