4#include "boost/geometry/geometry.hpp"
5#include <boost/container_hash/hash.hpp>
21using BoostBox = boost::geometry::model::box<LsstPoint>;
39 using type = cs::cartesian;
42struct dimension<
LsstPoint> : boost::mpl::int_<2> {};
43template <std::
size_t dim>
116 for (
size_t i = 1; i < num; ++i) {
130 boost::geometry::intersection(
poly,
pixel, overlap);
132 for (
auto const &i : overlap) {
133 double const polyArea = boost::geometry::area(i);
141 int const xStart,
int const xStop,
int const y) {
144 x <= xStop; ++i, ++
x) {
145 *i = pixelOverlap(
poly,
x,
y);
164 for (
size_t i = 0; i < num - 1; ++i) {
173 return os <<
"BoostPolygon(" <<
poly.outer() <<
")";
184 boost::geometry::assign(
poly, box);
199 template <
class PolyT>
201 return !boost::geometry::disjoint(
poly, other);
204 template <
class PolyT>
207 template <
class PolyT>
210 template <
class PolyT>
213 template <
class PolyT>
216 template <
class PolyT>
226 for (
auto const &boostPolygon : boostPolygons) {
233template <
class PolyT>
236 boost::geometry::intersection(
poly, other,
result);
243 (
boost::format(
"Multiple polygons (%d) created by intersection()") %
result.size()).str());
248template <
class PolyT>
251 boost::geometry::intersection(
poly, other, boostResult);
252 return convertBoostPolygons(boostResult);
255template <
class PolyT>
267template <
class PolyT>
270 boost::geometry::union_(
poly, other, boostResult);
271 return convertBoostPolygons(boostResult);
274template <
class PolyT>
277 boost::geometry::sym_difference(
poly, other, boostResult);
278 return convertBoostPolygons(boostResult);
294 auto corners =
transform.applyForward(boxToCorners(box));
295 boost::geometry::assign(_impl->poly, corners);
302 for (
auto & corner : corners) {
305 boost::geometry::assign(_impl->poly, corners);
311 return boost::geometry::num_points(_impl->poly) - 1;
315 return boostBoxToLsst(boost::geometry::return_envelope<BoostBox>(_impl->poly));
319 return boost::geometry::return_centroid<LsstPoint>(_impl->poly);
342 return _impl->poly.outer().end() - 1;
346 return boost::geometry::equals(_impl->poly, other._impl->poly);
352 static boost::hash<BoostPolygon::ring_type> polygonHash;
353 return polygonHash(_impl->poly.outer());
363 return _impl->intersectionSingle(other._impl->poly);
367 return _impl->intersectionSingle(box);
371 return _impl->intersection(other._impl->poly);
375 return _impl->intersection(box);
379 return _impl->unionSingle(other._impl->poly);
385 return _impl->union_(other._impl->poly);
391 return _impl->symDifference(other._impl->poly);
395 return _impl->symDifference(box);
406 boost::geometry::convex_hull(_impl->poly, hull);
418 for (
auto const &i : _impl->poly.outer()) {
428 for (
auto const &edge : edges) {
429 addSubSampledEdge(
vertices, edge.first, edge.second, num);
438 for (
auto const &edge : edges) {
439 Point const &p1 = edge.first, p2 = edge.second;
441 addSubSampledEdge(
vertices, p1, p2,
static_cast<size_t>(::
ceil(dist / maxLength)));
456 for (
int y = yMin;
y <= yMax; ++
y) {
457 double const yPixelMin = (
double)
y - 0.5, yPixelMax = (
double)
y + 0.5;
459 boost::geometry::assign(
462 boost::geometry::intersection(_impl->poly,
row, intersections);
464 if (intersections.
size() == 1 && boost::geometry::num_points(intersections[0]) == 5) {
473 double const xCoord = i->getX(), yCoord = i->getY();
474 if (yCoord == yPixelMin) {
476 }
else if (yCoord == yPixelMax) {
483 if (!failed && top.
size() == 2 && bottom.
size() == 2) {
486 int const xMin =
std::min(top[0], bottom[0]);
488 int const xStop =
std::min(top[1], bottom[1]) - 1;
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;
514 pixelRowOverlap(
image, _impl->poly,
std::max(
static_cast<int>(xMinRow),
bbox.getMinX()),
528struct PolygonSchema {
532 static PolygonSchema
const& get() {
533 static PolygonSchema instance;
538 PolygonSchema(
const PolygonSchema&) =
delete;
539 PolygonSchema& operator=(
const PolygonSchema&) =
delete;
542 PolygonSchema(PolygonSchema&&) =
delete;
543 PolygonSchema& operator=(PolygonSchema&&) =
delete;
552class PolygonFactory :
public table::io::PersistableFactory {
557 CatalogVector
const& catalogs)
const override {
558 static PolygonSchema
const&
keys = PolygonSchema::get();
572std::string getPolygonPersistenceName() {
return "Polygon"; }
574PolygonFactory registration(getPolygonPersistenceName());
581 static PolygonSchema
const&
keys = PolygonSchema::get();
585 for (
auto const &vertice :
vertices) {
587 record->set(
keys.vertices, vertice);
594 return std::make_unique<Polygon>(*
this);
599 buffer <<
"Polygon(" << this->
getVertices() <<
")";
604 return singleClassEquals(*
this, other);
table::Key< std::string > name
table::PointKey< int > pixel
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
lsst::afw::geom::polygon::Polygon::Box LsstBox
boost::geometry::model::linestring< LsstPoint > BoostLineString
afw::table::PointKey< double > vertices
afw::table::Schema schema
lsst::afw::geom::polygon::Polygon::Point LsstPoint
boost::geometry::model::box< LsstPoint > BoostBox
boost::geometry::model::polygon< LsstPoint > BoostPolygon
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
lsst::geom::Point2D Point
std::shared_ptr< Polygon > unionSingle(Polygon const &other) const
Returns the union of two polygons.
std::vector< Point >::const_iterator begin() const
Iterator for vertices.
bool overlaps(Polygon const &other) const
Returns whether the polygons overlap each other.
Box getBBox() const
Return bounding box.
std::shared_ptr< Polygon > convexHull() const
Produce a polygon from the convex hull.
std::vector< std::pair< Point, Point > > getEdges() const
Get vector of edges.
std::shared_ptr< Polygon > intersectionSingle(Polygon const &other) const
Returns the intersection of two polygons.
std::shared_ptr< afw::image::Image< float > > createImage(lsst::geom::Box2I const &bbox) const
Create image of polygon.
Polygon(Box const &box)
Construct a rectangular Polygon whose vertices are the corners of a box.
std::shared_ptr< Polygon > subSample(size_t num) const
Sub-sample each edge.
std::vector< std::shared_ptr< Polygon > > intersection(Polygon const &other) const
Returns the intersection of two polygons.
Point calculateCenter() const
size_t getNumEdges() const
Return number of edges.
std::shared_ptr< Polygon > transform(TransformPoint2ToPoint2 const &transform) const
Transform the polygon.
double calculateArea() const
std::shared_ptr< typehandling::Storable > cloneStorable() const override
Create a new Polygon that is a copy of this one.
std::vector< Point > getVertices() const
Get vector of vertices.
std::shared_ptr< Polygon > simplify(double const distance) const
Return a simplified polygon.
bool operator==(Polygon const &other) const
std::string toString() const override
Create a string representation of this object.
std::vector< std::shared_ptr< Polygon > > union_(Polygon const &other) const
Returns the union of two polygons.
std::size_t hash_value() const noexcept override
Return a hash of this object.
std::vector< std::shared_ptr< Polygon > > symDifference(Polygon const &other) const
Return the symmetric difference of two polygons.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
bool contains(Point const &point) const
Returns whether the polygon contains the point.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
Polygon & operator=(Polygon const &)
std::vector< Point >::const_iterator end() const
bool equals(typehandling::Storable const &other) const noexcept override
Compare this object to another Storable.
double calculatePerimeter() const
An exception that indicates the single-polygon assumption has been violated.
typename _view_t::x_iterator x_iterator
An iterator for traversing the pixels in a row.
A class to represent a 2-dimensional array of pixels.
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
CatalogIterator< typename Internal::const_iterator > const_iterator
reference front() const
Return the first record.
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.
A floating-point coordinate rectangle geometry.
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
An integer coordinate rectangle.
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.
T emplace_back(T... args)
std::ostream & operator<<(std::ostream &os, Polygon const &poly)
Stream polygon.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
CatalogT< BaseRecord > BaseCatalog
Low-level polynomials (including special polynomials) in C++.
Extent< int, N > ceil(Extent< double, N > const &input) noexcept
Return the component-wise ceil (round towards more positive).
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
A base class for image defects.
static void set(LsstPoint &p, LsstPoint::Element const &value)
static double get(LsstPoint const &p)
static double get(LsstBox const &box)
static double get(LsstBox const &box)
static double get(LsstBox const &box)
static double get(LsstBox const &box)
static std::vector< std::shared_ptr< Polygon > > convertBoostPolygons(std::vector< BoostPolygon > const &boostPolygons)
Impl(BoostPolygon const &_poly)
std::vector< std::shared_ptr< Polygon > > symDifference(PolyT const &other) const
Impl(Polygon::Box const &box)
bool overlaps(PolyT const &other) const
std::shared_ptr< Polygon > intersectionSingle(PolyT const &other) const
std::vector< std::shared_ptr< Polygon > > union_(PolyT const &other) const
std::shared_ptr< Polygon > unionSingle(PolyT const &other) const
std::vector< std::shared_ptr< Polygon > > intersection(PolyT const &other) const
Impl(std::vector< LsstPoint > const &vertices)
std::shared_ptr< table::io::Persistable > read(table::io::InputArchive const &archive, table::io::CatalogVector const &catalogs) const override