[postgis-users] Left of/Right of test

Andreas Neumann a.neumann at carto.net
Wed Jul 24 06:12:19 PDT 2013


 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


More information about the postgis-users mailing list