[postgis-users] ST_LineToCurve for less than 4 points

Simon Greener simon at spatialdbadvisor.com
Tue Feb 28 15:08:45 PST 2012


Finding the centre and radius of a circle (for projected data) can be done as follows:

CREATE OR REPLACE FUNCTION Find_Circle(p_pt1 geometry, p_pt2 geometry, p_pt3 geometry)
   RETURNS geometry AS
$BODY$
DECLARE
    v_Centre geometry;
    v_radius Numeric;
    v_CX     Numeric;
    v_CY     Numeric;
    v_dA     Numeric;
    v_dB     Numeric;
    v_dC     Numeric;
    v_dD     Numeric;
    v_dE     Numeric;
    v_dF     Numeric;
    v_dG     Numeric;
BEGIN
    IF ( p_pt1 is null OR p_pt2 is null OR p_pt3 is null ) Then
       RAISE EXCEPTION 'All supplied points must be not null.';
       Return Null;
    End If;
    If ( ST_GeometryType(p_pt1) <> 'ST_Point' OR
         ST_GeometryType(p_pt1) <> 'ST_Point' OR
         ST_GeometryType(p_pt1) <> 'ST_Point' ) Then
       RAISE EXCEPTION 'All supplied geometries must be points.';
       Return Null;
    End If;
    v_dA := ST_X(p_pt2) - ST_X(p_pt1);
    v_dB := ST_Y(p_pt2) - ST_Y(p_pt1);
    v_dC := ST_X(p_pt3) - ST_X(p_pt1);
    v_dD := ST_Y(p_pt3) - ST_Y(p_pt1);
    v_dE := v_dA * (ST_X(p_pt1) + ST_X(p_pt2)) + v_dB * (ST_Y(p_pt1) + ST_Y(p_pt2));
    v_dF := v_dC * (ST_X(p_pt1) + ST_X(p_pt3)) + v_dD * (ST_Y(p_pt1) + ST_Y(p_pt3));
    v_dG := 2.0  * (v_dA * (ST_Y(p_pt3) - ST_Y(p_pt2)) - v_dB * (ST_X(p_pt3) - ST_X(p_pt2)));
    -- If v_dG is zero then the three points are collinear and no finite-radius
    -- circle through them exists.
    If ( v_dG = 0 ) Then
       RETURN NULL;
    Else
       v_CX := (v_dD * v_dE - v_dB * v_dF) / v_dG;
       v_CY := (v_dA * v_dF - v_dC * v_dE) / v_dG;
       v_Radius := sqrt(power(ST_X(p_pt1) - v_CX,2) + power(ST_Y(p_pt1) - v_CY,2) );
    End If;
    RETURN ST_SetSRID(ST_MakePoint(v_CX, v_CY, v_radius),ST_Srid(p_pt1));
END;
$BODY$
   LANGUAGE plpgsql VOLATILE STRICT;

select ST_AsText(Finv_dCircle(ST_MakePoint(525000, 5202000),
                             ST_MakePoint(525500, 5202000),
                             ST_MakePoint(525500, 5202500)));

select ST_AsEWKT(Finv_dCircle(ST_SetSrid(ST_MakePoint(525000, 5202000),32615),
                             ST_SetSrid(ST_MakePoint(525500, 5202000),32615),
                             ST_SetSrid(ST_MakePoint(525500, 5202500),32615)));

I have a whole bunch of COGO functions for PostGIS that I have never posted on my website.
Perhaps it is time to do this.

regards
Simon
On Wed, 29 Feb 2012 01:06:58 +1100, Stephen Woodbridge <woodbri at swoodbridge.com> wrote:

> On 2/28/2012 3:38 AM, Sandro Santilli wrote:
>> On Tue, Feb 28, 2012 at 09:36:34AM +0100, Denis Rouzaud wrote:
>>> Hi,
>>>
>>> Can someone tells me why ST_LineToCurve needs at least a linestring
>>> of 4 points to be run?
>>> If I have three points, I should be able to create a circularstring, right?
>>>
>>> Here the error I have:
>>> SELECT ST_LineToCurve(ST_GeomFromText('LINESTRING(554803.177682475
>>> 145390.853708235,554796.469135702 145401.404724093,554769.634948609
>>> 145404.042478058)'));
>>> ERROR:  pta_desegmentize needs implementation for npoints<  4
>>
>> If I read the message correctly it answers exactly your questions.
>> It "needs implementation". A patch is welcome.
>
> Is this the algorithm that is needed to solve this?
> http://paulbourke.net/geometry/circlefrom3/
>
> -Steve
> _______________________________________________
> postgis-users mailing list
> postgis-users at postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-users
>


-- 
Holder of "2011 Oracle Spatial Excellence Award for Education and Research."
SpatialDB Advice and Design, Solutions Architecture and Programming,
Oracle Database 10g Administrator Certified Associate; Oracle Database 10g SQL Certified Professional
Oracle Spatial, SQL Server, PostGIS, MySQL, ArcSDE, Manifold GIS, FME, Radius Topology and Studio Specialist.
39 Cliff View Drive, Allens Rivulet, 7150, Tasmania, Australia.
Website: www.spatialdbadvisor.com
   Email: simon at spatialdbadvisor.com
   Voice: +61 362 396397
Mobile: +61 418 396391
Skype: sggreener
Longitude: 147.20515 (147° 12' 18" E)
Latitude: -43.01530 (43° 00' 55" S)
GeoHash: r22em9r98wg
NAC:W80CK 7SWP3



More information about the postgis-users mailing list