Skip to content

Commit

Permalink
Merge pull request #3858 from rldhont/fix-getLegendGraphics-bbox
Browse files Browse the repository at this point in the history
fix getLegendGraphics when BBox parameter is used
  • Loading branch information
rldhont authored Dec 12, 2016
2 parents e5127c9 + 3e4a19e commit 7e40fb4
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 22 deletions.
42 changes: 22 additions & 20 deletions src/server/qgswmsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -849,8 +849,6 @@ QImage* QgsWMSServer::getLegendGraphics()
}
QgsLayerTreeModel legendModel( &rootGroup );

QList<QgsLayerTreeNode*> rootChildren = rootGroup.children();

if ( scaleDenominator > 0 )
legendModel.setLegendFilterByScale( scaleDenominator );

Expand Down Expand Up @@ -890,7 +888,7 @@ QImage* QgsWMSServer::getLegendGraphics()
}

// find out DPI
QImage* tmpImage = createImage( 1, 1 );
QImage* tmpImage = createImage( 1, 1, false );
if ( !tmpImage )
return nullptr;
qreal dpmm = tmpImage->dotsPerMeterX() / 1000.0;
Expand Down Expand Up @@ -920,7 +918,7 @@ QImage* QgsWMSServer::getLegendGraphics()
if ( !rule.isEmpty() )
{
//create second image with the right dimensions
QImage* paintImage = createImage( ruleSymbolWidth, ruleSymbolHeight );
QImage* paintImage = createImage( ruleSymbolWidth, ruleSymbolHeight, false );

//go through the items a second time for painting
QPainter p( paintImage );
Expand All @@ -942,6 +940,7 @@ QImage* QgsWMSServer::getLegendGraphics()
return paintImage;
}

QList<QgsLayerTreeNode*> rootChildren = rootGroup.children();
Q_FOREACH ( QgsLayerTreeNode* node, rootChildren )
{
if ( QgsLayerTree::isLayer( node ) )
Expand Down Expand Up @@ -981,7 +980,7 @@ QImage* QgsWMSServer::getLegendGraphics()
QSizeF minSize = legendRenderer.minimumSize();
QSize s( minSize.width() * dpmm, minSize.height() * dpmm );

QImage* paintImage = createImage( s.width(), s.height() );
QImage* paintImage = createImage( s.width(), s.height(), false );

QPainter p( paintImage );
p.setRenderHint( QPainter::Antialiasing, true );
Expand Down Expand Up @@ -1980,7 +1979,7 @@ QImage* QgsWMSServer::initializeRendering( QStringList& layersList, QStringList&
return theImage;
}

QImage* QgsWMSServer::createImage( int width, int height ) const
QImage* QgsWMSServer::createImage( int width, int height, bool useBbox ) const
{
bool conversionSuccess;

Expand All @@ -2002,23 +2001,26 @@ QImage* QgsWMSServer::createImage( int width, int height ) const

//Adapt width / height if the aspect ratio does not correspond with the BBOX.
//Required by WMS spec. 1.3.
bool bboxOk;
QgsRectangle mapExtent = _parseBBOX( mParameters.value( "BBOX" ), bboxOk );
if ( bboxOk )
if ( useBbox )
{
double mapWidthHeightRatio = mapExtent.width() / mapExtent.height();
double imageWidthHeightRatio = ( double )width / ( double )height;
if ( !qgsDoubleNear( mapWidthHeightRatio, imageWidthHeightRatio, 0.0001 ) )
bool bboxOk;
QgsRectangle mapExtent = _parseBBOX( mParameters.value( "BBOX" ), bboxOk );
if ( bboxOk )
{
if ( mapWidthHeightRatio >= imageWidthHeightRatio )
double mapWidthHeightRatio = mapExtent.width() / mapExtent.height();
double imageWidthHeightRatio = ( double )width / ( double )height;
if ( !qgsDoubleNear( mapWidthHeightRatio, imageWidthHeightRatio, 0.0001 ) )
{
//decrease image height
height = width / mapWidthHeightRatio;
}
else
{
//decrease image width
width = height * mapWidthHeightRatio;
if ( mapWidthHeightRatio >= imageWidthHeightRatio )
{
//decrease image height
height = width / mapWidthHeightRatio;
}
else
{
//decrease image width
width = height * mapWidthHeightRatio;
}
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/server/qgswmsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,11 @@ class QgsWMSServer: public QgsOWSServer
/** Creates a QImage from the HEIGHT and WIDTH parameters
@param width image width (or -1 if width should be taken from WIDTH wms parameter)
@param height image height (or -1 if height should be taken from HEIGHT wms parameter)
@param useBbox flag to indicate if the BBOX has to be used to adapt aspect ratio
@return 0 in case of error*/
QImage* createImage( int width = -1, int height = -1 ) const;
/** Configures mMapRenderer to the parameters
QImage* createImage( int width = -1, int height = -1, bool useBbox = true ) const;

/** Configures mapSettings to the parameters
HEIGHT, WIDTH, BBOX, CRS.
@param paintDevice the device that is used for painting (for dpi)
@return 0 in case of success*/
Expand Down
130 changes: 130 additions & 0 deletions tests/src/python/test_qgsserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class TestQgsServer(unittest.TestCase):
def setUp(self):
"""Create the server instance"""
self.testdata_path = unitTestDataPath('qgis_server') + '/'

d = unitTestDataPath('qgis_server_accesscontrol') + '/'
self.projectPath = os.path.join(d, "project.qgs")

# Clean env just to be sure
env_vars = ['QUERY_STRING', 'QGIS_PROJECT_FILE']
for ev in env_vars:
Expand Down Expand Up @@ -423,6 +427,132 @@ def test_getLegendGraphics_layertitle(self):
r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_test_layertitle_false", 250, QSize(10, 10))

def test_wms_GetLegendGraphic_Basic(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetLegendGraphic",
"LAYER": "Country,Hello",
"LAYERTITLE": "FALSE",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_Basic")

def test_wms_GetLegendGraphic_BoxSpace(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetLegendGraphic",
"LAYER": "Country,Hello",
"LAYERTITLE": "FALSE",
"BOXSPACE": "100",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_BoxSpace")

def test_wms_GetLegendGraphic_SymbolSpace(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetLegendGraphic",
"LAYER": "Country,Hello",
"LAYERTITLE": "FALSE",
"SYMBOLSPACE": "100",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_SymbolSpace")

def test_wms_GetLegendGraphic_IconLabelSpace(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetLegendGraphic",
"LAYER": "Country,Hello",
"LAYERTITLE": "FALSE",
"ICONLABELSPACE": "100",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_IconLabelSpace")

def test_wms_GetLegendGraphic_SymbolSize(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetLegendGraphic",
"LAYER": "Country,Hello",
"LAYERTITLE": "FALSE",
"SYMBOLWIDTH": "50",
"SYMBOLHEIGHT": "30",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_SymbolSize")

def test_wms_GetLegendGraphic_BBox(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetLegendGraphic",
"LAYER": "Country,Hello,db_point",
"LAYERTITLE": "FALSE",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"BBOX": "-151.7,-38.9,51.0,78.0",
"CRS": "EPSG:4326"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_BBox")

def test_wms_GetLegendGraphic_BBox2(self):
qs = "&".join(["%s=%s" % i for i in list({
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetLegendGraphic",
"LAYER": "Country,Hello,db_point",
"LAYERTITLE": "FALSE",
"FORMAT": "image/png",
"HEIGHT": "500",
"WIDTH": "500",
"BBOX": "-76.08,-6.4,-19.38,38.04",
"SRS": "EPSG:4326"
}.items())])

r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_BBox2")

def _result(self, data):
headers = {}
for line in data[0].decode('UTF-8').split("\n"):
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 7e40fb4

Please sign in to comment.