Skip to content
Permalink
Browse files
Add shapefile provider tests
+ Fix OGR provider so it does not return features without geometry when
filtering with a FilterRect
  • Loading branch information
m-kuhn committed May 22, 2015
1 parent e7b7549 commit afc3996f6cd142b4f5fbea3e6b6b5b292b300656
@@ -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;

OGR_G_CreateFromWkt(( char ** )&wktText, NULL, &filter );
QgsDebugMsg( "Setting spatial filter using " + wktExtent );
OGR_L_SetSpatialFilter( ogrLayer, filter );
OGR_G_DestroyGeometry( filter );
const QgsRectangle& rect = mRequest.filterRect();

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 );
@@ -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" );
@@ -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)
@@ -15,19 +15,23 @@
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 @@ def testGetFeaturesCompiled(self):

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 @@ def testMaxValue(self):
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
@@ -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()
Binary file not shown.
@@ -0,0 +1 @@
GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
@@ -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"]]
Binary file not shown.
Binary file not shown.

0 comments on commit afc3996

Please sign in to comment.