LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
Polygon.cc
Go to the documentation of this file.
1#include <cmath>
2#include <algorithm>
3
4#include "boost/geometry/geometry.hpp"
5#include <boost/container_hash/hash.hpp>
6#include <memory>
7
9#include "lsst/geom/Extent.h"
11
16
20using BoostPolygon = boost::geometry::model::polygon<LsstPoint>;
21using BoostBox = boost::geometry::model::box<LsstPoint>;
22using BoostLineString = boost::geometry::model::linestring<LsstPoint>;
23
24namespace boost {
25namespace geometry {
26namespace traits {
27
28// Setting up LsstPoint
29template <>
30struct tag<LsstPoint> {
31 using type = point_tag;
32};
33template <>
34struct coordinate_type<LsstPoint> {
36};
37template <>
38struct coordinate_system<LsstPoint> {
39 using type = cs::cartesian;
40};
41template <>
42struct dimension<LsstPoint> : boost::mpl::int_<2> {};
43template <std::size_t dim>
44struct access<LsstPoint, dim> {
45 static double get(LsstPoint const& p) { return p[dim]; }
46 static void set(LsstPoint& p, LsstPoint::Element const& value) { p[dim] = value; }
47};
48
49// Setting up LsstBox
50//
51// No setters, because it's inefficient (can't set individual elements of lsst::geom::Box2D directly).
52// For box outputs from boost::geometry we'll use BoostBox and then convert.
53template <>
54struct tag<LsstBox> {
55 using type = box_tag;
56};
57template <>
58struct point_type<LsstBox> {
59 using type = LsstPoint;
60};
61template <>
62struct indexed_access<LsstBox, 0, 0> {
63 static double get(LsstBox const& box) { return box.getMinX(); }
64};
65template <>
66struct indexed_access<LsstBox, 1, 0> {
67 static double get(LsstBox const& box) { return box.getMaxX(); }
68};
69template <>
70struct indexed_access<LsstBox, 0, 1> {
71 static double get(LsstBox const& box) { return box.getMinY(); }
72};
73template <>
74struct indexed_access<LsstBox, 1, 1> {
75 static double get(LsstBox const& box) { return box.getMaxY(); }
76};
77
78// Setting up LsstRing
79template <>
80struct tag<LsstRing> {
81 using type = ring_tag;
82};
83// template<> struct range_value<LsstRing> { typedef LsstPoint type; };
84} // namespace traits
85} // namespace geometry
86} // namespace boost
87
88namespace {
89
91LsstBox boostBoxToLsst(BoostBox const& box) { return LsstBox(box.min_corner(), box.max_corner()); }
92
94std::vector<LsstPoint> boxToCorners(LsstBox const& box) {
96 corners.reserve(4);
97 corners.push_back(box.getMin());
98 corners.emplace_back(box.getMaxX(), box.getMinY());
99 corners.push_back(box.getMax());
100 corners.emplace_back(box.getMinX(), box.getMaxY());
101 return corners;
102}
103
109void addSubSampledEdge(std::vector<LsstPoint>& vertices, // Vector of points to which to add
110 LsstPoint const& first, // First vertex defining edge
111 LsstPoint const& second, // Second vertex defining edge
112 size_t const num // Number of parts to divide edge into
113) {
114 lsst::geom::Extent2D const delta = (second - first) / num;
115 vertices.push_back(first);
116 for (size_t i = 1; i < num; ++i) {
117 vertices.push_back(first + delta * i);
118 }
119}
120
122double pixelOverlap(BoostPolygon const& poly, int const x, int const y) {
123 std::vector<BoostPolygon> overlap; // Overlap between pixel and polygon
124 LsstBox const pixel(lsst::geom::Point2D(static_cast<double>(x) - 0.5, static_cast<double>(y) - 0.5),
125 lsst::geom::Point2D(static_cast<double>(x) + 0.5, static_cast<double>(y) + 0.5));
126 // Note that the output of boost::geometry::intersection depends
127 // on values down to the precision limit, so minor variations
128 // in poly input can lead to surprisingly large variations in the
129 // output overlap regions and area computation.
130 boost::geometry::intersection(poly, pixel, overlap);
131 double area = 0.0;
132 for (auto const &i : overlap) {
133 double const polyArea = boost::geometry::area(i);
134 area += std::min(polyArea, 1.0); // remove any rounding error
135 }
136 return area;
137}
138
140void pixelRowOverlap(std::shared_ptr<lsst::afw::image::Image<float>> const image, BoostPolygon const& poly,
141 int const xStart, int const xStop, int const y) {
142 int x = xStart;
143 for (lsst::afw::image::Image<float>::x_iterator i = image->x_at(x - image->getX0(), y - image->getY0());
144 x <= xStop; ++i, ++x) {
145 *i = pixelOverlap(poly, x, y);
146 }
147}
148
149} // anonymous namespace
150
151namespace lsst {
152namespace afw {
153
154template std::shared_ptr<geom::polygon::Polygon> table::io::PersistableFacade<
155 geom::polygon::Polygon>::dynamicCast(std::shared_ptr<table::io::Persistable> const&);
156
157namespace geom {
158namespace polygon {
159
162 os << "[";
163 size_t num = vertices.size();
164 for (size_t i = 0; i < num - 1; ++i) {
165 os << vertices[i] << ",";
166 }
167 os << vertices[vertices.size() - 1] << "]";
168 return os;
169}
170
173 return os << "BoostPolygon(" << poly.outer() << ")";
174}
175
177 os << poly.toString();
178 return os;
179}
180
182 Impl() : poly() {}
183 explicit Impl(Polygon::Box const& box) : poly() {
184 boost::geometry::assign(poly, box);
185 // Assignment from a box is correctly handled by BoostPolygon, so doesn't need a "check()"
186 }
188 boost::geometry::assign(poly, vertices);
189 check(); // because the vertices might not have the correct orientation (CW vs CCW) or be open
190 }
191 explicit Impl(BoostPolygon const& _poly) : poly(_poly) {}
192
193 void check() { boost::geometry::correct(poly); }
194
197 std::vector<BoostPolygon> const& boostPolygons);
198
199 template <class PolyT>
200 bool overlaps(PolyT const& other) const {
201 return !boost::geometry::disjoint(poly, other);
202 }
203
204 template <class PolyT>
205 std::shared_ptr<Polygon> intersectionSingle(PolyT const& other) const;
206
207 template <class PolyT>
208 std::vector<std::shared_ptr<Polygon>> intersection(PolyT const& other) const;
209
210 template <class PolyT>
211 std::shared_ptr<Polygon> unionSingle(PolyT const& other) const;
212
213 template <class PolyT>
214 std::vector<std::shared_ptr<Polygon>> union_(PolyT const& other) const;
215
216 template <class PolyT>
217 std::vector<std::shared_ptr<Polygon>> symDifference(PolyT const& other) const;
218
220};
221
223 std::vector<BoostPolygon> const& boostPolygons) {
225 lsstPolygons.reserve(boostPolygons.size());
226 for (auto const &boostPolygon : boostPolygons) {
227 std::shared_ptr<Polygon> tmp(new Polygon(std::make_shared<Polygon::Impl>(boostPolygon)));
228 lsstPolygons.push_back(tmp);
229 }
230 return lsstPolygons;
231}
232
233template <class PolyT>
236 boost::geometry::intersection(poly, other, result);
237 if (result.size() == 0) {
238 throw LSST_EXCEPT(SinglePolygonException, "Polygons have no intersection");
239 }
240 if (result.size() > 1) {
241 throw LSST_EXCEPT(
243 (boost::format("Multiple polygons (%d) created by intersection()") % result.size()).str());
244 }
245 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(result[0])));
246}
247
248template <class PolyT>
250 std::vector<BoostPolygon> boostResult;
251 boost::geometry::intersection(poly, other, boostResult);
252 return convertBoostPolygons(boostResult);
253}
254
255template <class PolyT>
258 boost::geometry::union_(poly, other, result);
259 if (result.size() != 1) {
260 throw LSST_EXCEPT(
262 (boost::format("Multiple polygons (%d) created by union_()") % result.size()).str());
263 }
264 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(result[0])));
265}
266
267template <class PolyT>
269 std::vector<BoostPolygon> boostResult;
270 boost::geometry::union_(poly, other, boostResult);
271 return convertBoostPolygons(boostResult);
272}
273
274template <class PolyT>
276 std::vector<BoostPolygon> boostResult;
277 boost::geometry::sym_difference(poly, other, boostResult);
278 return convertBoostPolygons(boostResult);
279}
280
281Polygon::Polygon(Polygon const&) = default;
282Polygon::Polygon(Polygon&&) = default;
283Polygon& Polygon::operator=(Polygon const&) = default;
285
286Polygon::~Polygon() = default;
287
288Polygon::Polygon(Polygon::Box const& box) : _impl(new Polygon::Impl(box)) {}
289
291
293 : _impl(new Polygon::Impl()) {
294 auto corners = transform.applyForward(boxToCorners(box));
295 boost::geometry::assign(_impl->poly, corners);
296 _impl->check();
297}
298
300 : _impl(new Polygon::Impl()) {
301 std::vector<LsstPoint> corners = boxToCorners(box);
302 for (auto & corner : corners) {
303 corner = transform(corner);
304 }
305 boost::geometry::assign(_impl->poly, corners);
306 _impl->check();
307}
308
309size_t Polygon::getNumEdges() const {
310 // boost::geometry::models::polygon uses a "closed" polygon: the start/end point is included twice
311 return boost::geometry::num_points(_impl->poly) - 1;
312}
313
315 return boostBoxToLsst(boost::geometry::return_envelope<BoostBox>(_impl->poly));
316}
317
319 return boost::geometry::return_centroid<LsstPoint>(_impl->poly);
320}
321
322double Polygon::calculateArea() const { return boost::geometry::area(_impl->poly); }
323
324double Polygon::calculatePerimeter() const { return boost::geometry::perimeter(_impl->poly); }
325
329 edges.reserve(getNumEdges());
330 for (std::vector<LsstPoint>::const_iterator i = vertices.begin(), j = vertices.begin() + 1;
331 j != vertices.end(); ++i, ++j) {
332 edges.emplace_back(*i, *j);
333 }
334 return edges;
335}
336
337std::vector<LsstPoint> Polygon::getVertices() const { return _impl->poly.outer(); }
338
339std::vector<LsstPoint>::const_iterator Polygon::begin() const { return _impl->poly.outer().begin(); }
340
342 return _impl->poly.outer().end() - 1; // Note removal of final "closed" point
343}
344
345bool Polygon::operator==(Polygon const& other) const {
346 return boost::geometry::equals(_impl->poly, other._impl->poly);
347}
348
350 // boost::hash allows hash functions to throw, but the container hashes throw
351 // only if the element [geom::Point] has a throwing hash
352 static boost::hash<BoostPolygon::ring_type> polygonHash;
353 return polygonHash(_impl->poly.outer());
354}
355
356bool Polygon::contains(LsstPoint const& point) const { return boost::geometry::within(point, _impl->poly); }
357
358bool Polygon::overlaps(Polygon const& other) const { return _impl->overlaps(other._impl->poly); }
359
360bool Polygon::overlaps(Box const& box) const { return _impl->overlaps(box); }
361
363 return _impl->intersectionSingle(other._impl->poly);
364}
365
367 return _impl->intersectionSingle(box);
368}
369
371 return _impl->intersection(other._impl->poly);
372}
373
375 return _impl->intersection(box);
376}
377
379 return _impl->unionSingle(other._impl->poly);
380}
381
382std::shared_ptr<Polygon> Polygon::unionSingle(Box const& box) const { return _impl->unionSingle(box); }
383
385 return _impl->union_(other._impl->poly);
386}
387
388std::vector<std::shared_ptr<Polygon>> Polygon::union_(Box const& box) const { return _impl->union_(box); }
389
391 return _impl->symDifference(other._impl->poly);
392}
393
395 return _impl->symDifference(box);
396}
397
400 boost::geometry::simplify(_impl->poly, result, distance);
401 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(result)));
402}
403
405 BoostPolygon hull;
406 boost::geometry::convex_hull(_impl->poly, hull);
407 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(hull)));
408}
409
411 auto newVertices = transform.applyForward(getVertices());
412 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(newVertices)));
413}
414
416 std::vector<LsstPoint> vertices; // New vertices
417 vertices.reserve(getNumEdges());
418 for (auto const &i : _impl->poly.outer()) {
419 vertices.push_back(transform(i));
420 }
421 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(vertices)));
422}
423
425 std::vector<LsstPoint> vertices; // New vertices
426 vertices.reserve(getNumEdges() * num);
428 for (auto const &edge : edges) {
429 addSubSampledEdge(vertices, edge.first, edge.second, num);
430 }
431 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(vertices)));
432}
433
435 std::vector<LsstPoint> vertices; // New vertices
436 vertices.reserve(getNumEdges() + static_cast<size_t>(::ceil(calculatePerimeter() / maxLength)));
438 for (auto const &edge : edges) {
439 Point const &p1 = edge.first, p2 = edge.second;
440 double const dist = ::sqrt(p1.distanceSquared(p2));
441 addSubSampledEdge(vertices, p1, p2, static_cast<size_t>(::ceil(dist / maxLength)));
442 }
443 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(vertices)));
444}
445
447 using Image = afw::image::Image<float>;
448 std::shared_ptr<Image> image = std::make_shared<Image>(bbox);
449 image->setXY0(bbox.getMin());
450 *image = 0.0;
451 lsst::geom::Box2D bounds = getBBox(); // Polygon bounds
452 int xMin = std::max(static_cast<int>(bounds.getMinX()), bbox.getMinX());
453 int xMax = std::min(static_cast<int>(::ceil(bounds.getMaxX())), bbox.getMaxX());
454 int yMin = std::max(static_cast<int>(bounds.getMinY()), bbox.getMinY());
455 int yMax = std::min(static_cast<int>(::ceil(bounds.getMaxY())), bbox.getMaxY());
456 for (int y = yMin; y <= yMax; ++y) {
457 double const yPixelMin = (double)y - 0.5, yPixelMax = (double)y + 0.5;
458 BoostPolygon row; // A polygon of row y
459 boost::geometry::assign(
460 row, LsstBox(lsst::geom::Point2D(xMin, yPixelMin), lsst::geom::Point2D(xMax, yPixelMax)));
461 std::vector<BoostPolygon> intersections;
462 boost::geometry::intersection(_impl->poly, row, intersections);
463
464 if (intersections.size() == 1 && boost::geometry::num_points(intersections[0]) == 5) {
465 // This row is fairly tame, and should have a long run of pixels within the polygon
466 BoostPolygon const& row = intersections[0];
467 std::vector<double> top, bottom;
468 top.reserve(2);
469 bottom.reserve(2);
470 bool failed = false;
471 for (std::vector<Point>::const_iterator i = row.outer().begin(); i != row.outer().end() - 1;
472 ++i) {
473 double const xCoord = i->getX(), yCoord = i->getY();
474 if (yCoord == yPixelMin) {
475 bottom.push_back(xCoord);
476 } else if (yCoord == yPixelMax) {
477 top.push_back(xCoord);
478 } else {
479 failed = true;
480 break;
481 }
482 }
483 if (!failed && top.size() == 2 && bottom.size() == 2) {
484 std::sort(top.begin(), top.end());
485 std::sort(bottom.begin(), bottom.end());
486 int const xMin = std::min(top[0], bottom[0]);
487 int const xStart = ::ceil(std::max(top[0], bottom[0])) + 1;
488 int const xStop = std::min(top[1], bottom[1]) - 1;
489 int const xMax = ::ceil(std::max(top[1], bottom[1]));
490 pixelRowOverlap(image, _impl->poly, std::max(xMin, bbox.getMinX()),
491 std::min(xStart, bbox.getMaxX()), y);
492 int x = xStart;
493 for (Image::x_iterator i = image->x_at(std::max(xStart, bbox.getMinX()) - image->getX0(),
494 y - image->getY0());
495 x <= std::min(xStop, bbox.getMaxX()); ++i, ++x) {
496 *i = 1.0;
497 }
498 pixelRowOverlap(image, _impl->poly, std::max(xStop, bbox.getMinX()),
499 std::min(xMax, bbox.getMaxX()), y);
500 continue;
501 }
502 }
503
504 // Last resort: do each pixel independently...
505 for (auto const &intersection : intersections) {
506 double xMinRow = xMax, xMaxRow = xMin;
508 for (auto const &vertice : vertices) {
509 double const x = vertice.getX();
510 if (x < xMinRow) xMinRow = x;
511 if (x > xMaxRow) xMaxRow = x;
512 }
513
514 pixelRowOverlap(image, _impl->poly, std::max(static_cast<int>(xMinRow), bbox.getMinX()),
515 std::min(static_cast<int>(::ceil(xMaxRow)), bbox.getMaxX()), y);
516 }
517 }
518 return image;
519}
520
521// -------------- Table-based Persistence -------------------------------------------------------------------
522
523/*
524 *
525 */
526namespace {
527
528struct PolygonSchema {
529 afw::table::Schema schema;
530 afw::table::PointKey<double> vertices;
531
532 static PolygonSchema const& get() {
533 static PolygonSchema instance;
534 return instance;
535 }
536
537 // No copying
538 PolygonSchema(const PolygonSchema&) = delete;
539 PolygonSchema& operator=(const PolygonSchema&) = delete;
540
541 // No moving
542 PolygonSchema(PolygonSchema&&) = delete;
543 PolygonSchema& operator=(PolygonSchema&&) = delete;
544
545private:
546 PolygonSchema()
547 : schema(),
548 vertices(afw::table::PointKey<double>::addFields(schema, "vertices", "list of vertex points",
549 "")) {}
550};
551
552class PolygonFactory : public table::io::PersistableFactory {
553public:
554 explicit PolygonFactory(std::string const& name) : table::io::PersistableFactory(name) {}
555
556 std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
557 CatalogVector const& catalogs) const override {
558 static PolygonSchema const& keys = PolygonSchema::get();
559
560 LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
561 afw::table::BaseCatalog const& cat = catalogs.front();
562
564 for (afw::table::BaseCatalog::const_iterator iter = cat.begin(); iter != cat.end(); ++iter) {
565 vertices.push_back(iter->get(keys.vertices));
566 }
568 return result;
569 }
570};
571
572std::string getPolygonPersistenceName() { return "Polygon"; }
573
574PolygonFactory registration(getPolygonPersistenceName());
575
576} // anonymous namespace
577
578std::string Polygon::getPersistenceName() const { return getPolygonPersistenceName(); }
579
581 static PolygonSchema const& keys = PolygonSchema::get();
582 afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
583
585 for (auto const &vertice : vertices) {
587 record->set(keys.vertices, vertice);
588 }
589
590 handle.saveCatalog(catalog);
591}
592
594 return std::make_unique<Polygon>(*this);
595}
596
598 std::stringstream buffer;
599 buffer << "Polygon(" << this->getVertices() << ")";
600 return buffer.str();
601}
602
603bool Polygon::equals(typehandling::Storable const& other) const noexcept {
604 return singleClassEquals(*this, other);
605}
606
607} // namespace polygon
608} // namespace geom
609} // namespace afw
610} // namespace lsst
py::object result
Definition: _schema.cc:429
table::Key< std::string > name
Definition: Amplifier.cc:116
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
double x
table::PointKey< int > pixel
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
afw::table::Key< afw::table::Array< ImagePixelT > > image
lsst::afw::geom::polygon::Polygon::Box LsstBox
Definition: Polygon.cc:18
boost::geometry::model::linestring< LsstPoint > BoostLineString
Definition: Polygon.cc:22
afw::table::PointKey< double > vertices
Definition: Polygon.cc:530
afw::table::Schema schema
Definition: Polygon.cc:529
lsst::afw::geom::polygon::Polygon::Point LsstPoint
Definition: Polygon.cc:17
boost::geometry::model::box< LsstPoint > BoostBox
Definition: Polygon.cc:21
boost::geometry::model::polygon< LsstPoint > BoostPolygon
Definition: Polygon.cc:20
std::ostream * os
Definition: Schema.cc:557
int y
Definition: SpanSet.cc:48
table::Key< int > transform
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.h:48
T begin(T... args)
Transform LSST spatial data, such as lsst::geom::Point2D and lsst::geom::SpherePoint,...
Definition: Transform.h:68
Cartesian polygons.
Definition: Polygon.h:59
lsst::geom::Point2D Point
Definition: Polygon.h:62
std::shared_ptr< Polygon > unionSingle(Polygon const &other) const
Returns the union of two polygons.
Definition: Polygon.cc:378
std::vector< Point >::const_iterator begin() const
Iterator for vertices.
Definition: Polygon.cc:339
bool overlaps(Polygon const &other) const
Returns whether the polygons overlap each other.
Definition: Polygon.cc:358
Box getBBox() const
Return bounding box.
Definition: Polygon.cc:314
std::shared_ptr< Polygon > convexHull() const
Produce a polygon from the convex hull.
Definition: Polygon.cc:404
std::vector< std::pair< Point, Point > > getEdges() const
Get vector of edges.
Definition: Polygon.cc:326
std::shared_ptr< Polygon > intersectionSingle(Polygon const &other) const
Returns the intersection of two polygons.
Definition: Polygon.cc:362
std::shared_ptr< afw::image::Image< float > > createImage(lsst::geom::Box2I const &bbox) const
Create image of polygon.
Definition: Polygon.cc:446
Polygon(Box const &box)
Construct a rectangular Polygon whose vertices are the corners of a box.
Definition: Polygon.cc:288
std::shared_ptr< Polygon > subSample(size_t num) const
Sub-sample each edge.
Definition: Polygon.cc:424
std::vector< std::shared_ptr< Polygon > > intersection(Polygon const &other) const
Returns the intersection of two polygons.
Definition: Polygon.cc:370
size_t getNumEdges() const
Return number of edges.
Definition: Polygon.cc:309
std::shared_ptr< Polygon > transform(TransformPoint2ToPoint2 const &transform) const
Transform the polygon.
Definition: Polygon.cc:410
std::shared_ptr< typehandling::Storable > cloneStorable() const override
Create a new Polygon that is a copy of this one.
Definition: Polygon.cc:593
std::vector< Point > getVertices() const
Get vector of vertices.
Definition: Polygon.cc:337
std::shared_ptr< Polygon > simplify(double const distance) const
Return a simplified polygon.
Definition: Polygon.cc:398
bool operator==(Polygon const &other) const
Definition: Polygon.cc:345
std::string toString() const override
Create a string representation of this object.
Definition: Polygon.cc:597
std::vector< std::shared_ptr< Polygon > > union_(Polygon const &other) const
Returns the union of two polygons.
Definition: Polygon.cc:384
std::size_t hash_value() const noexcept override
Return a hash of this object.
Definition: Polygon.cc:349
std::vector< std::shared_ptr< Polygon > > symDifference(Polygon const &other) const
Return the symmetric difference of two polygons.
Definition: Polygon.cc:390
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Definition: Polygon.cc:578
bool contains(Point const &point) const
Returns whether the polygon contains the point.
Definition: Polygon.cc:356
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Definition: Polygon.cc:580
Polygon & operator=(Polygon const &)
std::vector< Point >::const_iterator end() const
Definition: Polygon.cc:341
bool equals(typehandling::Storable const &other) const noexcept override
Compare this object to another Storable.
Definition: Polygon.cc:603
double calculatePerimeter() const
Definition: Polygon.cc:324
An exception that indicates the single-polygon assumption has been violated.
Definition: Polygon.h:53
typename _view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
Definition: ImageBase.h:133
A class to represent a 2-dimensional array of pixels.
Definition: Image.h:51
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
Definition: Catalog.h:490
CatalogIterator< typename Internal::const_iterator > const_iterator
Definition: Catalog.h:112
reference front() const
Return the first record.
Definition: Catalog.h:458
An object passed to Persistable::write to allow it to persist itself.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
Interface supporting iteration over heterogenous containers.
Definition: Storable.h:58
An affine coordinate transformation consisting of a linear transformation and an offset.
A floating-point coordinate rectangle geometry.
Definition: Box.h:413
double getMaxY() const noexcept
Definition: Box.h:519
Point2D const getMax() const noexcept
Definition: Box.h:517
double getMaxX() const noexcept
Definition: Box.h:518
double getMinY() const noexcept
Definition: Box.h:515
Point2D const getMin() const noexcept
Definition: Box.h:513
double getMinX() const noexcept
Definition: Box.h:514
An integer coordinate rectangle.
Definition: Box.h:55
double distanceSquared(PointBase< T, N > const &other) const noexcept(Super::IS_ELEMENT_NOTHROW_COPYABLE)
Cast this object to an Extent of the same numeric type and dimensionality.
Definition: Point.h:138
T emplace_back(T... args)
T end(T... args)
T max(T... args)
T min(T... args)
Definition: Polygon.cc:24
std::ostream & operator<<(std::ostream &os, Polygon const &poly)
Stream polygon.
Definition: Polygon.cc:176
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
CatalogT< BaseRecord > BaseCatalog
Definition: fwd.h:72
Low-level polynomials (including special polynomials) in C++.
Extent< int, N > ceil(Extent< double, N > const &input) noexcept
Return the component-wise ceil (round towards more positive).
Definition: Extent.cc:118
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
A base class for image defects.
T push_back(T... args)
T reserve(T... args)
T size(T... args)
T sort(T... args)
int row
Definition: CR.cc:145
T str(T... args)
static void set(LsstPoint &p, LsstPoint::Element const &value)
Definition: Polygon.cc:46
static double get(LsstPoint const &p)
Definition: Polygon.cc:45
static std::vector< std::shared_ptr< Polygon > > convertBoostPolygons(std::vector< BoostPolygon > const &boostPolygons)
Definition: Polygon.cc:222
Impl(BoostPolygon const &_poly)
Definition: Polygon.cc:191
std::vector< std::shared_ptr< Polygon > > symDifference(PolyT const &other) const
Definition: Polygon.cc:275
Impl(Polygon::Box const &box)
Definition: Polygon.cc:183
bool overlaps(PolyT const &other) const
Definition: Polygon.cc:200
std::shared_ptr< Polygon > intersectionSingle(PolyT const &other) const
Definition: Polygon.cc:234
std::vector< std::shared_ptr< Polygon > > union_(PolyT const &other) const
Definition: Polygon.cc:268
std::shared_ptr< Polygon > unionSingle(PolyT const &other) const
Definition: Polygon.cc:256
std::vector< std::shared_ptr< Polygon > > intersection(PolyT const &other) const
Definition: Polygon.cc:249
Impl(std::vector< LsstPoint > const &vertices)
Definition: Polygon.cc:187
std::shared_ptr< table::io::Persistable > read(table::io::InputArchive const &archive, table::io::CatalogVector const &catalogs) const override
Definition: warpExposure.cc:0