# This is a list of objects still missing lwgeom support
-FNCAST: KEEPING FNCAST geometry(text) (see CAST)
FUNC: KEEPING FUNCTION: [line_interpolate_point(geometry, double precision)]
FUNC: KEEPING FUNCTION: [simplify(geometry, double precision)]
FUNC: KEEPING FUNCTION: [segmentize(geometry, double precision)]
+- WKB: what to do with that ? do we want to keep it as a type ?
+
- Check spheroid misure functions
o can't understand if 3d computation works since
I get same result w/ 2d and 3d.
POINTARRAY *points; // array of POINT3D
} LWLINE; //"light-weight line"
-// construct a new LWLINE. points will be copied
+// construct a new LWLINE. points will *NOT* be copied
// use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
extern LWLINE *lwline_construct(int ndims, int SRID, POINTARRAY *points);
// if this has a pre-built BOX2d, then we use it,
// otherwise we need to compute it.
extern BOX2DFLOAT4 getbox2d(char *serialized_form);
-extern void getbox2d_p(char *serialized_form, BOX2DFLOAT4 *box);
+extern int getbox2d_p(char *serialized_form, BOX2DFLOAT4 *box);
// Expand given box of 'd' units in all directions
void expand_box2d(BOX2DFLOAT4 *box, double d);
#endif
#define abs(a) ((a) < (0) ? (-a) : (a))
+
+// general utilities
+double lwgeom_polygon_area(LWPOLY *poly);
+double lwgeom_polygon_perimeter(LWPOLY *poly);
+double lwgeom_polygon_perimeter2d(LWPOLY *poly);
+double lwgeom_pointarray_length2d(POINTARRAY *pts);
+double lwgeom_pointarray_length(POINTARRAY *pts);
+void lwgeom_force2d_recursive(char *serialized, char *optr, int *retsize);
+void lwgeom_force3d_recursive(char *serialized, char *optr, int *retsize);
+double distance2d_pt_pt(POINT2D *p1, POINT2D *p2);
+double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B);
+double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D);
+double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa);
+double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2);
+int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring);
+int pt_in_poly_2d(POINT2D *p, LWPOLY *poly);
+double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly);
+double distance2d_point_point(LWPOINT *point1, LWPOINT *point2);
+double distance2d_point_line(LWPOINT *point, LWLINE *line);
+double distance2d_line_line(LWLINE *line1, LWLINE *line2);
+double distance2d_point_poly(LWPOINT *point, LWPOLY *poly);
+double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2);
+double distance2d_line_poly(LWLINE *line, LWPOLY *poly);
+double lwgeom_mindistance2d_recursive(char *lw1, char *lw2);
+void lwgeom_translate_recursive(char *serialized, double xoff, double yoff, double zoff);
+void lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff);
+int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
// same as getbox2d, but modifies box instead of returning result on the stack
-void
+int
getbox2d_p(char *serialized_form, BOX2DFLOAT4 *box)
{
unsigned char type = (unsigned char) serialized_form[0];
//woot - this is easy
//elog(NOTICE,"getbox2d has box");
memcpy(box,loc, sizeof(BOX2DFLOAT4));
- return ;
+ return 1;
}
//we have to actually compute it!
//elog(NOTICE,"getbox2d_p:: computing box");
box3d = lw_geom_getBB_simple(serialized_form);
+ if ( ! box3d )
+ {
+ return 0;
+ }
box2 = box3d_to_box2df(box3d);
memcpy(box,box2, sizeof(BOX2DFLOAT4));
pfree(box3d);
pfree(box2);
+ return 1;
}
//************************************************************************
// basic LWLINE functions
-// construct a new LWLINE. points will be copied
+// construct a new LWLINE. points will *NOT* be copied
// use SRID=-1 for unknown SRID (will have 8bit type's S = 0)
LWLINE *lwline_construct(int ndims, int SRID, POINTARRAY *points)
{
BOX3D *box3d;
char *ser;
+ if ( exploded->npoints + exploded->nlines + exploded->npolys == 0 )
+ {
+ return lwgeom_constructempty(exploded->SRID, exploded->ndims);
+ }
+
// find size of all geoms.
// If BBOX and SRID are included this size could be
// larger then needed, but that should not be a problem
elog(NOTICE, " computed outtype: %d, ngeoms: %d", outtype, ngeoms);
#endif
+ if ( ! ngeoms )
+ {
+ return lwgeom_constructempty(exploded->SRID, exploded->ndims);
+ }
+
// For a single geometry just set SRID and BBOX (if requested)
if ( ngeoms < 2 )
BOX2DFLOAT4 *result;
result = palloc(sizeof(BOX2DFLOAT4));
- getbox2d_p(SERIALIZED_FORM(lwgeom), result);
+ if ( ! getbox2d_p(SERIALIZED_FORM(lwgeom), result) )
+ {
+ PG_RETURN_NULL(); // must be the empty geometry
+ }
PG_RETURN_POINTER(result);
}
if (box2d_ptr == NULL)
{
lwgeom = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
-
- box = getbox2d(lwgeom+4);
+ // empty geom would make getbox2d_p return NULL
+ if ( ! getbox2d_p(lwgeom+4, &box) ) PG_RETURN_NULL();
memcpy(result, &box, sizeof(BOX2DFLOAT4));
PG_RETURN_POINTER(result);
}
//combine_bbox(BOX3D, geometry) => union(BOX3D, geometry->bvol)
lwgeom = (char *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
- box = getbox2d(lwgeom+4);
+ if ( ! getbox2d_p(lwgeom+4, &box) )
+ {
+ // must be the empty geom
+ memcpy(result, (char *)PG_GETARG_DATUM(0), sizeof(BOX2DFLOAT4));
+ PG_RETURN_POINTER(result);
+ }
a = (BOX2DFLOAT4 *)PG_GETARG_DATUM(0);
b = &box;
{
lwgeom = (LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
box = lw_geom_getBB(SERIALIZED_FORM(lwgeom));
+ if ( ! box ) PG_RETURN_NULL(); // must be the empty geom
memcpy(result, box, sizeof(BOX3D));
PG_RETURN_POINTER(result);
}
lwgeom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
box = lw_geom_getBB(SERIALIZED_FORM(lwgeom));
+ if ( ! box ) // must be the empty geom
+ {
+ memcpy(result, (char *)PG_GETARG_DATUM(0), sizeof(BOX3D));
+ PG_RETURN_POINTER(result);
+ }
a = (BOX3D *)PG_GETARG_DATUM(0);
b = box;
+#include "postgres.h"
+#include "lwgeom.h"
+
+/***********************************************************************
+ * Simple Douglas-Peucker line simplification.
+ * No checks are done to avoid introduction of self-intersections.
+ * No topology relations are considered.
+ *
+ * --strk@keybit.net;
+ ***********************************************************************/
+
+#define SAMEPOINT(a,b) ((a)->x==(b)->x&&(a)->y==(b)->y&&(a)->z==(b)->z)
+#define VERBOSE 0
+
+#if VERBOSE > 0
+#define REPORT_POINTS_REDUCTION
+#define REPORT_RINGS_REDUCTION
+#define REPORT_RINGS_ADJUSTMENTS
+#endif
+
+/* Prototypes */
+void DP_findsplit2d(POINTARRAY *pts, int p1, int p2, int *split, double *dist);
+POINTARRAY *DP_simplify2d(POINTARRAY *inpts, double epsilon);
+LWLINE *simplify2d_lwline(LWLINE *iline, double dist);
+LWPOLY *simplify2d_lwpoly(LWPOLY *ipoly, double dist);
+Datum LWGEOM_simplify2d(PG_FUNCTION_ARGS);
+
+
+/*
+ * Search farthest point from segment p1-p2
+ * returns distance in an int pointer
+ */
+void
+DP_findsplit2d(POINTARRAY *pts, int p1, int p2, int *split, double *dist)
+{
+ int k;
+ POINT2D *pa, *pb, *pk;
+ double tmp;
+
+#if VERBOSE > 4
+elog(NOTICE, "DP_findsplit called");
+#endif
+
+ *dist = -1;
+ *split = p1;
+
+ if (p1 + 1 < p2)
+ {
+
+ pa = (POINT2D *)getPoint(pts, p1);
+ pb = (POINT2D *)getPoint(pts, p2);
+
+#if VERBOSE > 4
+elog(NOTICE, "DP_findsplit: P%d(%f,%f) to P%d(%f,%f)",
+ p1, pa->x, pa->y, p2, pb->x, pb->y);
+#endif
+
+ for (k=p1+1; k<p2; k++)
+ {
+ pk = (POINT2D *)getPoint(pts, k);
+
+#if VERBOSE > 4
+elog(NOTICE, "DP_findsplit: P%d(%f,%f)", k, pk->x, pk->y);
+#endif
+
+ /* distance computation */
+ tmp = distance2d_pt_seg(pk, pa, pb);
+
+ if (tmp > *dist)
+ {
+ *dist = tmp; /* record the maximum */
+ *split = k;
+#if VERBOSE > 4
+elog(NOTICE, "DP_findsplit: P%d is farthest (%g)", k, *dist);
+#endif
+ }
+ }
+
+ } /* length---should be redone if can == 0 */
+
+ else
+ {
+#if VERBOSE > 3
+elog(NOTICE, "DP_findsplit: segment too short, no split/no dist");
+#endif
+ }
+
+}
+
+
+POINTARRAY *
+DP_simplify2d(POINTARRAY *inpts, double epsilon)
+{
+ int stack[inpts->npoints]; /* recursion stack */
+ int sp=-1; /* recursion stack pointer */
+ int p1, split;
+ double dist;
+ POINTARRAY *outpts;
+ int ptsize = sizeof(double)*inpts->ndims;
+
+ p1 = 0;
+ stack[++sp] = inpts->npoints-1;
+
+#if VERBOSE > 4
+ elog(NOTICE, "DP_simplify called input has %d pts and %d dims (ptsize: %d)", inpts->npoints, inpts->ndims, ptsize);
+#endif
+
+ // allocate space for output POINTARRAY
+ outpts = palloc(sizeof(POINTARRAY));
+ outpts->ndims = inpts->ndims;
+ outpts->npoints=1;
+ outpts->serialized_pointlist = (char *)palloc(ptsize*inpts->npoints);
+ memcpy(getPoint(outpts, 0), getPoint(inpts, 0), ptsize);
+
+#if VERBOSE > 3
+ elog(NOTICE, "DP_simplify: added P0 to simplified point array (size 1)");
+#endif
+
+
+ do
+ {
+
+ DP_findsplit2d(inpts, p1, stack[sp], &split, &dist);
+#if VERBOSE > 3
+ elog(NOTICE, "DP_simplify: farthest point from P%d-P%d is P%d (dist. %g)", p1, stack[sp], split, dist);
+#endif
+
+ if (dist > epsilon) {
+ stack[++sp] = split;
+ } else {
+ outpts->npoints++;
+ memcpy(getPoint(outpts, outpts->npoints-1),
+ getPoint(inpts, stack[sp]),
+ ptsize);
+#if VERBOSE > 3
+ elog(NOTICE, "DP_simplify: added P%d to simplified point array (size: %d)", stack[sp], outpts->npoints);
+#endif
+ p1 = stack[sp--];
+ }
+#if VERBOSE > 5
+ elog(NOTICE, "stack pointer = %d", sp);
+#endif
+ }
+ while (! (sp<0) );
+
+ /*
+ * If we have reduced the number of points realloc
+ * outpoints array to free up some memory.
+ * Might be turned on and off with a SAVE_MEMORY define ...
+ */
+ if ( outpts->npoints < inpts->npoints )
+ {
+ outpts->serialized_pointlist = (char *)repalloc(
+ outpts->serialized_pointlist,
+ ptsize*outpts->npoints);
+ if ( outpts->serialized_pointlist == NULL ) {
+ elog(ERROR, "Out of virtual memory");
+ }
+ }
+
+ return outpts;
+}
+
+LWLINE *
+simplify2d_lwline(LWLINE *iline, double dist)
+{
+ POINTARRAY *ipts;
+ POINTARRAY *opts;
+ LWLINE *oline;
+
+#if VERBOSE
+ elog(NOTICE, "simplify2d_lwline called");
+#endif
+
+ ipts = iline->points;
+ opts = DP_simplify2d(ipts, dist);
+ oline = lwline_construct(ipts->ndims, iline->SRID, opts);
+
+ return oline;
+}
+
+// TODO
+LWPOLY *
+simplify2d_lwpoly(LWPOLY *ipoly, double dist)
+{
+ POINTARRAY *ipts;
+ POINTARRAY **orings = NULL;
+ LWPOLY *opoly;
+ int norings=0, ri;
+
+#ifdef REPORT_RINGS_REDUCTION
+ elog(NOTICE, "simplify_polygon3d: simplifying polygon with %d rings", ipoly->nrings);
+#endif
+
+ orings = (POINTARRAY **)palloc(sizeof(POINTARRAY *)*ipoly->nrings);
+
+ for (ri=0; ri<ipoly->nrings; ri++)
+ {
+ POINTARRAY *opts;
+
+ ipts = ipoly->rings[ri];
+
+ opts = DP_simplify2d(ipts, dist);
+
+
+ if ( opts->npoints < 2 )
+ {
+ /* There as to be an error in DP_simplify */
+ elog(NOTICE, "DP_simplify returned a <2 pts array");
+ pfree(opts);
+ continue;
+ }
+
+ if ( opts->npoints < 4 )
+ {
+ pfree(opts);
+#ifdef REPORT_RINGS_ADJUSTMENTS
+ elog(NOTICE, "simplify_polygon3d: ring%d skipped ( <4 pts )", ri);
+#endif
+
+ if ( ri ) continue;
+ else break;
+ }
+
+
+#ifdef REPORT_POINTS_REDUCTION
+ elog(NOTICE, "simplify_polygon3d: ring%d simplified from %d to %d points", ri, ipts->npoints, opts->npoints);
+#endif
+
+
+ /*
+ * Add ring to simplified ring array
+ * (TODO: dinamic allocation of pts_per_ring)
+ */
+ orings[norings] = opts;
+ norings++;
+
+ }
+
+#ifdef REPORT_RINGS_REDUCTION
+elog(NOTICE, "simplify_polygon3d: simplified polygon with %d rings", norings);
+#endif
+
+ if ( ! norings ) return NULL;
+
+ opoly = palloc(sizeof(LWPOLY));
+ opoly->SRID = ipoly->SRID;
+ opoly->ndims = ipoly->ndims;
+ opoly->nrings = norings;
+ opoly->rings = orings;
+
+ return opoly;
+}
+
+PG_FUNCTION_INFO_V1(LWGEOM_simplify2d);
+Datum LWGEOM_simplify2d(PG_FUNCTION_ARGS)
+{
+ LWGEOM *geom = (LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+ LWGEOM_EXPLODED *exp = lwgeom_explode(SERIALIZED_FORM(geom));
+ double dist = PG_GETARG_FLOAT8(1);
+ int i;
+ char **newlines;
+ int newlinesnum=0;
+ char **newpolys;
+ int newpolysnum=0;
+ LWGEOM *result;
+ char *serialized;
+
+ // no lines, no points... return input
+ if ( exp->nlines + exp->npolys == 0 )
+ {
+ pfree_exploded(exp);
+ PG_RETURN_POINTER(geom);
+ }
+
+ if ( exp->nlines )
+ {
+#if VERBOSE
+ elog(NOTICE, "%d lines in exploded geom", exp->nlines);
+#endif
+ newlines = palloc(sizeof(char *)*exp->nlines);
+ for ( i=0; i<exp->nlines; i++ )
+ {
+ LWLINE *iline = lwline_deserialize(exp->lines[i]);
+#if VERBOSE
+ elog(NOTICE, " line %d deserialized", i);
+#endif
+ LWLINE *oline = simplify2d_lwline(iline, dist);
+#if VERBOSE
+ elog(NOTICE, " line %d simplified", i);
+#endif
+ if ( oline == NULL ) continue;
+ newlines[newlinesnum] = lwline_serialize(oline);
+ newlinesnum++;
+ }
+ pfree(exp->lines);
+ exp->lines = newlines;
+ exp->nlines = newlinesnum;
+ }
+
+ if ( exp->npolys )
+ {
+ newpolys = palloc(sizeof(char *)*exp->npolys);
+ for ( i=0; i<exp->npolys; i++ )
+ {
+ LWPOLY *ipoly = lwpoly_deserialize(exp->polys[i]);
+ LWPOLY *opoly = simplify2d_lwpoly(ipoly, dist);
+ if ( opoly == NULL ) continue;
+ newpolys[newpolysnum] = lwpoly_serialize(opoly);
+ newpolysnum++;
+ }
+ pfree(exp->polys);
+ exp->polys = newpolys;
+ exp->npolys = newpolysnum;
+ }
+
+ // copy 1 (when lwexploded_serialize_buf will be implemented this
+ // can be avoided)
+ serialized = lwexploded_serialize(exp, lwgeom_hasBBOX(geom->type));
+ pfree_exploded(exp);
+
+
+ // copy 2 (see above)
+ result = LWGEOM_construct(serialized,
+ lwgeom_getSRID(geom), lwgeom_hasBBOX(geom->type));
+
+ PG_RETURN_POINTER(result);
+}
+
+/***********************************************************************
+ * --strk@keybit.net;
+ ***********************************************************************/
int32 lwgeom_nrings_recursive(char *serialized);
void dump_lwexploded(LWGEOM_EXPLODED *exploded);
-// general utilities (might be moved in lwgeom_api.c)
-double lwgeom_polygon_area(LWPOLY *poly);
-double lwgeom_polygon_perimeter(LWPOLY *poly);
-double lwgeom_polygon_perimeter2d(LWPOLY *poly);
-double lwgeom_pointarray_length2d(POINTARRAY *pts);
-double lwgeom_pointarray_length(POINTARRAY *pts);
-void lwgeom_force2d_recursive(char *serialized, char *optr, int *retsize);
-void lwgeom_force3d_recursive(char *serialized, char *optr, int *retsize);
-double distance2d_pt_pt(POINT2D *p1, POINT2D *p2);
-double distance2d_pt_seg(POINT2D *p, POINT2D *A, POINT2D *B);
-double distance2d_seg_seg(POINT2D *A, POINT2D *B, POINT2D *C, POINT2D *D);
-double distance2d_pt_ptarray(POINT2D *p, POINTARRAY *pa);
-double distance2d_ptarray_ptarray(POINTARRAY *l1, POINTARRAY *l2);
-int pt_in_ring_2d(POINT2D *p, POINTARRAY *ring);
-int pt_in_poly_2d(POINT2D *p, LWPOLY *poly);
-double distance2d_ptarray_poly(POINTARRAY *pa, LWPOLY *poly);
-double distance2d_point_point(LWPOINT *point1, LWPOINT *point2);
-double distance2d_point_line(LWPOINT *point, LWLINE *line);
-double distance2d_line_line(LWLINE *line1, LWLINE *line2);
-double distance2d_point_poly(LWPOINT *point, LWPOLY *poly);
-double distance2d_poly_poly(LWPOLY *poly1, LWPOLY *poly2);
-double distance2d_line_poly(LWLINE *line, LWPOLY *poly);
-double lwgeom_mindistance2d_recursive(char *lw1, char *lw2);
-void lwgeom_translate_recursive(char *serialized, double xoff, double yoff, double zoff);
-void lwgeom_translate_ptarray(POINTARRAY *pa, double xoff, double yoff, double zoff);
-int lwgeom_pt_inside_circle(POINT2D *p, double cx, double cy, double rad);
/*------------------------------------------------------------------*/
LWLINE *line=NULL;
LWPOINT *point=NULL;
LWPOLY *poly=NULL;
- char *subgeom=NULL;
+ char *subgeom=lwgeom_getsubgeometry_inspected(inspected, j);
+
+ if ( lwgeom_getType(subgeom[0]) == 0 )
+ {
+ size += 32;
+ result = repalloc(result,size);
+ sprintf(tmp,"Object %i is EMPTY()\n", idx++);
+ strcat(result,tmp);
+ continue;
+ }
+
point = lwgeom_getpoint_inspected(inspected,j);
if (point !=NULL)
{
- size += 30;
+ size += 32;
result = repalloc(result,size);
- sprintf(tmp,"Object %i is a POINT()\n",
- idx++);
+ sprintf(tmp,"Object %i is a POINT()\n", idx++);
strcat(result,tmp);
continue;
}
poly = lwgeom_getpoly_inspected(inspected, j);
if (poly !=NULL)
{
- size += 57*(poly->nrings+1);
+ size += 60*(poly->nrings+1);
result = repalloc(result,size);
sprintf(tmp,"Object %i is a POLYGON() with %i rings\n",
- idx++, poly->nrings);
+ idx++, poly->nrings);
strcat(result,tmp);
for (i=0; i<poly->nrings;i++)
{
{
size += 57;
result = repalloc(result,size);
- sprintf(tmp,
- "Object %i is a LINESTRING() with %i points\n",
- idx++, line->points->npoints);
+ sprintf(tmp, "Object %i is a LINESTRING() with %i points\n", idx++, line->points->npoints);
strcat(result,tmp);
continue;
}
- subgeom = lwgeom_getsubgeometry_inspected(inspected, j);
- if ( subgeom != NULL )
- {
- ptr = lwgeom_summary_recursive(subgeom, 1);
- size += strlen(ptr);
- result = repalloc(result,size);
- strcat(result, ptr);
- pfree(ptr);
- }
- else
- {
- elog(ERROR, "What ? lwgeom_getsubgeometry_inspected returned NULL??");
- }
+ ptr = lwgeom_summary_recursive(subgeom, j);
+ size += strlen(ptr);
+ result = repalloc(result,size);
+ strcat(result, ptr);
+ pfree(ptr);
}
pfree_inspected(inspected);
// collect( geom, geom ) returns a geometry which contains
// all the sub_objects from both of the argument geometries
// returned geometry is the simplest possible, based on the types
-// of the colelct objects
+// of the collected objects
// ie. if all are of either X or multiX, then a multiX is returned.
PG_FUNCTION_INFO_V1(LWGEOM_collect);
Datum LWGEOM_collect(PG_FUNCTION_ARGS)
LWGEOM *result;
char *ser;
- // get geometry box and SRID
- getbox2d_p(SERIALIZED_FORM(geom), &box);
+ // get geometry box
+ if ( ! getbox2d_p(SERIALIZED_FORM(geom), &box) )
+ {
+ // must be an EMPTY geometry
+ PG_RETURN_POINTER(geom);
+ }
+
+ // get geometry SRID
SRID = lwgeom_getsrid(SERIALIZED_FORM(geom));
// expand it
BOX2DFLOAT4 box2d;
BOX *result = (BOX *)palloc(sizeof(BOX));
- getbox2d_p(SERIALIZED_FORM(lwgeom), &box2d);
+ if ( ! getbox2d_p(SERIALIZED_FORM(lwgeom), &box2d) )
+ {
+ PG_RETURN_NULL(); // must be the empty geometry
+ }
box2df_to_box_p(&box2d, result);
PG_RETURN_POINTER(result);
LWGEOM *result;
char *ser;
- // get geometry box and SRID
- getbox2d_p(SERIALIZED_FORM(geom), &box);
+ // get bounding box
+ if ( ! getbox2d_p(SERIALIZED_FORM(geom), &box) )
+ {
+ // must be the EMPTY geometry
+ PG_RETURN_POINTER(geom);
+ }
+
+ // get geometry SRID
SRID = lwgeom_getsrid(SERIALIZED_FORM(geom));
// Assign coordinates to POINT2D array
PG_FUNCTION_INFO_V1(LWGEOMFromWKB);
Datum LWGEOMFromWKB(PG_FUNCTION_ARGS)
{
- WellKnownBinary *wkb_input = (WellKnownBinary *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
- char *wkb_srid_hexized;
- int size_result,size_header;
- int SRID = -1;
- char sridText[100];
- char *loc;
- char *lwgeom;
- int t;
-
-
- if ( ( PG_NARGS()>1) && ( ! PG_ARGISNULL(1) ))
- SRID = PG_GETARG_INT32(1);
- else
- SRID = -1;
+ WellKnownBinary *wkb_input;
+ char *wkb_srid_hexized;
+ int size_result,size_header;
+ int SRID = -1;
+ char sridText[100];
+ char *loc;
+ char *lwgeom;
+ int t;
+
+ wkb_input = (WellKnownBinary *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
+ if ( ( PG_NARGS()>1) && ( ! PG_ARGISNULL(1) ))
+ SRID = PG_GETARG_INT32(1);
+ else
+ SRID = -1;
// elog(NOTICE,"LWGEOMFromWKB: entry with SRID=%i",SRID);
elog(NOTICE,"wkb => lwgeom CONVERSION");
- // convert WKB to hexized WKB string
-
-
-
+ // convert WKB to hexized WKB string
- size_header = sprintf(sridText,"SRID=%i;",SRID);
- size_result = size_header + 2*(wkb_input->size -4) + 1; //SRID text size + wkb size (+1 = NULL term)
+ size_header = sprintf(sridText,"SRID=%i;",SRID);
+ //SRID text size + wkb size (+1 = NULL term)
+ size_result = size_header + 2*(wkb_input->size -4) + 1;
- wkb_srid_hexized = palloc(size_result);
- wkb_srid_hexized[0] = 0; // empty
- strcpy(wkb_srid_hexized, sridText);
- loc = wkb_srid_hexized + size_header; // points to null in "SRID=#;"
+ wkb_srid_hexized = palloc(size_result);
+ wkb_srid_hexized[0] = 0; // empty
+ strcpy(wkb_srid_hexized, sridText);
+ loc = wkb_srid_hexized + size_header; // points to null in "SRID=#;"
- for (t=0; t< (wkb_input->size -4); t++)
- {
- deparse_hex( ((unsigned char *) wkb_input)[4 + t], &loc[t*2]);
- }
+ for (t=0; t< (wkb_input->size -4); t++)
+ {
+ deparse_hex( ((unsigned char *) wkb_input)[4 + t], &loc[t*2]);
+ }
- wkb_srid_hexized[size_result-1] = 0; // null term
+ wkb_srid_hexized[size_result-1] = 0; // null term
//elog(NOTICE,"size_header = %i",size_header);
//elog(NOTICE,"size_result = %i", size_result);
//elog(NOTICE,"LWGEOMFromWKB :: '%s'", wkb_srid_hexized);
- lwgeom = parse_lwgeom_wkt(wkb_srid_hexized);
+ lwgeom = parse_lwgeom_wkt(wkb_srid_hexized);
- pfree(wkb_srid_hexized);
+ pfree(wkb_srid_hexized);
- PG_RETURN_POINTER(lwgeom);
+ PG_RETURN_POINTER(lwgeom);
}
// WKBFromLWGEOM(lwgeom) --> wkb
char *lwgeom_input = (char *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
// SRID=#;<hexized wkb>
- char *hexized_wkb_srid = unparse_WKB(lwgeom_input,palloc_fn,free_fn);
+ char *hexized_wkb_srid = unparse_WKB(lwgeom_input, palloc_fn, free_fn);
char *hexized_wkb; // hexized_wkb_srid w/o srid
char *result; //wkb
int len_hexized_wkb;
int size_result;
char *semicolonLoc;
- int t;
+ int t;
//elog(NOTICE, "in WKBFromLWGEOM with WKB = '%s'", hexized_wkb_srid);
elog(NOTICE,"lwgeom => wkb CONVERSION");
- hexized_wkb = hexized_wkb_srid;
- semicolonLoc = strchr(hexized_wkb_srid,';');
+ hexized_wkb = hexized_wkb_srid;
+ semicolonLoc = strchr(hexized_wkb_srid,';');
- if (semicolonLoc != NULL)
- {
- hexized_wkb = (semicolonLoc+1);
- }
+ if (semicolonLoc != NULL)
+ {
+ hexized_wkb = (semicolonLoc+1);
+ }
//elog(NOTICE, "in WKBFromLWGEOM with WKB (with no 'SRID=#;' = '%s'", hexized_wkb);
+ len_hexized_wkb = strlen(hexized_wkb);
+ size_result = len_hexized_wkb/2 + 4;
+ result = palloc(size_result);
- len_hexized_wkb = strlen(hexized_wkb);
- size_result = len_hexized_wkb/2 + 4;
- result = palloc(size_result);
-
- memcpy(result, &size_result,4); // size header
+ memcpy(result, &size_result,4); // size header
- // have a hexized string, want to make it binary
+ // have a hexized string, want to make it binary
- for (t=0; t< (len_hexized_wkb/2); t++)
- {
- ((unsigned char *) result +4)[t] = parse_hex( hexized_wkb + (t*2) );
- }
+ for (t=0; t< (len_hexized_wkb/2); t++)
+ {
+ ((unsigned char *) result +4)[t] = parse_hex( hexized_wkb + (t*2) );
+ }
- pfree(hexized_wkb_srid);
+ pfree(hexized_wkb_srid);
- PG_RETURN_POINTER(result);
+ PG_RETURN_POINTER(result);
}
//return result;
}
-
-
-
-
-
-
);
-CREATEFUNCTION geometry(text)
- RETURNS geometry
- AS '@MODULE_FILENAME@','parse_WKT_lwgeom'
- LANGUAGE 'C' WITH (isstrict,iscachable);
-
-------------------------------------------------------------------
-- BOX3D TYPE
-------------------------------------------------------------------
CREATE CAST (box3d as geometry) WITH FUNCTION geometry(box3d) AS IMPLICIT ;
+CREATEFUNCTION geometry(text)
+ RETURNS geometry
+ AS '@MODULE_FILENAME@','parse_WKT_lwgeom'
+ LANGUAGE 'C' WITH (isstrict,iscachable);
+
+CREATE CAST ( text AS geometry) WITH FUNCTION geometry(text) AS IMPLICIT;
+
+---------------------------------------------------------------
+-- Algorithms
+---------------------------------------------------------------
+
+CREATEFUNCTION simplify(geometry, float8)
+ RETURNS geometry
+ AS '@MODULE_FILENAME@', 'LWGEOM_simplify2d'
+ LANGUAGE 'C' WITH (isstrict);
+
---------------------------------------------------------------
-- END
---------------------------------------------------------------