[postgis-devel] Use of lwgeom API?

strk at refractions.net strk at refractions.net
Tue Nov 16 23:44:37 PST 2004


On Tue, Nov 16, 2004 at 11:18:01PM -0500, Christoph Spoerri wrote:
> Hi,
> I'm wrote some code for linear referencing a couple months ago using the 'old' 
> GEOMETRY type. Now, I'm trying to move my code to the new LWGEOM type. 
> Looking at the existing code, I'm getting fairly confused about the different 
> structures (PG_LWGEOM, LWGEOM, LWGEOM_INSPECTED, etc.) representing the new 
> type.
> 
> I'm now wondering if there's a short description of the different structures 
> and when to use them. Or is there even a documented API that would describe 
> all the different functions available to the developer (e.g. 
> lwgeom_getsubgeometry_inspected() does this or that ...).
> 
> This type of info would make it a lot easier for me, since I'm only an 
> occasional C users and POSTGIS coder.
> 
> thanks in advance,
> Christoph

Chistoph, I suggest you get used to the LWGEOM structure, as it
it the easier abstraction (IMO). PG_LWGEOM is just an LWGEOM with
a 32bit header containing its size in bytes, as requested by PostGresql.

So basically you do

	PG_LWGEOM *pggeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	LWGEOM *lwgeom = lwgeom_deserialize(SERIALIZED_FORM(pggeom));
	... your handling here ...
	PG_LWGEOM *pgresult = pglwgeom_serialize(lwgeom);
		

Both PG_LWGEOM.type and LWGEOM.type contain type info, which is
accessible with the TYPE_* macros:

	TYPE_GETTYPE(t) // POINTTYPE,LINETYPE,POLYGONTYPE,MULTI*,COLLECTION
	TYPE_HASZ(t)
	TYPE_HASM(t)
	TYPE_NDIMS(t) // 2+HASZ+HASM	

To dinamically cast LWGEOM to a more specific type you can use these
functions:

	// Casts LWGEOM->LW* (return NULL if cast is illegal)
	extern LWMPOLY *lwgeom_as_lwmpoly(LWGEOM *lwgeom);
	extern LWMLINE *lwgeom_as_lwmline(LWGEOM *lwgeom);
	extern LWMPOINT *lwgeom_as_lwmpoint(LWGEOM *lwgeom);
	extern LWCOLLECTION *lwgeom_as_lwcollection(LWGEOM *lwgeom);
	extern LWPOLY *lwgeom_as_lwpoly(LWGEOM *lwgeom);
	extern LWLINE *lwgeom_as_lwline(LWGEOM *lwgeom);
	extern LWPOINT *lwgeom_as_lwpoint(LWGEOM *lwgeom);

Upcasts are always safe, but you might want to use special functions
in this case also:

	// Casts LW*->LWGEOM (always cast)
	extern LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj);
	extern LWGEOM *lwmline_as_lwgeom(LWMLINE *obj);
	extern LWGEOM *lwmpoint_as_lwgeom(LWMPOINT *obj);
	extern LWGEOM *lwcollection_as_lwgeom(LWCOLLECTION *obj);
	extern LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj);
	extern LWGEOM *lwline_as_lwgeom(LWLINE *obj);
	extern LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj);

Whatever computation you're going to make you'll end up working
with POINTARRAY. This is still a picky part. You can have a point
copied to a point buffer (2d,3dm,3dz or 4d), and this would be
the safer way:

	POINTARRAY *pa;
	POINT2D pbuf; getPoint2d_p(pa, 0, &pbuf);
	POINT3DZ pbuf; getPoint3dz_p(pa, 0, &pbuf);
	POINT3DM pbuf; getPoint3dm_p(pa, 0, &pbuf);
	POINT4M pbuf; getPoint4d_p(pa, 0, &pbuf);

To get a pointer inside the POINTARRAY (more dangerous) you can use:

	char *getPoint(POINTARRAY *, int n);
	POINTARRAY *pa;
	POINT3DZ *p3dz = (POINT3DZ *)getPoint(pa, 0);
	// now if the pointarray was 2d access of p3dz->z 
	// might be fatal!

To know dimensions and semantics of a pointarray points:

	TYPE_NDIMS(pa->dims);
	TYPE_HASZ(pa->dims);
	TYPE_HASM(pa->dims);

	
That's enough for today folks. Maybe somewhere in the future we'll
have a document about its use in the postgis documentation.

If we want to reduce the chances of an API break in the future we
should take out any problem now so to fix it before 1.0 release.
Any lack of abstraction should be analyzed for a solution (the
POINTARRAY access methods?).

Let me know.

--strk;




More information about the postgis-devel mailing list