# [postgis-users] Are there script examples for determine where vertices run clockwise or anti-clockwise?

Marcin Mionskowski mionskowskimarcin at gmail.com
Thu Feb 17 10:09:27 PST 2022

```"The terms clockwise and counterclockwise can only be applied to a
rotational motion once a side of the rotational plane is specified, from
which the rotation is observed."
https://en.wikipedia.org/wiki/Clockwise
So, you need some kind of rotation (direction change) and some reference.
In case of a polygon (or a closed line representing boundary of a polygon)
both are obvious -> boundary direction and interior of a polygon.
In case of a line the reference part is missing.
What seams reasonable to me is to:
- divide LINESTRING into segments,
- combine consecutive segments into pairs,
- chose 1st segment as a reference,
- calculate the angle between segments (with respect to its direction OFC)
using ST_Angle.
The problem is, that one LINESTRING can have different "orientations". The
CW/CCW is a property of {segment pair|the middle vertex of a pair of
segments}.
You can also use some direction as a reference (north in your example), but
than the azimuth/azimuth class.

Anyway, the SQL could look like:

with
a_line as (
select 1 gid,ST_geomfromtext('LINESTRING(0 0,1 1,2 0,3 1)') a_line
union all
select 2 gid,ST_geomfromtext('LINESTRING(0 0,0.5 1,2 0.5,3.5 1)') a_line
)
, points as (
select gid,(ST_DumpPoints(a_line)).*
from a_line
)
, segments as (
select p1.gid,p1.path||p2.path
start_end_points,ST_MakeLine(p1.geom,p2.geom) seg_geom
from points p1, points p2
where p1.gid=p2.gid and p1.path[1]+1=p2.path[1]
)
select s1.gid
, s1.start_end_points||s2.start_end_points[2] points
, case floor(st_angle(s1.seg_geom,s2.seg_geom)/pi()) when 0 then 'CW' else
'CCW' end
from segments s1,segments s2
where s1.gid=s2.gid and s1.start_end_points[2]=s2.start_end_points[1];

If you insist on using the azimuth, replace the part from ", segments as ("
with:

select p1.gid,p1.path||p2.path start_end_points,ST_Azimuth(p1.geom,p2.geom)
from points p1, points p2
where p1.gid=p2.gid and p1.path[1]+1=p2.path[1]

You can use LEAD() to optimize performance, but the SQL above is more
readable in my opinion (it explains the logic better, I think).

czw., 17 lut 2022 o 08:32 Shaozhong SHI <shishaozhong at gmail.com> napisał(a):

> How about each line gets split into segments.  .  Each segment is
> constructed with two points (current and next points.
> Then, calculate bearing/azimuth
> Then, determine whether it is clockwise or counter-clockwise.
>
> Can this be done?
>
> Regards,
>
> David
>
> On Wed, 16 Feb 2022 at 20:39, Marcin Mionskowski <
> mionskowskimarcin at gmail.com> wrote:
>
>> It doesn't make sense for lines.
>> Imagine LINESTRING(1 0,1 1) - which "part of a square" is this i.e. where
>> is "the center of the square": (1) 0.5,0.5 or (2) 1.5,0.5?
>> If (1) it's CCW, if (2) CW.
>>
>>
>> śr., 16 lut 2022 o 21:29 Shaozhong SHI <shishaozhong at gmail.com>
>> napisał(a):
>>
>>> The problem now is that I can not find anything for lines.
>>>
>>> Anything like ST_IsPolygonCW|ST_IsPolygonCCW for lines for instance,
>>> something like ST_IsLineCW|ST_IsLineCCW.
>>>
>>> Regards,
>>>
>>> David
>>>
>>> On Wed, 16 Feb 2022 at 19:43, Marcin Mionskowski <
>>> mionskowskimarcin at gmail.com> wrote:
>>>
>>>> Assuming simple polygons, composed from exterior ring only (i.e. no
>>>> multipolygons), I think that you are looking for a function
>>>> {ST_IsPolygonCW|ST_IsPolygonCCW}.
>>>>
>>>> Greetings,
>>>> Marcin
>>>>
>>>> śr., 16 lut 2022 o 19:55 Imre Samu <pella.samu at gmail.com> napisał(a):
>>>>
>>>>> > how vertices run?  clockwise or anti-clockwise?
>>>>>
>>>>> maybe the:
>>>>> https://postgis.net/docs/ST_Angle.html  *"Computes the clockwise
>>>>> angle between two vectors."*
>>>>> or https://postgis.net/docs/ST_Azimuth.html
>>>>>
>>>>> regards,
>>>>>  Imre
>>>>>
>>>>>
>>>>> Shaozhong SHI <shishaozhong at gmail.com> ezt írta (időpont: 2022. febr.
>>>>> 16., Sze, 17:06):
>>>>>
>>>>>> Can we use PostGIS to find out how vertices run?  clockwise or
>>>>>> anti-clockwise?
>>>>>>
>>>>>> Regards,
>>>>>>
>>>>>> David
>>>>>> _______________________________________________
>>>>>> postgis-users mailing list
>>>>>> postgis-users at lists.osgeo.org
>>>>>> https://lists.osgeo.org/mailman/listinfo/postgis-users
>>>>>>
>>>>> _______________________________________________
>>>>> postgis-users mailing list
>>>>> postgis-users at lists.osgeo.org
>>>>> https://lists.osgeo.org/mailman/listinfo/postgis-users
>>>>>
>>>> _______________________________________________
>>>> postgis-users mailing list
>>>> postgis-users at lists.osgeo.org
>>>> https://lists.osgeo.org/mailman/listinfo/postgis-users
>>>>
>>> _______________________________________________
>>> postgis-users mailing list
>>> postgis-users at lists.osgeo.org
>>> https://lists.osgeo.org/mailman/listinfo/postgis-users
>>>
>> _______________________________________________
>> postgis-users mailing list
>> postgis-users at lists.osgeo.org
>> https://lists.osgeo.org/mailman/listinfo/postgis-users
>>
> _______________________________________________
> postgis-users mailing list
> postgis-users at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/postgis-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20220217/080ae7dd/attachment.html>
```