[Gdal-dev] ogr.py Intersect with wkbGeometryCollection
Ryan, Adam
ARyan at co.linn.or.us
Thu May 5 18:37:33 EDT 2005
> -----Original Message-----
> From: Frank Warmerdam [mailto:fwarmerdam at gmail.com]
> Sent: Thursday, May 05, 2005 11:22 AM
> To: Ryan, Adam
> Cc: gdal-dev at remotesensing.org
> Subject: Re: [Gdal-dev] ogr.py Intersect with wkbGeometryCollection
>
>
> On 5/5/05, Ryan, Adam <ARyan at co.linn.or.us> wrote:
> >
> > Hi,
> >
> > I tried to use Geometry.Intersect with a wkbGeometryCollection type
> > Geometry and got hung. Is this not permited?
>
> Adam,
>
> I am not aware of a problem with this, but then I doubt I
> have specifically tried it. Can you prepare a relatively
> simple example to trigger this
> problem?
Frank, thanks for your reply on this. I'm still on the steep learning curve
here so bear with me. I've made a little test script and have noted what
works and what doesn't.
The goal for me is to write a generic theme-on-theme spatial query method,
where you would pass an ogrQueryLayer and an ogrSelectLayer with a
selectList (of record indexes obtained from a previous query that likely
involved mapscript and not ogr directly) and a method (for this test I just
do an intersect) and a mode (new, and, or, xor, not - for later) and
optionally an queryList(again, later).
This test is a step towards that goal. Any advice on how to optimize for
speed would be greatly appreciated (including rewriting using a whole
different approach).
But first, one comment about pymod.ogr.Geometry.Empty().
When I try:
selectPoly.Empty()
I get:
TypeError: Empty() takes exactly 2 arguments (1 given)
If I change ogr.py from:
def Empty( self, other_geom ):
return _gdal.OGR_G_Empty( self._o, other_geom._o )
to:
def Empty( self ): # , other_geom ):
return _gdal.OGR_G_Empty( self._o ) # , other_geom._o )
It seems to work.
And my test script. Note that I'm using Howard Butler's ogr.py for python24
on Windows XP:
--------------
#!C:\python24\python.exe
from pymod import ogr,gdal
# queryLayer is the layer I want a result list for
# selectLayer is the layer that's previously been queried
# selectList is the list of record numbers from the previous query
#
# This will return a list of queryLayer indexes, or an empty list
#
def intersectByList(queryLayer,selectLayer,selectList):
from pymod import ogr,gdal
import sys
import time
# Keep track of time so I can try to optimize performance
starttime = time.clock()
# Start a polygon geometry of feature envelopes
# that get all unioned together
selectEnvelopes = ogr.Geometry(ogr.wkbPolygon)
# Start a geometryCollection of select Geometries
selectGeomCol = ogr.Geometry(ogr.wkbGeometryCollection)
# Create a couple of geometries that I use when processing
# the envelopes
selectPoly = ogr.Geometry(ogr.wkbPolygon)
selectRing = ogr.Geometry(ogr.wkbLinearRing)
# Step through the passed record list
for selectRec in selectList:
# Get the select Feature and Geometry
selectFea = selectLayer.GetFeature(selectRec)
selectGeom = selectFea.GetGeometryRef()
# Add the Geometry to our collection
selectGeomCol.AddGeometry(selectGeom.Clone())
# Add the points of the envelope to the selectRing
# and add it to the selectPoly
selectEnv = selectGeom.GetEnvelope()
selectRing.AddPoint(selectEnv[0],selectEnv[2])
selectRing.AddPoint(selectEnv[1],selectEnv[2])
selectRing.AddPoint(selectEnv[1],selectEnv[3])
selectRing.AddPoint(selectEnv[0],selectEnv[3])
selectRing.AddPoint(selectEnv[0],selectEnv[2])
selectPoly.AddGeometry(selectRing)
# Union the existing selectEnvelopes with this polygon
selectEnvelopes = selectEnvelopes.Union(selectPoly)
# CleanUp
selectPoly.Empty()
selectRing.Empty()
selectFea.Destroy()
# Check time
print "Made envelops in: ", time.clock()
# Set a spatial filter on the qlayer with selectEnvelopes
queryLayer.SetSpatialFilter(selectEnvelopes)
# Check time
print "SetSpatialFilter in : ", time.clock()
# Start the return list
queryList = []
# Step through the query features and test for intersect
queryFeature = queryLayer.GetNextFeature()
while queryFeature is not None:
queryGeom = queryFeature.GetGeometryRef()
#-------------------------------------
"""#***** This doesn't work:
# Test for Intersect against select collection
if queryGeom.Intersect(selectGeomCol):
queryList.append(queryFeature.GetFID())
"""
#-------------------------------------
# So I do the following ...
# Step through the list of features in the select collection
for selectI in range(selectGeomCol.GetGeometryCount()):
# Get one select geometry out of the collection
selectGeom = selectGeomCol.GetGeometryRef(selectI)
# Test for Intersect and if true move on to next query Feature
if queryGeom.Intersect(selectGeom):
queryList.append(queryFeature.GetFID())
break
#-------------------------------------
queryFeature.Destroy()
queryFeature = queryLayer.GetNextFeature()
# Check time
print "Intersected in : ", time.clock()
# Return the list
return queryList
#===========================
# RUN TIME
# Open ogr select layer
ogrSDS = ogr.Open("c:/gis/shapefiles/surveys.shp")
ogrSlayer = ogrSDS.GetLayer(0)
slayerSet = [27735, 27776, 27782, 27784, 27794, 27795, 27806, 27810, 27812,
27815, 27816, 27829, 27833, 27835, 27838, 27846, 27850, 27851, 27863, 27870,
27877, 27878, 27883, 27884, 27892, 27898, 27899, 27902, 27903, 27905, 27906,
27908, 27910, 27917, 27925, 27942, 27951, 27952, 27953]
# Open ogr query layer
ogrQDS = ogr.Open("c:/gis/shapefiles/taxlots.shp")
ogrQlayer = ogrQDS.GetLayer(0)
# Get the intersect list
qlayerSet = intersectByList(ogrQlayer,ogrSlayer,slayerSet)
print qlayerSet
ogrSDS.Destroy()
ogrQDS.Destroy()
-----
Thanks for any help. The speed is OK if I'm noodling around on my own, but
kind of slow for a weblication. Like I said, I'm still learning lots daily.
Cheers,
Adam
More information about the Gdal-dev
mailing list