In an earlier post, I was frustrated with the intersection of a polygon and line datasets coming out as a geometry collection instead of a simple line dataset as expected. Nicklas Avén was kind enough to point out that this is a natural consequence of the logic of an intersection, the definition of ST_Intersects is: Returns TRUE if the Geometries/Geography “spatially intersect” – (share any portion of space) and FALSE if they don’t (they are Disjoint). Any portion of space, being the critical phrase. So when lines intersect the edges of the polygon, that too is an intersection and is included. How do we avoid this? First I tried this:
CREATE TABLE public.contour_2_cut AS
SELECT contour.elevation, ST_Intersection(contour.the_geom, cutline) AS the_geom, gid FROM
public.cuy_contours_2 AS contour, ST_GeomFromText('POLYGON((2136548 635811, 2137743 635811, 2137743 635010, 2136548 635010,2136548 635811))', 3734) AS cutline
WHERE ST_Overlaps(contour.the_geom, cutline) OR ST_Within(contour.the_geom, cutline);
Which for a dataset like this:
Hmm, something isn’t quite right. That something is that the contours that we’re clipping lay partially outside the frame we’re clipping– and these ones don’t pass either test, st_overlaps or st_within (although, to be honest, I would have expected them to pass the st_overlaps query).
If instead, I change the query such that it tests whether it is within or crosses my polygon, thus:
CREATE TABLE public.contour_2_cut_4 AS
SELECT contour.elevation, ST_Intersection(contour.the_geom, cutline) AS the_geom, gid FROM
public.cuy_contours_2 AS contour, ST_GeomFromText('POLYGON((2136548 635811, 2137743 635811, 2137743 635010, 2136548 635010,2136548 635811))', 3734) AS cutline
WHERE ST_Within(contour.the_geom, cutline) OR ST_Crosses(contour.the_geom, cutline);
I get the correct output: