I am working with postgres/postGIS I have two tables I am interested in querying:
table A: contains geometry values as (POINT) such as (P1, P2,P3,...)
table B: contains geometry values as (POLYGON) such as (Polygon 1, polygon 2, ...)
I am trying to find each point lies within which polygon. The answer I am most likely looking for lists the point and the polygon it contains, for example:
Point | Polygon |
---|---|
P1 | Polygon 3 |
P2 | Polygon 1 |
what I tried is the following:
SELECT *
FROM area, points
WHERE st_intersects(area.polygons, points.point) ;
And I am getting the following error: ERROR: ST_Intersects: Operation on mixed SRID geometries (Polygon, 4326),= (Point, 8307)
would much appreciate your help.
As stated in the previous answer, you cannot perform spatial operations involving geometries encoded in different SRS. In other words, you must use ST_Transform
, eg
SELECT * FROM area a
JOIN points p ON ST_Contains(a.polygons, ST_Transform(p.point,4326));
The observation regarding indexing is also well put. However, you do not necessarily need to create a further column in order to use the spatial index in a different SRS. It would mean that you need to 1) duplicate your columns, which depending on the geometries size can become pretty expensive and 2) have a significant overhead to keep both columns in sync. What you need is to create a separated index that takes the coordinates previously transformed, so that it does not need to do it in query time:
CREATE INDEX idx_points_geom_4326 ON points USING gist (ST_Transform(point,4326));
Demo: db<>fiddle
- mind the node Index Scan using idx_points_geom_4326 on points p
:
EXPLAIN ANALYSE
SELECT * FROM area a
JOIN points p ON ST_Contains(a.polygons, ST_Transform(p.point,4326));
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=0.14..59.18 rows=1 width=64) (actual time=0.036..0.175 rows=94 loops=1)
-> Seq Scan on area a (cost=0.00..1.01 rows=1 width=32) (actual time=0.004..0.005 rows=1 loops=1)
-> Index Scan using idx_points_geom_4326 on points p (cost=0.14..58.16 rows=1 width=32) (actual time=0.029..0.161 rows=94 loops=1)
Index Cond: (st_transform(point, 4326) @ a.polygons)
Filter: st_contains(a.polygons, st_transform(point, 4326))
Planning Time: 0.064 ms
Execution Time: 0.193 ms
You can't compare geometries in different spatial reference systems , so you'll need to transform one of the columns to match the other one's SRID. You could fix this on the fly:
SELECT *
FROM area, points
WHERE st_intersects(area.polygons, st_transform(points.point,4326));
--or, dynamically: st_transform(points.point,st_srid(area.polygons))
but this will perform poorly, being unable to use an index. So instead, you can make a version of your point
column with the point transformed to 4326.
alter table points add column point_4326 geometry;
update points set point_4326=st_transform(point,4326);
create index on area using gist(polygons);
create index on points using gist(point_4326);
SELECT *
FROM area, points
WHERE st_intersects(area.polygons, points.point_4326);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.