lsst.afw g28e9080985+60ce4897b0
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(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
135void 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
146namespace lsst {
147namespace afw {
148
149template std::shared_ptr<geom::polygon::Polygon> table::io::PersistableFacade<
150 geom::polygon::Polygon>::dynamicCast(std::shared_ptr<table::io::Persistable> const&);
151
152namespace geom {
153namespace 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 }
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
228template <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
243template <class PolyT>
245 std::vector<BoostPolygon> boostResult;
246 boost::geometry::intersection(poly, other, boostResult);
247 return convertBoostPolygons(boostResult);
248}
249
250template <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
262template <class PolyT>
264 std::vector<BoostPolygon> boostResult;
265 boost::geometry::union_(poly, other, boostResult);
266 return convertBoostPolygons(boostResult);
267}
268
269template <class PolyT>
271 std::vector<BoostPolygon> boostResult;
272 boost::geometry::sym_difference(poly, other, boostResult);
273 return convertBoostPolygons(boostResult);
274}
275
276Polygon::Polygon(Polygon const&) = default;
277Polygon::Polygon(Polygon&&) = default;
278Polygon& Polygon::operator=(Polygon const&) = default;
280
281Polygon::~Polygon() = default;
282
283Polygon::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
304size_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
317double Polygon::calculateArea() const { return boost::geometry::area(_impl->poly); }
318
319double 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
332std::vector<LsstPoint> Polygon::getVertices() const { return _impl->poly.outer(); }
333
334std::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
340bool 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
351bool Polygon::contains(LsstPoint const& point) const { return boost::geometry::within(point, _impl->poly); }
352
353bool Polygon::overlaps(Polygon const& other) const { return _impl->overlaps(other._impl->poly); }
354
355bool 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
377std::shared_ptr<Polygon> Polygon::unionSingle(Box const& box) const { return _impl->unionSingle(box); }
378
380 return _impl->union_(other._impl->poly);
381}
382
383std::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
394 BoostPolygon result;
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 */
521namespace {
522
523struct 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
540private:
541 PolygonSchema()
542 : schema(),
543 vertices(afw::table::PointKey<double>::addFields(schema, "vertices", "list of vertex points",
544 "")) {}
545};
546
547class PolygonFactory : public table::io::PersistableFactory {
548public:
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 }
562 std::shared_ptr<Polygon> result(new Polygon(vertices));
563 return result;
564 }
565};
566
567std::string getPolygonPersistenceName() { return "Polygon"; }
568
569PolygonFactory registration(getPolygonPersistenceName());
570
571} // anonymous namespace
572
573std::string Polygon::getPersistenceName() const { return getPolygonPersistenceName(); }
574
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
598bool 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
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,...)
afw::table::Key< afw::table::Array< ImagePixelT > > image
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
Definition: Persistable.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: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
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
double getMaxY() const noexcept
Point2D const getMax() const noexcept
double getMaxX() const noexcept
double getMinY() const noexcept
Point2D const getMin() const noexcept
double getMinX() const noexcept
double distanceSquared(PointBase< T, N > const &other) const noexcept(Super::IS_ELEMENT_NOTHROW_COPYABLE)
T emplace_back(T... args)
T end(T... args)
T max(T... args)
T min(T... args)
def iter(self)
def keys(self)
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
A base class for image defects.
T push_back(T... args)
T reserve(T... args)
T size(T... args)
T sort(T... args)
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