Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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
  • Loading branch information
tudorbarascu authored and nyalldawson committed Apr 17, 2021
1 parent 21a6372 commit 2d1057d
Show file tree
Hide file tree
Showing 5 changed files with 727 additions and 1 deletion.
47 changes: 46 additions & 1 deletion src/server/services/wms/qgswmsrenderer.cpp
Expand Up @@ -862,9 +862,54 @@ namespace QgsWms
dxfLayers.append( QgsDxfExport::DxfLayer( vlayer, layerAttribute ) );
}

//map extent
QgsRectangle mapExtent = mWmsParameters.bboxAsRectangle();

QString crs = mWmsParameters.crs();
if ( crs.compare( QStringLiteral( "CRS:84" ), Qt::CaseInsensitive ) == 0 )
{
crs = QStringLiteral( "EPSG:4326" );
mapExtent.invert();
}
else if ( crs.isEmpty() )
{
crs = QStringLiteral( "EPSG:4326" );
}

QgsCoordinateReferenceSystem outputCRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crs );

if ( !outputCRS.isValid() )
{
QgsServiceException::ExceptionCode code;
QgsWmsParameter parameter;

if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) )
{
code = QgsServiceException::OGC_InvalidCRS;
parameter = mWmsParameters[ QgsWmsParameter::CRS ];
}
else
{
code = QgsServiceException::OGC_InvalidSRS;
parameter = mWmsParameters[ QgsWmsParameter::SRS ];
}

throw QgsBadRequestException( code, parameter );
}

//then set destinationCrs

// Change x- and y- of BBOX for WMS 1.3.0 if axis inverted
if ( mWmsParameters.versionAsNumber() >= QgsProjectVersion( 1, 3, 0 ) && outputCRS.hasAxisInverted() )
{
mapExtent.invert();
}


// add layers to dxf
std::unique_ptr<QgsDxfExport> dxf = qgis::make_unique<QgsDxfExport>();
dxf->setExtent( mWmsParameters.bboxAsRectangle() );
dxf->setExtent( mapExtent );
dxf->setDestinationCrs( outputCRS );
dxf->addLayers( dxfLayers );
dxf->setLayerTitleAsName( mWmsParameters.dxfUseLayerTitleAsName() );
dxf->setSymbologyExport( mWmsParameters.dxfMode() );
Expand Down
1 change: 1 addition & 0 deletions tests/src/python/CMakeLists.txt
Expand Up @@ -382,6 +382,7 @@ if (WITH_SERVER)
ADD_PYTHON_TEST(PyQgsServerLandingPage test_qgsserver_landingpage.py)
ADD_PYTHON_TEST(PyQgsServerApiContext test_qgsserver_apicontext.py)
ADD_PYTHON_TEST(PyQgsServerWMSGetMap test_qgsserver_wms_getmap.py)
ADD_PYTHON_TEST(PyQgsServerWMSGetMapDxf test_qgsserver_wms_dxf.py)
ADD_PYTHON_TEST(PyQgsServerWMSGetMapSizeProject test_qgsserver_wms_getmap_size_project.py)
ADD_PYTHON_TEST(PyQgsServerWMSGetMapSizeServer test_qgsserver_wms_getmap_size_server.py)
ADD_PYTHON_TEST(PyQgsServerWMSGetMapIgnoreBadLayers test_qgsserver_wms_getmap_ignore_bad_layers.py)
Expand Down
72 changes: 72 additions & 0 deletions tests/src/python/test_qgsserver_wms_dxf.py
@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsServer WMS GetPrint.
From build dir, run: ctest -R PyQgsServerWMSGetMapDxf -V
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Tudor Bărăscu'
__date__ = '27/01/2021'
__copyright__ = 'Copyright 2020, The QGIS Project'

import os

import urllib.parse

from qgis.testing import unittest

from test_qgsserver import QgsServerTestBase

from qgis.core import (QgsVectorLayer)

from qgis.PyQt import QtCore

# Needed on Qt 5 so that the serialization of XML is consistent among all executions
os.environ['QT_HASH_SEED'] = '1'


class PyQgsServerWMSGetMapDxf(QgsServerTestBase):

def test_dxf_export_works_with_reverse_axis_epsg(self):
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(os.path.join(self.testdata_path,
'test_dxf_export.qgs')),
"SERVICE": "WMS",
"VERSION": "1.3.0",
"REQUEST": "GetMap",
"BBOX": "399980,449980,400050,450100",
"CRS": "EPSG:3844",
"LAYERS": "test_dxf_export",
"STYLES": ",",
"FORMAT": "application/dxf",
"SCALE": "500",
"FILE_NAME": "test_dxf_export.dxf"
}.items())])

r, h = self._result(self._execute_request(qs))

tempDir = QtCore.QTemporaryDir()
dxf = os.path.join(tempDir.path(), 'test_dxf_export.dxf')
f = open(dxf, 'wb')
f.write(r)
f.close()

vl = QgsVectorLayer(dxf, "lyr", "ogr")
myMessage = ('Expected downloaded dxf contains: %s line\nGot: %s\n' %
(1, vl.featureCount()))

self.assertEqual(vl.featureCount(), 1, myMessage)

line_from_dxf = next(vl.getFeatures()).geometry().asWkt()
line = 'LineString (450000 400000, 450100 400000)'

self.assertEqual(line_from_dxf, line)


if __name__ == '__main__':
unittest.main()
8 changes: 8 additions & 0 deletions tests/testdata/qgis_server/test_dxf_export.geojson
@@ -0,0 +1,8 @@
{
"type": "FeatureCollection",
"name": "test_dxf_export",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::3844" } },
"features": [
{ "type": "Feature", "properties": { }, "geometry": { "type": "LineString", "coordinates": [ [ 450000, 400000 ], [ 450100, 400000 ] ] } }
]
}

0 comments on commit 2d1057d

Please sign in to comment.