Changeset: 040e83c81719 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=040e83c81719
Modified Files:
        geom/monetdb5/geom.c
        geom/monetdb5/geom.mal
        geom/sql/40_geom.sql
Branch: default
Log Message:

added one more contains function


diffs (truncated from 372 to 300 lines):

diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -69,6 +69,10 @@ geom_export str wkbgetcoordX(dbl *out, w
 geom_export str wkbgetcoordY(dbl *out, wkb **geom);
 geom_export str wkbcreatepoint(wkb **out, const dbl *x, const dbl *y);
 geom_export str wkbcreatepoint_bat(bat *out, const bat *x, const bat *y);
+geom_export str pnpoly_(int *out, int nvert, dbl *vx, dbl *vy, int *point_x, 
int *point_y);
+geom_export double isLeft( double P0x, double P0y, double P1x, double P1y, 
double P2x, double P2y);
+geom_export str pnpolyWithHoles_(int *out, int nvert, dbl *vx, dbl *vy, int 
nholes, dbl **hx, dbl **hy, int *hn, int *point_x, int *point_y);
+geom_export str wkbContains_bat(int *out, wkb **a, int *point_x, int *point_y);
 geom_export str mbroverlaps(bit *out, mbr **b1, mbr **b2);
 geom_export str wkbDimension(int *out, wkb **geom);
 geom_export str wkbGeometryTypeId(int *out, wkb **geom);
@@ -481,8 +485,8 @@ wkbFromText(wkb **w, const str *wkt, con
 
        *w = NULL;
        if (wkbFROMSTR(*wkt, &len, w) &&
-           (wkb_isnil(*w) || *tpe == wkbGeometryCollection ||
-            (te = *((*w)->data + 1) & 0x0f) == *tpe))
+        (wkb_isnil(*w) || *tpe == wkbGeometryCollection ||
+        (te = *((*w)->data + 1) & 0x0f) == *tpe))
                return MAL_SUCCEED;
        if (*w == NULL)
                *w = (wkb *) GDKmalloc(sizeof(wkb));
@@ -586,7 +590,7 @@ wkbWRITE(wkb *a, stream *s, size_t cnt)
        if (!mnstr_writeInt(s, len))    /* 64bit: check for overflow */
                return GDK_FAIL;
        if (len > 0 &&                  /* 64bit: check for overflow */
-           mnstr_write(s, (char *) a->data, len, 1) < 0)
+        mnstr_write(s, (char *) a->data, len, 1) < 0)
                return GDK_FAIL;
        return GDK_SUCCEED;
 }
@@ -627,7 +631,7 @@ ordinatesMBR(mbr **res, const flt *minX,
        if ((*res = (mbr *) GDKmalloc(sizeof(mbr))) == NULL)
                throw(MAL, "geom.mbr", MAL_MALLOC_FAIL);
        if (*minX == flt_nil || *minY == flt_nil ||
-           *maxX == flt_nil || *maxY == flt_nil)
+        *maxX == flt_nil || *maxY == flt_nil)
                **res = *mbrNULL();
        else {
                (*res)->xmin = *minX;
@@ -807,6 +811,282 @@ wkbcreatepoint_bat(bat *out, const bat *
        return MAL_SUCCEED;
 }
 
+       inline double
+isLeft( double P0x, double P0y, double P1x, double P1y, double P2x, double P2y)
+{
+       return ( (P1x - P0x) * (P2y - P0y)
+                       - (P2x -  P0x) * (P1y - P0y) );
+}
+
+str
+pnpoly_(int *out, int nvert, dbl *vx, dbl *vy, int *point_x, int *point_y)
+{
+       BAT *bo = NULL, *bpx = NULL, *bpy;
+       dbl *px = NULL, *py = NULL;
+       BUN i = 0, cnt;
+       int j = 0, nv;
+       bte *cs = NULL;
+
+       /*Get the BATs*/
+       if ((bpx = BATdescriptor(*point_x)) == NULL) {
+               throw(MAL, "geom.point", RUNTIME_OBJECT_MISSING);
+       }
+
+       if ((bpy = BATdescriptor(*point_y)) == NULL) {
+               BBPunfix(bpx->batCacheid);
+               throw(MAL, "geom.point", RUNTIME_OBJECT_MISSING);
+       }
+
+       /*Check BATs alignment*/
+       if ( bpx->htype != TYPE_void ||
+                       bpy->htype != TYPE_void ||
+                       bpx->hseqbase != bpy->hseqbase ||
+                       BATcount(bpx) != BATcount(bpy)) {
+               BBPunfix(bpx->batCacheid);
+               BBPunfix(bpy->batCacheid);
+               throw(MAL, "geom.point", "both point bats must have dense and 
aligned heads");
+       }
+
+       /*Create output BAT*/
+       if ((bo = BATnew(TYPE_void, ATOMindex("bte"), BATcount(bpx), 
TRANSIENT)) == NULL) {
+               BBPunfix(bpx->batCacheid);
+               BBPunfix(bpy->batCacheid);
+               throw(MAL, "geom.point", MAL_MALLOC_FAIL);
+       }
+       BATseqbase(bo, bpx->hseqbase);
+
+       /*Iterate over the Point BATs and determine if they are in Polygon 
represented by vertex BATs*/
+       px = (dbl *) Tloc(bpx, BUNfirst(bpx));
+       py = (dbl *) Tloc(bpy, BUNfirst(bpx));
+
+       nv = nvert -1;
+       cnt = BATcount(bpx);
+       cs = (bte*) Tloc(bo,BUNfirst(bo));
+       for (i = 0; i < cnt; i++) {
+               int wn = 0;
+               for (j = 0; j < nv; j++) {
+                       if (vy[j] <= py[i]) {
+                               if (vy[j+1] > py[i])
+                                       if (isLeft( vx[j], vy[j], vx[j+1], 
vy[j+1], px[i], py[i]) > 0)
+                                               ++wn;
+                       }
+                       else {
+                               if (vy[j+1]  <= py[i])
+                                       if (isLeft( vx[j], vy[j], vx[j+1], 
vy[j+1], px[i], py[i]) < 0)
+                                               --wn;
+                       }
+               }
+               *cs++ = wn & 1;
+       }
+
+       BATsetcount(bo,cnt);
+       BATderiveProps(bo,FALSE);
+       BBPunfix(bpx->batCacheid);
+       BBPunfix(bpy->batCacheid);
+       BBPkeepref(*out = bo->batCacheid);
+       return MAL_SUCCEED;
+}
+
+str
+pnpolyWithHoles_(int *out, int nvert, dbl *vx, dbl *vy, int nholes, dbl **hx, 
dbl **hy, int *hn, int *point_x, int *point_y)
+{
+       BAT *bo = NULL, *bpx = NULL, *bpy;
+       dbl *px = NULL, *py = NULL;
+       BUN i = 0, cnt = 0;
+       int j = 0, h = 0;
+       bte *cs = NULL;
+
+       /*Get the BATs*/
+       if ((bpx = BATdescriptor(*point_x)) == NULL) {
+               throw(MAL, "geom.point", RUNTIME_OBJECT_MISSING);
+       }
+       if ((bpy = BATdescriptor(*point_y)) == NULL) {
+               BBPunfix(bpx->batCacheid);
+               throw(MAL, "geom.point", RUNTIME_OBJECT_MISSING);
+       }
+
+       /*Check BATs alignment*/
+       if ( bpx->htype != TYPE_void ||
+                       bpy->htype != TYPE_void ||
+                       bpx->hseqbase != bpy->hseqbase ||
+                       BATcount(bpx) != BATcount(bpy)) {
+               BBPunfix(bpx->batCacheid);
+               BBPunfix(bpy->batCacheid);
+               throw(MAL, "geom.point", "both point bats must have dense and 
aligned heads");
+       }
+
+       /*Create output BAT*/
+       if ((bo = BATnew(TYPE_void, ATOMindex("bte"), BATcount(bpx), 
TRANSIENT)) == NULL) {
+               BBPunfix(bpx->batCacheid);
+               BBPunfix(bpy->batCacheid);
+               throw(MAL, "geom.point", MAL_MALLOC_FAIL);
+       }
+       BATseqbase(bo, bpx->hseqbase);
+
+       /*Iterate over the Point BATs and determine if they are in Polygon 
represented by vertex BATs*/
+       px = (dbl *) Tloc(bpx, BUNfirst(bpx));
+       py = (dbl *) Tloc(bpy, BUNfirst(bpx));
+       cnt = BATcount(bpx);
+       cs = (bte*) Tloc(bo,BUNfirst(bo));
+       for (i = 0; i < cnt; i++) {
+               int wn = 0;
+
+               /*First check the holes*/
+               for (h = 0; h < nholes; h++) {
+                       int nv = hn[h]-1;
+                       wn = 0;
+                       for (j = 0; j < nv; j++) {
+                               if (hy[h][j] <= py[i]) {
+                                       if (hy[h][j+1] > py[i])
+                                               if (isLeft( hx[h][j], hy[h][j], 
hx[h][j+1], hy[h][j+1], px[i], py[i]) > 0)
+                                                       ++wn;
+                               }
+                               else {
+                                       if (hy[h][j+1]  <= py[i])
+                                               if (isLeft( hx[h][j], hy[h][j], 
hx[h][j+1], hy[h][j+1], px[i], py[i]) < 0)
+                                                       --wn;
+                               }
+                       }
+
+                       /*It is in one of the holes*/
+                       if (wn) {
+                               break;
+                       }
+               }
+
+               if (wn)
+                       continue;
+
+               /*If not in any of the holes, check inside the Polygon*/
+               for (j = 0; j < nvert-1; j++) {
+                       if (vy[j] <= py[i]) {
+                               if (vy[j+1] > py[i])
+                                       if (isLeft( vx[j], vy[j], vx[j+1], 
vy[j+1], px[i], py[i]) > 0)
+                                               ++wn;
+                       }
+                       else {
+                               if (vy[j+1]  <= py[i])
+                                       if (isLeft( vx[j], vy[j], vx[j+1], 
vy[j+1], px[i], py[i]) < 0)
+                                               --wn;
+                       }
+               }
+               *cs++ = wn&1;
+       }
+       BATsetcount(bo,cnt);
+       BATderiveProps(bo,FALSE);
+       BBPunfix(bpx->batCacheid);
+       BBPunfix(bpy->batCacheid);
+       BBPkeepref(*out = bo->batCacheid);
+       return MAL_SUCCEED;
+}
+
+#define POLY_NUM_VERT 120
+#define POLY_NUM_HOLE 10
+
+str
+wkbContains_bat(int *out, wkb **a, int *point_x, int *point_y) {
+       double *vert_x, *vert_y, **holes_x = NULL, **holes_y= NULL;
+       int *holes_n= NULL, j;
+       wkb *geom = NULL;
+       str msg = NULL;
+
+
+       str err = NULL;
+       str geom_str = NULL;
+       char *str2, *token, *subtoken;
+       char *saveptr1 = NULL, *saveptr2 = NULL;
+       int nvert = 0, nholes = 0;
+
+       geom = (wkb*) *a;
+
+       if ((err = wkbAsText(&geom_str, &geom)) != MAL_SUCCEED) {
+               msg = createException(MAL, "geom.Contain_bat", "%s", err);
+               GDKfree(err);
+               return msg;
+       }
+       geom_str = strchr(geom_str, '(');
+       geom_str+=2;
+
+       /*Lets get the polygon*/
+       token = strtok_r(geom_str, ")", &saveptr1);
+       vert_x = GDKmalloc(POLY_NUM_VERT*sizeof(double));
+       vert_y = GDKmalloc(POLY_NUM_VERT*sizeof(double));
+
+       for (str2 = token; ; str2 = NULL) {
+               subtoken = strtok_r(str2, ",", &saveptr2);
+               if (subtoken == NULL)
+                       break;
+               sscanf(subtoken, "%lf %lf", &vert_x[nvert], &vert_y[nvert]);
+               nvert++;
+               if ((nvert%POLY_NUM_VERT) == 0) {
+                       vert_x = GDKrealloc(vert_x, nvert*2*sizeof(double));
+                       vert_y = GDKrealloc(vert_y, nvert*2*sizeof(double));
+               }
+       }
+
+       token = strtok_r(NULL, ")", &saveptr1);
+       if (token) {
+               holes_x = GDKzalloc(POLY_NUM_HOLE*sizeof(double*));
+               holes_y = GDKzalloc(POLY_NUM_HOLE*sizeof(double*));
+               holes_n = GDKzalloc(POLY_NUM_HOLE*sizeof(double*));
+       }
+       /*Lets get all the holes*/
+       while (token) {
+               int nhole = 0;
+               token = strchr(token, '(');
+               if (!token)
+                       break;
+               token++;
+
+               if (!holes_x[nholes])
+                       holes_x[nholes] = 
GDKzalloc(POLY_NUM_VERT*sizeof(double));
+               if (!holes_y[nholes])
+                       holes_y[nholes] = 
GDKzalloc(POLY_NUM_VERT*sizeof(double));
+
+               for (str2 = token; ; str2 = NULL) {
+                       subtoken = strtok_r(str2, ",", &saveptr2);
+                       if (subtoken == NULL)
+                               break;
+                       sscanf(subtoken, "%lf %lf", &holes_x[nholes][nhole], 
&holes_y[nholes][nhole]);
+                       nhole++;
+                       if ((nhole%POLY_NUM_VERT) == 0) {
+                               holes_x[nholes] = GDKrealloc(holes_x[nholes], 
nhole*2*sizeof(double));
+                               holes_y[nholes] = GDKrealloc(holes_y[nholes], 
nhole*2*sizeof(double));
+                       }
+               }
+
+               holes_n[nholes] = nhole;
+               nholes++;
+               if ((nholes%POLY_NUM_HOLE) == 0) {
+                       holes_x = GDKrealloc(holes_x, nholes*2*sizeof(double*));
+                       holes_y = GDKrealloc(holes_y, nholes*2*sizeof(double*));
+                       holes_n = GDKrealloc(holes_n, nholes*2*sizeof(int));
+               }
+               token = strtok_r(NULL, ")", &saveptr1);
+       }
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to