Don't allow building QGIS on proj 6.0 versions

Require at least 6.1.0. We need proj_normalize_for_visualization,
and the workarounds for building without it are too extensive,
too fragile, and result in too much spaghetti code.

Gotta make the hard call here ;)
This commit is contained in:
Nyall Dawson 2019-06-03 11:32:18 +10:00
parent 5db70523ec
commit f8655dc8a4
5 changed files with 17 additions and 50 deletions

View File

@ -57,6 +57,9 @@ IF (PROJ_FOUND)
STRING(REGEX REPLACE "^.*PROJ_VERSION_MINOR +([0-9]+).*$" "\\1" PROJ_VERSION_MINOR "${proj_version}") STRING(REGEX REPLACE "^.*PROJ_VERSION_MINOR +([0-9]+).*$" "\\1" PROJ_VERSION_MINOR "${proj_version}")
STRING(REGEX REPLACE "^.*PROJ_VERSION_PATCH +([0-9]+).*$" "\\1" PROJ_VERSION_PATCH "${proj_version}") STRING(REGEX REPLACE "^.*PROJ_VERSION_PATCH +([0-9]+).*$" "\\1" PROJ_VERSION_PATCH "${proj_version}")
STRING(CONCAT PROJ_VERSION_STR "(" ${PROJ_VERSION_MAJOR} "." ${PROJ_VERSION_MINOR} "." ${PROJ_VERSION_PATCH} ")") STRING(CONCAT PROJ_VERSION_STR "(" ${PROJ_VERSION_MAJOR} "." ${PROJ_VERSION_MINOR} "." ${PROJ_VERSION_PATCH} ")")
IF ((PROJ_VERSION_MAJOR EQUAL 6) AND (PROJ_VERSION_MINOR EQUAL 0))
MESSAGE (FATAL_ERROR "Cannot build QGIS using Proj ${PROJ_VERSION_MAJOR}.${PROJ_VERSION_MINOR}.${PROJ_VERSION_PATCH} Use 6.1.0 or higher.")
ENDIF ((PROJ_VERSION_MAJOR EQUAL 6) AND (PROJ_VERSION_MINOR EQUAL 0))
ELSE(EXISTS ${PROJ_INCLUDE_DIR}/proj.h) ELSE(EXISTS ${PROJ_INCLUDE_DIR}/proj.h)
SET(PROJ_VERSION_MAJOR 4) SET(PROJ_VERSION_MAJOR 4)
ENDIF(EXISTS ${PROJ_INCLUDE_DIR}/proj.h) ENDIF(EXISTS ${PROJ_INCLUDE_DIR}/proj.h)

View File

@ -652,7 +652,18 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
// if the source/destination projection is lat/long, convert the points to radians // if the source/destination projection is lat/long, convert the points to radians
// prior to transforming // prior to transforming
ProjData projData = d->threadLocalProjData(); ProjData projData = d->threadLocalProjData();
#if PROJ_VERSION_MAJOR<6
int projResult = 0;
#if PROJ_VERSION_MAJOR>=6
proj_errno_reset( projData );
proj_trans_generic( projData, direction == ForwardTransform ? PJ_FWD : PJ_INV,
x, sizeof( double ), numPoints,
y, sizeof( double ), numPoints,
z, sizeof( double ), numPoints,
nullptr, sizeof( double ), 0 );
projResult = proj_errno( projData );
// ewww - this logic is gross. We should drop support for PROJ 6.0 as quickly as possible and dump this code (in favour of built in methods used for >=6.1 builds)
#else
bool sourceIsLatLong = false; bool sourceIsLatLong = false;
bool destIsLatLong = false; bool destIsLatLong = false;
@ -672,28 +683,7 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
} }
#endif #endif
int projResult = 0; #if PROJ_VERSION_MAJOR<6
#if PROJ_VERSION_MAJOR>=6
const bool sourceAxisOrderSwapped = direction == ForwardTransform ? d->mSourceAxisOrderSwapped : d->mDestAxisOrderSwapped;
proj_errno_reset( projData );
proj_trans_generic( projData, direction == ForwardTransform ? PJ_FWD : PJ_INV,
!sourceAxisOrderSwapped ? x : y, sizeof( double ), numPoints,
!sourceAxisOrderSwapped ? y : x, sizeof( double ), numPoints,
z, sizeof( double ), numPoints,
nullptr, sizeof( double ), 0 );
projResult = proj_errno( projData );
// ewww - this logic is gross. We should drop support for PROJ 6.0 as quickly as possible and dump this code (in favour of built in methods used for >=6.1 builds)
if ( projResult == 0 && ( d->mSourceAxisOrderSwapped != d->mDestAxisOrderSwapped ) )
{
size_t size = sizeof( double ) * numPoints;
void *tmp = malloc( size );
memcpy( tmp, x, size );
memcpy( x, y, size );
memcpy( y, tmp, size );
free( tmp );
}
#else
if ( direction == ReverseTransform ) if ( direction == ReverseTransform )
{ {
projResult = pj_transform( destProj, sourceProj, numPoints, 0, x, y, z ); projResult = pj_transform( destProj, sourceProj, numPoints, 0, x, y, z );

View File

@ -100,8 +100,6 @@ QgsCoordinateTransformPrivate::QgsCoordinateTransformPrivate( const QgsCoordinat
, mDestCRS( other.mDestCRS ) , mDestCRS( other.mDestCRS )
, mSourceDatumTransform( other.mSourceDatumTransform ) , mSourceDatumTransform( other.mSourceDatumTransform )
, mDestinationDatumTransform( other.mDestinationDatumTransform ) , mDestinationDatumTransform( other.mDestinationDatumTransform )
, mSourceAxisOrderSwapped( other.mSourceAxisOrderSwapped )
, mDestAxisOrderSwapped( other.mDestAxisOrderSwapped )
{ {
//must reinitialize to setup mSourceProjection and mDestinationProjection //must reinitialize to setup mSourceProjection and mDestinationProjection
initialize(); initialize();
@ -193,19 +191,6 @@ bool QgsCoordinateTransformPrivate::initialize()
// create proj projections for current thread // create proj projections for current thread
ProjData res = threadLocalProjData(); ProjData res = threadLocalProjData();
#if PROJ_VERSION_MAJOR>=6
#if PROJ_VERSION_MINOR<1
// because proj 6.0 does not have proj_normalize_for_visualization - we have to handle this manually and inefficiently!
PJ_CONTEXT *context = QgsProjContext::get();
QgsProjUtils::proj_pj_unique_ptr sourceCrs( proj_get_source_crs( context, res ) );
if ( sourceCrs )
mSourceAxisOrderSwapped = QgsProjUtils::axisOrderIsSwapped( sourceCrs.get() );
QgsProjUtils::proj_pj_unique_ptr destCrs( proj_get_target_crs( context, res ) );
if ( destCrs )
mDestAxisOrderSwapped = QgsProjUtils::axisOrderIsSwapped( destCrs.get() );
#endif
#endif
#ifdef COORDINATE_TRANSFORM_VERBOSE #ifdef COORDINATE_TRANSFORM_VERBOSE
QgsDebugMsg( "From proj : " + mSourceCRS.toProj4() ); QgsDebugMsg( "From proj : " + mSourceCRS.toProj4() );
QgsDebugMsg( "To proj : " + mDestCRS.toProj4() ); QgsDebugMsg( "To proj : " + mDestCRS.toProj4() );
@ -311,7 +296,6 @@ ProjData QgsCoordinateTransformPrivate::threadLocalProjData()
locker.changeMode( QgsReadWriteLocker::Write ); locker.changeMode( QgsReadWriteLocker::Write );
#if PROJ_VERSION_MAJOR>=6 #if PROJ_VERSION_MAJOR>=6
#if PROJ_VERSION_MINOR>=1
QgsProjUtils::proj_pj_unique_ptr transform; QgsProjUtils::proj_pj_unique_ptr transform;
if ( !mProjCoordinateOperation.isEmpty() ) if ( !mProjCoordinateOperation.isEmpty() )
transform.reset( proj_create( context, mProjCoordinateOperation.toUtf8().constData() ) ); transform.reset( proj_create( context, mProjCoordinateOperation.toUtf8().constData() ) );
@ -493,12 +477,6 @@ ProjData QgsCoordinateTransformPrivate::threadLocalProjData()
ProjData res = transform.release(); ProjData res = transform.release();
mProjProjections.insert( reinterpret_cast< uintptr_t>( context ), res ); mProjProjections.insert( reinterpret_cast< uintptr_t>( context ), res );
#else
// proj 6.0 does not have proj_normalize_for_visualization - we have to handle this manually and inefficiently!
ProjData res = proj_create_crs_to_crs( context, mSourceProjString.toUtf8().constData(), mDestProjString.toUtf8().constData(), nullptr );
mProjProjections.insert( reinterpret_cast< uintptr_t>( context ), res );
#endif
#else #else
#ifdef USE_THREAD_LOCAL #ifdef USE_THREAD_LOCAL
Q_NOWARN_DEPRECATED_PUSH Q_NOWARN_DEPRECATED_PUSH

View File

@ -127,9 +127,6 @@ class QgsCoordinateTransformPrivate : public QSharedData
Q_DECL_DEPRECATED int mDestinationDatumTransform = -1; Q_DECL_DEPRECATED int mDestinationDatumTransform = -1;
QString mProjCoordinateOperation; QString mProjCoordinateOperation;
bool mSourceAxisOrderSwapped = false;
bool mDestAxisOrderSwapped = false;
#if PROJ_VERSION_MAJOR<6 #if PROJ_VERSION_MAJOR<6
/** /**

View File

@ -313,11 +313,10 @@ QgsDatumTransform::TransformDetails QgsDatumTransform::transformDetailsFromPj( P
if ( !op ) if ( !op )
return details; return details;
#if PROJ_VERSION_MINOR >= 1 // really, QGIS is pretty broken on PROJ 6.0 due to the absence of proj_normalize_for_visualization. Just don't use it.
QgsProjUtils::proj_pj_unique_ptr normalized( proj_normalize_for_visualization( pjContext, op ) ); QgsProjUtils::proj_pj_unique_ptr normalized( proj_normalize_for_visualization( pjContext, op ) );
if ( normalized ) if ( normalized )
details.proj = QString( proj_as_proj_string( pjContext, normalized.get(), PJ_PROJ_5, nullptr ) ); details.proj = QString( proj_as_proj_string( pjContext, normalized.get(), PJ_PROJ_5, nullptr ) );
#endif
if ( details.proj.isEmpty() ) if ( details.proj.isEmpty() )
details.proj = QString( proj_as_proj_string( pjContext, op, PJ_PROJ_5, nullptr ) ); details.proj = QString( proj_as_proj_string( pjContext, op, PJ_PROJ_5, nullptr ) );
details.name = QString( proj_get_name( op ) ); details.name = QString( proj_get_name( op ) );