Skip to content

Commit 2d1057d

Browse files
tudorbarascunyalldawson
authored andcommittedApr 17, 2021
fix dxf export for espg's with reverse axes + test
The dxf export didn't work for reverse axis projections (north, east) as the BBOX for WMS 1.3.0 comes in South, West, North, East and the dxf export treated it like West, South, East, North. The logic is taken from the normal GetMap, GetPrint requests. Backport from #41160
1 parent 21a6372 commit 2d1057d

File tree

5 files changed

+727
-1
lines changed

5 files changed

+727
-1
lines changed
 

‎src/server/services/wms/qgswmsrenderer.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,9 +862,54 @@ namespace QgsWms
862862
dxfLayers.append( QgsDxfExport::DxfLayer( vlayer, layerAttribute ) );
863863
}
864864

865+
//map extent
866+
QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();
867+
868+
QString crs = mWmsParameters.crs();
869+
if ( crs.compare( QStringLiteral( "CRS:84" ), Qt::CaseInsensitive ) == 0 )
870+
{
871+
crs = QStringLiteral( "EPSG:4326" );
872+
mapExtent.invert();
873+
}
874+
else if ( crs.isEmpty() )
875+
{
876+
crs = QStringLiteral( "EPSG:4326" );
877+
}
878+
879+
QgsCoordinateReferenceSystem outputCRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crs );
880+
881+
if ( !outputCRS.isValid() )
882+
{
883+
QgsServiceException::ExceptionCode code;
884+
QgsWmsParameter parameter;
885+
886+
if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
887+
{
888+
code = QgsServiceException::OGC_InvalidCRS;
889+
parameter = mWmsParameters[ QgsWmsParameter::CRS ];
890+
}
891+
else
892+
{
893+
code = QgsServiceException::OGC_InvalidSRS;
894+
parameter = mWmsParameters[ QgsWmsParameter::SRS ];
895+
}
896+
897+
throw QgsBadRequestException( code, parameter );
898+
}
899+
900+
//then set destinationCrs
901+
902+
// Change x- and y- of BBOX for WMS 1.3.0 if axis inverted
903+
if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.hasAxisInverted() )
904+
{
905+
mapExtent.invert();
906+
}
907+
908+
865909
// add layers to dxf
866910
std::unique_ptr<QgsDxfExport> dxf = qgis::make_unique<QgsDxfExport>();
867-
dxf->setExtent( mWmsParameters.bboxAsRectangle() );
911+
dxf->setExtent( mapExtent );
912+
dxf->setDestinationCrs( outputCRS );
868913
dxf->addLayers( dxfLayers );
869914
dxf->setLayerTitleAsName( mWmsParameters.dxfUseLayerTitleAsName() );
870915
dxf->setSymbologyExport( mWmsParameters.dxfMode() );

‎tests/src/python/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ if (WITH_SERVER)
382382
ADD_PYTHON_TEST(PyQgsServerLandingPage test_qgsserver_landingpage.py)
383383
ADD_PYTHON_TEST(PyQgsServerApiContext test_qgsserver_apicontext.py)
384384
ADD_PYTHON_TEST(PyQgsServerWMSGetMap test_qgsserver_wms_getmap.py)
385+
ADD_PYTHON_TEST(PyQgsServerWMSGetMapDxf test_qgsserver_wms_dxf.py)
385386
ADD_PYTHON_TEST(PyQgsServerWMSGetMapSizeProject test_qgsserver_wms_getmap_size_project.py)
386387
ADD_PYTHON_TEST(PyQgsServerWMSGetMapSizeServer test_qgsserver_wms_getmap_size_server.py)
387388
ADD_PYTHON_TEST(PyQgsServerWMSGetMapIgnoreBadLayers test_qgsserver_wms_getmap_ignore_bad_layers.py)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# -*- coding: utf-8 -*-
2+
"""QGIS Unit tests for QgsServer WMS GetPrint.
3+
4+
From build dir, run: ctest -R PyQgsServerWMSGetMapDxf -V
5+
6+
7+
.. note:: This program is free software; you can redistribute it and/or modify
8+
it under the terms of the GNU General Public License as published by
9+
the Free Software Foundation; either version 2 of the License, or
10+
(at your option) any later version.
11+
12+
"""
13+
__author__ = 'Tudor Bărăscu'
14+
__date__ = '27/01/2021'
15+
__copyright__ = 'Copyright 2020, The QGIS Project'
16+
17+
import os
18+
19+
import urllib.parse
20+
21+
from qgis.testing import unittest
22+
23+
from test_qgsserver import QgsServerTestBase
24+
25+
from qgis.core import (QgsVectorLayer)
26+
27+
from qgis.PyQt import QtCore
28+
29+
# Needed on Qt 5 so that the serialization of XML is consistent among all executions
30+
os.environ['QT_HASH_SEED'] = '1'
31+
32+
33+
class PyQgsServerWMSGetMapDxf(QgsServerTestBase):
34+
35+
def test_dxf_export_works_with_reverse_axis_epsg(self):
36+
qs = "?" + "&".join(["%s=%s" % i for i in list({
37+
"MAP": urllib.parse.quote(os.path.join(self.testdata_path,
38+
'test_dxf_export.qgs')),
39+
"SERVICE": "WMS",
40+
"VERSION": "1.3.0",
41+
"REQUEST": "GetMap",
42+
"BBOX": "399980,449980,400050,450100",
43+
"CRS": "EPSG:3844",
44+
"LAYERS": "test_dxf_export",
45+
"STYLES": ",",
46+
"FORMAT": "application/dxf",
47+
"SCALE": "500",
48+
"FILE_NAME": "test_dxf_export.dxf"
49+
}.items())])
50+
51+
r, h = self._result(self._execute_request(qs))
52+
53+
tempDir = QtCore.QTemporaryDir()
54+
dxf = os.path.join(tempDir.path(), 'test_dxf_export.dxf')
55+
f = open(dxf, 'wb')
56+
f.write(r)
57+
f.close()
58+
59+
vl = QgsVectorLayer(dxf, "lyr", "ogr")
60+
myMessage = ('Expected downloaded dxf contains: %s line\nGot: %s\n' %
61+
(1, vl.featureCount()))
62+
63+
self.assertEqual(vl.featureCount(), 1, myMessage)
64+
65+
line_from_dxf = next(vl.getFeatures()).geometry().asWkt()
66+
line = 'LineString (450000 400000, 450100 400000)'
67+
68+
self.assertEqual(line_from_dxf, line)
69+
70+
71+
if __name__ == '__main__':
72+
unittest.main()
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"type": "FeatureCollection",
3+
"name": "test_dxf_export",
4+
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::3844" } },
5+
"features": [
6+
{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 450000, 400000 ], [ 450100, 400000 ] ] } }
7+
]
8+
}

‎tests/testdata/qgis_server/test_dxf_export.qgs

Lines changed: 600 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.