LSST Applications  21.0.0+c4f5df5339,21.0.0+e70536a077,21.0.0-1-ga51b5d4+7c60f8a6ea,21.0.0-10-g560fb7b+411cd868f8,21.0.0-10-gcf60f90+8c49d86aa0,21.0.0-13-gc485e61d+38156233bf,21.0.0-16-g7a993c7b9+1041c3824f,21.0.0-2-g103fe59+d9ceee3e5a,21.0.0-2-g1367e85+0b2f7db15a,21.0.0-2-g45278ab+e70536a077,21.0.0-2-g5242d73+0b2f7db15a,21.0.0-2-g7f82c8f+feb9862f5e,21.0.0-2-g8f08a60+9c9a9cfcc8,21.0.0-2-ga326454+feb9862f5e,21.0.0-2-gde069b7+bedfc5e1fb,21.0.0-2-gecfae73+417509110f,21.0.0-2-gfc62afb+0b2f7db15a,21.0.0-3-g21c7a62+a91f7c0b59,21.0.0-3-g357aad2+062581ff1a,21.0.0-3-g4be5c26+0b2f7db15a,21.0.0-3-g65f322c+85aa0ead76,21.0.0-3-g7d9da8d+c4f5df5339,21.0.0-3-gaa929c8+411cd868f8,21.0.0-3-gc44e71e+fd4029fd48,21.0.0-3-ge02ed75+5d9b90b8aa,21.0.0-38-g070523fc+44fda2b515,21.0.0-4-g591bb35+5d9b90b8aa,21.0.0-4-g88306b8+3cdc83ea97,21.0.0-4-gc004bbf+d52368b591,21.0.0-4-gccdca77+a5c54364a0,21.0.0-5-g7ebb681+81e2098694,21.0.0-5-gdf36809+87b8d260e6,21.0.0-6-g2d4f3f3+e70536a077,21.0.0-6-g4e60332+5d9b90b8aa,21.0.0-6-g5ef7dad+3f4e29eeae,21.0.0-7-gc8ca178+0f5e56d48f,21.0.0-9-g9eb8d17+cc2c7a81aa,master-gac4afde19b+5d9b90b8aa,w.2021.07
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 
17 
21 typedef boost::geometry::model::polygon<LsstPoint> BoostPolygon;
22 typedef boost::geometry::model::box<LsstPoint> BoostBox;
23 typedef boost::geometry::model::linestring<LsstPoint> BoostLineString;
24 
25 namespace boost {
26 namespace geometry {
27 namespace traits {
28 
29 // Setting up LsstPoint
30 template <>
31 struct tag<LsstPoint> {
32  typedef point_tag type;
33 };
34 template <>
35 struct coordinate_type<LsstPoint> {
37 };
38 template <>
39 struct coordinate_system<LsstPoint> {
40  typedef cs::cartesian type;
41 };
42 template <>
43 struct dimension<LsstPoint> : boost::mpl::int_<2> {};
44 template <std::size_t dim>
45 struct access<LsstPoint, dim> {
46  static double get(LsstPoint const& p) { return p[dim]; }
47  static void set(LsstPoint& p, LsstPoint::Element const& value) { p[dim] = value; }
48 };
49 
50 // Setting up LsstBox
51 //
52 // No setters, because it's inefficient (can't set individual elements of lsst::geom::Box2D directly).
53 // For box outputs from boost::geometry we'll use BoostBox and then convert.
54 template <>
55 struct tag<LsstBox> {
56  typedef box_tag type;
57 };
58 template <>
59 struct point_type<LsstBox> {
60  typedef LsstPoint type;
61 };
62 template <>
63 struct indexed_access<LsstBox, 0, 0> {
64  static double get(LsstBox const& box) { return box.getMinX(); }
65 };
66 template <>
67 struct indexed_access<LsstBox, 1, 0> {
68  static double get(LsstBox const& box) { return box.getMaxX(); }
69 };
70 template <>
71 struct indexed_access<LsstBox, 0, 1> {
72  static double get(LsstBox const& box) { return box.getMinY(); }
73 };
74 template <>
75 struct indexed_access<LsstBox, 1, 1> {
76  static double get(LsstBox const& box) { return box.getMaxY(); }
77 };
78 
79 // Setting up LsstRing
80 template <>
81 struct tag<LsstRing> {
82  typedef ring_tag type;
83 };
84 // template<> struct range_value<LsstRing> { typedef LsstPoint type; };
85 } // namespace traits
86 } // namespace geometry
87 } // namespace boost
88 
89 namespace {
90 
92 LsstBox boostBoxToLsst(BoostBox const& box) { return LsstBox(box.min_corner(), box.max_corner()); }
93 
95 std::vector<LsstPoint> boxToCorners(LsstBox const& box) {
96  std::vector<LsstPoint> corners;
97  corners.reserve(4);
98  corners.push_back(box.getMin());
99  corners.push_back(LsstPoint(box.getMaxX(), box.getMinY()));
100  corners.push_back(box.getMax());
101  corners.push_back(LsstPoint(box.getMinX(), box.getMaxY()));
102  return corners;
103 }
104 
110 void addSubSampledEdge(std::vector<LsstPoint>& vertices, // Vector of points to which to add
111  LsstPoint const& first, // First vertex defining edge
112  LsstPoint const& second, // Second vertex defining edge
113  size_t const num // Number of parts to divide edge into
114 ) {
115  lsst::geom::Extent2D const delta = (second - first) / num;
116  vertices.push_back(first);
117  for (size_t i = 1; i < num; ++i) {
118  vertices.push_back(first + delta * i);
119  }
120 }
121 
123 double pixelOverlap(BoostPolygon const& poly, int const x, int const y) {
124  std::vector<BoostPolygon> overlap; // Overlap between pixel and polygon
125  LsstBox const pixel(lsst::geom::Point2D(x - 0.5, y - 0.5), lsst::geom::Point2D(x + 0.5, y + 0.5));
126  boost::geometry::intersection(poly, pixel, overlap);
127  double area = 0.0;
128  for (std::vector<BoostPolygon>::const_iterator i = overlap.begin(); i != overlap.end(); ++i) {
129  double const polyArea = boost::geometry::area(*i);
130  area += std::min(polyArea, 1.0); // remove any rounding error
131  }
132  return area;
133 }
134 
136 void pixelRowOverlap(std::shared_ptr<lsst::afw::image::Image<float>> const image, BoostPolygon const& poly,
137  int const xStart, int const xStop, int const y) {
138  int x = xStart;
139  for (lsst::afw::image::Image<float>::x_iterator i = image->x_at(x - image->getX0(), y - image->getY0());
140  x <= xStop; ++i, ++x) {
141  *i = pixelOverlap(poly, x, y);
142  }
143 }
144 
145 } // anonymous namespace
146 
147 namespace lsst {
148 namespace afw {
149 
150 template std::shared_ptr<geom::polygon::Polygon> table::io::PersistableFacade<
151  geom::polygon::Polygon>::dynamicCast(std::shared_ptr<table::io::Persistable> const&);
152 
153 namespace geom {
154 namespace polygon {
155 
158  os << "[";
159  size_t num = vertices.size();
160  for (size_t i = 0; i < num - 1; ++i) {
161  os << vertices[i] << ",";
162  }
163  os << vertices[vertices.size() - 1] << "]";
164  return os;
165 }
166 
169  return os << "BoostPolygon(" << poly.outer() << ")";
170 }
171 
173  os << poly.toString();
174  return os;
175 }
176 
178  Impl() : poly() {}
179  explicit Impl(Polygon::Box const& box) : poly() {
180  boost::geometry::assign(poly, box);
181  // Assignment from a box is correctly handled by BoostPolygon, so doesn't need a "check()"
182  }
183  explicit Impl(std::vector<LsstPoint> const& vertices) : poly() {
184  boost::geometry::assign(poly, vertices);
185  check(); // because the vertices might not have the correct orientation (CW vs CCW) or be open
186  }
187  explicit Impl(BoostPolygon const& _poly) : poly(_poly) {}
188 
189  void check() { boost::geometry::correct(poly); }
190 
193  std::vector<BoostPolygon> const& boostPolygons);
194 
195  template <class PolyT>
196  bool overlaps(PolyT const& other) const {
197  return !boost::geometry::disjoint(poly, other);
198  }
199 
200  template <class PolyT>
202 
203  template <class PolyT>
205 
206  template <class PolyT>
207  std::shared_ptr<Polygon> unionSingle(PolyT const& other) const;
208 
209  template <class PolyT>
211 
212  template <class PolyT>
214 
216 };
217 
219  std::vector<BoostPolygon> const& boostPolygons) {
221  lsstPolygons.reserve(boostPolygons.size());
222  for (std::vector<BoostPolygon>::const_iterator i = boostPolygons.begin(); i != boostPolygons.end(); ++i) {
224  lsstPolygons.push_back(tmp);
225  }
226  return lsstPolygons;
227 }
228 
229 template <class PolyT>
232  boost::geometry::intersection(poly, other, result);
233  if (result.size() == 0) {
234  throw LSST_EXCEPT(SinglePolygonException, "Polygons have no intersection");
235  }
236  if (result.size() > 1) {
237  throw LSST_EXCEPT(
239  (boost::format("Multiple polygons (%d) created by intersection()") % result.size()).str());
240  }
242 }
243 
244 template <class PolyT>
246  std::vector<BoostPolygon> boostResult;
247  boost::geometry::intersection(poly, other, boostResult);
248  return convertBoostPolygons(boostResult);
249 }
250 
251 template <class PolyT>
254  boost::geometry::union_(poly, other, result);
255  if (result.size() != 1) {
256  throw LSST_EXCEPT(
258  (boost::format("Multiple polygons (%d) created by union_()") % result.size()).str());
259  }
261 }
262 
263 template <class PolyT>
265  std::vector<BoostPolygon> boostResult;
266  boost::geometry::union_(poly, other, boostResult);
267  return convertBoostPolygons(boostResult);
268 }
269 
270 template <class PolyT>
272  std::vector<BoostPolygon> boostResult;
273  boost::geometry::sym_difference(poly, other, boostResult);
274  return convertBoostPolygons(boostResult);
275 }
276 
277 Polygon::Polygon(Polygon const&) = default;
278 Polygon::Polygon(Polygon&&) = default;
279 Polygon& Polygon::operator=(Polygon const&) = default;
280 Polygon& Polygon::operator=(Polygon&&) = default;
281 
282 Polygon::~Polygon() = default;
283 
284 Polygon::Polygon(Polygon::Box const& box) : _impl(new Polygon::Impl(box)) {}
285 
287 
289  : _impl(new Polygon::Impl()) {
290  auto corners = transform.applyForward(boxToCorners(box));
291  boost::geometry::assign(_impl->poly, corners);
292  _impl->check();
293 }
294 
296  : _impl(new Polygon::Impl()) {
297  std::vector<LsstPoint> corners = boxToCorners(box);
298  for (std::vector<LsstPoint>::iterator p = corners.begin(); p != corners.end(); ++p) {
299  *p = transform(*p);
300  }
301  boost::geometry::assign(_impl->poly, corners);
302  _impl->check();
303 }
304 
305 size_t Polygon::getNumEdges() const {
306  // boost::geometry::models::polygon uses a "closed" polygon: the start/end point is included twice
307  return boost::geometry::num_points(_impl->poly) - 1;
308 }
309 
311  return boostBoxToLsst(boost::geometry::return_envelope<BoostBox>(_impl->poly));
312 }
313 
315  return boost::geometry::return_centroid<LsstPoint>(_impl->poly);
316 }
317 
318 double Polygon::calculateArea() const { return boost::geometry::area(_impl->poly); }
319 
320 double Polygon::calculatePerimeter() const { return boost::geometry::perimeter(_impl->poly); }
321 
325  edges.reserve(getNumEdges());
326  for (std::vector<LsstPoint>::const_iterator i = vertices.begin(), j = vertices.begin() + 1;
327  j != vertices.end(); ++i, ++j) {
328  edges.push_back(std::make_pair(*i, *j));
329  }
330  return edges;
331 }
332 
333 std::vector<LsstPoint> Polygon::getVertices() const { return _impl->poly.outer(); }
334 
335 std::vector<LsstPoint>::const_iterator Polygon::begin() const { return _impl->poly.outer().begin(); }
336 
338  return _impl->poly.outer().end() - 1; // Note removal of final "closed" point
339 }
340 
341 bool Polygon::operator==(Polygon const& other) const {
342  return boost::geometry::equals(_impl->poly, other._impl->poly);
343 }
344 
346  // boost::hash allows hash functions to throw, but the container hashes throw
347  // only if the element [geom::Point] has a throwing hash
348  static boost::hash<BoostPolygon::ring_type> polygonHash;
349  return polygonHash(_impl->poly.outer());
350 }
351 
352 bool Polygon::contains(LsstPoint const& point) const { return boost::geometry::within(point, _impl->poly); }
353 
354 bool Polygon::overlaps(Polygon const& other) const { return _impl->overlaps(other._impl->poly); }
355 
356 bool Polygon::overlaps(Box const& box) const { return _impl->overlaps(box); }
357 
359  return _impl->intersectionSingle(other._impl->poly);
360 }
361 
363  return _impl->intersectionSingle(box);
364 }
365 
367  return _impl->intersection(other._impl->poly);
368 }
369 
371  return _impl->intersection(box);
372 }
373 
375  return _impl->unionSingle(other._impl->poly);
376 }
377 
378 std::shared_ptr<Polygon> Polygon::unionSingle(Box const& box) const { return _impl->unionSingle(box); }
379 
381  return _impl->union_(other._impl->poly);
382 }
383 
384 std::vector<std::shared_ptr<Polygon>> Polygon::union_(Box const& box) const { return _impl->union_(box); }
385 
387  return _impl->symDifference(other._impl->poly);
388 }
389 
391  return _impl->symDifference(box);
392 }
393 
396  boost::geometry::simplify(_impl->poly, result, distance);
398 }
399 
401  BoostPolygon hull;
402  boost::geometry::convex_hull(_impl->poly, hull);
404 }
405 
407  auto newVertices = transform.applyForward(getVertices());
408  return std::shared_ptr<Polygon>(new Polygon(std::shared_ptr<Impl>(new Impl(newVertices))));
409 }
410 
412  std::vector<LsstPoint> vertices; // New vertices
413  vertices.reserve(getNumEdges());
414  for (std::vector<LsstPoint>::const_iterator i = _impl->poly.outer().begin();
415  i != _impl->poly.outer().end(); ++i) {
416  vertices.push_back(transform(*i));
417  }
419 }
420 
422  std::vector<LsstPoint> vertices; // New vertices
423  vertices.reserve(getNumEdges() * num);
425  for (std::vector<std::pair<Point, Point>>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
426  addSubSampledEdge(vertices, i->first, i->second, num);
427  }
429 }
430 
432  std::vector<LsstPoint> vertices; // New vertices
433  vertices.reserve(getNumEdges() + static_cast<size_t>(::ceil(calculatePerimeter() / maxLength)));
435  for (std::vector<std::pair<Point, Point>>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
436  Point const &p1 = i->first, p2 = i->second;
437  double const dist = ::sqrt(p1.distanceSquared(p2));
438  addSubSampledEdge(vertices, p1, p2, static_cast<size_t>(::ceil(dist / maxLength)));
439  }
441 }
442 
444  typedef afw::image::Image<float> Image;
445  std::shared_ptr<Image> image = std::make_shared<Image>(bbox);
446  image->setXY0(bbox.getMin());
447  *image = 0.0;
448  lsst::geom::Box2D bounds = getBBox(); // Polygon bounds
449  int xMin = std::max(static_cast<int>(bounds.getMinX()), bbox.getMinX());
450  int xMax = std::min(static_cast<int>(::ceil(bounds.getMaxX())), bbox.getMaxX());
451  int yMin = std::max(static_cast<int>(bounds.getMinY()), bbox.getMinY());
452  int yMax = std::min(static_cast<int>(::ceil(bounds.getMaxY())), bbox.getMaxY());
453  for (int y = yMin; y <= yMax; ++y) {
454  double const yPixelMin = (double)y - 0.5, yPixelMax = (double)y + 0.5;
455  BoostPolygon row; // A polygon of row y
456  boost::geometry::assign(
457  row, LsstBox(lsst::geom::Point2D(xMin, yPixelMin), lsst::geom::Point2D(xMax, yPixelMax)));
458  std::vector<BoostPolygon> intersections;
459  boost::geometry::intersection(_impl->poly, row, intersections);
460 
461  if (intersections.size() == 1 && boost::geometry::num_points(intersections[0]) == 5) {
462  // This row is fairly tame, and should have a long run of pixels within the polygon
463  BoostPolygon const& row = intersections[0];
464  std::vector<double> top, bottom;
465  top.reserve(2);
466  bottom.reserve(2);
467  bool failed = false;
468  for (std::vector<Point>::const_iterator i = row.outer().begin(); i != row.outer().end() - 1;
469  ++i) {
470  double const xCoord = i->getX(), yCoord = i->getY();
471  if (yCoord == yPixelMin) {
472  bottom.push_back(xCoord);
473  } else if (yCoord == yPixelMax) {
474  top.push_back(xCoord);
475  } else {
476  failed = true;
477  break;
478  }
479  }
480  if (!failed && top.size() == 2 && bottom.size() == 2) {
481  std::sort(top.begin(), top.end());
482  std::sort(bottom.begin(), bottom.end());
483  int const xMin = std::min(top[0], bottom[0]);
484  int const xStart = ::ceil(std::max(top[0], bottom[0])) + 1;
485  int const xStop = std::min(top[1], bottom[1]) - 1;
486  int const xMax = ::ceil(std::max(top[1], bottom[1]));
487  pixelRowOverlap(image, _impl->poly, std::max(xMin, bbox.getMinX()),
488  std::min(xStart, bbox.getMaxX()), y);
489  int x = xStart;
490  for (Image::x_iterator i = image->x_at(std::max(xStart, bbox.getMinX()) - image->getX0(),
491  y - image->getY0());
492  x <= std::min(xStop, bbox.getMaxX()); ++i, ++x) {
493  *i = 1.0;
494  }
495  pixelRowOverlap(image, _impl->poly, std::max(xStop, bbox.getMinX()),
496  std::min(xMax, bbox.getMaxX()), y);
497  continue;
498  }
499  }
500 
501  // Last resort: do each pixel independently...
502  for (std::vector<BoostPolygon>::const_iterator p = intersections.begin(); p != intersections.end();
503  ++p) {
504  double xMinRow = xMax, xMaxRow = xMin;
505  std::vector<LsstPoint> const vertices = p->outer();
506  for (std::vector<LsstPoint>::const_iterator q = vertices.begin(); q != vertices.end(); ++q) {
507  double const x = q->getX();
508  if (x < xMinRow) xMinRow = x;
509  if (x > xMaxRow) xMaxRow = x;
510  }
511 
512  pixelRowOverlap(image, _impl->poly, std::max(static_cast<int>(xMinRow), bbox.getMinX()),
513  std::min(static_cast<int>(::ceil(xMaxRow)), bbox.getMaxX()), y);
514  }
515  }
516  return image;
517 }
518 
519 // -------------- Table-based Persistence -------------------------------------------------------------------
520 
521 /*
522  *
523  */
524 namespace {
525 
526 struct PolygonSchema {
527  afw::table::Schema schema;
528  afw::table::PointKey<double> vertices;
529 
530  static PolygonSchema const& get() {
531  static PolygonSchema instance;
532  return instance;
533  }
534 
535  // No copying
536  PolygonSchema(const PolygonSchema&) = delete;
537  PolygonSchema& operator=(const PolygonSchema&) = delete;
538 
539  // No moving
540  PolygonSchema(PolygonSchema&&) = delete;
541  PolygonSchema& operator=(PolygonSchema&&) = delete;
542 
543 private:
544  PolygonSchema()
545  : schema(),
546  vertices(afw::table::PointKey<double>::addFields(schema, "vertices", "list of vertex points",
547  "")) {}
548 };
549 
550 class PolygonFactory : public table::io::PersistableFactory {
551 public:
552  explicit PolygonFactory(std::string const& name) : table::io::PersistableFactory(name) {}
553 
554  std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
555  CatalogVector const& catalogs) const override {
556  static PolygonSchema const& keys = PolygonSchema::get();
557 
558  LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
559  afw::table::BaseCatalog const& cat = catalogs.front();
560 
562  for (afw::table::BaseCatalog::const_iterator iter = cat.begin(); iter != cat.end(); ++iter) {
563  vertices.push_back(iter->get(keys.vertices));
564  }
566  return result;
567  }
568 };
569 
570 std::string getPolygonPersistenceName() { return "Polygon"; }
571 
572 PolygonFactory registration(getPolygonPersistenceName());
573 
574 } // anonymous namespace
575 
576 std::string Polygon::getPersistenceName() const { return getPolygonPersistenceName(); }
577 
578 void Polygon::write(OutputArchiveHandle& handle) const {
579  static PolygonSchema const& keys = PolygonSchema::get();
580  afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
581 
583  for (std::vector<LsstPoint>::const_iterator i = vertices.begin(); i != vertices.end(); ++i) {
585  record->set(keys.vertices, *i);
586  }
587 
588  handle.saveCatalog(catalog);
589 }
590 
592  return std::make_unique<Polygon>(*this);
593 }
594 
596  std::stringstream buffer;
597  buffer << "Polygon(" << this->getVertices() << ")";
598  return buffer.str();
599 }
600 
601 bool Polygon::equals(typehandling::Storable const& other) const noexcept {
602  return singleClassEquals(*this, other);
603 }
604 
605 } // namespace polygon
606 } // namespace geom
607 } // namespace afw
608 } // namespace lsst
py::object result
Definition: _schema.cc:429
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
ItemVariant const * other
Definition: Schema.cc:56
std::ostream * os
Definition: Schema.cc:746
#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
std::shared_ptr< Polygon > unionSingle(Polygon const &other) const
Returns the union of two polygons.
Definition: Polygon.cc:374
std::vector< Point >::const_iterator begin() const
Iterator for vertices.
Definition: Polygon.cc:335
bool overlaps(Polygon const &other) const
Returns whether the polygons overlap each other.
Definition: Polygon.cc:354
Box getBBox() const
Return bounding box.
Definition: Polygon.cc:310
std::shared_ptr< Polygon > convexHull() const
Produce a polygon from the convex hull.
Definition: Polygon.cc:400
std::vector< std::pair< Point, Point > > getEdges() const
Get vector of edges.
Definition: Polygon.cc:322
std::shared_ptr< Polygon > intersectionSingle(Polygon const &other) const
Returns the intersection of two polygons.
Definition: Polygon.cc:358
std::shared_ptr< afw::image::Image< float > > createImage(lsst::geom::Box2I const &bbox) const
Create image of polygon.
Definition: Polygon.cc:443
Polygon(Box const &box)
Construct a rectangular Polygon whose vertices are the corners of a box.
Definition: Polygon.cc:284
std::shared_ptr< Polygon > subSample(size_t num) const
Sub-sample each edge.
Definition: Polygon.cc:421
std::vector< std::shared_ptr< Polygon > > intersection(Polygon const &other) const
Returns the intersection of two polygons.
Definition: Polygon.cc:366
size_t getNumEdges() const
Return number of edges.
Definition: Polygon.cc:305
std::shared_ptr< Polygon > transform(TransformPoint2ToPoint2 const &transform) const
Transform the polygon.
Definition: Polygon.cc:406
std::shared_ptr< typehandling::Storable > cloneStorable() const override
Create a new Polygon that is a copy of this one.
Definition: Polygon.cc:591
std::vector< Point > getVertices() const
Get vector of vertices.
Definition: Polygon.cc:333
std::shared_ptr< Polygon > simplify(double const distance) const
Return a simplified polygon.
Definition: Polygon.cc:394
bool operator==(Polygon const &other) const
Definition: Polygon.cc:341
std::string toString() const override
Create a string representation of this object.
Definition: Polygon.cc:595
std::vector< std::shared_ptr< Polygon > > union_(Polygon const &other) const
Returns the union of two polygons.
Definition: Polygon.cc:380
std::size_t hash_value() const noexcept override
Return a hash of this object.
Definition: Polygon.cc:345
std::vector< std::shared_ptr< Polygon > > symDifference(Polygon const &other) const
Return the symmetric difference of two polygons.
Definition: Polygon.cc:386
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Definition: Polygon.cc:576
bool contains(Point const &point) const
Returns whether the polygon contains the point.
Definition: Polygon.cc:352
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Definition: Polygon.cc:578
Polygon & operator=(Polygon const &)
std::vector< Point >::const_iterator end() const
Definition: Polygon.cc:337
bool equals(typehandling::Storable const &other) const noexcept override
Compare this object to another Storable.
Definition: Polygon.cc:601
double calculatePerimeter() const
Definition: Polygon.cc:320
An exception that indicates the single-polygon assumption has been violated.
Definition: Polygon.h:53
_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:58
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:485
CatalogIterator< typename Internal::const_iterator > const_iterator
Definition: Catalog.h:111
reference front() const
Return the first record.
Definition: Catalog.h:453
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 end(T... args)
T make_pair(T... args)
T max(T... args)
T min(T... args)
Definition: Polygon.cc:25
std::ostream & operator<<(std::ostream &os, Polygon const &poly)
Stream polygon.
Definition: Polygon.cc:172
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
FilterProperty & operator=(FilterProperty const &)=default
CatalogT< BaseRecord > BaseCatalog
Definition: fwd.h:71
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)
AmpInfoBoxKey bbox
Definition: Amplifier.cc:117
table::Key< int > transform
int row
Definition: CR.cc:145
boost::geometry::model::box< LsstPoint > BoostBox
Definition: Polygon.cc:22
std::vector< LsstPoint > LsstRing
Definition: Polygon.cc:20
boost::geometry::model::polygon< LsstPoint > BoostPolygon
Definition: Polygon.cc:21
afw::table::PointKey< double > vertices
Definition: Polygon.cc:528
lsst::afw::geom::polygon::Polygon::Point LsstPoint
Definition: Polygon.cc:18
boost::geometry::model::linestring< LsstPoint > BoostLineString
Definition: Polygon.cc:23
afw::table::Schema schema
Definition: Polygon.cc:527
lsst::afw::geom::polygon::Polygon::Box LsstBox
Definition: Polygon.cc:19
int y
Definition: SpanSet.cc:49
T str(T... args)
static void set(LsstPoint &p, LsstPoint::Element const &value)
Definition: Polygon.cc:47
static double get(LsstPoint const &p)
Definition: Polygon.cc:46
static std::vector< std::shared_ptr< Polygon > > convertBoostPolygons(std::vector< BoostPolygon > const &boostPolygons)
Definition: Polygon.cc:218
Impl(BoostPolygon const &_poly)
Definition: Polygon.cc:187
std::vector< std::shared_ptr< Polygon > > symDifference(PolyT const &other) const
Definition: Polygon.cc:271
Impl(Polygon::Box const &box)
Definition: Polygon.cc:179
bool overlaps(PolyT const &other) const
Definition: Polygon.cc:196
std::shared_ptr< Polygon > intersectionSingle(PolyT const &other) const
Definition: Polygon.cc:230
std::vector< std::shared_ptr< Polygon > > union_(PolyT const &other) const
Definition: Polygon.cc:264
std::shared_ptr< Polygon > unionSingle(PolyT const &other) const
Definition: Polygon.cc:252
std::vector< std::shared_ptr< Polygon > > intersection(PolyT const &other) const
Definition: Polygon.cc:245
Impl(std::vector< LsstPoint > const &vertices)
Definition: Polygon.cc:183