Skip to content

Commit 9d81938

Browse files
committed
Merge pull request #2605 from nyalldawson/delimited
Add support for curved geometries and M/Z values to delimited text provider
2 parents 5838819 + 809c925 commit 9d81938

File tree

6 files changed

+37
-45
lines changed

6 files changed

+37
-45
lines changed

src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ QgsGeometry* QgsDelimitedTextFeatureIterator::loadGeometryWkt( const QStringList
377377
}
378378

379379
isNull = false;
380-
geom = QgsDelimitedTextProvider::geomFromWkt( sWkt, mSource->mWktHasPrefix, mSource->mWktHasZM );
380+
geom = QgsDelimitedTextProvider::geomFromWkt( sWkt, mSource->mWktHasPrefix );
381381

382382
if ( geom && geom->type() != mSource->mGeometryType )
383383
{
@@ -482,7 +482,6 @@ QgsDelimitedTextFeatureSource::QgsDelimitedTextFeatureSource( const QgsDelimited
482482
, mXFieldIndex( p->mXFieldIndex )
483483
, mYFieldIndex( p->mYFieldIndex )
484484
, mWktFieldIndex( p->mWktFieldIndex )
485-
, mWktHasZM( p->mWktHasZM )
486485
, mWktHasPrefix( p->mWktHasPrefix )
487486
, mGeometryType( p->mGeometryType )
488487
, mDecimalPoint( p->mDecimalPoint )

src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.h

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class QgsDelimitedTextFeatureSource : public QgsAbstractFeatureSource
4545
int mXFieldIndex;
4646
int mYFieldIndex;
4747
int mWktFieldIndex;
48-
bool mWktHasZM;
4948
bool mWktHasPrefix;
5049
QGis::GeometryType mGeometryType;
5150
QString mDecimalPoint;

src/providers/delimitedtext/qgsdelimitedtextprovider.cpp

+3-12
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ static const QString TEXT_PROVIDER_DESCRIPTION = "Delimited text data provider";
5353
static const int SUBSET_ID_THRESHOLD_FACTOR = 10;
5454

5555
QRegExp QgsDelimitedTextProvider::WktPrefixRegexp( "^\\s*(?:\\d+\\s+|SRID\\=\\d+\\;)", Qt::CaseInsensitive );
56-
QRegExp QgsDelimitedTextProvider::WktZMRegexp( "\\s*(?:z|m|zm)(?=\\s*\\()", Qt::CaseInsensitive );
57-
QRegExp QgsDelimitedTextProvider::WktCrdRegexp( "(\\-?\\d+(?:\\.\\d*)?\\s+\\-?\\d+(?:\\.\\d*)?)\\s[\\s\\d\\.\\-]+" );
5856
QRegExp QgsDelimitedTextProvider::CrdDmsRegexp( "^\\s*(?:([-+nsew])\\s*)?(\\d{1,3})(?:[^0-9.]+([0-5]?\\d))?[^0-9.]+([0-5]?\\d(?:\\.\\d+)?)[^0-9.]*([-+nsew])?\\s*$", Qt::CaseInsensitive );
5957

6058
QgsDelimitedTextProvider::QgsDelimitedTextProvider( const QString& uri )
@@ -67,7 +65,6 @@ QgsDelimitedTextProvider::QgsDelimitedTextProvider( const QString& uri )
6765
, mXFieldIndex( -1 )
6866
, mYFieldIndex( -1 )
6967
, mWktFieldIndex( -1 )
70-
, mWktHasZM( false )
7168
, mWktHasPrefix( false )
7269
, mXyDms( false )
7370
, mSubsetString( "" )
@@ -447,9 +444,7 @@ void QgsDelimitedTextProvider::scanFile( bool buildIndexes )
447444
QgsGeometry *geom = nullptr;
448445
if ( !mWktHasPrefix && sWkt.indexOf( WktPrefixRegexp ) >= 0 )
449446
mWktHasPrefix = true;
450-
if ( !mWktHasZM && sWkt.indexOf( WktZMRegexp ) >= 0 )
451-
mWktHasZM = true;
452-
geom = geomFromWkt( sWkt, mWktHasPrefix, mWktHasZM );
447+
geom = geomFromWkt( sWkt, mWktHasPrefix );
453448

454449
if ( geom )
455450
{
@@ -812,7 +807,7 @@ void QgsDelimitedTextProvider::rescanFile()
812807
mUseSpatialIndex = buildSpatialIndex;
813808
}
814809

815-
QgsGeometry *QgsDelimitedTextProvider::geomFromWkt( QString &sWkt, bool wktHasPrefixRegexp, bool wktHasZM )
810+
QgsGeometry *QgsDelimitedTextProvider::geomFromWkt( QString &sWkt, bool wktHasPrefixRegexp )
816811
{
817812
QgsGeometry *geom = nullptr;
818813
try
@@ -822,10 +817,6 @@ QgsGeometry *QgsDelimitedTextProvider::geomFromWkt( QString &sWkt, bool wktHasPr
822817
sWkt.remove( WktPrefixRegexp );
823818
}
824819

825-
if ( wktHasZM )
826-
{
827-
sWkt.remove( WktZMRegexp ).replace( WktCrdRegexp, "\\1" );
828-
}
829820
geom = QgsGeometry::fromWkt( sWkt );
830821
}
831822
catch ( ... )
@@ -1148,7 +1139,7 @@ bool QgsDelimitedTextProvider::isValid()
11481139

11491140
int QgsDelimitedTextProvider::capabilities() const
11501141
{
1151-
return SelectAtId | CreateSpatialIndex;
1142+
return SelectAtId | CreateSpatialIndex | CircularGeometries;
11521143
}
11531144

11541145

src/providers/delimitedtext/qgsdelimitedtextprovider.h

+2-19
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,6 @@ class QgsDelimitedTextProvider : public QgsVectorDataProvider
217217

218218
private:
219219

220-
static QRegExp WktZMRegexp;
221-
static QRegExp WktCrdRegexp;
222-
223220
void scanFile( bool buildIndexes );
224221
void rescanFile();
225222
void resetCachedSubset();
@@ -231,7 +228,7 @@ class QgsDelimitedTextProvider : public QgsVectorDataProvider
231228
void setUriParameter( const QString& parameter, const QString& value );
232229

233230

234-
static QgsGeometry *geomFromWkt( QString &sWkt, bool wktHasPrefixRegexp, bool wktHasZM );
231+
static QgsGeometry *geomFromWkt( QString &sWkt, bool wktHasPrefixRegexp );
235232
static bool pointFromXY( QString &sX, QString &sY, QgsPoint &point, const QString& decimalPoint, bool xyDms );
236233
static double dmsStringToDouble( const QString &sX, bool *xOk );
237234

@@ -258,13 +255,8 @@ class QgsDelimitedTextProvider : public QgsVectorDataProvider
258255
int mYFieldIndex;
259256
int mWktFieldIndex;
260257

261-
// Handling of WKT types with .. Z, .. M, and .. ZM geometries (ie
262-
// Z values and/or measures). mWktZMRegexp is used to test for and
263-
// remove the Z or M fields, and mWktCrdRegexp is used to remove the
264-
// extra coordinate values. mWktPrefix regexp is used to clean up
258+
// mWktPrefix regexp is used to clean up
265259
// prefixes sometimes used for WKT (postgis EWKT, informix SRID)
266-
267-
bool mWktHasZM;
268260
bool mWktHasPrefix;
269261

270262
//! Layer extent
@@ -295,15 +287,6 @@ class QgsDelimitedTextProvider : public QgsVectorDataProvider
295287
//! Record file updates, flags rescan required
296288
bool mRescanRequired;
297289

298-
struct wkbPoint
299-
{
300-
unsigned char byteOrder;
301-
quint32 wkbType;
302-
double x;
303-
double y;
304-
};
305-
wkbPoint mWKBpt;
306-
307290
// Coordinate reference sytem
308291
QgsCoordinateReferenceSystem mCrs;
309292

tests/src/python/test_qgsdelimitedtextprovider_wanted.py

+27-9
Original file line numberDiff line numberDiff line change
@@ -460,13 +460,13 @@ def test_011_read_wkt():
460460
'id': u'10',
461461
'description': u'Measure in point',
462462
'#fid': 11,
463-
'#geometry': 'Point (10 20)',
463+
'#geometry': 'PointM (10 20 30)',
464464
},
465465
}
466466
wanted['log'] = [
467467
u'Errors in file testwkt.csv',
468468
u'1 records discarded due to invalid geometry definitions',
469-
u'7 records discarded due to incompatible geometry types',
469+
u'10 records discarded due to incompatible geometry types',
470470
u'The following lines were not loaded into QGIS due to errors:',
471471
u'Invalid WKT at line 8',
472472
]
@@ -507,13 +507,13 @@ def test_012_read_wkt_point():
507507
'id': u'10',
508508
'description': u'Measure in point',
509509
'#fid': 11,
510-
'#geometry': 'Point (10 20)',
510+
'#geometry': 'PointM (10 20 30)',
511511
},
512512
}
513513
wanted['log'] = [
514514
u'Errors in file testwkt.csv',
515515
u'1 records discarded due to invalid geometry definitions',
516-
u'7 records discarded due to incompatible geometry types',
516+
u'10 records discarded due to incompatible geometry types',
517517
u'The following lines were not loaded into QGIS due to errors:',
518518
u'Invalid WKT at line 8',
519519
]
@@ -542,25 +542,37 @@ def test_013_read_wkt_line():
542542
'id': u'11',
543543
'description': u'Measure in line',
544544
'#fid': 12,
545-
'#geometry': 'LineString (10 20, 11 21)',
545+
'#geometry': 'LineStringM (10 20 30, 11 21 31)',
546546
},
547547
13: {
548548
'id': u'12',
549549
'description': u'Z in line',
550550
'#fid': 13,
551-
'#geometry': 'LineString (10 20, 11 21)',
551+
'#geometry': 'LineStringZ (10 20 30, 11 21 31)',
552552
},
553553
14: {
554554
'id': u'13',
555555
'description': u'Measure and Z in line',
556556
'#fid': 14,
557-
'#geometry': 'LineString (10 20, 11 21)',
557+
'#geometry': 'LineStringZM (10 20 30 40, 11 21 31 41)',
558+
},
559+
15: {
560+
'id': u'14',
561+
'description': u'CircularString',
562+
'#fid': 15,
563+
'#geometry': 'CircularString (268 415, 227 505, 227 406)',
564+
},
565+
17: {
566+
'id': u'16',
567+
'description': u'CompoundCurve',
568+
'#fid': 17,
569+
'#geometry': 'CompoundCurve ((5 3, 5 13), CircularString(5 13, 7 15, 9 13), (9 13, 9 3), CircularString(9 3, 7 1, 5 3))',
558570
},
559571
}
560572
wanted['log'] = [
561573
u'Errors in file testwkt.csv',
562574
u'1 records discarded due to invalid geometry definitions',
563-
u'7 records discarded due to incompatible geometry types',
575+
u'8 records discarded due to incompatible geometry types',
564576
u'The following lines were not loaded into QGIS due to errors:',
565577
u'Invalid WKT at line 8',
566578
]
@@ -585,11 +597,17 @@ def test_014_read_wkt_polygon():
585597
'#fid': 7,
586598
'#geometry': 'MultiPolygon (((10 10,10 20,20 20,20 10,10 10),(14 14,14 16,16 16,14 14)),((30 30,30 35,35 35,30 30)))',
587599
},
600+
16: {
601+
'id': u'15',
602+
'description': u'CurvePolygon',
603+
'#fid': 16,
604+
'#geometry': 'CurvePolygon (CircularString (1 3, 3 5, 4 7, 7 3, 1 3))',
605+
},
588606
}
589607
wanted['log'] = [
590608
u'Errors in file testwkt.csv',
591609
u'1 records discarded due to invalid geometry definitions',
592-
u'10 records discarded due to incompatible geometry types',
610+
u'12 records discarded due to incompatible geometry types',
593611
u'The following lines were not loaded into QGIS due to errors:',
594612
u'Invalid WKT at line 8',
595613
]

tests/testdata/delimitedtext/testwkt.csv

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ id|description|geom_wkt
99
8|EWKT prefix|SRID=1234;POINT(10 10)
1010
9|Informix prefix|1 POINT(10 10)
1111
10|Measure in point|POINTM(10 20 30)
12-
11|Measure in line|LINESTRING(10.0 20.0 30.0, 11.0 21.0 31.0)
12+
11|Measure in line|LINESTRINGM(10.0 20.0 30.0, 11.0 21.0 31.0)
1313
12|Z in line|LINESTRING Z(10.0 20.0 30.0, 11.0 21.0 31.0)
1414
13|Measure and Z in line|LINESTRING ZM(10.0 20.0 30.0 40.0, 11.0 21.0 31.0 41.0)
15-
15+
14|CircularString|CIRCULARSTRING(268 415,227 505,227 406)
16+
15|CurvePolygon|CURVEPOLYGON(CIRCULARSTRING(1 3, 3 5, 4 7, 7 3, 1 3))
17+
16|CompoundCurve|COMPOUNDCURVE((5 3, 5 13), CIRCULARSTRING(5 13, 7 15, 9 13), (9 13, 9 3), CIRCULARSTRING(9 3, 7 1, 5 3))

0 commit comments

Comments
 (0)