Skip to content

Commit

Permalink
Add method to get SingleCrs from crs
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed May 13, 2019
1 parent 18fb3f2 commit 1fac288
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 25 deletions.
43 changes: 18 additions & 25 deletions src/core/qgscoordinatereferencesystem.cpp
Expand Up @@ -533,15 +533,9 @@ bool QgsCoordinateReferenceSystem::loadFromDatabase( const QString &db, const QS
QString auth = parts.at( 0 );
QString code = parts.at( 1 );

QgsProjUtils::proj_pj_unique_ptr crs( proj_create_from_database( QgsProjContext::get(), auth.toLatin1(), code.toLatin1(), PJ_CATEGORY_CRS, false, nullptr ) );
if ( crs && proj_get_type( crs.get() ) == PJ_TYPE_COMPOUND_CRS )
{
// freaking take a guess that 0 is horizontal, because we are only mortal
d->mPj.reset( proj_crs_get_sub_crs( QgsProjContext::get(), crs.get(), 0 ) );
}
else
{
d->mPj = std::move( crs );
QgsProjUtils::proj_pj_unique_ptr crs( proj_create_from_database( QgsProjContext::get(), auth.toLatin1(), code.toLatin1(), PJ_CATEGORY_CRS, false, nullptr ) );
d->mPj = QgsProjUtils::crsToSingleCrs( crs.get() );
}

d->mIsValid = static_cast< bool >( d->mPj );
Expand Down Expand Up @@ -625,15 +619,9 @@ bool QgsCoordinateReferenceSystem::createFromWkt( const QString &wkt )
PROJ_STRING_LIST warnings = nullptr;
PROJ_STRING_LIST grammerErrors = nullptr;

QgsProjUtils::proj_pj_unique_ptr crs( proj_create_from_wkt( QgsProjContext::get(), wkt.toLatin1().constData(), nullptr, &warnings, &grammerErrors ) );
if ( crs && proj_get_type( crs.get() ) == PJ_TYPE_COMPOUND_CRS )
{
// freaking take a guess that 0 is horizontal, because we are only mortal
d->mPj.reset( proj_crs_get_sub_crs( QgsProjContext::get(), crs.get(), 0 ) );
}
else
{
d->mPj = std::move( crs );
QgsProjUtils::proj_pj_unique_ptr crs( proj_create_from_wkt( QgsProjContext::get(), wkt.toLatin1().constData(), nullptr, &warnings, &grammerErrors ) );
d->mPj = QgsProjUtils::crsToSingleCrs( crs.get() );
}

res = static_cast< bool >( d->mPj );
Expand Down Expand Up @@ -1232,20 +1220,14 @@ void QgsCoordinateReferenceSystem::setProj4String( const QString &proj4String )
d->mProj4 = proj4String;

QgsLocaleNumC l;
const QString trimmed = proj4String.trimmed();
const QString trimmed = proj4String.trimmed() + QStringLiteral( " +type=crs" );

#if PROJ_VERSION_MAJOR>=6
PJ_CONTEXT *ctx = QgsProjContext::get();

QgsProjUtils::proj_pj_unique_ptr crs( proj_create( ctx, trimmed.toLatin1().constData() ) );
if ( crs && proj_get_type( crs.get() ) == PJ_TYPE_COMPOUND_CRS )
{
// freaking take a guess that 0 is horizontal, because we are only mortal
d->mPj.reset( proj_crs_get_sub_crs( QgsProjContext::get(), crs.get(), 0 ) );
}
else
{
d->mPj = std::move( crs );
QgsProjUtils::proj_pj_unique_ptr crs( proj_create( ctx, trimmed.toLatin1().constData() ) );
d->mPj = QgsProjUtils::crsToSingleCrs( crs.get() );
}

if ( !d->mPj )
Expand Down Expand Up @@ -2128,6 +2110,17 @@ int QgsCoordinateReferenceSystem::syncDatabase()
continue;
}

switch ( proj_get_type( crs.get() ) )
{
case PJ_TYPE_VERTICAL_CRS: // don't need these in the CRS db
continue;

default:
break;
}

crs = QgsProjUtils::crsToSingleCrs( crs.get() );

QString proj4( proj_as_proj_string( pjContext, crs.get(), PJ_PROJ_4, nullptr ) );
proj4 = proj4.trimmed();

Expand Down
33 changes: 33 additions & 0 deletions src/core/qgsprojutils.cpp
Expand Up @@ -143,5 +143,38 @@ bool QgsProjUtils::axisOrderIsSwapped( const PJ *crs )
return false;
}


QgsProjUtils::proj_pj_unique_ptr QgsProjUtils::crsToSingleCrs( const PJ *crs )
{
if ( !crs )
return nullptr;

PJ_CONTEXT *context = QgsProjContext::get();
switch ( proj_get_type( crs ) )
{
case PJ_TYPE_BOUND_CRS:
return QgsProjUtils::proj_pj_unique_ptr( proj_get_source_crs( context, crs ) );

case PJ_TYPE_COMPOUND_CRS:
{
int i = 0;
QgsProjUtils::proj_pj_unique_ptr res( proj_crs_get_sub_crs( context, crs, i ) );
while ( res && ( proj_get_type( res.get() ) == PJ_TYPE_VERTICAL_CRS || proj_get_type( res.get() ) == PJ_TYPE_TEMPORAL_CRS ) )
{
i++;
res.reset( proj_crs_get_sub_crs( context, crs, i ) );
}
return res;
}

// maybe other types to handle??

default:
return QgsProjUtils::proj_pj_unique_ptr( proj_clone( context, crs ) );
}

return nullptr;
}

#endif

6 changes: 6 additions & 0 deletions src/core/qgsprojutils.h
Expand Up @@ -87,6 +87,12 @@ class CORE_EXPORT QgsProjUtils
*/
static bool axisOrderIsSwapped( const PJ *crs );

/**
* Given a PROJ crs (which may be a compound or bound crs, or some other type), extract a single crs
* from it.
*/
static proj_pj_unique_ptr crsToSingleCrs( const PJ *crs );

#endif
#endif
};
Expand Down

0 comments on commit 1fac288

Please sign in to comment.