Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgis – Opposite of ST_Within

I'm trying to get all points that are NOT inside a few polygons:

SELECT pt.geom 
FROM points pt, polygons po
WHERE ST_Within(pt.geom, po.geom) = false;

But doesn't work – I get all the points instead.

like image 223
Bernardo Loureiro Avatar asked Mar 13 '23 22:03

Bernardo Loureiro


1 Answers

The reason why you see "all the points" is that you have more than one point and more than one polygon. If you had only one of either, it would work.

There are actually several ways to solve this one, but this is probably the most simple and quickest.

If you have a primary or unique key (e.g. gid):

SELECT pt.*
FROM points pt
WHERE pt.gid NOT IN (
    SELECT pt.gid FROM points pt, polygons po
    WHERE ST_Within(pt.geom, po.geom)
);

note that it will also return any points with NULL geometries.

Another method is to use EXCEPT:

SELECT pt.*
FROM points pt
EXCEPT SELECT pt.*
FROM points  pt, polygons po
WHERE ST_Within(pt.geom, po.geom);

And yet another method is to use ST_Union to fuse all the polygons into one large geometry, but this method would be much much slower.

like image 134
Mike T Avatar answered May 01 '23 02:05

Mike T