[postgis-devel] Use of lwgeom API?
cspoerri at cavtel.net
Thu Nov 18 19:33:21 PST 2004
Thanks, that's exactly what I was looking for.
On Wednesday 17 November 2004 02:44, strk at refractions.net wrote:
> 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_NDIMS(t) // 2+HASZ+HASM
> To dinamically cast LWGEOM to a more specific type you can use these
> // 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:
> 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.
More information about the postgis-devel