LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
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 
8 #include "lsst/pex/exceptions.h"
9 #include "lsst/geom/Extent.h"
11 
16 
20 using BoostPolygon = boost::geometry::model::polygon<LsstPoint>;
21 using BoostBox = boost::geometry::model::box<LsstPoint>;
22 using BoostLineString = boost::geometry::model::linestring<LsstPoint>;
23 
24 namespace boost {
25 namespace geometry {
26 namespace traits {
27 
28 // Setting up LsstPoint
29 template <>
30 struct tag<LsstPoint> {
31  using type = point_tag;
32 };
33 template <>
34 struct coordinate_type<LsstPoint> {
36 };
37 template <>
38 struct coordinate_system<LsstPoint> {
39  using type = cs::cartesian;
40 };
41 template <>
42 struct dimension<LsstPoint> : boost::mpl::int_<2> {};
43 template <std::size_t dim>
44 struct 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.
53 template <>
54 struct tag<LsstBox> {
55  using type = box_tag;
56 };
57 template <>
58 struct point_type<LsstBox> {
59  using type = LsstPoint;
60 };
61 template <>
62 struct indexed_access<LsstBox, 0, 0> {
63  static double get(LsstBox const& box) { return box.getMinX(); }
64 };
65 template <>
66 struct indexed_access<LsstBox, 1, 0> {
67  static double get(LsstBox const& box) { return box.getMaxX(); }
68 };
69 template <>
70 struct indexed_access<LsstBox, 0, 1> {
71  static double get(LsstBox const& box) { return box.getMinY(); }
72 };
73 template <>
74 struct indexed_access<LsstBox, 1, 1> {
75  static double get(LsstBox const& box) { return box.getMaxY(); }
76 };
77 
78 // Setting up LsstRing
79 template <>
80 struct 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 
88 namespace {
89 
91 LsstBox boostBoxToLsst(BoostBox const& box) { return LsstBox(box.min_corner(), box.max_corner()); }
92 
94 std::vector<LsstPoint> boxToCorners(LsstBox const& box) {
95  std::vector<LsstPoint> corners;
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 
109 void 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 
122 double 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(x - 0.5, y - 0.5), lsst::geom::Point2D(x + 0.5, y + 0.5));
125  boost::geometry::intersection(poly, pixel, overlap);
126  double area = 0.0;
127  for (auto const &i : overlap) {
128  double const polyArea = boost::geometry::area(i);
129  area += std::min(polyArea, 1.0); // remove any rounding error
130  }
131  return area;
132 }
133 
135 void pixelRowOverlap(std::shared_ptr<lsst::afw::image::Image<float>> const image, BoostPolygon const& poly,
136  int const xStart, int const xStop, int const y) {
137  int x = xStart;
138  for (lsst::afw::image::Image<float>::x_iterator i = image->x_at(x - image->getX0(), y - image->getY0());
139  x <= xStop; ++i, ++x) {
140  *i = pixelOverlap(poly, x, y);
141  }
142 }
143 
144 } // anonymous namespace
145 
146 namespace lsst {
147 namespace afw {
148 
149 template std::shared_ptr<geom::polygon::Polygon> table::io::PersistableFacade<
150  geom::polygon::Polygon>::dynamicCast(std::shared_ptr<table::io::Persistable> const&);
151 
152 namespace geom {
153 namespace polygon {
154 
157  os << "[";
158  size_t num = vertices.size();
159  for (size_t i = 0; i < num - 1; ++i) {
160  os << vertices[i] << ",";
161  }
162  os << vertices[vertices.size() - 1] << "]";
163  return os;
164 }
165 
168  return os << "BoostPolygon(" << poly.outer() << ")";
169 }
170 
172  os << poly.toString();
173  return os;
174 }
175 
177  Impl() : poly() {}
178  explicit Impl(Polygon::Box const& box) : poly() {
179  boost::geometry::assign(poly, box);
180  // Assignment from a box is correctly handled by BoostPolygon, so doesn't need a "check()"
181  }
182  explicit Impl(std::vector<LsstPoint> const& vertices) : poly() {
183  boost::geometry::assign(poly, vertices);
184  check(); // because the vertices might not have the correct orientation (CW vs CCW) or be open
185  }
186  explicit Impl(BoostPolygon const& _poly) : poly(_poly) {}
187 
188  void check() { boost::geometry::correct(poly); }
189 
192  std::vector<BoostPolygon> const& boostPolygons);
193 
194  template <class PolyT>
195  bool overlaps(PolyT const& other) const {
196  return !boost::geometry::disjoint(poly, other);
197  }
198 
199  template <class PolyT>
200  std::shared_ptr<Polygon> intersectionSingle(PolyT const& other) const;
201 
202  template <class PolyT>
203  std::vector<std::shared_ptr<Polygon>> intersection(PolyT const& other) const;
204 
205  template <class PolyT>
206  std::shared_ptr<Polygon> unionSingle(PolyT const& other) const;
207 
208  template <class PolyT>
209  std::vector<std::shared_ptr<Polygon>> union_(PolyT const& other) const;
210 
211  template <class PolyT>
212  std::vector<std::shared_ptr<Polygon>> symDifference(PolyT const& other) const;
213 
215 };
216 
218  std::vector<BoostPolygon> const& boostPolygons) {
220  lsstPolygons.reserve(boostPolygons.size());
221  for (auto const &boostPolygon : boostPolygons) {
222  std::shared_ptr<Polygon> tmp(new Polygon(std::make_shared<Polygon::Impl>(boostPolygon)));
223  lsstPolygons.push_back(tmp);
224  }
225  return lsstPolygons;
226 }
227 
228 template <class PolyT>
231  boost::geometry::intersection(poly, other, result);
232  if (result.size() == 0) {
233  throw LSST_EXCEPT(SinglePolygonException, "Polygons have no intersection");
234  }
235  if (result.size() > 1) {
236  throw LSST_EXCEPT(
238  (boost::format("Multiple polygons (%d) created by intersection()") % result.size()).str());
239  }
240  return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(result[0])));
241 }
242 
243 template <class PolyT>
245  std::vector<BoostPolygon> boostResult;
246  boost::geometry::intersection(poly, other, boostResult);
247  return convertBoostPolygons(boostResult);
248 }
249 
250 template <class PolyT>
253  boost::geometry::union_(poly, other, result);
254  if (result.size() != 1) {
255  throw LSST_EXCEPT(
257  (boost::format("Multiple polygons (%d) created by union_()") % result.size()).str());
258  }
259  return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(result[0])));
260 }
261 
262 template <class PolyT>
264  std::vector<BoostPolygon> boostResult;
265  boost::geometry::union_(poly, other, boostResult);
266  return convertBoostPolygons(boostResult);
267 }
268 
269 template <class PolyT>
271  std::vector<BoostPolygon> boostResult;
272  boost::geometry::sym_difference(poly, other, boostResult);
273  return convertBoostPolygons(boostResult);
274 }
275 
276 Polygon::Polygon(Polygon const&) = default;
277 Polygon::Polygon(Polygon&&) = default;
278 Polygon& Polygon::operator=(Polygon const&) = default;
279 Polygon& Polygon::operator=(Polygon&&) = default;
280 
281 Polygon::~Polygon() = default;
282 
283 Polygon::Polygon(Polygon::Box const& box) : _impl(new Polygon::Impl(box)) {}
284 
286 
288  : _impl(new Polygon::Impl()) {
289  auto corners = transform.applyForward(boxToCorners(box));
290  boost::geometry::assign(_impl->poly, corners);
291  _impl->check();
292 }
293 
295  : _impl(new Polygon::Impl()) {
296  std::vector<LsstPoint> corners = boxToCorners(box);
297  for (auto & corner : corners) {
298  corner = transform(corner);
299  }
300  boost::geometry::assign(_impl->poly, corners);
301  _impl->check();
302 }
303 
304 size_t Polygon::getNumEdges() const {
305  // boost::geometry::models::polygon uses a "closed" polygon: the start/end point is included twice
306  return boost::geometry::num_points(_impl->poly) - 1;
307 }
308 
310  return boostBoxToLsst(boost::geometry::return_envelope<BoostBox>(_impl->poly));
311 }
312 
314  return boost::geometry::return_centroid<LsstPoint>(_impl->poly);
315 }
316 
317 double Polygon::calculateArea() const { return boost::geometry::area(_impl->poly); }
318 
319 double Polygon::calculatePerimeter() const { return boost::geometry::perimeter(_impl->poly); }
320 
324  edges.reserve(getNumEdges());
325  for (std::vector<LsstPoint>::const_iterator i = vertices.begin(), j = vertices.begin() + 1;
326  j != vertices.end(); ++i, ++j) {
327  edges.emplace_back(*i, *j);
328  }
329  return edges;
330 }
331 
332 std::vector<LsstPoint> Polygon::getVertices() const { return _impl->poly.outer(); }
333 
334 std::vector<LsstPoint>::const_iterator Polygon::begin() const { return _impl->poly.outer().begin(); }
335 
337  return _impl->poly.outer().end() - 1; // Note removal of final "closed" point
338 }
339 
340 bool Polygon::operator==(Polygon const& other) const {
341  return boost::geometry::equals(_impl->poly, other._impl->poly);
342 }
343 
345  // boost::hash allows hash functions to throw, but the container hashes throw
346  // only if the element [geom::Point] has a throwing hash
347  static boost::hash<BoostPolygon::ring_type> polygonHash;
348  return polygonHash(_impl->poly.outer());
349 }
350 
351 bool Polygon::contains(LsstPoint const& point) const { return boost::geometry::within(point, _impl->poly); }
352 
353 bool Polygon::overlaps(Polygon const& other) const { return _impl->overlaps(other._impl->poly); }
354 
355 bool Polygon::overlaps(Box const& box) const { return _impl->overlaps(box); }
356 
358  return _impl->intersectionSingle(other._impl->poly);
359 }
360 
362  return _impl->intersectionSingle(box);
363 }
364 
366  return _impl->intersection(other._impl->poly);
367 }
368 
370  return _impl->intersection(box);
371 }
372 
374  return _impl->unionSingle(other._impl->poly);
375 }
376 
377 std::shared_ptr<Polygon> Polygon::unionSingle(Box const& box) const { return _impl->unionSingle(box); }
378 
380  return _impl->union_(other._impl->poly);
381 }
382 
383 std::vector<std::shared_ptr<Polygon>> Polygon::union_(Box const& box) const { return _impl->union_(box); }
384 
386  return _impl->symDifference(other._impl->poly);
387 }
388 
390  return _impl->symDifference(box);
391 }
392 
395  boost::geometry::simplify(_impl->poly, result, distance);
396  return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(result)));
397 }
398 
400  BoostPolygon hull;
401  boost::geometry::convex_hull(_impl->poly, hull);
402  return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(hull)));
403 }
404 
406  auto newVertices = transform.applyForward(getVertices());
407  return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(newVertices)));
408 }
409 
411  std::vector<LsstPoint> vertices; // New vertices
412  vertices.reserve(getNumEdges());
413  for (auto const &i : _impl->poly.outer()) {
414  vertices.push_back(transform(i));
415  }
416  return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(vertices)));
417 }
418 
420  std::vector<LsstPoint> vertices; // New vertices
421  vertices.reserve(getNumEdges() * num);
423  for (auto const &edge : edges) {
424  addSubSampledEdge(vertices, edge.first, edge.second, num);
425  }
426  return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(vertices)));
427 }
428 
430  std::vector<LsstPoint> vertices; // New vertices
431  vertices.reserve(getNumEdges() + static_cast<size_t>(::ceil(calculatePerimeter() / maxLength)));
433  for (auto const &edge : edges) {
434  Point const &p1 = edge.first, p2 = edge.second;
435  double const dist = ::sqrt(p1.distanceSquared(p2));
436  addSubSampledEdge(vertices, p1, p2, static_cast<size_t>(::ceil(dist / maxLength)));
437  }
438  return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(vertices)));
439 }
440 
442  using Image = afw::image::Image<float>;
443  std::shared_ptr<Image> image = std::make_shared<Image>(bbox);
444  image->setXY0(bbox.getMin());
445  *image = 0.0;
446  lsst::geom::Box2D bounds = getBBox(); // Polygon bounds
447  int xMin = std::max(static_cast<int>(bounds.getMinX()), bbox.getMinX());
448  int xMax = std::min(static_cast<int>(::ceil(bounds.getMaxX())), bbox.getMaxX());
449  int yMin = std::max(static_cast<int>(bounds.getMinY()), bbox.getMinY());
450  int yMax = std::min(static_cast<int>(::ceil(bounds.getMaxY())), bbox.getMaxY());
451  for (int y = yMin; y <= yMax; ++y) {
452  double const yPixelMin = (double)y - 0.5, yPixelMax = (double)y + 0.5;
453  BoostPolygon row; // A polygon of row y
454  boost::geometry::assign(
455  row, LsstBox(lsst::geom::Point2D(xMin, yPixelMin), lsst::geom::Point2D(xMax, yPixelMax)));
456  std::vector<BoostPolygon> intersections;
457  boost::geometry::intersection(_impl->poly, row, intersections);
458 
459  if (intersections.size() == 1 && boost::geometry::num_points(intersections[0]) == 5) {
460  // This row is fairly tame, and should have a long run of pixels within the polygon
461  BoostPolygon const& row = intersections[0];
462  std::vector<double> top, bottom;
463  top.reserve(2);
464  bottom.reserve(2);
465  bool failed = false;
466  for (std::vector<Point>::const_iterator i = row.outer().begin(); i != row.outer().end() - 1;
467  ++i) {
468  double const xCoord = i->getX(), yCoord = i->getY();
469  if (yCoord == yPixelMin) {
470  bottom.push_back(xCoord);
471  } else if (yCoord == yPixelMax) {
472  top.push_back(xCoord);
473  } else {
474  failed = true;
475  break;
476  }
477  }
478  if (!failed && top.size() == 2 && bottom.size() == 2) {
479  std::sort(top.begin(), top.end());
480  std::sort(bottom.begin(), bottom.end());
481  int const xMin = std::min(top[0], bottom[0]);
482  int const xStart = ::ceil(std::max(top[0], bottom[0])) + 1;
483  int const xStop = std::min(top[1], bottom[1]) - 1;
484  int const xMax = ::ceil(std::max(top[1], bottom[1]));
485  pixelRowOverlap(image, _impl->poly, std::max(xMin, bbox.getMinX()),
486  std::min(xStart, bbox.getMaxX()), y);
487  int x = xStart;
488  for (Image::x_iterator i = image->x_at(std::max(xStart, bbox.getMinX()) - image->getX0(),
489  y - image->getY0());
490  x <= std::min(xStop, bbox.getMaxX()); ++i, ++x) {
491  *i = 1.0;
492  }
493  pixelRowOverlap(image, _impl->poly, std::max(xStop, bbox.getMinX()),
494  std::min(xMax, bbox.getMaxX()), y);
495  continue;
496  }
497  }
498 
499  // Last resort: do each pixel independently...
500  for (auto const &intersection : intersections) {
501  double xMinRow = xMax, xMaxRow = xMin;
503  for (auto const &vertice : vertices) {
504  double const x = vertice.getX();
505  if (x < xMinRow) xMinRow = x;
506  if (x > xMaxRow) xMaxRow = x;
507  }
508 
509  pixelRowOverlap(image, _impl->poly, std::max(static_cast<int>(xMinRow), bbox.getMinX()),
510  std::min(static_cast<int>(::ceil(xMaxRow)), bbox.getMaxX()), y);
511  }
512  }
513  return image;
514 }
515 
516 // -------------- Table-based Persistence -------------------------------------------------------------------
517 
518 /*
519  *
520  */
521 namespace {
522 
523 struct PolygonSchema {
524  afw::table::Schema schema;
525  afw::table::PointKey<double> vertices;
526 
527  static PolygonSchema const& get() {
528  static PolygonSchema instance;
529  return instance;
530  }
531 
532  // No copying
533  PolygonSchema(const PolygonSchema&) = delete;
534  PolygonSchema& operator=(const PolygonSchema&) = delete;
535 
536  // No moving
537  PolygonSchema(PolygonSchema&&) = delete;
538  PolygonSchema& operator=(PolygonSchema&&) = delete;
539 
540 private:
541  PolygonSchema()
542  : schema(),
543  vertices(afw::table::PointKey<double>::addFields(schema, "vertices", "list of vertex points",
544  "")) {}
545 };
546 
547 class PolygonFactory : public table::io::PersistableFactory {
548 public:
549  explicit PolygonFactory(std::string const& name) : table::io::PersistableFactory(name) {}
550 
551  std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
552  CatalogVector const& catalogs) const override {
553  static PolygonSchema const& keys = PolygonSchema::get();
554 
555  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
556  afw::table::BaseCatalog const& cat = catalogs.front();
557 
559  for (afw::table::BaseCatalog::const_iterator iter = cat.begin(); iter != cat.end(); ++iter) {
560  vertices.push_back(iter->get(keys.vertices));
561  }
563  return result;
564  }
565 };
566 
567 std::string getPolygonPersistenceName() { return "Polygon"; }
568 
569 PolygonFactory registration(getPolygonPersistenceName());
570 
571 } // anonymous namespace
572 
573 std::string Polygon::getPersistenceName() const { return getPolygonPersistenceName(); }
574 
575 void Polygon::write(OutputArchiveHandle& handle) const {
576  static PolygonSchema const& keys = PolygonSchema::get();
577  afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
578 
580  for (auto const &vertice : vertices) {
582  record->set(keys.vertices, vertice);
583  }
584 
585  handle.saveCatalog(catalog);
586 }
587 
589  return std::make_unique<Polygon>(*this);
590 }
591 
593  std::stringstream buffer;
594  buffer << "Polygon(" << this->getVertices() << ")";
595  return buffer.str();
596 }
597 
598 bool Polygon::equals(typehandling::Storable const& other) const noexcept {
599  return singleClassEquals(*this, other);
600 }
601 
602 } // namespace polygon
603 } // namespace geom
604 } // namespace afw
605 } // 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:525
afw::table::Schema schema
Definition: Polygon.cc:524
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:373
std::vector< Point >::const_iterator begin() const
Iterator for vertices.
Definition: Polygon.cc:334
bool overlaps(Polygon const &other) const
Returns whether the polygons overlap each other.
Definition: Polygon.cc:353
Box getBBox() const
Return bounding box.
Definition: Polygon.cc:309
std::shared_ptr< Polygon > convexHull() const
Produce a polygon from the convex hull.
Definition: Polygon.cc:399
std::vector< std::pair< Point, Point > > getEdges() const
Get vector of edges.
Definition: Polygon.cc:321
std::shared_ptr< Polygon > intersectionSingle(Polygon const &other) const
Returns the intersection of two polygons.
Definition: Polygon.cc:357
std::shared_ptr< afw::image::Image< float > > createImage(lsst::geom::Box2I const &bbox) const
Create image of polygon.
Definition: Polygon.cc:441
Polygon(Box const &box)
Construct a rectangular Polygon whose vertices are the corners of a box.
Definition: Polygon.cc:283
std::shared_ptr< Polygon > subSample(size_t num) const
Sub-sample each edge.
Definition: Polygon.cc:419
std::vector< std::shared_ptr< Polygon > > intersection(Polygon const &other) const
Returns the intersection of two polygons.
Definition: Polygon.cc:365
size_t getNumEdges() const
Return number of edges.
Definition: Polygon.cc:304
std::shared_ptr< Polygon > transform(TransformPoint2ToPoint2 const &transform) const
Transform the polygon.
Definition: Polygon.cc:405
std::shared_ptr< typehandling::Storable > cloneStorable() const override
Create a new Polygon that is a copy of this one.
Definition: Polygon.cc:588
std::vector< Point > getVertices() const
Get vector of vertices.
Definition: Polygon.cc:332
std::shared_ptr< Polygon > simplify(double const distance) const
Return a simplified polygon.
Definition: Polygon.cc:393
bool operator==(Polygon const &other) const
Definition: Polygon.cc:340
std::string toString() const override
Create a string representation of this object.
Definition: Polygon.cc:592
std::vector< std::shared_ptr< Polygon > > union_(Polygon const &other) const
Returns the union of two polygons.
Definition: Polygon.cc:379
std::size_t hash_value() const noexcept override
Return a hash of this object.
Definition: Polygon.cc:344
std::vector< std::shared_ptr< Polygon > > symDifference(Polygon const &other) const
Return the symmetric difference of two polygons.
Definition: Polygon.cc:385
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Definition: Polygon.cc:573
bool contains(Point const &point) const
Returns whether the polygon contains the point.
Definition: Polygon.cc:351
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Definition: Polygon.cc:575
Polygon & operator=(Polygon const &)
std::vector< Point >::const_iterator end() const
Definition: Polygon.cc:336
bool equals(typehandling::Storable const &other) const noexcept override
Compare this object to another Storable.
Definition: Polygon.cc:598
double calculatePerimeter() const
Definition: Polygon.cc:319
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:171
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
FilterProperty & operator=(FilterProperty const &)=default
CatalogT< BaseRecord > BaseCatalog
Definition: fwd.h:72
Low-level polynomials (including special polynomials) in C++.
Definition: Basis1d.h:26
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:217
Impl(BoostPolygon const &_poly)
Definition: Polygon.cc:186
std::vector< std::shared_ptr< Polygon > > symDifference(PolyT const &other) const
Definition: Polygon.cc:270
Impl(Polygon::Box const &box)
Definition: Polygon.cc:178
bool overlaps(PolyT const &other) const
Definition: Polygon.cc:195
std::shared_ptr< Polygon > intersectionSingle(PolyT const &other) const
Definition: Polygon.cc:229
std::vector< std::shared_ptr< Polygon > > union_(PolyT const &other) const
Definition: Polygon.cc:263
std::shared_ptr< Polygon > unionSingle(PolyT const &other) const
Definition: Polygon.cc:251
std::vector< std::shared_ptr< Polygon > > intersection(PolyT const &other) const
Definition: Polygon.cc:244
Impl(std::vector< LsstPoint > const &vertices)
Definition: Polygon.cc:182
std::shared_ptr< table::io::Persistable > read(table::io::InputArchive const &archive, table::io::CatalogVector const &catalogs) const override
Definition: warpExposure.cc:0