I have these database tables defined:
CREATE TABLE regions (
id SERIAL PRIMARY KEY,
name VARCHAR(150) NOT NULL
)
CREATE TABLE region_points (
id SERIAL PRIMARY KEY,
region_id SERIAL REFERENCES regions (id) ON DELETE CASCADE,
index INTEGER NOT NULL,
point GEOMETRY(Point, 4326) NOT NULL
)
CREATE TABLE stations (
id SERIAL PRIMARY KEY,
name VARCHAR(150) NOT NULL,
point GEOMETRY(Point, 4326) NOT NULL
)
A region
is a polygon, its points being defined in the region_points
table. A station
may reside at a single point somewhere inside a region
polygon.
I'd like to write a single query that gets all station
s inside a particular region
polygon. At the moment, I don't know how, so I do it in multiple steps:
# 1. Get all points that comprise the region polygon.
SELECT point
FROM region_points
WHERE region_id = 1234
ORDER BY index
# 2. Programmatically (non-SQL) construct a linestring from the points. Not shown here.
# 3. Get all stations inside the polygon.
SELECT id, name, point
FROM (
SELECT ST_GeomFromText($1, 4326) AS polygon
) AS query1, (
SELECT id, name, point
FROM stations
) AS query2
WHERE ST_Contains(query1.polygon, query2.point)
As you can see, I have to construct the linestring programmatically and then pass it into the query as an argument to ST_GeomFromText
, because I don't know how to do it in SQL.
I don't want to do anything programmatically. How can I re-write all of this as one SQL query?
Best Answer
The general workflow to construct your polygon would be something like this:
st_makepolygon(st_linefromMultipoint(st_collect(points.geom)))
But you have to be aware that :
a rudimary sql querry to create a polygon from a set of points would be the following:
Afterwards since you have constructed your polygon just wrap the above in your main query:
ofc it is very possible that your nodes in the region table do not follow an ordering at all you could use ST_ConvexHull functions to 'simplify' the polygon creation: