[postgis-users] Intersection testing with one-to-many relationships

Nicolas Ribot nicolas.ribot at gmail.com
Mon Dec 24 06:29:23 PST 2012


There must be a simpler solution than the one provided, but can't see it
right now.
Maybe using windows functions...

Your 2 questions are the same: for the first one, you will add a WHERE
clause defining the task id you want results for.

The following query is using Common Table Expression (CTE) with WITH
construct, easier to read and write than subqueries.
The first "tasks" query just gives the number of turnpoints per task. It
will be used to filter out flights that do not intersect ALL turnpoints for
a task.
The second "inter" query performs the actual intersection and count the
number of intersected turnpoints for a flight-task pair
Finally, the outer query makes a join between the 2 first CTE tables and
filters rows to keep only flights intersecting ALL turnpoints.

with tasks as (
select t.id, count(tu.id) as num_turnpoint
from task t, turnpoint tu
where t.id = tu.task_id
group by t.id
order by t.id
), inter as (
select  t.id as taskid, f.id as flightid, count(p.id) as cnt
from tasks t, flight f, turnpoint p
where t.id = p.task_id
and st_intersects(f.geometry, p.geometry)
group by t.id, f.id
) select i.*
from inter i, tasks t
where i.cnt = t.num_turnpoint
and t.id = i.taskid;


On 24 December 2012 13:17, Tom Payne <twpayne at gmail.com> wrote:

> Hi,
> tl;dr How to select rows that intersect _all_ geometries defined in a
> one-to-many relationship?
> I'm using PostGIS as the core of a new system for scoring paragliding
> competitions. In such a competition, a task is defined by sequence of
> turnpoints (polygons) that must be visited in order. The pilot submits a
> GPS trace (linestring) as evidence. I'm trying to write a PostGIS query
> that returns all GPS traces that intersect all turnpoints in a given task.
> I've spent time Googling, but this is beyond my current PostGIS/SQL
> abilities.
> My schema looks like:
> -- a task has many turnpoints
> );
> -- a turnpoint belongs to a task and has a geometry
> CREATE TABLE turnpoint (
> task_id INTEGER,
> seq INTEGER NOT NULL, -- index within its task
>  geom geometry(POLYGON,-1) NOT NULL,
> UNIQUE (task_id, seq),
>  FOREIGN KEY(task_id) REFERENCES task (id)
> );
> -- a flight has a geometry
> CREATE TABLE flight (
>  geom geometry(LINESTRING,-1) NOT NULL,
> );
> What I want is:
> (1) for a given task, return all flight.ids that intersect all of that
> task's turnpoints' geoms; intersection tests can be approximate
> (i.e.intersecting with && is sufficient)
> (2) a list of (task.id, flight.id) pairs where the flight's geom
> intersects all of the task's turnpoints' geoms (intersecting with && is
> sufficient)
> I'm a bit stuck on how to achieve the above. If I use ST_Collect to
> combine all the turnpoints of a single task, and then do the intersection
> test with ST_Intersects then I'll select all flights that intersect ANY of
> the task's turnpoints; not all flights that intersect ALL of the task's
> turnpoints.
> If it is necessary to change the schema (e.g. to represent a task's
> turnpoints as an array of geometries rather than a one-to-many
> relationship) then that's fine.
> Many thanks for any help or pointers on how to achieve this with PostGIS.
> Tom
> P.S. Background information, probably not relevant to question:
> - I'd like to use the queries above as an initial filter, the precise
> intersection tests and the checks that the turnpoints are visited in the
> correct order is done in my application
> - Each task typically has 2-5 turnpoints
> - The database will eventually contain thousands of tasks and tens of
> thousands of flights, I plan to make it possible to do query (2) above
> incrementally
> _______________________________________________
> postgis-users mailing list
> postgis-users at lists.osgeo.org
> http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20121224/ec990237/attachment.html>

More information about the postgis-users mailing list