Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #52962 from qgis/queued_ltr_backports
Queued LTR backports (3.28.7)
  • Loading branch information
nyalldawson committed May 2, 2023
2 parents af5da62 + d169bac commit 63e61e0
Show file tree
Hide file tree
Showing 48 changed files with 1,223 additions and 160 deletions.
Expand Up @@ -80,22 +80,65 @@ Returns whether this style is enabled (used for rendering)

void setMinZoomLevel( int minZoom );
%Docstring
Sets minimum zoom level index (negative number means no limit)
Sets minimum zoom level index (negative number means no limit).

The style will be rendered if the zoom level is greater than or equal
to ``minZoom``.

.. seealso:: :py:func:`minZoomLevel`

.. seealso:: :py:func:`setMaxZoomLevel`
%End

int minZoomLevel() const;
%Docstring
Returns minimum zoom level index (negative number means no limit)
Returns the minimum zoom level index (negative number means no limit).

The style will be rendered if the zoom level is greater than or equal
to the this level.

.. seealso:: :py:func:`setMinZoomLevel`

.. seealso:: :py:func:`maxZoomLevel`
%End

void setMaxZoomLevel( int maxZoom );
%Docstring
Sets maximum zoom level index (negative number means no limit)
Sets maximum zoom level index (negative number means no limit).

The style will be rendered if the zoom level is less than or equal
to ``maxZoom``.

.. warning::

This differs from the handling of the max zoom as defined
in the MapBox Style Specifications, where the style is rendered
only if the zoom level is less than the maximum zoom.

.. seealso:: :py:func:`maxZoomLevel`

.. seealso:: :py:func:`setMinZoomLevel`
%End

int maxZoomLevel() const;
%Docstring
Returns maxnimum zoom level index (negative number means no limit)
Returns the maximum zoom level index (negative number means no limit).

The style will be rendered if the zoom level is less than or equal
to the maximum zoom.

.. warning::

This differs from the handling of the max zoom as defined
in the MapBox Style Specifications, where the style is rendered
only if the zoom level is less than the maximum zoom.

.. seealso:: :py:func:`setMaxZoomLevel`

.. seealso:: :py:func:`minZoomLevel`
%End


bool isActive( int zoomLevel ) const;
%Docstring
Returns whether the style is active at given zoom level (also checks "enabled" flag)
Expand Down
Expand Up @@ -100,20 +100,62 @@ Returns whether this style is enabled (used for rendering)

void setMinZoomLevel( int minZoom );
%Docstring
Sets minimum zoom level index (negative number means no limit)
Sets minimum zoom level index (negative number means no limit).

The style will be rendered if the zoom level is greater than or equal
to ``minZoom``.

.. seealso:: :py:func:`minZoomLevel`

.. seealso:: :py:func:`setMaxZoomLevel`
%End

int minZoomLevel() const;
%Docstring
Returns minimum zoom level index (negative number means no limit)
Returns the minimum zoom level index (negative number means no limit).

The style will be rendered if the zoom level is greater than or equal
to the this level.

.. seealso:: :py:func:`setMinZoomLevel`

.. seealso:: :py:func:`maxZoomLevel`
%End

void setMaxZoomLevel( int maxZoom );
%Docstring
Sets maximum zoom level index (negative number means no limit)
Sets maximum zoom level index (negative number means no limit).

The style will be rendered if the zoom level is less than or equal
to ``maxZoom``.

.. warning::

This differs from the handling of the max zoom as defined
in the MapBox Style Specifications, where the style is rendered
only if the zoom level is less than the maximum zoom.

.. seealso:: :py:func:`maxZoomLevel`

.. seealso:: :py:func:`setMinZoomLevel`
%End

int maxZoomLevel() const;
%Docstring
Returns maxnimum zoom level index (negative number means no limit)
Returns the maximum zoom level index (negative number means no limit).

The style will be rendered if the zoom level is less than or equal
to the maximum zoom.

.. warning::

This differs from the handling of the max zoom as defined
in the MapBox Style Specifications, where the style is rendered
only if the zoom level is less than the maximum zoom.

.. seealso:: :py:func:`setMaxZoomLevel`

.. seealso:: :py:func:`minZoomLevel`
%End

bool isActive( int zoomLevel ) const;
Expand Down
19 changes: 17 additions & 2 deletions src/3d/qgs3daxis.cpp
Expand Up @@ -38,6 +38,7 @@ typedef Qt3DCore::QBuffer Qt3DQBuffer;
#include <Qt3DRender/QLayer>
#include <Qt3DRender/QLayerFilter>
#include <Qt3DRender/QPointLight>
#include <Qt3DRender/QSortPolicy>
#include <QWidget>
#include <QScreen>
#include <QShortcut>
Expand Down Expand Up @@ -307,7 +308,14 @@ Qt3DRender::QViewport *Qgs3DAxis::constructAxisViewport( Qt3DCore::QEntity *pare
axisCameraSelector->setParent( axisLayerFilter );
axisCameraSelector->setCamera( mAxisCamera );

Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers( axisCameraSelector );
// This ensures to have the labels (Text2DEntity) rendered after the other objects and therefore
// avoid any transparency issue on the labels.
Qt3DRender::QSortPolicy *sortPolicy = new Qt3DRender::QSortPolicy( axisCameraSelector );
QVector<Qt3DRender::QSortPolicy::SortType> sortTypes = QVector<Qt3DRender::QSortPolicy::SortType>();
sortTypes << Qt3DRender::QSortPolicy::BackToFront;
sortPolicy->setSortTypes( sortTypes );

Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers( sortPolicy );
clearBuffers->setBuffers( Qt3DRender::QClearBuffers::DepthBuffer );

// cppcheck-suppress memleak
Expand Down Expand Up @@ -348,7 +356,14 @@ Qt3DRender::QViewport *Qgs3DAxis::constructLabelViewport( Qt3DCore::QEntity *par
twoDCameraSelector->setParent( twoDLayerFilter );
twoDCameraSelector->setCamera( mTwoDLabelCamera );

Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers( twoDCameraSelector );
// this ensures to have the labels (Text2DEntity) rendered after the other objects and therefore
// avoid any transparency issue on the labels.
Qt3DRender::QSortPolicy *sortPolicy = new Qt3DRender::QSortPolicy( twoDCameraSelector );
QVector<Qt3DRender::QSortPolicy::SortType> sortTypes = QVector<Qt3DRender::QSortPolicy::SortType>();
sortTypes << Qt3DRender::QSortPolicy::BackToFront;
sortPolicy->setSortTypes( sortTypes );

Qt3DRender::QClearBuffers *clearBuffers = new Qt3DRender::QClearBuffers( sortPolicy );
clearBuffers->setBuffers( Qt3DRender::QClearBuffers::DepthBuffer );

// cppcheck-suppress memleak
Expand Down
25 changes: 22 additions & 3 deletions src/app/maptools/qgsmaptoolshapecircleabstract.cpp
Expand Up @@ -15,6 +15,9 @@

#include "qgsmaptoolshapecircleabstract.h"
#include "qgsmaptoolcapture.h"
#include "qgsmapcanvas.h"
#include "qgssettingsentryimpl.h"
#include "qgssettingsregistrycore.h"

void QgsMapToolShapeCircleAbstract::clean()
{
Expand All @@ -29,7 +32,23 @@ void QgsMapToolShapeCircleAbstract::addCircleToParentTool()

mParentTool->clearCurve();

std::unique_ptr<QgsCircularString> lineString( mCircle.toCircularString() );

mParentTool->addCurve( lineString.release() );
// Check whether to draw the circle as a polygon or a circular string
bool drawAsPolygon = false;
if ( QgsMapLayer *layer = mParentTool->layer() )
{
const QgsCoordinateReferenceSystem layerCrs = layer->crs();
const QgsCoordinateReferenceSystem mapCrs = mParentTool->canvas()->mapSettings().destinationCrs();
drawAsPolygon = layerCrs != mapCrs;
}
if ( drawAsPolygon )
{
const int segments = QgsSettingsRegistryCore::settingsDigitizingOffsetQuadSeg.value() * 12;
std::unique_ptr<QgsLineString> ls( mCircle.toLineString( segments ) );
mParentTool->addCurve( ls.release() );
}
else
{
std::unique_ptr<QgsCircularString> ls( mCircle.toCircularString() );
mParentTool->addCurve( ls.release() );
}
}
1 change: 1 addition & 0 deletions src/app/qgslayertreegrouppropertieswidget.cpp
Expand Up @@ -107,6 +107,7 @@ void QgsLayerTreeGroupPropertiesWidget::apply()
groupLayer->setPaintEffect( mPaintEffect->clone() );

groupLayer->triggerRepaint();
QgsProject::instance()->setDirty( true );
}
else if ( mMapLayerConfigWidgetContext.mapCanvas() )
{
Expand Down
15 changes: 13 additions & 2 deletions src/app/qgsmapcanvasdockwidget.cpp
Expand Up @@ -227,6 +227,15 @@ QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *pa
connect( &mResizeTimer, &QTimer::timeout, this, [ = ]
{
mBlockExtentSync = false;

if ( mSyncScaleCheckBox->isChecked() )
{
mBlockExtentSync = true;
const double scale = mMapCanvas->scale();
mMainCanvas->zoomScale( scale * mScaleFactorWidget->value() );
mBlockExtentSync = false;
}

if ( mSyncExtentCheck->isChecked() )
syncViewCenter( mMainCanvas );
} );
Expand Down Expand Up @@ -393,8 +402,10 @@ void QgsMapCanvasDockWidget::mapExtentChanged()

if ( sourceCanvas == mMapCanvas && mSyncScaleCheckBox->isChecked() )
{
const double newScaleFactor = mMainCanvas->scale() / mMapCanvas->scale();
mScaleFactorWidget->setValue( newScaleFactor );
mBlockExtentSync = true;
const double scale = mMapCanvas->scale();
mMainCanvas->zoomScale( scale * mScaleFactorWidget->value() );
mBlockExtentSync = false;
}

if ( mSyncExtentCheck->isChecked() )
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgsmapcanvasdockwidget.h
Expand Up @@ -190,6 +190,8 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
QgsRubberBand *mExtentRubberBand = nullptr;
void syncViewCenter( QgsMapCanvas *sourceCanvas );
void syncSelection();

friend class TestQgsMapCanvasDockWidget;
};

/**
Expand Down
12 changes: 6 additions & 6 deletions src/core/qgscoordinateformatter.cpp
Expand Up @@ -117,7 +117,7 @@ QString QgsCoordinateFormatter::formatXAsDegreesMinutesSeconds( double val, int
wrappedX = wrappedX + 360.0;
}

const int precisionMultiplier = std::pow( 10.0, precision );
const double precisionMultiplier = std::pow( 10.0, precision );

int degreesX = int( std::fabs( wrappedX ) );
const double floatMinutesX = ( std::fabs( wrappedX ) - degreesX ) * 60.0;
Expand Down Expand Up @@ -199,7 +199,7 @@ QString QgsCoordinateFormatter::formatYAsDegreesMinutesSeconds( double val, int
wrappedY = wrappedY + 180.0;
}

const int precisionMultiplier = std::pow( 10.0, precision );
const double precisionMultiplier = std::pow( 10.0, precision );

int degreesY = int( std::fabs( wrappedY ) );
const double floatMinutesY = ( std::fabs( wrappedY ) - degreesY ) * 60.0;
Expand Down Expand Up @@ -278,7 +278,7 @@ QString QgsCoordinateFormatter::formatXAsDegreesMinutes( double val, int precisi
int degreesX = int( std::fabs( wrappedX ) );
double floatMinutesX = ( std::fabs( wrappedX ) - degreesX ) * 60.0;

const int precisionMultiplier = std::pow( 10.0, precision );
const double precisionMultiplier = std::pow( 10.0, precision );

//make sure rounding to specified precision doesn't create minutes >= 60
if ( std::round( floatMinutesX * precisionMultiplier ) >= 60 * precisionMultiplier )
Expand Down Expand Up @@ -341,7 +341,7 @@ QString QgsCoordinateFormatter::formatYAsDegreesMinutes( double val, int precisi
int degreesY = int( std::fabs( wrappedY ) );
double floatMinutesY = ( std::fabs( wrappedY ) - degreesY ) * 60.0;

const int precisionMultiplier = std::pow( 10.0, precision );
const double precisionMultiplier = std::pow( 10.0, precision );

//make sure rounding to specified precision doesn't create minutes >= 60
if ( std::round( floatMinutesY * precisionMultiplier ) >= 60 * precisionMultiplier )
Expand Down Expand Up @@ -398,7 +398,7 @@ QString QgsCoordinateFormatter::formatXAsDegrees( double val, int precision, For

const double absX = std::fabs( wrappedX );

const int precisionMultiplier = std::pow( 10.0, precision );
const double precisionMultiplier = std::pow( 10.0, precision );

QString hemisphere;
QString sign;
Expand Down Expand Up @@ -447,7 +447,7 @@ QString QgsCoordinateFormatter::formatYAsDegrees( double val, int precision, For

const double absY = std::fabs( wrappedY );

const int precisionMultiplier = std::pow( 10.0, precision );
const double precisionMultiplier = std::pow( 10.0, precision );

QString hemisphere;
QString sign;
Expand Down
26 changes: 19 additions & 7 deletions src/core/qgsfield.cpp
Expand Up @@ -572,16 +572,28 @@ bool QgsField::convertCompatible( QVariant &v, QString *errorMessage ) const
}
}

if ( d->type == QVariant::String && ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName == QLatin1String( "jsonb" ) ) )
if ( d->typeName.compare( QLatin1String( "json" ), Qt::CaseInsensitive ) == 0 || d->typeName.compare( QLatin1String( "jsonb" ), Qt::CaseInsensitive ) == 0 )
{
const QJsonDocument doc = QJsonDocument::fromVariant( v );
if ( !doc.isNull() )
if ( d->type == QVariant::String )
{
v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
return true;
const QJsonDocument doc = QJsonDocument::fromVariant( v );
if ( !doc.isNull() )
{
v = QString::fromUtf8( doc.toJson( QJsonDocument::Compact ).constData() );
return true;
}
v = QVariant( d->type );
return false;
}
else if ( d->type == QVariant::Map )
{
if ( v.type() == QVariant::StringList || v.type() == QVariant::List || v.type() == QVariant::Map )
{
return true;
}
v = QVariant( d->type );
return false;
}
v = QVariant( d->type );
return false;
}

if ( ( d->type == QVariant::StringList || ( d->type == QVariant::List && d->subType == QVariant::String ) )
Expand Down
9 changes: 8 additions & 1 deletion src/core/vector/qgsvectordataprovider.cpp
Expand Up @@ -660,6 +660,11 @@ static bool _compareEncodings( const QString &s1, const QString &s2 )
return s1.toLower() < s2.toLower();
}

static bool _removeDuplicateEncodings( const QString &s1, const QString &s2 )
{
return s1.compare( s2, Qt::CaseInsensitive ) == 0;
}

QStringList QgsVectorDataProvider::availableEncodings()
{
static std::once_flag initialized;
Expand Down Expand Up @@ -718,8 +723,10 @@ QStringList QgsVectorDataProvider::availableEncodings()
smEncodings << "System";
#endif

// Do case-insensitive sorting of encodings
// Do case-insensitive sorting of encodings then remove duplicates
std::sort( sEncodings.begin(), sEncodings.end(), _compareEncodings );
const auto last = std::unique( sEncodings.begin(), sEncodings.end(), _removeDuplicateEncodings );
sEncodings.erase( last, sEncodings.end() );

} );

Expand Down
12 changes: 11 additions & 1 deletion src/core/vectortile/qgsmapboxglstyleconverter.cpp
Expand Up @@ -136,7 +136,17 @@ void QgsMapBoxGlStyleConverter::parseLayers( const QVariantList &layers, QgsMapB
const QString layerName = jsonLayer.value( QStringLiteral( "source-layer" ) ).toString();

const int minZoom = jsonLayer.value( QStringLiteral( "minzoom" ), QStringLiteral( "-1" ) ).toInt();
const int maxZoom = jsonLayer.value( QStringLiteral( "maxzoom" ), QStringLiteral( "-1" ) ).toInt();

// WARNING -- the QGIS renderers for vector tiles treat maxzoom different to the MapBox Style Specifications.
// from the MapBox Specifications:
//
// "The maximum zoom level for the layer. At zoom levels equal to or greater than the maxzoom, the layer will be hidden."
//
// However the QGIS styles will be hidden if the zoom level is GREATER THAN (not equal to) maxzoom.
// Accordingly we need to subtract 1 from the maxzoom value in the JSON:
int maxZoom = jsonLayer.value( QStringLiteral( "maxzoom" ), QStringLiteral( "-1" ) ).toInt();
if ( maxZoom != -1 )
maxZoom--;

const bool enabled = jsonLayer.value( QStringLiteral( "visibility" ) ).toString() != QLatin1String( "none" );

Expand Down

0 comments on commit 63e61e0

Please sign in to comment.