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

Queued ltr backports #59578

Merged
merged 17 commits into from
Nov 25, 2024
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
2 changes: 1 addition & 1 deletion src/3d/qgs3daxis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ void Qgs3DAxis::createAxisScene()
if ( axisDirections.length() > 0 )
mTextX->setText( QgsCoordinateReferenceSystemUtils::axisDirectionToAbbreviatedString( axisDirections.at( 0 ) ) );
else
mTextY->setText( "X?" );
mTextX->setText( "X?" );

if ( axisDirections.length() > 1 )
mTextY->setText( QgsCoordinateReferenceSystemUtils::axisDirectionToAbbreviatedString( axisDirections.at( 1 ) ) );
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/processing/qgsalgorithmgltftovector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ QVariantMap QgsGltfToVectorFeaturesAlgorithm::processAlgorithm( const QVariantMa
{
QgsFeature f;
f.setGeometry( std::move( geometry ) );
polygonSink->addFeature( f, QgsFeatureSink::FastInsert );
lineSink->addFeature( f, QgsFeatureSink::FastInsert );
}
}
break;
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4761,7 +4761,7 @@ QgsMapCanvasDockWidget *QgisApp::createNewMapCanvasDock( const QString &name, bo
connect( mapCanvasWidget->dockableWidgetHelper(), &QgsDockableWidgetHelper::closed, this, [ this, mapCanvasWidget]
{
mOpen2DMapViews.remove( mapCanvasWidget );
delete mapCanvasWidget;
mapCanvasWidget->deleteLater();
markDirty();
} );
connect( mapCanvasWidget, &QgsMapCanvasDockWidget::renameTriggered, this, &QgisApp::renameView );
Expand Down
4 changes: 4 additions & 0 deletions src/core/proj/qgscoordinatereferencesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1627,7 +1627,11 @@ void QgsCoordinateReferenceSystem::setProjString( const QString &proj4String )
{
#ifdef QGISDEBUG
const int errNo = proj_context_errno( ctx );
#if PROJ_VERSION_MAJOR>=8
QgsDebugError( QStringLiteral( "proj string rejected: %1" ).arg( proj_context_errno_string( ctx, errNo ) ) );
#else
QgsDebugError( QStringLiteral( "proj string rejected: %1" ).arg( proj_errno_string( errNo ) ) );
#endif
#endif
d->mIsValid = false;
}
Expand Down
30 changes: 20 additions & 10 deletions src/core/proj/qgscoordinatetransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,7 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
}

mFallbackOperationOccurred = false;
bool errorOccurredDuringFallbackOperation = false;
if ( actualRes != 0
&& ( d->mAvailableOpCount > 1 || d->mAvailableOpCount == -1 ) // only use fallbacks if more than one operation is possible -- otherwise we've already tried it and it failed
&& ( d->mAllowFallbackTransforms || mBallparkTransformsAreAppropriate ) )
Expand All @@ -842,13 +843,14 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
// So here just check proj_errno() for single point transform
if ( numPoints == 1 )
{
projResult = proj_errno( transform );
// hmm - something very odd here. We can't trust proj_errno( transform ), as that's giving us incorrect error numbers
// (such as "failed to load datum shift file", which is definitely incorrect for a default proj created operation!)
// so we resort to testing values ourselves...
projResult = std::isinf( xprev[0] ) || std::isinf( yprev[0] ) || std::isinf( zprev[0] ) ? 1 : 0;
errorOccurredDuringFallbackOperation = std::isinf( xprev[0] ) || std::isinf( yprev[0] ) || std::isinf( zprev[0] );
}

if ( projResult == 0 )
if ( !errorOccurredDuringFallbackOperation )
{
memcpy( x, xprev.data(), sizeof( double ) * numPoints );
memcpy( y, yprev.data(), sizeof( double ) * numPoints );
Expand All @@ -873,25 +875,33 @@ void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *
z[pos] = std::numeric_limits<double>::quiet_NaN();
}

if ( projResult != 0 )
if ( projResult != 0 || errorOccurredDuringFallbackOperation )
{
//something bad happened....
QString points;

const QChar delim = numPoints > 1 ? '\n' : ' ';
for ( int i = 0; i < numPoints; ++i )
{
points += QStringLiteral( "(%1, %2)\n" ).arg( x[i], 0, 'f' ).arg( y[i], 0, 'f' );
points += QStringLiteral( "(%1, %2)" ).arg( xprev[i], 0, 'f' ).arg( yprev[i], 0, 'f' ) + delim;
}

const QString dir = ( direction == Qgis::TransformDirection::Forward ) ? QObject::tr( "forward transform" ) : QObject::tr( "inverse transform" );
const QString dir = ( direction == Qgis::TransformDirection::Forward ) ? QObject::tr( "Forward transform" ) : QObject::tr( "Inverse transform" );

const QString msg = QObject::tr( "%1 of\n"
"%2"
"Error: %3" )
#if PROJ_VERSION_MAJOR>=8
PJ_CONTEXT *projContext = QgsProjContext::get();
const QString projError = !errorOccurredDuringFallbackOperation ? QString::fromUtf8( proj_context_errno_string( projContext, projResult ) ) : QObject::tr( "Fallback transform failed" );
#else
const QString projError = !errorOccurredDuringFallbackOperation ? QString::fromUtf8( proj_errno_string( projResult ) ) : QObject::tr( "Fallback transform failed" );
#endif

const QString msg = QObject::tr( "%1 (%2 to %3) of%4%5Error: %6" )
.arg( dir,
( direction == Qgis::TransformDirection::Forward ) ? d->mSourceCRS.authid() : d->mDestCRS.authid(),
( direction == Qgis::TransformDirection::Forward ) ? d->mDestCRS.authid() : d->mSourceCRS.authid(),
QString( delim ),
points,
projResult < 0 ? QString::fromUtf8( proj_errno_string( projResult ) ) : QObject::tr( "Fallback transform failed" ) );

projError );

// don't flood console with thousands of duplicate transform error messages
if ( msg != mLastError )
Expand Down
13 changes: 11 additions & 2 deletions src/core/proj/qgscoordinatetransform_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,17 @@ ProjData QgsCoordinateTransformPrivate::threadLocalProjData()
{
// huh?
const int errNo = proj_context_errno( context );
if ( errNo && errNo != -61 )
if ( errNo )
{
#if PROJ_VERSION_MAJOR>=8
nonAvailableError = QString( proj_context_errno_string( context, errNo ) );
#else
nonAvailableError = QString( proj_errno_string( errNo ) );
#endif
}
else
{
// in theory should never be hit!
nonAvailableError = QObject::tr( "No coordinate operations are available between these two reference systems" );
}
}
Expand Down Expand Up @@ -463,9 +468,13 @@ ProjData QgsCoordinateTransformPrivate::threadLocalProjData()
{
const int errNo = proj_context_errno( context );
const QStringList projErrors = errorLogger.errors();
if ( errNo && errNo != -61 )
if ( errNo )
{
#if PROJ_VERSION_MAJOR>=8
nonAvailableError = QString( proj_context_errno_string( context, errNo ) );
#else
nonAvailableError = QString( proj_errno_string( errNo ) );
#endif
}
else if ( !projErrors.empty() )
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgscoordinateutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ double QgsCoordinateUtils::dmsToDecimal( const QString &string, bool *ok, bool *
value = !sign1.isEmpty() && negative.contains( sign1 ) ? -v : v;
if ( isEasting )
{
*isEasting = easting.contains( sign2 );
*isEasting = easting.contains( sign1 );
}
}
else
Expand Down
8 changes: 4 additions & 4 deletions src/core/qgspathresolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,12 @@ QString QgsPathResolver::setPathWriter( const std::function<QString( const QStri

bool QgsPathResolver::removePathWriter( const QString &id )
{
const size_t prevCount = sCustomWriters->size();
sCustomWriters()->erase( std::remove_if( sCustomWriters->begin(), sCustomWriters->end(), [id]( std::pair< QString, std::function< QString( const QString & ) > > &a )
const size_t prevCount = sCustomWriters()->size();
sCustomWriters()->erase( std::remove_if( sCustomWriters()->begin(), sCustomWriters()->end(), [id]( std::pair< QString, std::function< QString( const QString & ) > > &a )
{
return a.first == id;
} ), sCustomWriters->end() );
return prevCount != sCustomWriters->size();
} ), sCustomWriters()->end() );
return prevCount != sCustomWriters()->size();
}

QString QgsPathResolver::writePath( const QString &s ) const
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorfilewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3765,7 +3765,7 @@ QgsVectorFileWriter::WriterError QgsVectorFileWriter::writeAsVectorFormatV2( Qgs
if ( err != NoError )
return err;

return writeAsVectorFormatV2( details, fileName, transformContext, options, errorMessage, newFilename, newLayer );
return writeAsVectorFormatV2( details, fileName, transformContext, options, newFilename, newLayer, errorMessage );
}

QgsVectorFileWriter::WriterError QgsVectorFileWriter::writeAsVectorFormatV3( QgsVectorLayer *layer, const QString &fileName, const QgsCoordinateTransformContext &transformContext, const QgsVectorFileWriter::SaveVectorOptions &options, QString *errorMessage, QString *newFilename, QString *newLayer )
Expand Down
2 changes: 1 addition & 1 deletion src/core/raster/qgsrasterattributetable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ bool QgsRasterAttributeTable::insertField( int position, const Field &field, QSt
{
mType = Qgis::RasterAttributeTableType::Thematic;
}
else if ( field.usage == Qgis::RasterAttributeTableFieldUsage::Max || field.usage == Qgis::RasterAttributeTableFieldUsage::Max )
else if ( field.usage == Qgis::RasterAttributeTableFieldUsage::Min || field.usage == Qgis::RasterAttributeTableFieldUsage::Max )
{
mType = Qgis::RasterAttributeTableType::Athematic;
}
Expand Down
1 change: 0 additions & 1 deletion src/core/symbology/qgsfillsymbollayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2704,7 +2704,6 @@ QImage QgsLinePatternFillSymbolLayer::toTiledPatternImage() const
layerClone->drawPreviewIcon( symbolContext, pixmap.size() );
painter.end();
return pixmap.toImage();
return QImage();
}

double QgsLinePatternFillSymbolLayer::estimateMaxBleed( const QgsRenderContext & ) const
Expand Down
2 changes: 1 addition & 1 deletion src/core/textrenderer/qgstextbackgroundsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ QgsTextBackgroundSettings::~QgsTextBackgroundSettings() //NOLINT

bool QgsTextBackgroundSettings::operator==( const QgsTextBackgroundSettings &other ) const
{
if ( !d->enabled == other.enabled()
if ( d->enabled != other.enabled()
|| d->type != other.type()
|| d->svgFile != other.svgFile()
|| d->sizeType != other.sizeType()
Expand Down
2 changes: 1 addition & 1 deletion src/gui/editorwidgets/qgsrelationreferencewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ void QgsRelationReferenceWidget::filterChanged()
QgsAttributeList subset = attrs;

QString expression = filterExpression;
if ( ! filterExpression.isEmpty() && ! filtersAttrs.isEmpty() )
if ( ! expression.isEmpty() && ! filtersAttrs.isEmpty() )
expression += QLatin1String( " AND " );

expression += filtersAttrs.isEmpty() ? QString() : QStringLiteral( " ( " );
Expand Down
2 changes: 1 addition & 1 deletion src/gui/layout/qgslayoutelevationprofilewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ void QgsLayoutElevationProfileWidget::setGuiElementValues()
mDistanceAxisMinorLinesSymbolButton->setSymbol( mProfile->plot()->xAxis().gridMinorSymbol()->clone() );
if ( mProfile->plot()->yAxis().gridMajorSymbol() )
mElevationAxisMajorLinesSymbolButton->setSymbol( mProfile->plot()->yAxis().gridMajorSymbol()->clone() );
if ( mProfile->plot()->yAxis().gridMajorSymbol() )
if ( mProfile->plot()->yAxis().gridMinorSymbol() )
mElevationAxisMinorLinesSymbolButton->setSymbol( mProfile->plot()->yAxis().gridMinorSymbol()->clone() );

mDistanceAxisLabelFontButton->setTextFormat( mProfile->plot()->xAxis().textFormat() );
Expand Down
5 changes: 2 additions & 3 deletions src/gui/qgsattributeform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,9 +1010,8 @@ void QgsAttributeForm::onAttributeChanged( const QVariant &value, const QVariant
if ( formEditorWidget->editorWidget() == eww )
continue;

// formEditorWidget and eww points to the same field, so block signals
// as there is no need to handle valueChanged again for each duplicate
whileBlocking( formEditorWidget->editorWidget() )->setValue( value );
// formEditorWidget and eww points to the same field, so update its value
formEditorWidget->editorWidget()->setValue( value );
}

switch ( mMode )
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgslayermetadataresultsmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ void QgsLayerMetadataResultsModel::reloadAsync()

void QgsLayerMetadataResultsModel::resultsReady( const QgsLayerMetadataSearchResults &results )
{
mFeedback->setProgress( mFeedback->progress() + 100 / QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders().count() );
mFeedback->setProgress( mFeedback->progress() + static_cast< double >( 100 ) / QgsApplication::instance()->layerMetadataProviderRegistry()->layerMetadataProviders().count() );
beginInsertRows( QModelIndex(), mResult.metadata().count(), mResult.metadata().count() + results.metadata().count() - 1 );
const QList<QgsLayerMetadataProviderResult> metadata { results.metadata() };
for ( const QgsLayerMetadataProviderResult &result : std::as_const( metadata ) )
Expand Down
4 changes: 2 additions & 2 deletions src/gui/qgsmaptoolcapture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ bool QgsMapToolCapture::tracingAddVertex( const QgsPointXY &point )
{
const QgsGeometry linear = QgsGeometry( mCaptureCurve.segmentize() );
const QgsGeometry curved = linear.convertToCurves(
QgsSettingsRegistryCore::settingsDigitizingConvertToCurveAngleTolerance->value(),
QgsSettingsRegistryCore::settingsDigitizingConvertToCurveDistanceTolerance->value()
QgsSettingsRegistryCore::settingsDigitizingConvertToCurveDistanceTolerance->value(),
QgsSettingsRegistryCore::settingsDigitizingConvertToCurveAngleTolerance->value()
);
if ( QgsWkbTypes::flatType( curved.wkbType() ) != Qgis::WkbType::CompoundCurve )
{
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsnewvectortabledialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ QgsNewVectorTableDialog::QgsNewVectorTableDialog( QgsAbstractDatabaseProviderCon
mHasZChk->setEnabled( false );
mHasZChk->setChecked( false );
}
if ( ! hasM && ! hasM )
if ( ! hasM && ! hasZ )
{
mHasZChk->setVisible( false );
mHasMChk->setVisible( false );
Expand Down
20 changes: 20 additions & 0 deletions tests/src/gui/testqgsdualview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,11 +438,31 @@ void TestQgsDualView::testDuplicateField()

const QList<QgsAttributeFormEditorWidget *> formEditorWidgets = dualView.mAttributeForm->mFormEditorWidgets.values( 0 );

// reset mIsChanged state
formEditorWidgets[0]->changesCommitted();
formEditorWidgets[1]->changesCommitted();
QVERIFY( !formEditorWidgets[0]->hasChanged() );
QVERIFY( !formEditorWidgets[1]->hasChanged() );

formEditorWidgets[0]->editorWidget()->setValues( 20, QVariantList() );
QCOMPARE( formEditorWidgets[0]->editorWidget()->value().toInt(), 20 );
QCOMPARE( formEditorWidgets[1]->editorWidget()->value().toInt(), 20 );
QVERIFY( formEditorWidgets[0]->hasChanged() );
QVERIFY( formEditorWidgets[1]->hasChanged() );
ft = layer->getFeature( ft.id() );
QCOMPARE( ft.attribute( QStringLiteral( "col0" ) ).toInt(), 20 );

// reset mIsChanged state
formEditorWidgets[0]->changesCommitted();
formEditorWidgets[1]->changesCommitted();
QVERIFY( !formEditorWidgets[0]->hasChanged() );
QVERIFY( !formEditorWidgets[1]->hasChanged() );

formEditorWidgets[1]->editorWidget()->setValues( 21, QVariantList() );
QCOMPARE( formEditorWidgets[0]->editorWidget()->value().toInt(), 21 );
QCOMPARE( formEditorWidgets[1]->editorWidget()->value().toInt(), 21 );
QVERIFY( formEditorWidgets[0]->hasChanged() );
QVERIFY( formEditorWidgets[1]->hasChanged() );
ft = layer->getFeature( ft.id() );
QCOMPARE( ft.attribute( QStringLiteral( "col0" ) ).toInt(), 21 );

Expand Down
19 changes: 19 additions & 0 deletions tests/src/python/test_qgscoordinatetransform.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
import qgis # NOQA

from qgis.core import (
Qgis,
QgsCoordinateReferenceSystem,
QgsCoordinateTransform,
QgsCoordinateTransformContext,
QgsProject,
QgsRectangle,
QgsPointXY,
QgsCsException
)
import unittest
from qgis.testing import start_app, QgisTestCase
Expand Down Expand Up @@ -162,6 +165,22 @@ def testTransformBoundingBoxFullWorldToWebMercator(self):
self.assertAlmostEqual(transformedExtent.xMaximum(), 20037508.343, delta=1e-3)
self.assertAlmostEqual(transformedExtent.yMaximum(), 44927335.427, delta=1e-3)

def test_cs_exception(self):
ct = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:4326'),
QgsCoordinateReferenceSystem('EPSG:3857'), QgsProject.instance())
point = QgsPointXY(-7603859, -7324441)
with self.assertRaises(QgsCsException) as e:
ct.transform(point)
self.assertEqual(str(e.exception), 'Forward transform (EPSG:4326 to EPSG:3857) of (-7603859.000000, -7324441.000000) Error: Invalid coordinate')

# reverse transform
ct = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:3857'),
QgsCoordinateReferenceSystem('EPSG:4326'), QgsProject.instance())
point = QgsPointXY(-7603859, -7324441)
with self.assertRaises(QgsCsException) as e:
ct.transform(point, Qgis.TransformDirection.Reverse)
self.assertEqual(str(e.exception), 'Inverse transform (EPSG:4326 to EPSG:3857) of (-7603859.000000, -7324441.000000) Error: Invalid coordinate')


if __name__ == '__main__':
unittest.main()
Loading