Add shapefile provider tests

+ Fix OGR provider so it does not return features without geometry when
filtering with a FilterRect
This commit is contained in:
Matthias Kuhn 2015-05-22 21:02:14 +02:00
parent e7b7549c29
commit afc3996f6c
10 changed files with 88 additions and 25 deletions

View File

@ -74,15 +74,9 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool
// spatial query to select features
if ( mRequest.filterType() == QgsFeatureRequest::FilterRect )
{
OGRGeometryH filter = 0;
QString wktExtent = QString( "POLYGON((%1))" ).arg( mRequest.filterRect().asPolygon() );
QByteArray ba = wktExtent.toAscii();
const char *wktText = ba;
const QgsRectangle& rect = mRequest.filterRect();
OGR_G_CreateFromWkt(( char ** )&wktText, NULL, &filter );
QgsDebugMsg( "Setting spatial filter using " + wktExtent );
OGR_L_SetSpatialFilter( ogrLayer, filter );
OGR_G_DestroyGeometry( filter );
OGR_L_SetSpatialFilterRect( ogrLayer, rect.xMinimum(), rect.yMinimum(), rect.xMaximum(), rect.yMaximum() );
}
else
{
@ -186,6 +180,9 @@ bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )
if ( !readFeature( fet, feature ) )
continue;
if ( mRequest.filterType() == QgsFeatureRequest::FilterRect && !feature.constGeometry() )
continue;
// we have a feature, end this cycle
feature.setValid( true );
OGR_F_Destroy( fet );

View File

@ -144,6 +144,9 @@ bool QgsSpatiaLiteFeatureIterator::close()
bool QgsSpatiaLiteFeatureIterator::prepareStatement( QString whereClause )
{
if ( !mHandle )
return false;
try
{
QString sql = QString( "SELECT %1" ).arg( mHasPrimaryKey ? quotedPrimaryKey() : "0" );

View File

@ -45,6 +45,7 @@ ADD_PYTHON_TEST(PyQgsEditWidgets test_qgseditwidgets.py)
ADD_PYTHON_TEST(PyQgsRangeWidgets test_qgsrangewidgets.py)
ADD_PYTHON_TEST(PyQgsPostgresProvider test_provider_postgres.py)
ADD_PYTHON_TEST(PyQgsSpatialiteProvider test_provider_spatialite.py)
ADD_PYTHON_TEST(PyQgsShapefileProvider test_provider_shapefile.py)
ADD_PYTHON_TEST(PyQgsSpatialiteProviderOther test_qgsspatialiteprovider.py)
IF (WITH_APIDOC)
ADD_PYTHON_TEST(PyQgsDocCoverage test_qgsdoccoverage.py)

View File

@ -15,19 +15,23 @@ __revision__ = '$Format:%H$'
from qgis.core import QgsRectangle, QgsFeatureRequest, QgsGeometry, NULL
from utilities import TestCase
class ProviderTestCase(object):
class ProviderTestCase(object):
def runGetFeatureTests(self, provider):
assert len( [f for f in provider.getFeatures()] ) == 5
assert len( [f for f in provider.getFeatures( QgsFeatureRequest().setFilterExpression( 'name IS NOT NULL' ) )] ) == 4
assert len( [f for f in provider.getFeatures( QgsFeatureRequest().setFilterExpression('name LIKE \'Apple\'' ) )] ) == 1
assert len( [f for f in provider.getFeatures( QgsFeatureRequest().setFilterExpression('name ILIKE \'aPple\'' ) )] ) == 1
assert len( [f for f in provider.getFeatures( QgsFeatureRequest().setFilterExpression('name ILIKE \'%pp%\'' ) )] ) == 1
assert len( [f for f in provider.getFeatures( QgsFeatureRequest().setFilterExpression('cnt > 0' ) ) ] ) == 4
assert len( [f for f in provider.getFeatures( QgsFeatureRequest().setFilterExpression('cnt < 0' ) ) ] ) == 1
assert len( [f for f in provider.getFeatures( QgsFeatureRequest().setFilterExpression('cnt >= 100' ) ) ] ) == 4
assert len( [f for f in provider.getFeatures( QgsFeatureRequest().setFilterExpression('cnt <= 100' ) ) ] ) == 2
assert len( [f for f in provider.getFeatures( QgsFeatureRequest().setFilterExpression('pk IN (1, 2, 4, 8)' ) )] ) == 3
assert len([f for f in provider.getFeatures()]) == 5
assert len([f for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression('name IS NOT NULL'))]) == 4
assert len(
[f for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression('name LIKE \'Apple\''))]) == 1
assert len(
[f for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression('name ILIKE \'aPple\''))]) == 1
assert len(
[f for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression('name ILIKE \'%pp%\''))]) == 1
assert len([f for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression('cnt > 0'))]) == 4
assert len([f for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression('cnt < 0'))]) == 1
assert len([f for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression('cnt >= 100'))]) == 4
assert len([f for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression('cnt <= 100'))]) == 2
assert len(
[f for f in provider.getFeatures(QgsFeatureRequest().setFilterExpression('pk IN (1, 2, 4, 8)'))]) == 3
def testGetFeaturesUncompiled(self):
try:
@ -45,7 +49,7 @@ class ProviderTestCase(object):
def testGetFeaturesFilterRectTests(self):
extent = QgsRectangle(-70, 67, -60, 80)
features = [ f['pk'] for f in self.provider.getFeatures( QgsFeatureRequest().setFilterRect( extent ) ) ]
features = [f['pk'] for f in self.provider.getFeatures(QgsFeatureRequest().setFilterRect(extent))]
assert set(features) == set([2L, 4L]), 'Got {} instead'.format(features)
def testMinValue(self):
@ -57,14 +61,16 @@ class ProviderTestCase(object):
assert self.provider.maximumValue(2) == 'Pear'
def testExtent(self):
reference = QgsGeometry.fromRect(QgsRectangle(-71.1230000000000047,66.3299999999999983,-65.3199999999999932,78.2999999999999972))
provider_extent=QgsGeometry.fromRect(self.provider.extent())
reference = QgsGeometry.fromRect(
QgsRectangle(-71.1230000000000047, 66.3299999999999983, -65.3199999999999932, 78.2999999999999972))
provider_extent = QgsGeometry.fromRect(self.provider.extent())
assert QgsGeometry.compare( provider_extent.asPolygon(), reference.asPolygon(), 0.000001)
assert QgsGeometry.compare(provider_extent.asPolygon(), reference.asPolygon(), 0.000001)
def testUnique(self):
assert set(self.provider.uniqueValues(1)) == set([-200, 100, 200, 300, 400])
assert set([u'Apple', u'Honey', u'Orange', u'Pear', NULL]) == set(self.provider.uniqueValues(2)), 'Got {}'.format(set(self.provider.uniqueValues(2)))
assert set([u'Apple', u'Honey', u'Orange', u'Pear', NULL]) == set(
self.provider.uniqueValues(2)), 'Got {}'.format(set(self.provider.uniqueValues(2)))
def testFeatureCount(self):
assert self.provider.featureCount() == 5
assert self.provider.featureCount() == 5

View File

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for the postgres provider.
.. 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__ = 'Matthias Kuhn'
__date__ = '2015-04-23'
__copyright__ = 'Copyright 2015, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import qgis
import os
from qgis.core import QgsVectorLayer, QgsFeatureRequest, QgsFeature, QgsProviderRegistry
from PyQt4.QtCore import QSettings
from utilities import (unitTestDataPath,
getQgisTestApp,
unittest,
TestCase
)
from providertestbase import ProviderTestCase
QGISAPP, CANVAS, IFACE, PARENT = getQgisTestApp()
TEST_DATA_DIR = unitTestDataPath()
class TestPyQgsPostgresProvider(TestCase, ProviderTestCase):
@classmethod
def setUpClass(cls):
"""Run before all tests"""
# Create test layer
cls.vl = QgsVectorLayer(u'{}/provider/shapefile.shp|layerid=0'.format(TEST_DATA_DIR), u'test', u'ogr' )
assert(cls.vl.isValid())
cls.provider = cls.vl.dataProvider()
@classmethod
def tearDownClass(cls):
"""Run after all tests"""
def testUnique(self):
"""
Override parent method because OGR doesn't return NULL values in SELECT DISTINCT...
This is only to make the tests pass, not to define this as expected behavior so if it is possible to remove this
in the future even better.
"""
assert set(self.provider.uniqueValues(1)) == set([-200, 100, 200, 300, 400])
assert set([u'Apple', u'Honey', u'Orange', u'Pear']) == set(self.provider.uniqueValues(2)), 'Got {}'.format(set(self.provider.uniqueValues(2)))
if __name__ == '__main__':
unittest.main()

BIN
tests/testdata/provider/shapefile.dbf vendored Normal file

Binary file not shown.

1
tests/testdata/provider/shapefile.prj vendored Normal file
View File

@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]

1
tests/testdata/provider/shapefile.qpj vendored Normal file
View File

@ -0,0 +1 @@
GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]

BIN
tests/testdata/provider/shapefile.shp vendored Normal file

Binary file not shown.

BIN
tests/testdata/provider/shapefile.shx vendored Normal file

Binary file not shown.