I have a linestrings consist of 2 vertices. I want to get all lines that don't intersects with any polygons on the way. In my example: blue line Not intersects - only touches some polygons, but black line although touches with some polygon, it also intersects another. So in conclusion the result is only blue line.

enter image description here

What I did:

 SELECT lines.geom
 FROM lines, polygons
 WHERE ST_Intersects(lines.geom, polygons.geom) = false 
       ST_Touches(lines.geom, polygons.geom) = true;

The ST_Touches seems to work - I guess because the representation of the line-string consist of the vertex that really touches the polygon.

The ST_Intersects not working - The result is that there is no even 1 line that intersect any polygon.

So what I started to thinking: Maybe because in the space where the line intersect polygon - ain't any 'real' representation of the line-string: Because what is line-string? 2 vertices both outside the polygon...

Whats going on? I thought that GEO-DB should deal exactly with this kind of challenges and 'knows' what spatially intersection is...

Altough I don't know how to do this (because ST_Segmentize not worked for me from some reason) I prefer not to overcome this issue with just 'breaking' the line-string to more elements such that with high probability some vertex would be inside the polygon.

  • 2
    Your belief of the meaning of ST_Intersects is wrong. When touches=true also intersects=true. Intersects means the same as "not disjoint" postgis.net/docs/ST_Intersects.html.
    – user30184
    Commented Aug 29, 2015 at 17:48
  • You right, see my self answer
    – michael
    Commented Aug 29, 2015 at 17:49

2 Answers 2


As user30184 noted, you have to use ST_Crosses() instead of ST_Intersects().

Additional, your expression works on one line compared to one polygon only: The black line touches Polygon 1 and doesn't cross Polygon 1. In more detail:

SELECT x FROM line, polygons WHERE ...

means: Build a case from every pair of a line and a polygon, so number of cases is n_lines x n_polygons. Do the WHERE clause for every case and keep cases where it is true. Result: blue line, P1: false, blue line, P2: true, black line, P1: true, black line, P2: false.

Maybe you want something like this:

SELECT lines.geom
 FROM lines, polygons
 WHERE ST_Touches(lines.geom, polygons.geom) AND
                 NOT EXISTS (SELECT 1 FROM polygons p2 WHERE ST_Crosses(lines.geom, p2.geom));
  • Does the ST_Touches compares any line to ant polygon?
    – michael
    Commented Aug 29, 2015 at 17:28
  • I tried to explain more and added the change ST_Intersects -> ST_Crosses.
    – Redoute
    Commented Sep 15, 2015 at 6:56

The answer is what @Redoute wrote but change ST_Intersects to ST_Crosses. Because the blue line also intersects with polygon 2 when it touches him...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.