Skip to content
Permalink
Browse files
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 2d1057d77a87524c705e956c6fde19a9be9b0b9d
@@ -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() );
@@ -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)
@@ -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()
@@ -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.