[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