Well, I'll talk about DISTANCE vs BUFFER first. I'll leave the
Python script alone just at the moment.
I had a very similar problem to yours, and you should be able to use
Distance() no problem. In fact, used properly it will be far faster
than using computationally complex functions like Buffer() and GUnion
(). I can add further that I have ALSO used the Buffer() type
solution in the past to find nearest geometries. It works, but
performance-wise it isn't anywhere near as good as below.......waaaaay
slower, plus I needed a lot of code to analyse the Muliple Points
returned inside the Buffer() object.
Basically, your problem is "What Points are within x distance of this
Point?"
Here is how I solved my problem using SQL alone. (This is called the
"Nearest Neighbour" problem, if you search Google for this, you will
find several worked SQL examples, but not a lot for SpatiaLite).
In fact, Alessandro has provided a similar solution in this forum not
so long ago, and also has similar SQL script in his tutorial where
discussing Spatial Indices.
- I'll call the Table with the X,Y coords for the Reference Point
"RefPointsXY"
- I'll call the Points table you are searching for Nearest Points
"SearchPoints"
1. Create a Spatial Index on the Search Points Geometry field. Use
SpatiaLite function CreateSpatialIndex()
2.
a) SQL to return nearest points within say 50 distance units becomes:
SELECT S.Geometry 'NearestPointGeom'
FROM SearchPoints 'S', RefPointsXY 'R'
WHERE S.RowID IN(Select pkID FROM idx_SearchPoints_Geometry
WHERE xmin<X(MakePoint(R.X,R.Y))+50 AND xmax>X(MakePoint(R.X,R.Y))-50
AND
ymin<Y(MakePoint(R.X,R.Y))+50 AND ymax>X(MakePoint(R.X,R.Y))-50)
AND Distance(S.Geometry,MakePoint(R.X,R.Y)) < 50
For each Reference Point X,Y this yields multiple rows of Point
objects that are within 50 distance units of the Reference Point X,Y.
Obviously there are spots where you can parameterize this SQL
statement eg. The SearchDistance, The MakePoint(R.X,R.Y) statement
etc. and also get more performance out of it, but I've kept the
example syntax simple.
You can also introduce ORDER BY on the Distance() expression, and a
LIMIT clause to limit the returned points to say....the nearest 5
points maximum within 50 distance units.
b) I would personally write an SQL query that returned the RowID from
the "SearchPoints" table instead of returning the full Point
Geometry....but you may want to be storing separate copies of the
Nearest Points for some reason, in which case use example a) above.
So alternatively SQL becomes:
SELECT R.RowID 'RefPointRowID', S.RowID 'NearestPointRowID'
FROM SearchPoints 'S', RefPointsXY 'R'
WHERE S.RowID IN(Select pkID FROM idx_SearchPoints_Geometry
WHERE xmin<X(MakePoint(R.X,R.Y))+50 AND xmax>X(MakePoint(R.X,R.Y))-50
AND
ymin<Y(MakePoint(R.X,R.Y))+50 AND ymax>X(MakePoint(R.X,R.Y))-50)
AND Distance(S.Geometry,MakePoint(R.X,R.Y)) < 50
> > > - Show quoted text -- Hide quoted text -