From 9109e28eb793870de6a9d5b58830c0fd86fa865d Mon Sep 17 00:00:00 2001 From: Axel Lehmann Date: Thu, 2 May 2024 09:16:21 +0200 Subject: [PATCH] Implement obb checks for Line and Area --- src/spatialjoin/GeometryCache.cpp | 24 +++++++++++----------- src/spatialjoin/GeometryCache.h | 4 ++-- src/spatialjoin/SpatialJoinMain.cpp | 11 ++++++++-- src/spatialjoin/Stats.h | 27 +++++++++++++++++++++++++ src/spatialjoin/Sweeper.cpp | 31 ++++++++++++++++++++++++++++- src/spatialjoin/Sweeper.h | 1 + 6 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/spatialjoin/GeometryCache.cpp b/src/spatialjoin/GeometryCache.cpp index 803d306..eaea9c2 100644 --- a/src/spatialjoin/GeometryCache.cpp +++ b/src/spatialjoin/GeometryCache.cpp @@ -130,9 +130,9 @@ sj::Line sj::GeometryCache::getFromDisk(size_t off, } // OBB - // ret.obb.getOuter().resize(5); - // _geomsFReads[tid].read(reinterpret_cast(&ret.obb.getOuter()[0]), - // sizeof(util::geo::I32Point) * 5); + ret.obb.getOuter().resize(5); + _geomsFReads[tid].read(reinterpret_cast(&ret.obb.getOuter()[0]), + sizeof(util::geo::I32Point) * 5); return ret; } @@ -195,9 +195,9 @@ sj::Area sj::GeometryCache::getFromDisk(size_t off, // } // OBB - // ret.obb.getOuter().resize(5); - // _geomsFReads[tid].read(reinterpret_cast(&ret.obb.getOuter()[0]), - // sizeof(util::geo::I32Point) * 5); + ret.obb.getOuter().resize(5); + _geomsFReads[tid].read(reinterpret_cast(&ret.obb.getOuter()[0]), + sizeof(util::geo::I32Point) * 5); return ret; } @@ -281,9 +281,9 @@ size_t sj::GeometryCache::add(const sj::Line& val) { _geomsOffset += sizeof(uint32_t) + sizeof(sj::boxids::BoxId) * size; // OBB - // _geomsF.write(reinterpret_cast(&val.obb.getOuter()[0]), - // sizeof(util::geo::I32Point) * 5); - // _geomsOffset += sizeof(util::geo::I32Point) * 5; + _geomsF.write(reinterpret_cast(&val.obb.getOuter()[0]), + sizeof(util::geo::I32Point) * 5); + _geomsOffset += sizeof(util::geo::I32Point) * 5; return ret; } @@ -347,9 +347,9 @@ size_t sj::GeometryCache::add(const sj::Area& val) { // } // OBB - // _geomsF.write(reinterpret_cast(&val.obb.getOuter()[0]), - // sizeof(util::geo::I32Point) * 5); - // _geomsOffset += sizeof(util::geo::I32Point) * 5; + _geomsF.write(reinterpret_cast(&val.obb.getOuter()[0]), + sizeof(util::geo::I32Point) * 5); + _geomsOffset += sizeof(util::geo::I32Point) * 5; return ret; } diff --git a/src/spatialjoin/GeometryCache.h b/src/spatialjoin/GeometryCache.h index 18fe778..db39241 100644 --- a/src/spatialjoin/GeometryCache.h +++ b/src/spatialjoin/GeometryCache.h @@ -53,7 +53,7 @@ struct Area { // std::unordered_map cutouts; // OBB - // util::geo::I32Polygon obb; + util::geo::I32Polygon obb; }; struct SimpleLine { @@ -82,7 +82,7 @@ struct Line { std::vector boxIds; // OBB - // util::geo::I32Polygon obb; + util::geo::I32Polygon obb; }; struct Point { diff --git a/src/spatialjoin/SpatialJoinMain.cpp b/src/spatialjoin/SpatialJoinMain.cpp index ff2b0de..700eb85 100755 --- a/src/spatialjoin/SpatialJoinMain.cpp +++ b/src/spatialjoin/SpatialJoinMain.cpp @@ -54,6 +54,9 @@ void printHelp(int argc, char** argv) { << "disable box id criteria for contains/intersect computation\n" << std::setw(41) << " --no-surface-area" << "disable surface area criteria for polygon contains\n" + << std::setw(41) << " --no-oriented-envelope" + << "disable oriented envelope cirteria for contains/intersect" + << " computation\n" << std::endl; } @@ -219,6 +222,7 @@ int main(int argc, char** argv) { bool useBoxIds = true; bool useArea = true; + bool useOBB = true; for (int i = 1; i < argc; i++) { std::string cur = argv[i]; @@ -255,6 +259,9 @@ int main(int argc, char** argv) { if (cur == "--no-surface-area") { useArea = false; } + if (cur == "--no-oriented-envelope") { + useOBB = false; + } break; case 1: prefix = cur; @@ -291,8 +298,8 @@ int main(int argc, char** argv) { size_t NUM_THREADS = std::thread::hardware_concurrency(); - Sweeper sweeper({NUM_THREADS, prefix, intersects, contains, suffix, useBoxIds, useArea}, useCache, - cache, output); + Sweeper sweeper({NUM_THREADS, prefix, intersects, contains, suffix, useBoxIds, + useArea, useOBB}, useCache, cache, output); size_t gid = 0; diff --git a/src/spatialjoin/Stats.h b/src/spatialjoin/Stats.h index fef109b..4029d05 100644 --- a/src/spatialjoin/Stats.h +++ b/src/spatialjoin/Stats.h @@ -16,6 +16,11 @@ struct Stats { uint64_t timeBoxIdIsectAreaPoint = 0; uint64_t timeBoxIdIsectLineLine = 0; + uint64_t timeOBBIsectAreaArea = 0; + uint64_t timeOBBIsectAreaLine = 0; + uint64_t timeOBBIsectAreaPoint = 0; + uint64_t timeOBBIsectLineLine = 0; + uint64_t timeFullGeoCheckAreaArea = 0; uint64_t timeFullGeoCheckAreaLine = 0; uint64_t timeFullGeoCheckAreaPoint = 0; @@ -34,6 +39,8 @@ inline std::string Stats::toString() { double(timeGeoCacheRetrievalArea + timeGeoCacheRetrievalLine + timeWrite + timeBoxIdIsectAreaArea + timeBoxIdIsectAreaLine + timeBoxIdIsectAreaPoint + timeBoxIdIsectLineLine + + timeOBBIsectAreaArea + timeOBBIsectAreaLine + + timeOBBIsectAreaPoint + timeOBBIsectLineLine + timeFullGeoCheckAreaArea + timeFullGeoCheckAreaLine + timeFullGeoCheckAreaPoint + timeFullGeoCheckLineLine) / 1000000000.0; @@ -64,6 +71,22 @@ inline std::string Stats::toString() { ss << "time for box ID intersections LINE/LINE: " << t << " s (" << ((t / sum) * 100.0) << "%)\n"; + t = double(timeOBBIsectAreaArea) / 1000000000.0; + ss << "time for obb intersections AREA/AREA: " << t << " s (" + << ((t / sum) * 100.0) << "%)\n"; + + t = double(timeOBBIsectAreaLine) / 1000000000.0; + ss << "time for obb intersections AREA/LINE: " << t << " s (" + << ((t / sum) * 100.0) << "%)\n"; + + t = double(timeOBBIsectAreaPoint) / 1000000000.0; + ss << "time for obb intersections AREA/POINT: " << t << " s (" + << ((t / sum) * 100.0) << "%)\n"; + + t = double(timeOBBIsectLineLine) / 1000000000.0; + ss << "time for obb intersections LINE/LINE: " << t << " s (" + << ((t / sum) * 100.0) << "%)\n"; + t = double(timeFullGeoCheckAreaArea) / 1000000000.0; ss << "time for " << fullGeoChecksAreaArea << " full geom checks AREA/AREA: " << t << " s (" << ((t / sum) * 100.0) @@ -100,6 +123,10 @@ inline Stats operator+(const Stats& a, const Stats& b) { a.timeBoxIdIsectAreaLine + b.timeBoxIdIsectAreaLine, a.timeBoxIdIsectAreaPoint + b.timeBoxIdIsectAreaPoint, a.timeBoxIdIsectLineLine + b.timeBoxIdIsectLineLine, + a.timeOBBIsectAreaArea + b.timeOBBIsectAreaArea, + a.timeOBBIsectAreaLine + b.timeOBBIsectAreaLine, + a.timeOBBIsectAreaPoint + b.timeOBBIsectAreaPoint, + a.timeOBBIsectLineLine + b.timeOBBIsectLineLine, a.timeFullGeoCheckAreaArea + b.timeFullGeoCheckAreaArea, a.timeFullGeoCheckAreaLine + b.timeFullGeoCheckAreaLine, a.timeFullGeoCheckAreaPoint + b.timeFullGeoCheckAreaPoint, diff --git a/src/spatialjoin/Sweeper.cpp b/src/spatialjoin/Sweeper.cpp index 1e223e0..d91c3fa 100644 --- a/src/spatialjoin/Sweeper.cpp +++ b/src/spatialjoin/Sweeper.cpp @@ -96,6 +96,8 @@ void Sweeper::add(const util::geo::I32Polygon& poly, const std::string& gid, double areaSize = util::geo::area(poly); BoxIdList boxIds; if (_cfg.useBoxIds) boxIds = packBoxIds(getBoxIds(spoly, poly, box, areaSize)); + util::geo::I32Polygon obb; + if (_cfg.useOBB) obb = util::geo::convexHull(util::geo::getOrientedEnvelope(poly)); if (!_cfg.useArea) areaSize = 0; @@ -106,6 +108,7 @@ void Sweeper::add(const util::geo::I32Polygon& poly, const std::string& gid, subid, areaSize, boxIds, + obb }); diskAdd({id, box.getLowerLeft().getY(), box.getUpperRight().getY(), @@ -128,6 +131,8 @@ void Sweeper::add(const util::geo::I32Line& line, const std::string& gid, const auto& box = util::geo::getBoundingBox(line); BoxIdList boxIds; if (_cfg.useBoxIds) boxIds = packBoxIds(getBoxIds(line, box)); + util::geo::I32Polygon obb; + if (_cfg.useOBB) obb = util::geo::convexHull(util::geo::getOrientedEnvelope(line)); if (line.size() == 2 && (!_cfg.useBoxIds || boxIds.front().first == 1) && subid == 0) { // simple line @@ -142,7 +147,7 @@ void Sweeper::add(const util::geo::I32Line& line, const std::string& gid, const util::geo::I32XSortedLine sline(line); size_t id = _lineCache.add(Line{ - sline, box, gid, subid, boxIds, //{} // dummy + sline, box, gid, subid, boxIds, obb//{} // dummy }); diskAdd({id, box.getLowerLeft().getY(), box.getUpperRight().getY(), @@ -322,6 +327,14 @@ void Sweeper::sweep() { // _____________________________________________________________________________ std::pair Sweeper::check(const Area* a, const Area* b, size_t t) const { + if (_cfg.useOBB) { + auto ts = TIME(); + auto r = util::geo::intersects(a->obb, b->obb); + _stats[t].timeOBBIsectAreaArea += TOOK(ts); + if (!r) { + return {0, 0}; + } + } if (_cfg.useBoxIds) { auto ts = TIME(); auto r = boxIdIsect(a->boxIds, b->boxIds); @@ -353,6 +366,14 @@ std::pair Sweeper::check(const Area* a, const Area* b, // _____________________________________________________________________________ std::pair Sweeper::check(const Line* a, const Area* b, size_t t) const { + if (_cfg.useOBB) { + auto ts = TIME(); + auto r = util::geo::intersects(a->obb, b->obb); + _stats[t].timeOBBIsectAreaLine += TOOK(ts); + if (!r) { + return {0, 0}; + } + } if (_cfg.useBoxIds) { auto ts = TIME(); auto r = boxIdIsect(a->boxIds, b->boxIds); @@ -383,6 +404,14 @@ std::pair Sweeper::check(const Line* a, const Area* b, // _____________________________________________________________________________ bool Sweeper::check(const Line* a, const Line* b, size_t t) const { + if (_cfg.useOBB) { + auto ts = TIME(); + auto r = util::geo::intersects(a->obb, b->obb); + _stats[t].timeOBBIsectLineLine += TOOK(ts); + if (!r) { + return false; + } + } if (_cfg.useBoxIds) { auto ts = TIME(); auto r = boxIdIsect(a->boxIds, b->boxIds); diff --git a/src/spatialjoin/Sweeper.h b/src/spatialjoin/Sweeper.h index b44f1e1..ebce379 100644 --- a/src/spatialjoin/Sweeper.h +++ b/src/spatialjoin/Sweeper.h @@ -64,6 +64,7 @@ struct SweeperCfg { std::string& pairEnd; bool useBoxIds; bool useArea; + bool useOBB; }; // buffer sizes _must_ be multiples of sizeof(BoxVal)