Skip to content

Commit 1fb60b4

Browse files
committedApr 30, 2013
Adding subset test and help information
1 parent ea8617d commit 1fb60b4

File tree

4 files changed

+49
-199
lines changed

4 files changed

+49
-199
lines changed
 

‎resources/context_help/QgsDelimitedTextSourceSelect-en_US

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ The following options can be added
270270
<li><tt>xField=fieldname</tt> specifies the name or number (starting at 1) of the field the X coordinate (only applies if wktField is not defined)</li>
271271
<li><tt>yField=fieldname</tt> specifies the name or number (starting at 1) of the field the Y coordinate (only applies if wktField is not defined)</li>
272272
<li><tt>geomType=(auto|point|line|polygon|none)</tt> specifies type of geometry for wkt fields, or none to load the file as an attribute-only table. The default is auto.</li>
273+
<li><tt>subset=expression</tt> specifies an expression used to identify a subset of the records that will be
274+
used.</li>
273275
<li><tt>crs=...</tt> specifies the coordinate system to use for the vector layer, in a format accepted by QgsCoordinateReferenceSystem.createFromString (for example &quot;EPSG:4167&quot;). If this is not
274276
specified then a dialog box may request this information from the user
275277
when the layer is loaded (depending on QGIS CRS settings).</li>

‎src/core/qgsvectorlayer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ struct CORE_EXPORT QgsVectorJoinInfo
366366
* geomType can also be set to none, in which case the layer is loaded without
367367
* geometries.
368368
*
369+
* - subset=expression
370+
*
371+
* Defines an expression that will identify a subset of records to display
372+
*
369373
* - crs=crsstring
370374
*
371375
* Defines the coordinate reference system used for the layer. This can be

‎src/providers/delimitedtext/qgsdelimitedtextprovider.cpp

Lines changed: 0 additions & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -879,205 +879,6 @@ void QgsDelimitedTextProvider::fetchAttribute( QgsFeature& feature, int fieldIdx
879879
feature.setAttribute( fieldIdx, val );
880880
}
881881

882-
void QgsDelimitedTextProvider::resetDataSummary()
883-
{
884-
QgsFeatureIterator fi = getFeatures(QgsFeatureRequest());
885-
mNumberFeatures = 0;
886-
mExtent = QgsRectangle();
887-
QgsFeature f;
888-
while( fi.nextFeature(f))
889-
{
890-
if( mGeometryType != QGis::NoGeometry )
891-
{
892-
if( mNumberFeatures == 0 )
893-
{
894-
mExtent = f.geometry()->boundingBox();
895-
}
896-
else
897-
{
898-
QgsRectangle bbox( f.geometry()->boundingBox());
899-
mExtent.combineExtentWith( &bbox);
900-
}
901-
}
902-
mNumberFeatures++;
903-
}
904-
}
905-
906-
907-
bool QgsDelimitedTextProvider::nextFeature( QgsFeature& feature, QgsDelimitedTextFile *file, const QgsFeatureRequest& request )
908-
{
909-
QStringList tokens;
910-
while ( true )
911-
{
912-
// before we do anything else, assume that there's something wrong with
913-
// the feature
914-
feature.setValid( false );
915-
QgsDelimitedTextFile::Status status = file->nextRecord( tokens );
916-
if ( status == QgsDelimitedTextFile::RecordEOF ) break;
917-
if ( status != QgsDelimitedTextFile::RecordOk ) continue;
918-
919-
int fid = file->recordLineNumber();
920-
if( request.filterType() == QgsFeatureRequest::FilterFid && fid != request.filterFid()) continue;
921-
if ( recordIsEmpty( tokens ) ) continue;
922-
923-
while ( tokens.size() < mFieldCount )
924-
tokens.append( QString::null );
925-
926-
QgsGeometry *geom = 0;
927-
928-
if ( mWktFieldIndex >= 0 )
929-
{
930-
geom = loadGeometryWkt( tokens, request );
931-
}
932-
else if ( mXFieldIndex >= 0 && mYFieldIndex >= 0 )
933-
{
934-
geom = loadGeometryXY( tokens,request );
935-
}
936-
937-
if ( !geom && mWkbType != QGis::WKBNoGeometry )
938-
{
939-
// Already dealt with invalid lines in provider - no need to repeat
940-
// removed code (CC 2013-04-13) ...
941-
// mInvalidLines << line;
942-
// In any case it may be a valid line that is excluded because of
943-
// bounds check...
944-
continue;
945-
}
946-
947-
// At this point the current feature values are valid
948-
949-
feature.setValid( true );
950-
feature.setFields( &attributeFields ); // allow name-based attribute lookups
951-
feature.setFeatureId( fid );
952-
feature.initAttributes( attributeFields.count() );
953-
954-
if ( geom )
955-
feature.setGeometry( geom );
956-
957-
if ( request.flags() & QgsFeatureRequest::SubsetOfAttributes )
958-
{
959-
const QgsAttributeList& attrs = request.subsetOfAttributes();
960-
for ( QgsAttributeList::const_iterator i = attrs.begin(); i != attrs.end(); ++i )
961-
{
962-
int fieldIdx = *i;
963-
fetchAttribute( feature, fieldIdx, tokens );
964-
}
965-
}
966-
else
967-
{
968-
for ( int idx = 0; idx < attributeFields.count(); ++idx )
969-
fetchAttribute( feature, idx, tokens );
970-
}
971-
972-
// We have a good line, so return
973-
return true;
974-
975-
} // !mStream->atEnd()
976-
977-
return false;
978-
}
979-
980-
981-
QgsGeometry* QgsDelimitedTextProvider::loadGeometryWkt( const QStringList& tokens, const QgsFeatureRequest& request )
982-
{
983-
QgsGeometry* geom = 0;
984-
QString sWkt = tokens[mWktFieldIndex];
985-
986-
geom = geomFromWkt( sWkt );
987-
988-
if ( geom && geom->type() != mGeometryType )
989-
{
990-
delete geom;
991-
geom = 0;
992-
}
993-
if ( geom && !boundsCheck( geom, request ) )
994-
{
995-
delete geom;
996-
geom = 0;
997-
}
998-
return geom;
999-
}
1000-
1001-
1002-
QgsGeometry* QgsDelimitedTextProvider::loadGeometryXY( const QStringList& tokens, const QgsFeatureRequest& request )
1003-
{
1004-
QString sX = tokens[mXFieldIndex];
1005-
QString sY = tokens[mYFieldIndex];
1006-
QgsPoint pt;
1007-
bool ok = pointFromXY( sX, sY, pt );
1008-
1009-
if ( ok && boundsCheck( pt, request ) )
1010-
{
1011-
return QgsGeometry::fromPoint( pt );
1012-
}
1013-
return 0;
1014-
}
1015-
1016-
/**
1017-
* Check to see if the point is within the selection rectangle
1018-
*/
1019-
bool QgsDelimitedTextProvider::boundsCheck( const QgsPoint &pt, const QgsFeatureRequest& request )
1020-
{
1021-
// no selection rectangle or geometry => always in the bounds
1022-
if ( request.filterType() != QgsFeatureRequest::FilterRect || ( request.flags() & QgsFeatureRequest::NoGeometry ) )
1023-
return true;
1024-
1025-
return request.filterRect().contains( pt );
1026-
}
1027-
1028-
/**
1029-
* Check to see if the geometry is within the selection rectangle
1030-
*/
1031-
bool QgsDelimitedTextProvider::boundsCheck( QgsGeometry *geom, const QgsFeatureRequest& request )
1032-
{
1033-
// no selection rectangle or geometry => always in the bounds
1034-
if ( request.filterType() != QgsFeatureRequest::FilterRect || ( request.flags() & QgsFeatureRequest::NoGeometry ) )
1035-
return true;
1036-
1037-
if ( request.flags() & QgsFeatureRequest::ExactIntersect )
1038-
return geom->intersects( request.filterRect() );
1039-
else
1040-
return geom->boundingBox().intersects( request.filterRect() );
1041-
}
1042-
1043-
1044-
void QgsDelimitedTextProvider::fetchAttribute( QgsFeature& feature, int fieldIdx, const QStringList& tokens )
1045-
{
1046-
if( fieldIdx < 0 || fieldIdx >= attributeColumns.count()) return;
1047-
int column = attributeColumns[fieldIdx];
1048-
if( column < 0 || column >= tokens.count()) return;
1049-
const QString &value = tokens[column];
1050-
QVariant val;
1051-
switch ( attributeFields[fieldIdx].type() )
1052-
{
1053-
case QVariant::Int:
1054-
if ( value.isEmpty() )
1055-
val = QVariant( attributeFields[fieldIdx].type() );
1056-
else
1057-
val = QVariant( value );
1058-
break;
1059-
case QVariant::Double:
1060-
if ( value.isEmpty() )
1061-
{
1062-
val = QVariant( attributeFields[fieldIdx].type() );
1063-
}
1064-
else if ( mDecimalPoint.isEmpty() )
1065-
{
1066-
val = QVariant( value.toDouble() );
1067-
}
1068-
else
1069-
{
1070-
val = QVariant( QString( value ).replace( mDecimalPoint, "." ).toDouble() );
1071-
}
1072-
break;
1073-
default:
1074-
val = QVariant( value );
1075-
break;
1076-
}
1077-
feature.setAttribute( fieldIdx, val );
1078-
}
1079-
1080-
1081882
// Return the extent of the layer
1082883
QgsRectangle QgsDelimitedTextProvider::extent()
1083884
{

‎tests/src/python/test_qgsdelimitedtextprovider.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,49 @@ def test_033_filter_attributes(self):
16921692
]
16931693
runTest(description,wanted,filename,requests,**params)
16941694

1695+
def test_034_substring_test(self):
1696+
description='CSV file parsing'
1697+
filename='test.csv'
1698+
params={'geomType': 'none', 'subset': 'id % 2 = 1', 'type': 'csv'}
1699+
requests=None
1700+
if rebuildTests:
1701+
createTest(description,filename,requests,**params)
1702+
assert False,"Set rebuildTests to False to run delimited text tests"
1703+
wanted={}
1704+
wanted['uri']=u'file://file?geomType=none&type=csv&subset=id%20%25%202%20%3D%201'
1705+
wanted['data']={
1706+
2L: {
1707+
'id': u'1',
1708+
'description': u'Basic unquoted record',
1709+
'data': u'Some data',
1710+
'info': u'Some info',
1711+
'field_5': u'',
1712+
'#fid': 2L,
1713+
'#geometry': 'None',
1714+
},
1715+
4L: {
1716+
'id': u'3',
1717+
'description': u'Escaped quotes',
1718+
'data': u'Quoted "citation" data',
1719+
'info': u'Unquoted',
1720+
'field_5': u'',
1721+
'#fid': 4L,
1722+
'#geometry': 'None',
1723+
},
1724+
9L: {
1725+
'id': u'5',
1726+
'description': u'Extra fields',
1727+
'data': u'data',
1728+
'info': u'info',
1729+
'field_5': u'message',
1730+
'#fid': 9L,
1731+
'#geometry': 'None',
1732+
},
1733+
}
1734+
wanted['log']=[
1735+
]
1736+
runTest(description,wanted,filename,requests,**params)
1737+
16951738
#END
16961739

16971740
if __name__ == '__main__':

0 commit comments

Comments
 (0)
Please sign in to comment.