One of the most common problems is trying to determine whether a point is in the polygon. To solve this problem with PostGIS, you can use ST_Contains or ST_Intersects.
St_Contains takes two geometries and determines whether the first contains the second.
By using contains, no part of geometry b can be outside of geometry a. The following code solves a point in polygon (PIP) problem:
isin=Point(-106.558743,35.318618)
cur.execute("SELECT ST_Contains(polygon.location,ST_GeomFromText('{}'))
FROM poly polygon WHERE polygon.id=1".format(isin.wkt))
cur.fetchall()
The previous code creates a point and then uses ST_Contains(polygon,point) and returns True. The point is in the polygon. You can use ST_Contains with any other valid geometry. Just remember, it must contain the entire geometry to be true.
Another method to determine whether a point is in a polygon is by using ST_Intersects. ST_Intersects will return true if the point, or any other geometry, overlaps, touches, or is within the polygon. ST_Intersects can take either a geometry or a geography.
The following code will perform a PIP using ST_Intersects:
isin=Point(-106.558743,35.318618)
cur.execute("SELECT ST_Intersects(ST_GeomFromText('{}')::geography,polygon.location::geometry) FROM poly polygon WHERE polygon.id=1".format(isin.wkt))
cur.fetchall()
The previous code only differs from the ST_Contains example by the function that was used and that geometry was used. It also returns True. When using a polygon and a line, ST_Intersects will return true if any part of the line touches or is within the polygon. This differs from ST_Contains.
Using ST_Intersection, you can get the geometry that represents the intersection. In the lines example earlier, it was a point. In the case of a polygon and a line, which I will show later on, it will be a line. The following code uses ST_Intersection to get the LineString that intersects with the polygon:
isin=LineString([(-106.55,35.31),(-106.40,35.94)])
cur.execute("SELECT ST_AsText(ST_Intersection(polygon.location,ST_GeomFromText('{}')))
FROM poly polygon WHERE polygon.id=1".format(isin.wkt))
cur.fetchall()
The previous code is almost identical to the preceding example, except we used intersection versus intersects. The result is the LINESTRING:
[('LINESTRING(-106.55 35.31,-106.411712640251 35.8908069109443)',)]