LSST Applications g180d380827+0f66a164bb,g2079a07aa2+86d27d4dc4,g2305ad1205+7d304bc7a0,g29320951ab+500695df56,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g33d1c0ed96+0e5473021a,g3a166c0a6a+0e5473021a,g3ddfee87b4+e42ea45bea,g48712c4677+36a86eeaa5,g487adcacf7+2dd8f347ac,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+c70619cc9d,g5a732f18d5+53520f316c,g5ea96fc03c+341ea1ce94,g64a986408d+f7cd9c7162,g858d7b2824+f7cd9c7162,g8a8a8dda67+585e252eca,g99cad8db69+469ab8c039,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,gb0e22166c9+60f28cb32d,gba4ed39666+c2a2e4ac27,gbb8dafda3b+c92fc63c7e,gbd866b1f37+f7cd9c7162,gc120e1dc64+02c66aa596,gc28159a63d+0e5473021a,gc3e9b769f7+b0068a2d9f,gcf0d15dbbd+e42ea45bea,gdaeeff99f8+f9a426f77a,ge6526c86ff+84383d05b3,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gff1a9f87cc+f7cd9c7162,w.2024.17
LSST Data Management Base Package
Loading...
Searching...
No Matches
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
341std::vector<LsstPoint>::const_iterator Polygon::end() const {
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
359 std::vector<bool> results;
360 for (Point const & p : points) {
361 results.push_back(contains(p));
362 }
363 return results;
364}
365
367 std::vector<bool> results;
368 for (lsst::geom::PointI const & p : points) {
369 results.push_back(contains(Point(p)));
370 }
371 return results;
372}
373
374bool Polygon::overlaps(Polygon const& other) const { return _impl->overlaps(other._impl->poly); }
375
376bool Polygon::overlaps(Box const& box) const { return _impl->overlaps(box); }
377
379 return _impl->intersectionSingle(other._impl->poly);
380}
381
383 return _impl->intersectionSingle(box);
384}
385
387 return _impl->intersection(other._impl->poly);
388}
389
391 return _impl->intersection(box);
392}
393
395 return _impl->unionSingle(other._impl->poly);
396}
397
398std::shared_ptr<Polygon> Polygon::unionSingle(Box const& box) const { return _impl->unionSingle(box); }
399
401 return _impl->union_(other._impl->poly);
402}
403
404std::vector<std::shared_ptr<Polygon>> Polygon::union_(Box const& box) const { return _impl->union_(box); }
405
407 return _impl->symDifference(other._impl->poly);
408}
409
411 return _impl->symDifference(box);
412}
413
414std::shared_ptr<Polygon> Polygon::simplify(double const distance) const {
416 boost::geometry::simplify(_impl->poly, result, distance);
417 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(result)));
418}
419
421 BoostPolygon hull;
422 boost::geometry::convex_hull(_impl->poly, hull);
423 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(hull)));
424}
425
427 auto newVertices = transform.applyForward(getVertices());
428 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(newVertices)));
429}
430
432 std::vector<LsstPoint> vertices; // New vertices
434 for (auto const &i : _impl->poly.outer()) {
435 vertices.push_back(transform(i));
436 }
437 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(vertices)));
438}
439
441 std::vector<LsstPoint> vertices; // New vertices
444 for (auto const &edge : edges) {
445 addSubSampledEdge(vertices, edge.first, edge.second, num);
446 }
447 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(vertices)));
448}
449
451 std::vector<LsstPoint> vertices; // New vertices
452 vertices.reserve(getNumEdges() + static_cast<size_t>(::ceil(calculatePerimeter() / maxLength)));
454 for (auto const &edge : edges) {
455 Point const &p1 = edge.first, p2 = edge.second;
456 double const dist = ::sqrt(p1.distanceSquared(p2));
457 addSubSampledEdge(vertices, p1, p2, static_cast<size_t>(::ceil(dist / maxLength)));
458 }
459 return std::shared_ptr<Polygon>(new Polygon(std::make_shared<Impl>(vertices)));
460}
461
463 using Image = afw::image::Image<float>;
464 std::shared_ptr<Image> image = std::make_shared<Image>(bbox);
465 image->setXY0(bbox.getMin());
466 *image = 0.0;
467 lsst::geom::Box2D bounds = getBBox(); // Polygon bounds
468 int xMin = std::max(static_cast<int>(bounds.getMinX()), bbox.getMinX());
469 int xMax = std::min(static_cast<int>(::ceil(bounds.getMaxX())), bbox.getMaxX());
470 int yMin = std::max(static_cast<int>(bounds.getMinY()), bbox.getMinY());
471 int yMax = std::min(static_cast<int>(::ceil(bounds.getMaxY())), bbox.getMaxY());
472 for (int y = yMin; y <= yMax; ++y) {
473 double const yPixelMin = (double)y - 0.5, yPixelMax = (double)y + 0.5;
474 BoostPolygon row; // A polygon of row y
475 boost::geometry::assign(
476 row, LsstBox(lsst::geom::Point2D(xMin, yPixelMin), lsst::geom::Point2D(xMax, yPixelMax)));
477 std::vector<BoostPolygon> intersections;
478 boost::geometry::intersection(_impl->poly, row, intersections);
479
480 if (intersections.size() == 1 && boost::geometry::num_points(intersections[0]) == 5) {
481 // This row is fairly tame, and should have a long run of pixels within the polygon
482 BoostPolygon const& row = intersections[0];
483 std::vector<double> top, bottom;
484 top.reserve(2);
485 bottom.reserve(2);
486 bool failed = false;
487 for (std::vector<Point>::const_iterator i = row.outer().begin(); i != row.outer().end() - 1;
488 ++i) {
489 double const xCoord = i->getX(), yCoord = i->getY();
490 if (yCoord == yPixelMin) {
491 bottom.push_back(xCoord);
492 } else if (yCoord == yPixelMax) {
493 top.push_back(xCoord);
494 } else {
495 failed = true;
496 break;
497 }
498 }
499 if (!failed && top.size() == 2 && bottom.size() == 2) {
500 std::sort(top.begin(), top.end());
501 std::sort(bottom.begin(), bottom.end());
502 int const xMin = std::min(top[0], bottom[0]);
503 int const xStart = ::ceil(std::max(top[0], bottom[0])) + 1;
504 int const xStop = std::min(top[1], bottom[1]) - 1;
505 int const xMax = ::ceil(std::max(top[1], bottom[1]));
506 pixelRowOverlap(image, _impl->poly, std::max(xMin, bbox.getMinX()),
507 std::min(xStart, bbox.getMaxX()), y);
508 int x = xStart;
509 for (Image::x_iterator i = image->x_at(std::max(xStart, bbox.getMinX()) - image->getX0(),
510 y - image->getY0());
511 x <= std::min(xStop, bbox.getMaxX()); ++i, ++x) {
512 *i = 1.0;
513 }
514 pixelRowOverlap(image, _impl->poly, std::max(xStop, bbox.getMinX()),
515 std::min(xMax, bbox.getMaxX()), y);
516 continue;
517 }
518 }
519
520 // Last resort: do each pixel independently...
521 for (auto const &intersection : intersections) {
522 double xMinRow = xMax, xMaxRow = xMin;
524 for (auto const &vertice : vertices) {
525 double const x = vertice.getX();
526 if (x < xMinRow) xMinRow = x;
527 if (x > xMaxRow) xMaxRow = x;
528 }
529
530 pixelRowOverlap(image, _impl->poly, std::max(static_cast<int>(xMinRow), bbox.getMinX()),
531 std::min(static_cast<int>(::ceil(xMaxRow)), bbox.getMaxX()), y);
532 }
533 }
534 return image;
535}
536
537// -------------- Table-based Persistence -------------------------------------------------------------------
538
539/*
540 *
541 */
542namespace {
543
544struct PolygonSchema {
545 afw::table::Schema schema;
546 afw::table::PointKey<double> vertices;
547
548 static PolygonSchema const& get() {
549 static PolygonSchema instance;
550 return instance;
551 }
552
553 // No copying
554 PolygonSchema(const PolygonSchema&) = delete;
555 PolygonSchema& operator=(const PolygonSchema&) = delete;
556
557 // No moving
558 PolygonSchema(PolygonSchema&&) = delete;
559 PolygonSchema& operator=(PolygonSchema&&) = delete;
560
561private:
562 PolygonSchema()
563 : schema(),
564 vertices(afw::table::PointKey<double>::addFields(schema, "vertices", "list of vertex points",
565 "")) {}
566};
567
568class PolygonFactory : public table::io::PersistableFactory {
569public:
570 explicit PolygonFactory(std::string const& name) : table::io::PersistableFactory(name) {}
571
572 std::shared_ptr<table::io::Persistable> read(InputArchive const& archive,
573 CatalogVector const& catalogs) const override {
574 static PolygonSchema const& keys = PolygonSchema::get();
575
576 LSST_ARCHIVE_ASSERT(catalogs.size() == 1u);
577 afw::table::BaseCatalog const& cat = catalogs.front();
578
580 for (afw::table::BaseCatalog::const_iterator iter = cat.begin(); iter != cat.end(); ++iter) {
581 vertices.push_back(iter->get(keys.vertices));
582 }
584 return result;
585 }
586};
587
588std::string getPolygonPersistenceName() { return "Polygon"; }
589
590PolygonFactory registration(getPolygonPersistenceName());
591
592} // anonymous namespace
593
594std::string Polygon::getPersistenceName() const { return getPolygonPersistenceName(); }
595
597 static PolygonSchema const& keys = PolygonSchema::get();
598 afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
599
601 for (auto const &vertice : vertices) {
602 std::shared_ptr<afw::table::BaseRecord> record = catalog.addNew();
603 record->set(keys.vertices, vertice);
604 }
605
606 handle.saveCatalog(catalog);
607}
608
610 return std::make_unique<Polygon>(*this);
611}
612
614 std::stringstream buffer;
615 buffer << "Polygon(" << this->getVertices() << ")";
616 return buffer.str();
617}
618
619bool Polygon::equals(typehandling::Storable const& other) const noexcept {
620 return singleClassEquals(*this, other);
621}
622
623} // namespace polygon
624} // namespace geom
625} // namespace afw
626} // namespace lsst
py::object result
Definition _schema.cc:429
AmpInfoBoxKey bbox
Definition Amplifier.cc:117
table::PointKey< int > pixel
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
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:546
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
#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:394
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:374
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:420
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:378
std::shared_ptr< afw::image::Image< float > > createImage(lsst::geom::Box2I const &bbox) const
Create image of polygon.
Definition Polygon.cc:462
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:440
std::vector< std::shared_ptr< Polygon > > intersection(Polygon const &other) const
Returns the intersection of two polygons.
Definition Polygon.cc:386
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:426
std::shared_ptr< typehandling::Storable > cloneStorable() const override
Create a new Polygon that is a copy of this one.
Definition Polygon.cc:609
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:414
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:613
std::vector< std::shared_ptr< Polygon > > union_(Polygon const &other) const
Returns the union of two polygons.
Definition Polygon.cc:400
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:406
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
Definition Polygon.cc:594
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:596
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:619
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
CatalogIterator< typename Internal::const_iterator > const_iterator
Definition Catalog.h:111
reference front() const
Return the first record.
Definition Catalog.h:457
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)
DOXYGEN_IGNORE std::ostream & operator<<(std::ostream &os, Polygon const &poly)
Stream polygon.
Definition Polygon.cc:176
CatalogT< BaseRecord > BaseCatalog
Definition fwd.h:72
Low-level polynomials (including special polynomials) in C++.
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