4 #include "boost/geometry/geometry.hpp"
5 #include <boost/container_hash/hash.hpp>
22 using BoostBox = boost::geometry::model::box<LsstPoint>;
40 using type = cs::cartesian;
43 struct dimension<
LsstPoint> : boost::mpl::int_<2> {};
44 template <std::
size_t dim>
117 for (
size_t i = 1; i < num; ++i) {
126 boost::geometry::intersection(
poly,
pixel, overlap);
128 for (
auto const &i : overlap) {
129 double const polyArea = boost::geometry::area(i);
137 int const xStart,
int const xStop,
int const y) {
140 x <= xStop; ++i, ++
x) {
141 *i = pixelOverlap(
poly,
x,
y);
160 for (
size_t i = 0; i < num - 1; ++i) {
169 return os <<
"BoostPolygon(" <<
poly.outer() <<
")";
180 boost::geometry::assign(
poly, box);
195 template <
class PolyT>
197 return !boost::geometry::disjoint(
poly, other);
200 template <
class PolyT>
203 template <
class PolyT>
206 template <
class PolyT>
209 template <
class PolyT>
212 template <
class PolyT>
222 for (
auto const &boostPolygon : boostPolygons) {
229 template <
class PolyT>
232 boost::geometry::intersection(
poly, other, result);
233 if (result.
size() == 0) {
236 if (result.
size() > 1) {
239 (boost::format(
"Multiple polygons (%d) created by intersection()") % result.
size()).str());
244 template <
class PolyT>
247 boost::geometry::intersection(
poly, other, boostResult);
248 return convertBoostPolygons(boostResult);
251 template <
class PolyT>
254 boost::geometry::union_(
poly, other, result);
255 if (result.
size() != 1) {
258 (boost::format(
"Multiple polygons (%d) created by union_()") % result.
size()).str());
263 template <
class PolyT>
266 boost::geometry::union_(
poly, other, boostResult);
267 return convertBoostPolygons(boostResult);
270 template <
class PolyT>
273 boost::geometry::sym_difference(
poly, other, boostResult);
274 return convertBoostPolygons(boostResult);
290 auto corners =
transform.applyForward(boxToCorners(box));
291 boost::geometry::assign(_impl->poly, corners);
298 for (
auto & corner : corners) {
301 boost::geometry::assign(_impl->poly, corners);
307 return boost::geometry::num_points(_impl->poly) - 1;
311 return boostBoxToLsst(boost::geometry::return_envelope<BoostBox>(_impl->poly));
315 return boost::geometry::return_centroid<LsstPoint>(_impl->poly);
338 return _impl->poly.outer().end() - 1;
342 return boost::geometry::equals(_impl->poly, other._impl->poly);
348 static boost::hash<BoostPolygon::ring_type> polygonHash;
349 return polygonHash(_impl->poly.outer());
359 return _impl->intersectionSingle(other._impl->poly);
363 return _impl->intersectionSingle(box);
367 return _impl->intersection(other._impl->poly);
371 return _impl->intersection(box);
375 return _impl->unionSingle(other._impl->poly);
381 return _impl->union_(other._impl->poly);
387 return _impl->symDifference(other._impl->poly);
391 return _impl->symDifference(box);
396 boost::geometry::simplify(_impl->poly, result,
distance);
402 boost::geometry::convex_hull(_impl->poly, hull);
414 for (
auto const &i : _impl->poly.outer()) {
424 for (
auto const &edge : edges) {
425 addSubSampledEdge(
vertices, edge.first, edge.second, num);
434 for (
auto const &edge : edges) {
435 Point const &p1 = edge.first, p2 = edge.second;
437 addSubSampledEdge(
vertices, p1, p2,
static_cast<size_t>(::ceil(dist / maxLength)));
452 for (
int y = yMin;
y <= yMax; ++
y) {
453 double const yPixelMin = (double)
y - 0.5, yPixelMax = (
double)
y + 0.5;
455 boost::geometry::assign(
458 boost::geometry::intersection(_impl->poly, row, intersections);
460 if (intersections.
size() == 1 && boost::geometry::num_points(intersections[0]) == 5) {
469 double const xCoord = i->getX(), yCoord = i->getY();
470 if (yCoord == yPixelMin) {
472 }
else if (yCoord == yPixelMax) {
479 if (!failed && top.
size() == 2 && bottom.
size() == 2) {
482 int const xMin =
std::min(top[0], bottom[0]);
483 int const xStart = ::ceil(
std::max(top[0], bottom[0])) + 1;
484 int const xStop =
std::min(top[1], bottom[1]) - 1;
485 int const xMax = ::ceil(
std::max(top[1], bottom[1]));
502 double xMinRow = xMax, xMaxRow = xMin;
504 for (
auto const &vertice :
vertices) {
505 double const x = vertice.getX();
506 if (
x < xMinRow) xMinRow =
x;
507 if (
x > xMaxRow) xMaxRow =
x;
510 pixelRowOverlap(
image, _impl->poly,
std::max(
static_cast<int>(xMinRow),
bbox.getMinX()),
511 std::min(
static_cast<int>(::ceil(xMaxRow)),
bbox.getMaxX()),
y);
524 struct PolygonSchema {
528 static PolygonSchema
const& get() {
529 static PolygonSchema instance;
534 PolygonSchema(
const PolygonSchema&) =
delete;
535 PolygonSchema&
operator=(
const PolygonSchema&) =
delete;
538 PolygonSchema(PolygonSchema&&) =
delete;
539 PolygonSchema&
operator=(PolygonSchema&&) =
delete;
544 vertices(afw::table::PointKey<double>::addFields(
schema,
"vertices",
"list of vertex points",
548 class PolygonFactory :
public table::io::PersistableFactory {
553 CatalogVector
const& catalogs)
const override {
554 static PolygonSchema
const&
keys = PolygonSchema::get();
568 std::string getPolygonPersistenceName() {
return "Polygon"; }
570 PolygonFactory registration(getPolygonPersistenceName());
577 static PolygonSchema
const&
keys = PolygonSchema::get();
581 for (
auto const &vertice :
vertices) {
583 record->set(
keys.vertices, vertice);
590 return std::make_unique<Polygon>(*
this);
595 buffer <<
"Polygon(" << this->
getVertices() <<
")";
600 return singleClassEquals(*
this, other);
table::Key< std::string > name
table::PointKey< int > pixel
#define LSST_EXCEPT(type,...)
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
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
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.
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)
std::ostream & operator<<(std::ostream &os, Polygon const &poly)
Stream polygon.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
FilterProperty & operator=(FilterProperty const &)=default
CatalogT< BaseRecord > BaseCatalog
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