[postgis-devel] Can I call LWGEOM_x_point directly from another stored procedure?

Stephen Woodbridge woodbri at swoodbridge.com
Sun Nov 17 08:21:50 PST 2013


Hi Paul,

Thanks for that pointer.

So below is what I came up with (uncompiled and untested), but I have a 
few questions. Since this code is in another extension (ie: NOT PostGIS) 
I can not access PostGIS utility functions or headers. Questions:

1. Is the external function references below the correct way to define 
these so DirectFunctionCalls can reference those entry points or do I 
need to throw an external in front of them?

2. I mimiced the array access code in LWGEOM_makeline_garray but don't 
want to use GSERIALIZED *. Is the pointer returned from ARR_DATA_PTR() a 
pointer to a Datum? And is this the correct way to work with this:
       Datum geom = PointerGetDatum(ARR_DATA_PTR(pnts)+offset);
or should I use:
       Datum geom = ARR_DATA_PTR(pnts)+offset;
or something else all together? All I need is a Datum that I can pass 
into DirectFunctionCalln().

I would appreciate it is someone could code review this and correct me 
if I have it wrong.

By the way, this is for code that will be wrapping OSRM server into 
plpgsql functions as part of pgRouting or OSRM project. In essence, you 
will be able to pass an array of points to a function and get back the 
OSRM route geometry or a distance matrix. I'll also have to figure out 
how to construct a polyline object and return that in a similar way.

Thanks,
   -Steve

/* external function references */
Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS);
Datum LWGEOM_x_point(PG_FUNCTION_ARGS);
Datum LWGEOM_y_point(PG_FUNCTION_ARGS);

static void deconstruct_point(Datum datum, float8 *x, float8 *y, int *srid)
{
     *x = DatumGetFloat8(DirectFunctionCall1(LWGEOM_x_point, datum);
     *y = DatumGetFloat8(DirectFunctionCall1(LWGEOM_y_point, datum);
     *srid = DatumGetInt32(DirectFunctionCall1(LWGEOM_get_srid, datum);
}

And that would be getting called from something like:

     int nelems;
     int len;
     bits8 *bitmap;
     int bitmask;
     size_t offset;

     Datum datum    = PG_GETARG_DATUM(0);
     ArrayType pnts = DatumGetArrayTypeP(datum);
     nelems = ArrayGetNItems(ARR_NDIM(pnts), ARR_DIMS(pnts));

     bitmap = ARR_NULLBITMAP(pnts);
     bitmask = 1;
     offset = 0;
     for (i=0; i<nelems; i++) {
         /* Don't do anything for NULL values */
         if ((bitmap && (*bitmap & bitmask) != 0) || !bitmap) {
             Datum geom = PointerGetDatum(ARR_DATA_PTR(pnts)+offset);
             offset += INTALIGN(VARSIZE(geom));
             deconstruct_point(geom, &x, &y, &srid);
             // work with x, y, srid
         }
         /* Advance NULL bitmap */
         if (bitmap) {
             bitmask <<= 1;
             if (bitmask == 0x100) {
                 bitmap++;
                 bitmask = 1;
             }
         }
     }


On 11/16/2013 11:44 PM, Paul Ramsey wrote:
> Have you checked out the DirectFuctionCall PgSQL macros? Might do what you want.
>
>
> On Saturday, November 16, 2013 at 8:39 PM, Stephen Woodbridge wrote:
>> Hi strk,
>>
>> I would like to be able to pass a PostGIS point or point[] to a
>> pgRouting function and I'm wondering if is it is possible to directly
>> call LWGEOM_x_point() and somehow pass on of my args to that?
>>
>> Basically, I would like a simple way to get x, y, and srid from a point.
>> I guess I can clone the code from LWGEOM_x_point into a function to
>> extract those.
>>
>> Do I need to do anything to initialize stuff for postgis in my function?




More information about the postgis-devel mailing list