[postgis-users] points to polyline or polygon

Tyler Mitchell TMitchell at lignum.com
Wed Jul 16 11:39:28 PDT 2003






Thanks David, exactly what I was looking for.

Do you not see a benefit to using pl functions instead, since there is no
library compilation requirement.


                                                                                                                                
                      David Blasby                                                                                              
                      <dblasby at refractions.net>                 To:       PostGIS Users Discussion                              
                      Sent by:                                   <postgis-users at postgis.refractions.net>                        
                      postgis-users-bounces at postgis.refr        cc:                                                             
                      actions.net                               Fax to:                                                         
                                                                Subject:  Re: [postgis-users] points to polyline or polygon     
                                                                                                                                
                      07/16/2003 10:27 AM                                                                                       
                      Please respond to PostGIS Users                                                                           
                      Discussion                                                                                                
                                                                                                                                




> On a similar note can anyone comment or provide direction on writing
custom
> functions to help do this kind of thing?  I'd be particularly interested
in
> how the proces compares to Oracle's pl/sql.  I guess taking a peek at
> postgis.sql would be a good place for me to start eh?  Although I see a
lot
> of your functions are bundled into postgis.dll right?


I think these type of function would be great inside the actual postgis
distribution (ie. written in "C").  I want to do these functions, but
I'm too busy right now.  They are, fortunately, very easy to write.

So, if someone wanted to add the functions here's what you will have to
do (this is for multipoint to linestring):

1. Edit postgis.h, add a line like:
             Datum multipoint2linestring(PG_FUNCTION_ARGS);

2. Add the function to postgis_fn.c.

I just wrote this for this message - I have no idea if it even compiles,
let alone works.  But, it shows you the underlying idea of the
conversion function.
See postgis_inout.c:: make_point(), make_linestring(), make_polygon().
Also look at the functions in postgis_fn.c that do something like what
you want to do.  For example, if you want to create a polygon, look at
envelope() since it also returns a polygon.

// multipoint2linestring(<multipoint>)
//  returns a geometry (type linestring) that has its points in the
//  same order as the multipoint
PG_FUNCTION_INFO_V1(multipoint2linestring);
Datum multipoint2linestring(PG_FUNCTION_ARGS)
{
             GEOMETRY *geom_in = (GEOMETRY *)
PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
             int32                                     *offsets1;
             POINT3D                                   *allPts;
             LINE3D                                    *line;
             int                     t;
             POINT3D                                   *pt;
             int                                 size; //of the line object
             GEOMETRY                      *result;

                         // error check
             if (geom->type != MULTIPOINTTYPE )
             {
                         elog(ERROR,"multipoint2linestring(<multipoint>) -
you didnt give me a
multipoint\n");
                         PG_RETURN_NULL();
             }
             if (geom->nobjs < 2)
             {
                         elog(ERROR,"multipoint2linestring(<multipoint>) -
multipoint must have
at least 2 points in it\n");
                         PG_RETURN_NULL();
             }

                         // de-serialization step
             offsets1 = (int32 *) ( ((char *) &(geom->objType[0] ))+
sizeof(int32) *
geom->nobjs ) ;

                         // make an array of the points in the multipoint
object
             allPts = palloc( sizeof(POINT3D) * geom->nobjs);
             for(t =0; t<geom->nobjs; t++)
             {
                                     // get point t from the multipoint
                         pt = (POINT3D*)((char *) geom +offsets1[t]) ;
                                     // stick it in the allPts array
                         allPts[t] = *pt; // have the compiler do the copy
             }
                         // construct a line from the array of points
             line = make_line( geom->nobjs, allPts, &size);
             pfree(allPts);  // free up space

                         // create a geometry object from the line
             result = make_oneobj_geometry(size, (char*) line,
LINESTRINGTYPE,
geom->is3d,geom->SRID, geom->scale, geom->offx, geom->offy);

             return result;
}


3. add the function to the postgis_sql_common.sql.in file:
CREATE FUNCTION linestringfrommultipoint(geometry)
             RETURNS geometry
             AS '@MODULE_FILENAME@','multipoint2linestring'
             LANGUAGE 'C' WITH (isstrict);


4. build postgis (ie. 'make');

5. once you get it to compile, and think its going to work you can
either make a new database (and use the new postgis.sql that has your
function in it), or you can just add the function to an already existing
database (look in postgis.sql for your new function - then copy and past).

6. test it -

             select linestringFromMultipoint('MULTPOINT(0 0, 1 1)');
             select linestringFromMultipoint('MULTPOINT(0 0)');  -- error
             select linestringFromMultipoint('POINT(0 0)');  -- error



_______________________________________________
postgis-users mailing list
postgis-users at postgis.refractions.net
http://postgis.refractions.net/mailman/listinfo/postgis-users





More information about the postgis-users mailing list