Skip to content

Commit 9167cb4

Browse files
rouaultnyalldawson
authored andcommittedMay 27, 2019
QgsVectorFileWriter::writeAsVectorFormat(): return appropriate output layer name for GPX driver (github fixes #29819)
1 parent 29806b4 commit 9167cb4

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed
 

‎src/core/qgsvectorfilewriter.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,51 @@ void QgsVectorFileWriter::init( QString vectorFileName,
428428
{
429429
mLayer = OGR_DS_CreateLayer( mDS.get(), layerName.toUtf8().constData(), mOgrRef, wkbType, options );
430430
if ( newLayer && mLayer )
431+
{
431432
*newLayer = OGR_L_GetName( mLayer );
433+
if ( driverName == QLatin1String( "GPX" ) )
434+
{
435+
// See logic in GDAL ogr/ogrsf_frmts/gpx/ogrgpxdatasource.cpp ICreateLayer()
436+
switch ( QgsWkbTypes::flatType( geometryType ) )
437+
{
438+
case QgsWkbTypes::Point:
439+
{
440+
if ( !EQUAL( layerName.toUtf8().constData(), "track_points" ) &&
441+
!EQUAL( layerName.toUtf8().constData(), "route_points" ) )
442+
{
443+
*newLayer = QStringLiteral( "waypoints" );
444+
}
445+
}
446+
break;
447+
448+
case QgsWkbTypes::LineString:
449+
{
450+
const char *pszForceGPXTrack
451+
= CSLFetchNameValue( options, "FORCE_GPX_TRACK" );
452+
if ( pszForceGPXTrack && CPLTestBool( pszForceGPXTrack ) )
453+
*newLayer = QStringLiteral( "tracks" );
454+
else
455+
*newLayer = QStringLiteral( "routes" );
456+
457+
}
458+
break;
459+
460+
case QgsWkbTypes::MultiLineString:
461+
{
462+
const char *pszForceGPXRoute
463+
= CSLFetchNameValue( options, "FORCE_GPX_ROUTE" );
464+
if ( pszForceGPXRoute && CPLTestBool( pszForceGPXRoute ) )
465+
*newLayer = QStringLiteral( "routes" );
466+
else
467+
*newLayer = QStringLiteral( "tracks" );
468+
}
469+
break;
470+
471+
default:
472+
break;
473+
}
474+
}
475+
}
432476
}
433477
else if ( driverName == QLatin1String( "DGN" ) )
434478
{

‎tests/src/core/testqgsvectorfilewriter.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ class TestQgsVectorFileWriter: public QObject
6262
public:
6363
TestQgsVectorFileWriter();
6464

65+
void _testExportToGpx( const QString &geomTypeName,
66+
const QString &wkt,
67+
const QString &expectedLayerName,
68+
const QString &inputLayerName = QStringLiteral( "test" ),
69+
const QStringList &layerOptions = QStringList() );
70+
6571
private slots:
6672
void initTestCase();// will be called before the first testfunction is executed.
6773
void init() {} // will be called before each testfunction is executed.
@@ -84,6 +90,20 @@ class TestQgsVectorFileWriter: public QObject
8490
void prepareWriteAsVectorFormat();
8591
//! Test regression #21714 (Exported GeoPackages have wrong field definitions)
8692
void testTextFieldLength();
93+
//! Test https://issues.qgis.org/issues/22005
94+
void testExportToGpxPoint();
95+
//! Test https://issues.qgis.org/issues/22005
96+
void testExportToGpxPointTrackPoints();
97+
//! Test https://issues.qgis.org/issues/22005
98+
void testExportToGpxPointRoutePoints();
99+
//! Test https://issues.qgis.org/issues/22005
100+
void testExportToGpxLineString();
101+
//! Test https://issues.qgis.org/issues/22005
102+
void testExportToGpxLineStringForceTrack();
103+
//! Test https://issues.qgis.org/issues/22005
104+
void testExportToGpxMultiLineString();
105+
//! Test https://issues.qgis.org/issues/22005
106+
void testExportToGpxMultiLineStringForceRoute();
87107

88108
private:
89109
// a little util fn used by all tests
@@ -524,5 +544,111 @@ void TestQgsVectorFileWriter::testTextFieldLength()
524544

525545
}
526546

547+
void TestQgsVectorFileWriter::_testExportToGpx( const QString &geomTypeName,
548+
const QString &wkt,
549+
const QString &expectedLayerName,
550+
const QString &inputLayerName,
551+
const QStringList &layerOptions )
552+
{
553+
QTemporaryFile tmpFile( QDir::tempPath() + "/test_qgsvectorfilewriter_testExportToGpx" + geomTypeName + "_XXXXXX.gpx" );
554+
tmpFile.open();
555+
QString fileName( tmpFile.fileName( ) );
556+
QString memLayerDef( geomTypeName );
557+
if ( inputLayerName == QLatin1String( "track_points" ) )
558+
{
559+
memLayerDef += QStringLiteral( "?field=track_fid:int&field=track_seg_id:int" );
560+
}
561+
else if ( inputLayerName == QLatin1String( "route_points" ) )
562+
{
563+
memLayerDef += QStringLiteral( "?field=route_fid:int" );
564+
}
565+
QgsVectorLayer vl( memLayerDef, "test", "memory" );
566+
QgsFeature f { vl.fields() };
567+
if ( inputLayerName == QLatin1String( "track_points" ) )
568+
{
569+
f.setAttribute( 0, 1 );
570+
f.setAttribute( 1, 1 );
571+
}
572+
else if ( inputLayerName == QLatin1String( "route_points" ) )
573+
{
574+
f.setAttribute( 0, 1 );
575+
}
576+
f.setGeometry( QgsGeometry::fromWkt( wkt ) );
577+
QVERIFY( vl.startEditing() );
578+
QVERIFY( vl.addFeature( f ) );
579+
QgsVectorFileWriter::SaveVectorOptions options;
580+
options.driverName = "GPX";
581+
options.layerName = inputLayerName;
582+
options.layerOptions = layerOptions;
583+
QString outLayerName;
584+
QgsVectorFileWriter::WriterError error( QgsVectorFileWriter::writeAsVectorFormat(
585+
&vl,
586+
fileName,
587+
options,
588+
nullptr, // newFilename
589+
nullptr, // errorMessage
590+
&outLayerName ) );
591+
QCOMPARE( error, QgsVectorFileWriter::WriterError::NoError );
592+
QCOMPARE( outLayerName, expectedLayerName );
593+
QgsVectorLayer vl2( QStringLiteral( "%1|layername=%2" ).arg( fileName ).arg( outLayerName ), "src_test", "ogr" );
594+
QVERIFY( vl2.isValid() );
595+
QCOMPARE( vl2.featureCount(), 1L );
596+
}
597+
598+
void TestQgsVectorFileWriter::testExportToGpxPoint()
599+
{
600+
_testExportToGpx( QStringLiteral( "Point" ),
601+
QStringLiteral( "point(9 45)" ),
602+
QStringLiteral( "waypoints" ) );
603+
}
604+
605+
void TestQgsVectorFileWriter::testExportToGpxPointTrackPoints()
606+
{
607+
_testExportToGpx( QStringLiteral( "Point" ),
608+
QStringLiteral( "point(9 45)" ),
609+
QStringLiteral( "track_points" ),
610+
QStringLiteral( "track_points" ) );
611+
}
612+
613+
void TestQgsVectorFileWriter::testExportToGpxPointRoutePoints()
614+
{
615+
_testExportToGpx( QStringLiteral( "Point" ),
616+
QStringLiteral( "point(9 45)" ),
617+
QStringLiteral( "route_points" ),
618+
QStringLiteral( "route_points" ) );
619+
}
620+
621+
void TestQgsVectorFileWriter::testExportToGpxLineString()
622+
{
623+
_testExportToGpx( QStringLiteral( "LineString" ),
624+
QStringLiteral( "linestring(9 45,10 46)" ),
625+
QStringLiteral( "routes" ) );
626+
}
627+
628+
void TestQgsVectorFileWriter::testExportToGpxLineStringForceTrack()
629+
{
630+
_testExportToGpx( QStringLiteral( "LineString" ),
631+
QStringLiteral( "linestring(9 45,10 46)" ),
632+
QStringLiteral( "tracks" ),
633+
QStringLiteral( "test" ),
634+
QStringList() << QStringLiteral( "FORCE_GPX_TRACK=YES" ) );
635+
}
636+
637+
void TestQgsVectorFileWriter::testExportToGpxMultiLineString()
638+
{
639+
_testExportToGpx( QStringLiteral( "MultiLineString" ),
640+
QStringLiteral( "multilinestring((9 45,10 46))" ),
641+
QStringLiteral( "tracks" ) );
642+
}
643+
644+
void TestQgsVectorFileWriter::testExportToGpxMultiLineStringForceRoute()
645+
{
646+
_testExportToGpx( QStringLiteral( "MultiLineString" ),
647+
QStringLiteral( "multilinestring((9 45,10 46))" ),
648+
QStringLiteral( "routes" ),
649+
QStringLiteral( "test" ),
650+
QStringList() << QStringLiteral( "FORCE_GPX_ROUTE=YES" ) );
651+
}
652+
527653
QGSTEST_MAIN( TestQgsVectorFileWriter )
528654
#include "testqgsvectorfilewriter.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.