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) {
117 vertices.push_back(first + delta * 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() <<
")";
177 os <<
poly.toString();
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>
262 (boost::format(
"Multiple polygons (%d) created by union_()") %
result.size()).str());
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) {
303 corner = transform(corner);
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);
330 for (std::vector<LsstPoint>::const_iterator i =
vertices.begin(), j =
vertices.begin() + 1;
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());
360 for (
Point const & p : points) {
416 boost::geometry::simplify(_impl->
poly,
result, distance);
422 boost::geometry::convex_hull(_impl->
poly, hull);
427 auto newVertices = transform.applyForward(
getVertices());
434 for (
auto const &i : _impl->
poly.outer()) {
444 for (
auto const &edge : edges) {
445 addSubSampledEdge(
vertices, edge.first, edge.second, num);
454 for (
auto const &edge : edges) {
455 Point const &p1 = edge.first, p2 = edge.second;
457 addSubSampledEdge(
vertices, p1, p2,
static_cast<size_t>(::ceil(dist / maxLength)));
472 for (
int y = yMin;
y <= yMax; ++
y) {
473 double const yPixelMin = (double)
y - 0.5, yPixelMax = (
double)
y + 0.5;
475 boost::geometry::assign(
478 boost::geometry::intersection(_impl->
poly,
row, intersections);
480 if (intersections.
size() == 1 && boost::geometry::num_points(intersections[0]) == 5) {
487 for (std::vector<Point>::const_iterator i =
row.outer().begin(); i !=
row.outer().end() - 1;
489 double const xCoord = i->getX(), yCoord = i->getY();
490 if (yCoord == yPixelMin) {
492 }
else if (yCoord == yPixelMax) {
499 if (!failed && top.
size() == 2 && bottom.
size() == 2) {
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]));
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;
531 std::min(
static_cast<int>(::ceil(xMaxRow)),
bbox.getMaxX()),
y);
544struct PolygonSchema {
545 afw::table::Schema schema;
548 static PolygonSchema
const& get() {
549 static PolygonSchema instance;
554 PolygonSchema(
const PolygonSchema&) =
delete;
555 PolygonSchema& operator=(
const PolygonSchema&) =
delete;
558 PolygonSchema(PolygonSchema&&) =
delete;
559 PolygonSchema& operator=(PolygonSchema&&) =
delete;
564 vertices(
afw::table::PointKey<double>::addFields(schema,
"vertices",
"list of vertex points",
568class PolygonFactory :
public table::io::PersistableFactory {
570 explicit PolygonFactory(
std::string const& name) : table::io::PersistableFactory(name) {}
573 CatalogVector
const& catalogs)
const override {
574 static PolygonSchema
const&
keys = PolygonSchema::get();
588std::string getPolygonPersistenceName() {
return "Polygon"; }
590PolygonFactory registration(getPolygonPersistenceName());
597 static PolygonSchema
const& keys = PolygonSchema::get();
601 for (
auto const &vertice :
vertices) {
603 record->set(keys.vertices, vertice);
610 return std::make_unique<Polygon>(*
this);
615 buffer <<
"Polygon(" << this->
getVertices() <<
")";
620 return singleClassEquals(*
this, other);
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
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.
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)
DOXYGEN_IGNORE std::ostream & operator<<(std::ostream &os, Polygon const &poly)
Stream polygon.
CatalogT< BaseRecord > BaseCatalog
Low-level polynomials (including special polynomials) in C++.
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