Changeset: 6cdb359506cb for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6cdb359506cb
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.h
geom/monetdb5/geom.mal
Branch: sfcgal
Log Message:
Add another aggregation function, subMakLine. Allow the function to choose the
initiation point, an empty geometry of the first element of a BAT.
diffs (197 lines):
diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -15,6 +15,8 @@
int TYPE_mbr;
+static str BATgroupWKBWKBtoWKB(bat *outBAT_id, BAT *b, BAT *g, BAT *e, int
skip_nils, oid min, oid max, BUN ngrp, BUN start, BUN end, wkb **empty_geoms,
str (*func) (wkb **, wkb **, wkb**), const char* name);
+
static inline int
geometryHasZ(int info)
{
@@ -3633,6 +3635,51 @@ wkbMakeLineAggr(wkb **outWKB, bat *inBAT
return err;
}
+str
+wkbsubMakeLine(bat *outBAT_id, bat* bBAT_id, bat *gBAT_id, bat *eBAT_id, bit*
flag)
+{
+ (void) flag;
+ int skip_nils = 1, i = 0;
+ const char *msg = MAL_SUCCEED;
+ str err;
+ BAT *b = NULL, *g = NULL, *e = NULL;
+ oid min, max;
+ BUN ngrp;
+ BUN start, end, cnt;
+ wkb **empty_geoms = NULL;
+ const oid *cand = NULL, *candend = NULL;
+
+ if ((b = BATdescriptor(*bBAT_id)) == NULL) {
+ throw(MAL, "geom.subMakeLine", RUNTIME_OBJECT_MISSING);
+ }
+ if ((g = BATdescriptor(*gBAT_id)) == NULL) {
+ BBPunfix(b->batCacheid);
+ throw(MAL, "geom.subMakeLine", RUNTIME_OBJECT_MISSING);
+ }
+ if ((e = BATdescriptor(*eBAT_id)) == NULL) {
+ BBPunfix(b->batCacheid);
+ BBPunfix(g->batCacheid);
+ throw(MAL, "geom.subMakeLine", RUNTIME_OBJECT_MISSING);
+ }
+
+ if ((msg = BATgroupaggrinit(b, g, e, NULL, &min, &max, &ngrp,
+ &start, &end, &cnt,
+ &cand, &candend)) != NULL) {
+ throw(MAL, "BATgroupMakeLine: %s\n", msg);
+ }
+
+ err = BATgroupWKBWKBtoWKB(outBAT_id, b, g, e, skip_nils, min, max, ngrp,
start, end, empty_geoms, wkbMakeLine, "wkbMakeLine");
+ BBPkeepref(*outBAT_id);
+
+ GDKfree(empty_geoms);
+ BBPunfix(b->batCacheid);
+ BBPunfix(g->batCacheid);
+ BBPunfix(e->batCacheid);
+
+ return err;
+ return MAL_SUCCEED;
+}
+
/* Returns the first or last point of a linestring */
static str
wkbBorderPoint(wkb **out, wkb **geom, GEOSGeometry *(*func) (const
GEOSGeometry *), const char *name)
@@ -4952,29 +4999,49 @@ BATgroupWKBWKBtoWKB(bat *outBAT_id, BAT
"start " BUNFMT ", end " BUNFMT
", nonil = %d\n",
name, start, end, nonil);
+ gid = 0;
if (nonil) {
- aWKBs[0] = empty_geoms[0];
+ if (empty_geoms)
+ aWKBs[gid] = empty_geoms[gid];
// add one more segment for each following row
for (i = start; i < end; i++) {
+ if (aWKBs[gid] == NULL) {
+ aWKBs[gid] = (wkb *) BUNtail(bBAT_iter, i);
+ continue;
+ }
+
bWKB = (wkb *) BUNtail(bBAT_iter, i);
- outWKBs[0] = NULL;
-
- if ( (err = (*func)(&outWKBs[0], &aWKBs[0], &bWKB)) !=
MAL_SUCCEED )
- break;
- else
- *aWKBs[0] = *outWKBs[0];
+
+ if ( (msg = (*func)(&outWKBs[gid], &aWKBs[gid], &bWKB)) !=
MAL_SUCCEED ) {
+ GDKfree(aWKBs);
+ GDKfree(outWKBs);
+ GDKfree(grpWKBs);
+ BBPunfix(outBAT->batCacheid);
+ outBAT = NULL;
+ err = createException(MAL, name, msg);
+ GDKfree(msg);
+ return err;
+ } else
+ aWKBs[gid] = outWKBs[gid];
}
+ if (!outWKBs[gid])
+ outWKBs[gid] = aWKBs[gid];
} else {
nils = 1;
- aWKBs[0] = empty_geoms[0];
+ if (empty_geoms)
+ aWKBs[gid] = empty_geoms[gid];
for (i = start; i < end && nils == 0; i++) {
+ if (aWKBs[gid] == NULL) {
+ aWKBs[gid] = (wkb *) BUNtail(bBAT_iter, i);
+ continue;
+ }
bWKB = (wkb *) BUNtail(bBAT_iter, i);
if (wkb_isnil(bWKB)) {
if (!skip_nils) {
- if ((outWKBs[0] = wkbNULLcopy()) == NULL) {
+ if ((outWKBs[gid] = wkbNULLcopy()) == NULL) {
GDKfree(aWKBs);
GDKfree(outWKBs);
GDKfree(grpWKBs);
@@ -4985,14 +5052,23 @@ BATgroupWKBWKBtoWKB(bat *outBAT_id, BAT
nils = 1;
}
} else {
- if ( (err = (*func) (&outWKBs[0], &aWKBs[0], &bWKB)) !=
MAL_SUCCEED )
- break;
- else
- aWKBs[0] = outWKBs[0];
+ if ( (err = (*func) (&outWKBs[gid], &aWKBs[gid], &bWKB))
!= MAL_SUCCEED ) {
+ GDKfree(aWKBs);
+ GDKfree(outWKBs);
+ GDKfree(grpWKBs);
+ BBPunfix(outBAT->batCacheid);
+ outBAT = NULL;
+ err = createException(MAL, name, msg);
+ GDKfree(msg);
+ return err;
+ } else
+ aWKBs[gid] = outWKBs[gid];
}
}
+ if (!outWKBs[gid])
+ outWKBs[gid] = aWKBs[gid];
}
- grpWKBs[0] = outWKBs[0];
+ grpWKBs[gid] = outWKBs[gid];
} else {
/* multiple groups, no candidate list */
ALGODEBUG fprintf(stderr,
@@ -5011,7 +5087,12 @@ BATgroupWKBWKBtoWKB(bat *outBAT_id, BAT
/*Check if you already have aWKB*/
if (aWKBs[gid] == NULL) {
- aWKBs[gid] = empty_geoms[gid];
+ if (empty_geoms)
+ aWKBs[gid] = empty_geoms[gid];
+ else {
+ aWKBs[gid] = (wkb *) BUNtail(bBAT_iter, i);
+ continue;
+ }
}
/*Lets look for bWKB*/
bWKB = (wkb *) BUNtail(bBAT_iter, i);
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -190,6 +190,7 @@ geom_export str wkbEnvelopeFromCoordinat
geom_export str wkbMakePolygon(wkb** out, wkb** external, int* srid); /*Only
Polygons without holes*/
geom_export str wkbMakeLine(wkb**, wkb**, wkb**);
geom_export str wkbMakeLineAggr(wkb** outWKB, bat* inBAT_id);
+geom_export str wkbsubMakeLine(bat *outBAT_id, bat* bBAT_id, bat *gBAT_id, bat
*eBAT_id, bit* fla);
geom_export str wkbExteriorRing(wkb**, wkb**);
geom_export str wkbInteriorRingN(wkb**, wkb**, int*);
@@ -223,6 +224,7 @@ geom_export str wkbIntersection_bat_s(ba
geom_export str wkbUnion(wkb **out, wkb **a, wkb **b);
geom_export str wkbUnionAggr(wkb** outWKB, bat* inBAT_id);
geom_export str wkbUnionCascade(wkb** outWKB, bat* inBAT_id);
+geom_export str wkbsubUnion(bat *outBAT_id, bat* bBAT_id, bat *gBAT_id, bat
*eBAT_id, bit* fla);
geom_export str wkbCollect(wkb **out, wkb **a, wkb **b);
geom_export str wkbCollectCascade(wkb** outWKB, bat* inBAT_id);
geom_export str wkbsubCollect(bat *outBAT_id, bat* bBAT_id, bat *gBAT_id, bat
*eBAT_id, bit* flag);
diff --git a/geom/monetdb5/geom.mal b/geom/monetdb5/geom.mal
--- a/geom/monetdb5/geom.mal
+++ b/geom/monetdb5/geom.mal
@@ -437,7 +437,7 @@ command MakeLine(a:wkb, b:wkb) :wkb addr
comment "Gets two point or linestring geometries and returns a linestring
geometry";
command MakeLine(a:bat[:oid,:wkb]) :wkb address wkbMakeLineAggr
comment "Gets a BAT with point or linestring geometries and returns a single
linestring geometry";
-command subMakeLine(a:bat[:oid,:wkb], g:bat[:oid], e:bat[:oid], :bit)
:bat[:wkb] address wkbsubMakeLine
+command subMakeLine(a:bat[:wkb], g:bat[:oid], e:bat[:oid], :bit) :bat[:wkb]
address wkbsubMakeLine
comment "Gets a BAT with point or linestring geometries, a candidate group
list and returns a single linestring geometry per group.";
command PointOnSurface(w:wkb) :wkb address wkbPointOnSurface
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list