LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
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(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 
140 void 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 
151 namespace lsst {
152 namespace afw {
153 
154 template std::shared_ptr<geom::polygon::Polygon> table::io::PersistableFacade<
155  geom::polygon::Polygon>::dynamicCast(std::shared_ptr<table::io::Persistable> const&);
156 
157 namespace geom {
158 namespace 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  }
187  explicit Impl(std::vector<LsstPoint> const& vertices) : poly() {
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 
233 template <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 
248 template <class PolyT>
250  std::vector<BoostPolygon> boostResult;
251  boost::geometry::intersection(poly, other, boostResult);
252  return convertBoostPolygons(boostResult);
253 }
254 
255 template <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 
267 template <class PolyT>
269  std::vector<BoostPolygon> boostResult;
270  boost::geometry::union_(poly, other, boostResult);
271  return convertBoostPolygons(boostResult);
272 }
273 
274 template <class PolyT>
276  std::vector<BoostPolygon> boostResult;
277  boost::geometry::sym_difference(poly, other, boostResult);
278  return convertBoostPolygons(boostResult);
279 }
280 
281 Polygon::Polygon(Polygon const&) = default;
282 Polygon::Polygon(Polygon&&) = default;
283 Polygon& Polygon::operator=(Polygon const&) = default;
284 Polygon& Polygon::operator=(Polygon&&) = default;
285 
286 Polygon::~Polygon() = default;
287 
288 Polygon::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 
309 size_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 
322 double Polygon::calculateArea() const { return boost::geometry::area(_impl->poly); }
323 
324 double 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 
337 std::vector<LsstPoint> Polygon::getVertices() const { return _impl->poly.outer(); }
338 
339 std::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 
345 bool 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 
356 bool Polygon::contains(LsstPoint const& point) const { return boost::geometry::within(point, _impl->poly); }
357 
358 bool Polygon::overlaps(Polygon const& other) const { return _impl->overlaps(other._impl->poly); }
359 
360 bool 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 
382 std::shared_ptr<Polygon> Polygon::unionSingle(Box const& box) const { return _impl->unionSingle(box); }
383 
385  return _impl->union_(other._impl->poly);
386 }
387 
388 std::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  */
526 namespace {
527 
528 struct 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 
545 private:
546  PolygonSchema()
547  : schema(),
548  vertices(afw::table::PointKey<double>::addFields(schema, "vertices", "list of vertex points",
549  "")) {}
550 };
551 
552 class PolygonFactory : public table::io::PersistableFactory {
553 public:
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 
572 std::string getPolygonPersistenceName() { return "Polygon"; }
573 
574 PolygonFactory registration(getPolygonPersistenceName());
575 
576 } // anonymous namespace
577 
578 std::string Polygon::getPersistenceName() const { return getPolygonPersistenceName(); }
579 
580 void Polygon::write(OutputArchiveHandle& handle) const {
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 
603 bool 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.
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: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