Changeset: a106642cfc16 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a106642cfc16 Modified Files: geom/monetdb5/geom.h geom/monetdb5/geomPoints.c geom/sql/40_geom.sql Branch: geo Log Message:
Distance with coordinates diffs (219 lines): diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h --- a/geom/monetdb5/geom.h +++ b/geom/monetdb5/geom.h @@ -267,4 +267,7 @@ geom_export str wkbCoordinateFromMBR_bat geom_export str wkbPointsContains_geom_bat(bat* outBAT_id, wkb** geomWKB, bat* xBAT_id, bat* yBAT_id, int* srid); geom_export str wkbFilteredPointsContains_geom_bat(bat* outBAT_id, wkb** geomWKB, bat* xBAT_id, bat* yBAT_id, bat* OIDsBAT_id, int* srid); +geom_export str wkbPointsDistance_geom_bat(bat* outBAT_id, wkb** geomWKB, bat* xBAT_id, bat* yBAT_id, int* srid); +geom_export str wkbFilteredPointsDistance_geom_bat(bat* outBAT_id, wkb** geomWKB, bat* xBAT_id, bat* yBAT_id, bat* OIDsBAT_id, int* srid); + geom_export str wkbFilterWithImprints_geom_bat(bat*, wkb**, bat*, bat*); diff --git a/geom/monetdb5/geomPoints.c b/geom/monetdb5/geomPoints.c --- a/geom/monetdb5/geomPoints.c +++ b/geom/monetdb5/geomPoints.c @@ -292,6 +292,184 @@ clean: return ret; } +static BAT* BATDistance(wkb** geomWKB, BAT* geometriesBAT) { + BAT *outBAT = NULL; + BATiter geometriesBAT_iter; + BUN p=0, q=0; + + //check if the BAT has dense heads and are aligned + if (!BAThdense(geometriesBAT)) { + GDKerror("BATDistance: BAT must have dense heads"); + return NULL; + } + + //create a new BAT + if ((outBAT = BATnew(TYPE_void, ATOMindex("dbl"), BATcount(geometriesBAT), TRANSIENT)) == NULL) { + GDKerror("BATDistance: Could not create new BAT for the output"); + return NULL; + } + + //set the first idx of the new BAT equal to that of the x BAT (which is equal to the y BAT) + BATseqbase(outBAT, geometriesBAT->hseqbase); + + //iterator over the BATs + geometriesBAT_iter = bat_iterator(geometriesBAT); + + BATloop(geometriesBAT, p, q) { //iterate over all valid elements + str err = NULL; + double val = 0.0; + + wkb *geometryWKB = (wkb*) BUNtail(geometriesBAT_iter, p); + if ((err = wkbDistance(&val, geomWKB, &geometryWKB)) != MAL_SUCCEED) { + BBPreleaseref(outBAT->batCacheid); + GDKerror("BATDistance: %s", err); + GDKfree(err); + return NULL; + } + BUNappend(outBAT,&val,TRUE); + } + + return outBAT; + +} + +str wkbPointsDistance_geom_bat(bat* outBAT_id, wkb** geomWKB, bat* xBAT_id, bat* yBAT_id, int* srid) { + BAT *xBAT=NULL, *yBAT=NULL, *outBAT=NULL; + BAT *pointsBAT = NULL, *pointsWithSRIDBAT=NULL; + str ret=MAL_SUCCEED; + + //get the descriptors of the BATs + if ((xBAT = BATdescriptor(*xBAT_id)) == NULL) { + throw(MAL, "batgeom.Distance", RUNTIME_OBJECT_MISSING); + } + if ((yBAT = BATdescriptor(*yBAT_id)) == NULL) { + BBPreleaseref(xBAT->batCacheid); + throw(MAL, "batgeom.Distance", RUNTIME_OBJECT_MISSING); + } + + //check if the BATs have dense heads and are aligned + if (!BAThdense(xBAT) || !BAThdense(yBAT)) { + ret = createException(MAL, "batgeom.Distance", "BATs must have dense heads"); + goto clean; + } + if(xBAT->hseqbase != yBAT->hseqbase || BATcount(xBAT) != BATcount(yBAT)) { + ret=createException(MAL, "batgeom.Distance", "BATs must be aligned"); + goto clean; + } + + //here the BAT version of some contain function that takes the BATs of the x y coordinates should be called + //create the points BAT + if((pointsBAT = BATMakePoint2D(xBAT, yBAT)) == NULL) { + ret = createException(MAL, "batgeom.Distance", "Problem creating the points from the coordinates"); + goto clean; + } + + if((pointsWithSRIDBAT = BATSetSRID(pointsBAT, *srid)) == NULL) { + ret = createException(MAL, "batgeom.Distance", "Problem setting srid to the points"); + goto clean; + } + + if((outBAT = BATDistance(geomWKB, pointsWithSRIDBAT)) == NULL) { + ret = createException(MAL, "batgeom.Distance", "Problem evalauting the contains"); + goto clean; + } + + BBPkeepref(*outBAT_id = outBAT->batCacheid); + goto clean; + +clean: + if(xBAT) + BBPreleaseref(xBAT->batCacheid); + if(yBAT) + BBPreleaseref(yBAT->batCacheid); + if(pointsBAT) + BBPreleaseref(pointsBAT->batCacheid); + if(pointsWithSRIDBAT) + BBPreleaseref(pointsWithSRIDBAT->batCacheid); + return ret; +} + +str wkbFilteredPointsDistance_geom_bat(bat* outBAT_id, wkb** geomWKB, bat* xBAT_id, bat* yBAT_id, bat* OIDsBAT_id, int* srid) { + BAT *xBAT=NULL, *yBAT=NULL, *OIDsBAT=NULL, *outBAT=NULL, *xFilteredBAT=NULL, *yFilteredBAT=NULL; + BAT *pointsBAT = NULL, *pointsWithSRIDBAT=NULL; + str ret=MAL_SUCCEED; + + //get the descriptors of the BATs + if ((xBAT = BATdescriptor(*xBAT_id)) == NULL) { + throw(MAL, "batgeom.wkbDistanceFiltered", RUNTIME_OBJECT_MISSING); + } + if ((yBAT = BATdescriptor(*yBAT_id)) == NULL) { + BBPreleaseref(xBAT->batCacheid); + throw(MAL, "batgeom.wkbDistanceFiltered", RUNTIME_OBJECT_MISSING); + } + if ((OIDsBAT = BATdescriptor(*OIDsBAT_id)) == NULL) { + BBPreleaseref(xBAT->batCacheid); + BBPreleaseref(yBAT->batCacheid); + throw(MAL, "batgeom.wkbDistanceFiltered", RUNTIME_OBJECT_MISSING); + } + + //check if the BATs have dense heads and are aligned + if (!BAThdense(xBAT) || !BAThdense(yBAT) || !BAThdense(OIDsBAT)) { + ret = createException(MAL, "batgeom.wkbDistanceFiltered", "BATs must have dense heads"); + goto clean; + } + if(xBAT->hseqbase != yBAT->hseqbase || BATcount(xBAT) != BATcount(yBAT)) { + ret=createException(MAL, "batgeom.wkbDistanceFiltered", "BATs must be aligned"); + goto clean; + } + + //project the x and y BATs + xFilteredBAT = BATproject(OIDsBAT, xBAT); + if(xFilteredBAT == NULL) { + ret=createException(MAL,"batgeom.wkbDistanceFiltered","Problem projecting xBAT"); + goto clean; + } + yFilteredBAT = BATproject(OIDsBAT, yBAT); + if(xFilteredBAT == NULL) { + ret=createException(MAL,"batgeom.wkbDistanceFiltered","Problem projecting yBAT"); + goto clean; + } + + //here the BAT version of some contain function that takes the BATs of the x y coordinates should be called + //create the points BAT + if((pointsBAT = BATMakePoint2D(xFilteredBAT, yFilteredBAT)) == NULL) { + ret = createException(MAL, "batgeom.wkbDistanceFiltered", "Problem creating the points from the coordinates"); + goto clean; + } + //set the srid + if((pointsWithSRIDBAT = BATSetSRID(pointsBAT, *srid)) == NULL) { + ret = createException(MAL, "batgeom.wkbDistanceFiltered", "Problem setting srid to the points"); + goto clean; + } + //check the contains + if((outBAT = BATDistance(geomWKB, pointsWithSRIDBAT)) == NULL) { + ret = createException(MAL, "batgeom.wkbDistanceFiltered", "Problem evalauting the contains"); + goto clean; + } + + + BBPkeepref(*outBAT_id = outBAT->batCacheid); + goto clean; + +clean: + if(xBAT) + BBPreleaseref(xBAT->batCacheid); + if(yBAT) + BBPreleaseref(yBAT->batCacheid); + if(OIDsBAT) + BBPreleaseref(OIDsBAT->batCacheid); + if(xFilteredBAT) + BBPreleaseref(xFilteredBAT->batCacheid); + if(yFilteredBAT) + BBPreleaseref(yFilteredBAT->batCacheid); + if(pointsBAT) + BBPreleaseref(pointsBAT->batCacheid); + if(pointsWithSRIDBAT) + BBPreleaseref(pointsWithSRIDBAT->batCacheid); + return ret; +} + + str wkbFilterWithImprints_geom_bat(bat* candidateOIDsBAT_id, wkb** geomWKB, bat* xBAT_id, bat* yBAT_id) { BAT *xBAT=NULL, *yBAT=NULL, *xCandidateOIDsBAT=NULL, *candidateOIDsBAT=NULL; mbr* geomMBR; diff --git a/geom/sql/40_geom.sql b/geom/sql/40_geom.sql --- a/geom/sql/40_geom.sql +++ b/geom/sql/40_geom.sql @@ -4026,7 +4026,7 @@ CREATE FUNCTION mbr(geom Geometry) RETUR --Construct a Geometry from a WKT CREATE FUNCTION ST_WKTToSQL(wkt string) RETURNS Geometry external name geom."GeomFromText"; ---Construct a Geoemtry from a WKB +--Construct a Geometry from a WKB CREATE FUNCTION ST_WKBToSQL(geom string) RETURNS Geometry EXTERNAL NAME geom."FromBinary"; --Obtaining WKT from Geometry @@ -4057,6 +4057,7 @@ CREATE FUNCTION ST_Overlaps(geom1 Geomet CREATE FUNCTION ST_Relate(geom1 Geometry, geom2 Geometry, intersection_matrix_pattern string) RETURNS boolean EXTERNAL NAME geom."Relate"; --Distance between Geometries CREATE FUNCTION ST_Distance(geom1 Geometry, geom2 Geometry) RETURNS double EXTERNAL NAME geom."Distance"; +CREATE FUNCTION ST_Distance(geom1 Geometry, xCoordinate double, yCoordinate double, srid integer) RETURNS boolean EXTERNAL NAME geom."Distance"; --Functions that implement spatial operators CREATE FUNCTION ST_Intersection(geom1 Geometry, geom2 Geometry) RETURNS Geometry EXTERNAL NAME geom."Intersection"; CREATE FUNCTION ST_Difference(geom1 Geometry, geom2 Geometry) RETURNS Geometry EXTERNAL NAME geom."Differnce"; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list