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 Aug 29 '15 at 17:48
  • You right, see my self answer – michael Aug 29 '15 at 17:49

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));
| improve this answer | |
  • Does the ST_Touches compares any line to ant polygon? – michael Aug 29 '15 at 17:28
  • I tried to explain more and added the change ST_Intersects -> ST_Crosses. – Redoute Sep 15 '15 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...

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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