# Determining what side of line point is on using PostGIS?

I want this in order to generate house numbers, odd or even depending on wether a feature is on one side of a street line or not . Thanks

In the end i think the most portable way is to use this( BTW line is actually 'linestring' not segment):

ST_LineCrossingDirection( linefromAtoB,streetline) <0 where A is the point , B is ST_ShortestPoint(thepoint,streetline); if <0 then linefromAtoB enters through the left of The streetline; if >0 the it enters from right side of streetline). You have to determine what street line is closest to each point first.

I made a mistake: C is the symmetric of A in relation to B= ST_ShortestPoint(thepoint,streetline). C's coordinates are `XC=2*(XB-XA) -XA` and for y `YC=2*(YB-YA) -YA`.
ST_LineCrossingDirection( linefromAtoC,streetline) <0 where A is the point , ; if <0 then linefromAtoC enters through the left of The streetline; if >0 the it enters from right side of streetline). You have to determine what street line is closest to each point first.

• I think this is clear, but maybe some more detail would help. Obviously your streets are directional, so the side of the street the point falls on, will actually be determined not just by the physical location, but by the direction of the street, correct? Also, it might help to phrase your question, in the form of a question, to be more specific. What have you tried already? Is there a specific place you are running into problems? Etc. Additional detail will likely help you receive a more detailed answer. – Get Spatial Sep 17 '13 at 16:07

If you are doing this in code, start by getting the closest point on the line to the point:

http://paulbourke.net/geometry/pointlineplane/

Note you will need to test each segment of a LINESTRING, and make sure the point falls on the segment as the raw computation is for an infinite line.

Then get the vector from this point to the line (pt.x - intersection.x, pt.y - intersection.y)

This will be a perpendicular to the line, within floating point rounding errors.

A line with slope x, y (end.x - start.x, end.y - start.y) has two perpendiculars.

-y, x is to the left, y, -x is to the right. Compare to your vector. You will only need to compare the signs of the x and y components.

There are other ways to do this and if you need very high performance this may not be the fastest.

• One drawback to perpendiculars is that if you have a LINESTRING with bends, then you will have gaps where a point's intersection is off any segment. Given the equation for a segment, you could just apply the equation to the point's x and see if the resulting y is more or less than the point's y to get the side. Test every segment, if the result is consistent then you know the side, otherwise- possible on a LINESTRING with enough bends- you'll need to analyze further. – Russell at ISC Sep 17 '13 at 13:44
• If the segment is vertical, y test is invalid, just compare pt x to segment x. – Russell at ISC Sep 17 '13 at 13:47
• One thing you need to take into account with this is the directionality of the line. This represents a street, so figuring out whether, from a pure coordinate stand-point, the point is on the left or right side of the line, is only half the problem. The other is to then match that with the direction the street travels. A point may be on the left of the street coordinate-wise, but if a street has addresses increasing from north to south, the point may actually fall on the right side address range. – Get Spatial Sep 17 '13 at 15:24
• You can use the PostGIS functions ST_Line_Locate_Point() and ST_Line_Interpolate_point() to find the location of the closest point on the street. ST_Azimuth() will return the angle of that vector. – travis Sep 17 '13 at 16:45
• In the end i think i will just use ST_LineCrossingDirection. Although i will have to use ST_MakeLine to create an imaginary extension point on the already imaginary line between mypoint and the point on myline that is nearest to mypoint.Otherwise LineCrossingDirection will just return 0. – osh Sep 18 '13 at 8:43