📄 ogrct.cpp
字号:
/************************************************************************/
/* 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -