Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 3.34] Catch potential QgsCsException at various places; improve qgscoordinatetransform.h doc #56244

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions python/core/auto_generated/proj/qgscoordinatetransform.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,11 @@ otherwise points are transformed from destination to source CRS.
:param direction: transform direction (defaults to ForwardTransform)

:return: transformed point

:raises QgsCsException: if the transformation fails
%End

QgsPointXY transform( double x, double y, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const;
QgsPointXY transform( double x, double y, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const throw( QgsCsException );
%Docstring
Transform the point specified by x,y from the source CRS to the destination CRS.
If the direction is ForwardTransform then coordinates are transformed from source to destination,
Expand All @@ -254,9 +256,11 @@ otherwise points are transformed from destination to source CRS.
:param direction: transform direction (defaults to ForwardTransform)

:return: transformed point

:raises QgsCsException: if the transformation fails
%End

QgsVector3D transform( const QgsVector3D &point, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const;
QgsVector3D transform( const QgsVector3D &point, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const throw( QgsCsException );
%Docstring
Transform the point specified in 3D coordinates from the source CRS to the destination CRS.
If the direction is ForwardTransform then coordinates are transformed from source to destination,
Expand All @@ -267,6 +271,8 @@ otherwise points are transformed from destination to source CRS.

:return: transformed point

:raises QgsCsException: if the transformation fails

.. versionadded:: 3.18
%End

Expand All @@ -285,6 +291,8 @@ the returned rectangle.
crossing the 180 degree longitude line is required

:return: rectangle in destination CRS

:raises QgsCsException: if the transformation fails
%End

void transformInPlace( double &x, double &y, double &z, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const throw( QgsCsException );
Expand All @@ -299,6 +307,8 @@ otherwise points are transformed from destination to source CRS.
must represent height relative to the vertical datum of the source CRS (generally ellipsoidal
heights) and must be expressed in its vertical units (generally meters)
:param direction: transform direction (defaults to ForwardTransform)

:raises QgsCsException: if the transformation fails
%End


Expand All @@ -311,6 +321,8 @@ Transforms a polygon to the destination coordinate system.

:param polygon: polygon to transform (occurs in place)
:param direction: transform direction (defaults to forward transformation)

:raises QgsCsException: if the transformation fails
%End

QgsRectangle transform( const QgsRectangle &rectangle, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const throw( QgsCsException );
Expand All @@ -323,6 +335,8 @@ otherwise points are transformed from destination to source CRS.
:param direction: transform direction (defaults to ForwardTransform)

:return: transformed rectangle

:raises QgsCsException: if the transformation fails
%End

void transformCoords( int numPoint, double *x, double *y, double *z, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const throw( QgsCsException );
Expand All @@ -336,6 +350,8 @@ otherwise points are transformed from destination to source CRS.
:param y: array of y coordinates to transform
:param z: array of z coordinates to transform
:param direction: transform direction (defaults to ForwardTransform)

:raises QgsCsException: if the transformation fails
%End

bool isShortCircuited() const;
Expand Down
10 changes: 9 additions & 1 deletion src/core/dxf/qgsdxfexport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,15 @@ void QgsDxfExport::writeEntitiesSymbolLevels( DxfLayerJob *job )
QgsFeatureRequest req;
req.setSubsetOfAttributes( job->renderer->usedAttributes( ctx ), job->featureSource.fields() );
QgsCoordinateTransform ct( mMapSettings.destinationCrs(), job->crs, mMapSettings.transformContext() );
req.setFilterRect( ct.transform( mExtent ) );
try
{
req.setFilterRect( ct.transform( mMapSettings.extent() ) );
}
catch ( const QgsCsException & )
{
QgsDebugError( QStringLiteral( "QgsDxfExport::writeEntitiesSymbolLevels(): extent reprojection failed" ) );
return;
}

QgsFeatureIterator fit = job->featureSource.getFeatures( req );

Expand Down
16 changes: 14 additions & 2 deletions src/core/proj/qgscoordinatetransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ class CORE_EXPORT QgsCoordinateTransform
* \param point point to transform
* \param direction transform direction (defaults to ForwardTransform)
* \returns transformed point
* \throws QgsCsException if the transformation fails
*/
QgsPointXY transform( const QgsPointXY &point, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const SIP_THROW( QgsCsException );

Expand All @@ -237,8 +238,9 @@ class CORE_EXPORT QgsCoordinateTransform
* \param y y coordinate of point to transform
* \param direction transform direction (defaults to ForwardTransform)
* \returns transformed point
* \throws QgsCsException if the transformation fails
*/
QgsPointXY transform( double x, double y, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const;
QgsPointXY transform( double x, double y, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const SIP_THROW( QgsCsException );

/**
* Transform the point specified in 3D coordinates from the source CRS to the destination CRS.
Expand All @@ -247,9 +249,10 @@ class CORE_EXPORT QgsCoordinateTransform
* \param point coordinates of point to transform
* \param direction transform direction (defaults to ForwardTransform)
* \returns transformed point
* \throws QgsCsException if the transformation fails
* \since QGIS 3.18
*/
QgsVector3D transform( const QgsVector3D &point, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const;
QgsVector3D transform( const QgsVector3D &point, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const SIP_THROW( QgsCsException );

/**
* Transforms a rectangle from the source CRS to the destination CRS.
Expand All @@ -263,6 +266,7 @@ class CORE_EXPORT QgsCoordinateTransform
* \param handle180Crossover set to TRUE if destination CRS is geographic and handling of extents
* crossing the 180 degree longitude line is required
* \returns rectangle in destination CRS
* \throws QgsCsException if the transformation fails
*/
QgsRectangle transformBoundingBox( const QgsRectangle &rectangle, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward, bool handle180Crossover = false ) const SIP_THROW( QgsCsException );

Expand All @@ -276,6 +280,7 @@ class CORE_EXPORT QgsCoordinateTransform
* must represent height relative to the vertical datum of the source CRS (generally ellipsoidal
* heights) and must be expressed in its vertical units (generally meters)
* \param direction transform direction (defaults to ForwardTransform)
* \throws QgsCsException if the transformation fails
*/
void transformInPlace( double &x, double &y, double &z, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const SIP_THROW( QgsCsException );

Expand All @@ -289,6 +294,7 @@ class CORE_EXPORT QgsCoordinateTransform
* must represent height relative to the vertical datum of the source CRS (generally ellipsoidal
* heights) and must be expressed in its vertical units (generally meters)
* \param direction transform direction (defaults to ForwardTransform)
* \throws QgsCsException if the transformation fails
* \note not available in Python bindings
*/
void transformInPlace( float &x, float &y, double &z, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const SIP_SKIP;
Expand All @@ -303,6 +309,7 @@ class CORE_EXPORT QgsCoordinateTransform
* must represent height relative to the vertical datum of the source CRS (generally ellipsoidal
* heights) and must be expressed in its vertical units (generally meters)
* \param direction transform direction (defaults to ForwardTransform)
* \throws QgsCsException if the transformation fails
* \note not available in Python bindings
*/
void transformInPlace( float &x, float &y, float &z, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const SIP_SKIP;
Expand All @@ -317,6 +324,7 @@ class CORE_EXPORT QgsCoordinateTransform
* must represent height relative to the vertical datum of the source CRS (generally ellipsoidal
* heights) and must be expressed in its vertical units (generally meters)
* \param direction transform direction (defaults to ForwardTransform)
* \throws QgsCsException if the transformation fails
* \note not available in Python bindings
*/
void transformInPlace( QVector<float> &x, QVector<float> &y, QVector<float> &z,
Expand All @@ -332,6 +340,7 @@ class CORE_EXPORT QgsCoordinateTransform
* must represent height relative to the vertical datum of the source CRS (generally ellipsoidal
* heights) and must be expressed in its vertical units (generally meters)
* \param direction transform direction (defaults to ForwardTransform)
* \throws QgsCsException if the transformation fails
* \note not available in Python bindings
*/
void transformInPlace( QVector<double> &x, QVector<double> &y, QVector<double> &z,
Expand All @@ -341,6 +350,7 @@ class CORE_EXPORT QgsCoordinateTransform
* Transforms a polygon to the destination coordinate system.
* \param polygon polygon to transform (occurs in place)
* \param direction transform direction (defaults to forward transformation)
* \throws QgsCsException if the transformation fails
*/
void transformPolygon( QPolygonF &polygon, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const SIP_THROW( QgsCsException );

Expand All @@ -351,6 +361,7 @@ class CORE_EXPORT QgsCoordinateTransform
* \param rectangle rectangle to transform
* \param direction transform direction (defaults to ForwardTransform)
* \returns transformed rectangle
* \throws QgsCsException if the transformation fails
*/
QgsRectangle transform( const QgsRectangle &rectangle, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const SIP_THROW( QgsCsException );

Expand All @@ -363,6 +374,7 @@ class CORE_EXPORT QgsCoordinateTransform
* \param y array of y coordinates to transform
* \param z array of z coordinates to transform
* \param direction transform direction (defaults to ForwardTransform)
* \throws QgsCsException if the transformation fails
*/
void transformCoords( int numPoint, double *x, double *y, double *z, Qgis::TransformDirection direction = Qgis::TransformDirection::Forward ) const SIP_THROW( QgsCsException );

Expand Down
11 changes: 10 additions & 1 deletion src/core/qgsrendercontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,16 @@ double QgsRenderContext::convertMetersToMapUnits( double meters ) const
// Note: the default QgsCoordinateTransform() : authid() will return an empty String
if ( !mCoordTransform.isShortCircuited() )
{
pointCenter = mCoordTransform.transform( pointCenter );
try
{
pointCenter = mCoordTransform.transform( pointCenter );
}
catch ( const QgsCsException & )
{
QgsDebugError( QStringLiteral( "QgsRenderContext::convertMetersToMapUnits(): failed to reproject pointCenter" ) );
// what should we return;.. ?
return meters;
}
}

const int multiplier = meters < 0 ? -1 : 1;
Expand Down
34 changes: 21 additions & 13 deletions src/providers/wfs/qgswfscapabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,23 +580,31 @@ void QgsWfsCapabilities::capabilitiesReplyFinished()
QgsCoordinateReferenceSystem crsWGS84 = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "CRS:84" ) );

QgsCoordinateTransform ct( crsWGS84, crs, mOptions.transformContext );
try
{

QgsPointXY ptMin( featureType.bbox.xMinimum(), featureType.bbox.yMinimum() );
QgsPointXY ptMinBack( ct.transform( ct.transform( ptMin, Qgis::TransformDirection::Forward ), Qgis::TransformDirection::Reverse ) );
QgsPointXY ptMax( featureType.bbox.xMaximum(), featureType.bbox.yMaximum() );
QgsPointXY ptMaxBack( ct.transform( ct.transform( ptMax, Qgis::TransformDirection::Forward ), Qgis::TransformDirection::Reverse ) );

QgsPointXY ptMin( featureType.bbox.xMinimum(), featureType.bbox.yMinimum() );
QgsPointXY ptMinBack( ct.transform( ct.transform( ptMin, Qgis::TransformDirection::Forward ), Qgis::TransformDirection::Reverse ) );
QgsPointXY ptMax( featureType.bbox.xMaximum(), featureType.bbox.yMaximum() );
QgsPointXY ptMaxBack( ct.transform( ct.transform( ptMax, Qgis::TransformDirection::Forward ), Qgis::TransformDirection::Reverse ) );
QgsDebugMsgLevel( featureType.bbox.toString(), 2 );
QgsDebugMsgLevel( ptMinBack.toString(), 2 );
QgsDebugMsgLevel( ptMaxBack.toString(), 2 );

QgsDebugMsgLevel( featureType.bbox.toString(), 2 );
QgsDebugMsgLevel( ptMinBack.toString(), 2 );
QgsDebugMsgLevel( ptMaxBack.toString(), 2 );
if ( std::fabs( featureType.bbox.xMinimum() - ptMinBack.x() ) < 1e-5 &&
std::fabs( featureType.bbox.yMinimum() - ptMinBack.y() ) < 1e-5 &&
std::fabs( featureType.bbox.xMaximum() - ptMaxBack.x() ) < 1e-5 &&
std::fabs( featureType.bbox.yMaximum() - ptMaxBack.y() ) < 1e-5 )
{
QgsDebugMsgLevel( QStringLiteral( "Values of LatLongBoundingBox are consistent with WGS84 long/lat bounds, so as the CRS is projected, assume they are indeed in WGS84 and not in the CRS units" ), 2 );
featureType.bboxSRSIsWGS84 = true;
}

if ( std::fabs( featureType.bbox.xMinimum() - ptMinBack.x() ) < 1e-5 &&
std::fabs( featureType.bbox.yMinimum() - ptMinBack.y() ) < 1e-5 &&
std::fabs( featureType.bbox.xMaximum() - ptMaxBack.x() ) < 1e-5 &&
std::fabs( featureType.bbox.yMaximum() - ptMaxBack.y() ) < 1e-5 )
}
catch ( const QgsCsException & )
{
QgsDebugMsgLevel( QStringLiteral( "Values of LatLongBoundingBox are consistent with WGS84 long/lat bounds, so as the CRS is projected, assume they are indeed in WGS84 and not in the CRS units" ), 2 );
featureType.bboxSRSIsWGS84 = true;
// can be silently ignored
}
}
}
Expand Down
25 changes: 19 additions & 6 deletions src/providers/wms/qgswmsprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ QgsWmsProvider::QgsWmsProvider( QString const &uri, const ProviderOptions &optio
// we are working with XYZ tiles
// no need to get capabilities, the whole definition is in URI
// so we just generate a dummy WMTS definition
setupXyzCapabilities( uri );
if ( !setupXyzCapabilities( uri ) )
{
return;
}
}
else
{
Expand Down Expand Up @@ -1760,7 +1763,7 @@ bool QgsWmsProvider::retrieveServerCapabilities( bool forceRefresh )
}


void QgsWmsProvider::setupXyzCapabilities( const QString &uri, const QgsRectangle &sourceExtent, int sourceMinZoom, int sourceMaxZoom, double sourceTilePixelRatio )
bool QgsWmsProvider::setupXyzCapabilities( const QString &uri, const QgsRectangle &sourceExtent, int sourceMinZoom, int sourceMaxZoom, double sourceTilePixelRatio )
{
QgsDataSourceUri parsedUri;
parsedUri.setEncodedUri( uri );
Expand All @@ -1773,8 +1776,18 @@ void QgsWmsProvider::setupXyzCapabilities( const QString &uri, const QgsRectangl
// Y going from ~85 N to ~85 S (=atan(sinh(pi)) ... to get a square)
QgsPointXY topLeftLonLat( -180, 180.0 / M_PI * std::atan( std::sinh( M_PI ) ) );
QgsPointXY bottomRightLonLat( 180, 180.0 / M_PI * std::atan( std::sinh( -M_PI ) ) );
QgsPointXY topLeft = ct.transform( topLeftLonLat );
QgsPointXY bottomRight = ct.transform( bottomRightLonLat );
QgsPointXY topLeft;
QgsPointXY bottomRight;
try
{
topLeft = ct.transform( topLeftLonLat );
bottomRight = ct.transform( bottomRightLonLat );
}
catch ( const QgsCsException & )
{
QgsDebugError( QStringLiteral( "setupXyzCapabilities: failed to reproject corner coordinates" ) );
return false;
}
double xspan = ( bottomRight.x() - topLeft.x() );

QgsWmsBoundingBoxProperty bbox;
Expand Down Expand Up @@ -1877,6 +1890,7 @@ void QgsWmsProvider::setupXyzCapabilities( const QString &uri, const QgsRectangl
tmsLinkRef.limits[tm.identifier] = limits;
}
}
return true;
}

bool QgsWmsProvider::setupMBTilesCapabilities( const QString &uri )
Expand Down Expand Up @@ -1925,8 +1939,7 @@ bool QgsWmsProvider::setupMBTilesCapabilities( const QString &uri )
// MBTiles spec does not say anything about resolutions...
double sourceTilePixelRatio = 1;

setupXyzCapabilities( uri, sourceExtent, sourceMinZoom, sourceMaxZoom, sourceTilePixelRatio );
return true;
return setupXyzCapabilities( uri, sourceExtent, sourceMinZoom, sourceMaxZoom, sourceTilePixelRatio );
}


Expand Down
2 changes: 1 addition & 1 deletion src/providers/wms/qgswmsprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ class QgsWmsProvider final: public QgsRasterDataProvider
private:

//! In case of XYZ tile layer, setup capabilities from its URI
void setupXyzCapabilities( const QString &uri, const QgsRectangle &sourceExtent = QgsRectangle(), int sourceMinZoom = -1, int sourceMaxZoom = -1, double sourceTilePixelRatio = 0. );
bool setupXyzCapabilities( const QString &uri, const QgsRectangle &sourceExtent = QgsRectangle(), int sourceMinZoom = -1, int sourceMaxZoom = -1, double sourceTilePixelRatio = 0. );
//! In case of MBTiles layer, setup capabilities from its metadata
bool setupMBTilesCapabilities( const QString &uri );

Expand Down
Loading