Skip to content

Commit

Permalink
Add Region.getRegions()
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Wittgen authored and Matthias Wittgen committed Oct 15, 2024
1 parent d98c780 commit 4af5d3f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 24 deletions.
4 changes: 2 additions & 2 deletions include/lsst/sphgeom/Region.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ class Region {
static std::unique_ptr<Region> decode(std::uint8_t const * buffer, size_t n);
///@}

/// `flatten` flattens a nested Region to a list of regions.
static void flatten(Region const &region, std::vector<std::unique_ptr<Region>> &result);
/// `getRegions` returns a vector of Region.
static std::vector<std::unique_ptr<Region>> getRegions(Region const &region);
///@}
};

Expand Down
6 changes: 1 addition & 5 deletions python/lsst/sphgeom/_region.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,7 @@ void defineClass(py::class_<Region, std::unique_ptr<Region>> &cls) {
"region"_a);
cls.def("encode", &python::encode);
cls.def_static("decode", &python::decode<Region>, "bytes"_a);
cls.def_static("flatten", [](Region const &region) {
std::vector<std::unique_ptr<Region>> result;
Region::flatten(region, result);
return result;
}, "region"_a);
cls.def_static("getRegions", Region::getRegions, "region"_a);
}

} // sphgeom
Expand Down
28 changes: 15 additions & 13 deletions src/Region.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,22 @@ std::unique_ptr<Region> Region::decode(std::uint8_t const * buffer, size_t n) {
}
throw std::runtime_error("Byte-string is not an encoded Region");
}
void Region::flatten(Region const &region, std::vector<std::unique_ptr<Region>> &result) {
if (auto union_region = dynamic_cast<UnionRegion const *>(&region)) {
for(int i = 0; i < 2; ++i) {
union_region->getOperand(i);
flatten(union_region->getOperand(i), result);
}
} else if(auto intersection_region = dynamic_cast<IntersectionRegion const *>(&region)) {
for(int i = 0; i < 2; ++i) {
intersection_region->getOperand(i);
flatten(intersection_region->getOperand(i), result);
}
} else {
result.emplace_back(region.clone());

std::vector<std::unique_ptr<Region>> Region::getRegions(Region const &region) {
std::vector<std::unique_ptr<Region>> result;
if (auto union_region = dynamic_cast<UnionRegion const *>(&region)) {
for(int i = 0; i < 2; ++i) {
result.emplace_back(union_region->getOperand(i).clone());
}
} else if(auto intersection_region = dynamic_cast<IntersectionRegion const *>(&region)) {
for(int i = 0; i < 2; ++i) {
intersection_region->getOperand(i);
result.emplace_back(intersection_region->getOperand(i).clone());
}
} else {
result.emplace_back(region.clone());
}
return result;
}

}} // namespace lsst:sphgeom
14 changes: 10 additions & 4 deletions tests/test_CompoundRegion.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,16 +201,22 @@ def testRelate(self):
self.assertEqual(self.box.relate(self.instance), CONTAINS)
self.assertEqual(self.faraway.relate(self.instance), DISJOINT)

def testFlatten(self):
def testGetRegion(self):
c1 = Circle(UnitVector3d(0.0, 0.0, 1.0), 1.0)
c2 = Circle(UnitVector3d(1.0, 0.0, 1.0), 2.0)
b1 = Box.fromDegrees(90, 0, 180, 45)
b2 = Box.fromDegrees(135, 15, 135, 30)
u1 = UnionRegion(c1, b1)
u2 = UnionRegion(c2, b2)
c = UnionRegion(u1, u2)
d = Region.flatten(c)
self.assertEqual(d, [c1, b1, c2, b2])
i1 = IntersectionRegion(c1, b1)
i2 = IntersectionRegion(c2, b2)
ur = UnionRegion(u1, u2)
ir = IntersectionRegion(i1, i2)
self.assertEqual(Region.getRegions(c1), [c1])
self.assertEqual(Region.getRegions(Region.getRegions(ir)[0]), [c1, b1])
self.assertEqual(Region.getRegions(Region.getRegions(ir)[1]), [c2, b2])
self.assertEqual(Region.getRegions(Region.getRegions(ur)[0]), [c1, b1])
self.assertEqual(Region.getRegions(Region.getRegions(ur)[1]), [c2, b2])


if __name__ == "__main__":
Expand Down

0 comments on commit 4af5d3f

Please sign in to comment.