[gdal-dev] setting a spatial filter on a postgis layer gives wrong results
Landry Breuil
breuil at craig.fr
Fri Jul 5 01:12:41 PDT 2019
Hi,
initially saw this with gdal 2.2.3 on debian, and confirmed the
behaviour is the same with gdal 3.0 on openbsd.
I'm doing a spatial join between an union of geometries filtered from a
geopackage and a tileindex layer stored in postgis, and the spatial
filter set on the postgis layer behaves weird, the provided result is as
if the bbox of the spatial filter/geometry was used, instead of the
filter itself.
applying the exact same filter to a copy of the postgis layer stored in
memory gives correct results.
below my testing code:
from osgeo import gdal
from osgeo import ogr
dbhandle = gdal.OpenEx("PG: host=localhost dbname=gisdata-local
user=postgis", gdal.OF_VERBOSE_ERROR, allowed_drivers = ['PostgreSQL'])
gpkg = gdal.OpenEx('/tmp/dbdemogeor.gpkg')
communes = gpkg.GetLayerByName('adminexpress_201806_commune')
assert (dbhandle is not None)
layer = dbhandle.GetLayer('rtge.ortho')
print("{} tiles total, {} communes".format(layer.GetFeatureCount(),
communes.GetFeatureCount()))
outdriver=ogr.GetDriverByName('MEMORY')
source=outdriver.CreateDataSource('memData')
tmp=outdriver.Open('memData',1)
source.CopyLayer(layer, 'out')
layer2 = source.GetLayer('out')
communes.SetAttributeFilter("insee_dep='63'")
multi = ogr.Geometry(ogr.wkbMultiPolygon)
# compute the multigeometry for all the comms in the area list
for feature in communes:
g = feature.GetGeometryRef()
for i in range(0, g.GetGeometryCount()):
multi.AddGeometry(g.GetGeometryRef(i))
communes.ResetReading()
union = multi.UnionCascaded()
# filter tileindex on a 100m bufferized union of the comms
layer.SetSpatialFilter(union.Buffer(100))
print("{} tiles are inside the geomunion for {} comms ({}
surf)".format(layer.GetFeatureCount(), communes.GetFeatureCount(),
union.GetArea()))
print("{} tiles in memory layer".format(layer2.GetFeatureCount()))
layer2.SetSpatialFilter(union.Buffer(100))
print("{} tiles in memory layer after
filtering".format(layer2.GetFeatureCount()))
And the resulting output:
405557 tiles total, 4092 communes
131055 tiles are inside the geomunion for 467 comms (8001479208.5 surf)
405557 tiles in memory layer
82868 tiles in memory layer after filtering
is my code wrong, or the handling of spatial filters for postgis layers
should be done in a different way, ie directly using postgis methods
instead of trying to use gdal APIs?
--
Landry Breuil
Administrateur de données du CRAIG
----------------------------------------------------------------------------
Centre Régional Auvergne-Rhône-Alpes de l'Information Géographique
Bât. du CRRI - Campus des Cézeaux
7 avenue Blaise Pascal - CS 60026
63178 Aubière
https://www.craig.fr - @GipCraig
----------------------------------------------------------------------------
Support utilisateurs (tous les jours ouvrés de 8H30 à 12H30) : 04 73 405 405
More information about the gdal-dev
mailing list