[postgis-devel] length{,2d,3d}

Mark Cave-Ayland m.cave-ayland at webbased.co.uk
Wed Aug 25 03:29:56 PDT 2004


> -----Original Message-----
> From: postgis-devel-bounces at postgis.refractions.net 
> [mailto:postgis-devel-bounces at postgis.refractions.net] On 
> Behalf Of strk at refractions.net
> Sent: 25 August 2004 08:59
> To: postgis-devel at postgis.refractions.net
> Subject: [postgis-devel] length{,2d,3d}
> 
> 
> >From postgis manual:
> 
>    length2d(geometry)
>           Returns the 2-dimensional length of the geometry if it is a
>           linestring or multi-linestring.
> 
>    length(geometry)
>           The length of this Curve in its associated spatial 
> reference.
> 
>           synonym for length2d()
> 
>           OGC SPEC 2.1.5.1
> 
>    length3d(geometry)
>           Returns the 3-dimensional length of the geometry if it is a
>           linestring or multi-linestring.
> 
> ... but length2d is not defined in postgis.sql.in ...
> 
> Since OGC only defines 'length', what about dropping length3d 
> and length2d ? A 3d geom would get a 3d length computed, 
> while a 2d length would get a 2d length computed.
> 
> Comments ?
> 
> --strk;


Hi strk,

This is definitely an interesting issue that you've raised. I've just
had a look over the OpenGIS specification and looking at section 2.1.3.1
it would appear that the entire spec is only written based on a 2D point
:/. The other consideration is that 2D and 3D points are stored
differently in memory and on disk, and it doesn't seem right to start
mixing geometries with different dimensions in the same column......

I think I would be inclined to divide the functions into separate files
based on their dimensionality and type (like Curve or Surface), but have
a single wrapper function that is the publically available function,
such as length(). Each function would then check the dimensionality of
its geometry before handling off to the relevant function, something
like below:



lwgeom_curve.c

PG_FUNCTION_INFO_V1(length);
Datum length(PG_FUNCTION_ARGS)
{
	LWGEOM *lwgeom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	double length;

	switch(lwgeom_ndims(lwgeom))
	{
		case 2:
			length = lwgeom_length2d(lwgeom);
			break;

		case 3:
			length = lwgeom_length3d(lwdgeom);
			break;

		default:
			elog(ERROR, "function length() cannot work on a
geometry of %d 
			dimensions", lwgeom_ndims(lwgeom));
	}

	return length;
}


lwgeom_2dcurve.c

double lwgeom_length2d(LWGEOM lwgeom)
{
	..
	..
	return length;
}


lwgeom_3dcurve.c

double lwgeom_length3d(LWGEOM lwgeom)
{
	..
	..
	return length;
}

(one of my minor nitpicks with the existing PostGIS code is that so many
functions are included in so few .c files that it is often difficult to
find the function you are looking for, so I hope a setup like this would
help developers)

I think then that the distinction is fairly clear: if a user specifies
the points in 3 dimensions then all calculations are done in 3
dimensions; similarly this mechanism makes it very easy to add ERRORs
for things like GEOS functions which I believe should error when being
attempted on a 3 dimensional geometry, unless an explicit cast to 2D is
specified.

For this reason above, I would like to keep versions of the force2d()
and force3d() functions that convert all geometries between POINT2D and
POINT3D as required. However, I still think that 2D and 3D geometries
should not be mixed in a column, so I would suggest that the
dimensionality constraint in the geometry_columns table should still be
rigourously enforced.


Kind regards,

Mark.

---

Mark Cave-Ayland
Webbased Ltd.
Tamar Science Park
Derriford
Plymouth
PL6 8BX
England

Tel: +44 (0)1752 764445
Fax: +44 (0)1752 764446


This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender. You
should not copy it or use it for any purpose nor disclose or distribute
its contents to any other person.





More information about the postgis-devel mailing list