Hi,

I tried Nyalls approache and came up with this simple plpgsql script:

=========================
CREATE OR REPLACE FUNCTION left_of_test(geom_line geometry,geom_point geometry, offset_distance real) RETURNS boolean AS
$BODY$
DECLARE
  distance_offset_right real;
  distance_offset_left real;
BEGIN
  -- first we need to check if input has correct geometry types
  IF ST_GeometryType(geom_line) != 'ST_LineString' THEN
    RAISE EXCEPTION 'geom_line is not of type "ST_LineString"';
  END IF;
  IF ST_GeometryType(geom_point) != 'ST_Point' THEN
    RAISE EXCEPTION 'geom_point is not of type "ST_Point"';
  END IF;

distance_offset_right := ST_Distance(geom_point, ST_OffsetCurve(geom_line, offset_distance)); distance_offset_left := ST_Distance(geom_point, ST_OffsetCurve(geom_line, offset_distance * -1));

  IF distance_offset_right < distance_offset_left THEN
    RETURN TRUE;
  ELSIF distance_offset_right > distance_offset_left THEN
    RETURN FALSE;
  ELSE
    RETURN NULL;
  END IF;
END
$BODY$
LANGUAGE 'plpgsql';
=============================
Test:
=============================

SELECT left_of_test(ST_GeomFromText('LINESTRING(600000 200000,600000 210000,605000 215000)',21781),ST_GeomFromText('POINT(605000 205000)',21781),1);

=================================

Thanks for the idea - Nyall. There are probably faster approaches to solve the problem, but this was fairly easy to implement for me. It is, however limited to POINT and LINESTRINGs - MULTILINESTRINGS are not supported. Would need an additional loop.

Andreas


On Tue, 23 Jul 2013 15:31:13 -0700 (PDT), Nyall Dawson wrote:
Another approach is to use the ST_OffsetCurve function to create two
copies of the linestring, one which is slightly offset to the left (eg
"st_offsetcurve(geom, 1)"), and one which is offset to the right
("st_offsetcurve(geom, -1)"). Then you test the minimum distance from
the point to each of the offset curves to determine whether it's
closer to the left side or right side of the linestring.

eg, something along the lines of:

CASE WHEN ST_Distance(point_geom, ST_OffsetCurve(line_geom, 1)) <
ST_Distance(point_geom, ST_OffsetCurve(line_geom, -1)) THEN 'left'
ELSE 'right' END

Hope that helps!
Nyall

On Wednesday, 24 July 2013 05:07:09 UTC+10, Andreas Neumann wrote:

Hi Stephen and all,

Thank you for your proposal. I think I will try your proposal with
projection and cross-product. Will write a PostgreSQL left_of
function.

Thanks,
Andreas

--
--
Andreas Neumann
Böschacherstrasse 10A
8624 Grüt (Gossau ZH)
Switzerland
_______________________________________________
postgis-users mailing list
[email protected]
http://lists.osgeo.org/cgi-bin/mailman/listinfo/postgis-users

Reply via email to