Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Server getprint atlas: fix pk-less layers
Fix #30817
  • Loading branch information
elpaso committed Oct 14, 2021
1 parent 2d703b6 commit 9680806
Show file tree
Hide file tree
Showing 4 changed files with 855 additions and 12 deletions.
32 changes: 21 additions & 11 deletions src/server/services/wms/qgswmsrenderer.cpp
Expand Up @@ -362,18 +362,19 @@ namespace QgsWms
else
{
const QgsAttributeList pkIndexes = cLayer->primaryKeyAttributes();
if ( pkIndexes.size() < 1 )
const int pkIndexesSize {std::max( pkIndexes.size(), 1 )};
if ( pkIndexesSize )
{
throw QgsException( QStringLiteral( "An error occurred during the Atlas print" ) );
QgsDebugMsgLevel( QStringLiteral( "Atlas print: layer %1 has no primary key attributes" ).arg( cLayer->name() ), 2 );
}
QStringList pkAttributeNames;
for ( int pkIndex : pkIndexes )
{
pkAttributeNames.append( cLayer->fields().at( pkIndex ).name() );
}

int nAtlasFeatures = atlasPk.size() / pkIndexes.size();
if ( nAtlasFeatures * pkIndexes.size() != atlasPk.size() ) //Test is atlasPk.size() is a multiple of pkIndexes.size(). Bail out if not
const int nAtlasFeatures = atlasPk.size() / pkIndexesSize;
if ( nAtlasFeatures * pkIndexesSize != atlasPk.size() ) //Test is atlasPk.size() is a multiple of pkIndexesSize. Bail out if not
{
throw QgsBadRequestException( QgsServiceException::QGIS_InvalidParameterValue,
QStringLiteral( "Wrong number of ATLAS_PK parameters" ) );
Expand All @@ -383,7 +384,7 @@ namespace QgsWms
if ( nAtlasFeatures > maxAtlasFeatures )
{
throw QgsBadRequestException( QgsServiceException::QGIS_InvalidParameterValue,
QString( "%1 atlas features have been requestet, but the project configuration only allows printing %2 atlas features at a time" )
QString( "%1 atlas features have been requested, but the project configuration only allows printing %2 atlas features at a time" )
.arg( nAtlasFeatures ).arg( maxAtlasFeatures ) );
}

Expand All @@ -399,14 +400,23 @@ namespace QgsWms

filterString.append( "( " );

for ( int j = 0; j < pkIndexes.size(); ++j )
// If the layer has no PK attributes, assume FID
if ( pkAttributeNames.isEmpty() )
{
if ( j > 0 )
filterString.append( QStringLiteral( "$id = %1" ).arg( atlasPk.at( currentAtlasPk ) ) );
++currentAtlasPk;
}
else
{
for ( int j = 0; j < pkIndexes.size(); ++j )
{
filterString.append( " AND " );
if ( j > 0 )
{
filterString.append( " AND " );
}
filterString.append( QStringLiteral( "\"%1\" = %2" ).arg( pkAttributeNames.at( j ), atlasPk.at( currentAtlasPk ) ) );
++currentAtlasPk;
}
filterString.append( QString( "\"%1\" = %2" ).arg( pkAttributeNames.at( j ), atlasPk.at( currentAtlasPk ) ) );
++currentAtlasPk;
}

filterString.append( " )" );
Expand All @@ -417,7 +427,7 @@ namespace QgsWms
atlas->setFilterExpression( filterString, errorString );
if ( !errorString.isEmpty() )
{
throw QgsException( QStringLiteral( "An error occurred during the Atlas print" ) );
throw QgsException( QStringLiteral( "An error occurred during the Atlas print: %1" ).arg( errorString ) );
}
}
}
Expand Down
23 changes: 22 additions & 1 deletion tests/src/python/test_qgsserver_wms_getprint_atlas.py
Expand Up @@ -22,9 +22,11 @@
import urllib.parse

from qgis.testing import unittest

from utilities import unitTestDataPath
from test_qgsserver import QgsServerTestBase

from qgis.core import QgsProject


class TestQgsServerWMSGetPrintAtlas(QgsServerTestBase):
"""QGIS Server WMS Tests for GetPrint atlas request"""
Expand Down Expand Up @@ -55,6 +57,25 @@ def test_wms_getprint_atlas_getProjectSettings(self):
self.assertTrue('atlasEnabled="1"' in str(r))
self.assertTrue('<PrimaryKeyAttribute>' in str(r))

def test_wms_getprint_atlas_no_pk(self):
"""Test issue GH #30817"""

project = QgsProject()
self.assertTrue(project.read(os.path.join(unitTestDataPath(), 'qgis_server', 'bug_gh30817_atlas_pk.qgs')))
qs = "?" + "&".join(["%s=%s" % i for i in list({
"SERVICE": "WMS",
"VERSION": "1.3.0",
"REQUEST": "GetPrint",
"TEMPLATE": "layout_csv",
"TRANSPARENT": "true",
"FORMAT": "png",
"DPI": "50",
"CRS": "EPSG:2056",
"ATLAS_PK": "2",
}.items())])
r, h = self._result(self._execute_request_project(qs, project))
self._img_diff_error(r, h, "WMS_GetPrint_Atlas_No_Pk")


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

0 comments on commit 9680806

Please sign in to comment.