Detecting if point is on left or right side of line in PostGIS?
select (ST_Azimuth(h.vec) - ST_Azimuth(h.seg))
from (
select
ST_MakeLine(cp.p, point.geom) vec,
ST_MakeLine(cp.p,
ST_LineInterpolatePoint(
line.geom,
ST_LineLocatePoint(line.geom, cp.p) * 1.01)
) seg
from (
select
ST_ClosestPoint(line.geom, point.geom)
) p as cp
) as h
So the idea is to calculate angle between closest line segment, and vector from closest point on the line to your point.
get a closest point on a line
select ST_ClosestPoint(line.geom, point.geom)
create the vector from closest point to your point
ST_MakeLine(cp.p, point.geom) vec
create a vector among your line
ST_MakeLine(
--original point
cp.p,
--find a point next to the closest point on line
ST_LineInterpolatePoint(line.geom,
ST_LineLocatePoint(line.geom, cp.p) * 1.01)) seg
get the difference between directions
ST_Azimuth(h.vec) - ST_Azimuth(h.seg)
So right and left will be greater than zero and lower than zero.
An alternative method if you are using version 2.5.0 or later of PostGIS, you can supply a "side" argument to ST_Buffer
. So an alternative method to the ST_LineInterpolatePoint
with an scaled projection value is to use
ST_Contains(ST_Buffer(line.geom, 100, 'side=left'), point.geom)
One downside of this is the need to give a distance(in this case 100) to build the buffer on the left side of the LineString but in my case I already have a threshold of how close point.geom
needs to be to be associated with line.geom
.