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
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to