Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defined a geometry for polyhedron #789

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
36 changes: 36 additions & 0 deletions example/08_polyhedralsurface_example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Polyhedral surface example

#include <iostream>
#include <boost/geometry/geometry.hpp>

int main()
{
using namespace boost::geometry;
using point_t = model::point<double, 3, cs::cartesian>;
using ring_t = model::ring<point_t>;
using polyhedral_t = model::polyhedral_surface<ring_t>;

// intializing an empty polyhedral surface (deafault constructor)
polyhedral_t polyhedral2;

// creating a polyhderal surface using standard initiallized list
polyhedral_t polyhedral1 = {{{0,0,0}, {0, 1, 0}, {1, 1, 0}, {1, 0, 0}, {0, 0, 0}}, {{0, 0, 0}, {0, 1, 0}, {0, 1, 1}, {0, 0, 1}, {0, 0, 0}},
{{0, 0, 0}, {1, 0, 0}, {1, 0, 1}, {0, 0, 1}, {0, 0, 0}}, {{1, 1, 1}, {1, 0, 1}, {0, 0, 1}, {0, 1, 1}, {1, 1, 1}}, {{1, 1, 1}, {1, 0, 1}, {1, 0, 0}, {1, 1, 0}, {1, 1, 1}},
{{1, 1, 1}, {1, 1, 0}, {0, 1, 0}, {0, 1, 1}, {1, 1, 1}}};

// modifying a polyhedral surface
polyhedral1[0][1] = {1, 1, 1};

// read polyhedral surface wkt
read_wkt("POLYHEDRALSURFACE(((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),((0 0 0, 0 1 0, 0 1 1, 0 0 1, 0 0 0)),((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),((1 1 1, 1 0 1, 0 0 1, 0 1 1, 1 1 1)),((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1)))", polyhedral2);

// write polyhedral surface wkt
std::cout << wkt(polyhedral1) << std::endl;

std::cout << wkt(polyhedral2) << std::endl;

// clear polyhedral surface
clear(polyhedral1);
}
1 change: 1 addition & 0 deletions example/Jamfile
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ exe 06_a_transformation_example : 06_a_transformation_example.cpp ;
exe 06_b_transformation_example : 06_b_transformation_example.cpp ;
exe 07_a_graph_route_example : 07_a_graph_route_example.cpp ;
exe 07_b_graph_route_example : 07_b_graph_route_example.cpp ;
exe 08_polyhedralsurface_example : 08_polyhedralsurface_example.cpp ;

exe c01_custom_point_example : c01_custom_point_example.cpp ;
exe c02_custom_box_example : c02_custom_box_example.cpp ;
17 changes: 17 additions & 0 deletions include/boost/geometry/algorithms/clear.hpp
Original file line number Diff line number Diff line change
@@ -73,6 +73,18 @@ struct polygon_clear
}
};

template <typename Polyhedral_surface>
struct polyhedral_surface_clear
{
static inline void apply(Polyhedral_surface& polyhedral_surface)
{
traits::clear
<
typename std::remove_reference<Polyhedral_surface>::type
>::apply(polyhedral_surface);
}
};

template <typename Geometry>
struct no_action
{
@@ -123,6 +135,11 @@ struct clear<Geometry, ring_tag>
: detail::clear::collection_clear<Geometry>
{};

// Clear for Polyhedral surface
template <typename Geometry>
struct clear<Geometry, polyhedral_surface_tag>
: detail::clear::polyhedral_surface_clear<Geometry>
{};

// Polygon can (indirectly) use std for clear
template <typename Polygon>
6 changes: 6 additions & 0 deletions include/boost/geometry/core/point_type.hpp
Original file line number Diff line number Diff line change
@@ -92,6 +92,12 @@ struct point_type<ring_tag, Ring>
typedef typename boost::range_value<Ring>::type type;
};

// Specialization for PolyhedralSurface: the point-type is the point-type of its poly_ring_type
template <typename PolyhedralSurface>
struct point_type<polyhedral_surface_tag, PolyhedralSurface>
{
using type = typename point_type<ring_tag, typename ring_type<polyhedral_surface_tag, PolyhedralSurface>::type>::type;
};

// Specialization for polygon: the point-type is the point-type of its rings
template <typename Polygon>
19 changes: 18 additions & 1 deletion include/boost/geometry/core/ring_type.hpp
Original file line number Diff line number Diff line change
@@ -23,7 +23,6 @@
#include <type_traits>

#include <boost/range/value_type.hpp>

#include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -61,6 +60,13 @@ struct ring_mutable_type
Geometry);
};

template <typename Geometry>
struct poly_ring_type
{
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
"Not implemented for this Geometry type.",
Geometry);
};

} // namespace traits

@@ -87,6 +93,11 @@ struct ring_return_type<ring_tag, Ring>
typedef Ring& type;
};

template <typename PolyhedralSurface>
struct ring_return_type<polyhedral_surface_tag, PolyhedralSurface>
{
using type = typename traits::poly_ring_type<PolyhedralSurface>::type;
};

template <typename Polygon>
struct ring_return_type<polygon_tag, Polygon>
@@ -145,6 +156,12 @@ struct ring_type<ring_tag, Ring>
typedef Ring type;
};

template <typename PolyhedralSurface>
struct ring_type<polyhedral_surface_tag, PolyhedralSurface>
{
using type = typename std::remove_reference<typename ring_return_type<polyhedral_surface_tag, PolyhedralSurface>::type>::type;
};


template <typename Polygon>
struct ring_type<polygon_tag, Polygon>
3 changes: 3 additions & 0 deletions include/boost/geometry/core/tags.hpp
Original file line number Diff line number Diff line change
@@ -105,6 +105,9 @@ struct box_tag : single_tag, areal_tag {};
/// Convenience segment (2-points) identifying tag
struct segment_tag : single_tag, linear_tag {};

/// OGC Polyhedral surface identifying tag
struct polyhedral_surface_tag : single_tag, volumetric_tag {};


/// OGC Multi point identifying tag
struct multi_point_tag : multi_tag, pointlike_tag {};
11 changes: 10 additions & 1 deletion include/boost/geometry/geometries/concepts/check.hpp
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@
#include <boost/geometry/geometries/concepts/polygon_concept.hpp>
#include <boost/geometry/geometries/concepts/ring_concept.hpp>
#include <boost/geometry/geometries/concepts/segment_concept.hpp>

#include <boost/geometry/geometries/concepts/polyhedral_surface_concept.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>

namespace boost { namespace geometry
@@ -121,6 +121,15 @@ struct check<Geometry, polygon_tag, false>
: detail::concept_check::check<concepts::Polygon<Geometry> >
{};

template <typename Geometry>
struct check<Geometry, polyhedral_surface_tag, false>
: detail::concept_check::check<concepts::PolyhedralSurface<Geometry>>
{};

template <typename Geometry>
struct check<Geometry, polyhedral_surface_tag, true>
: detail::concept_check::check<concepts::ConstPolyhedralSurface<Geometry>>
{};

template <typename Geometry>
struct check<Geometry, box_tag, true>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POLYHEDRALSURFACE_HPP
#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POLYHEDRALSURFACE_HPP

#include <boost/concept_check.hpp>
#include <boost/range/concepts.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/geometries/concepts/ring_concept.hpp>

namespace boost { namespace geometry { namespace concepts
{

template <typename Geometry>
class PolyhedralSurface
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
using ring_type = typename ring_type<Geometry>::type;

BOOST_CONCEPT_ASSERT( (concepts::Ring<ring_type>) );
public:

BOOST_CONCEPT_USAGE(PolyhedralSurface)
{
}
#endif
};

// polyhedral surface(constant version)
template <typename Geometry>
class ConstPolyhedralSurface
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
using const_polyhedral_type = typename std::remove_const<Geometry>::type;
using ring_type = typename ring_type<const_polyhedral_type>::type;

BOOST_CONCEPT_ASSERT( (concepts::ConstRing<ring_type>) );

public:

BOOST_CONCEPT_USAGE(ConstPolyhedralSurface)
{
}

#endif
};

}}} // namespace boost::geometry::concepts
#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_POLYHEDRALSURFACE_HPP
1 change: 1 addition & 0 deletions include/boost/geometry/geometries/geometries.hpp
Original file line number Diff line number Diff line change
@@ -29,5 +29,6 @@
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/ring.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/geometries/polyhedral_surface.hpp>

#endif // BOOST_GEOMETRY_GEOMETRIES_HPP
104 changes: 104 additions & 0 deletions include/boost/geometry/geometries/polyhedral_surface.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#ifndef BOOST_GEOMETRY_GEOMETRIES_POLYHEDRALSURFACE_HPP
#define BOOST_GEOMETRY_GEOMETRIES_POLYHEDRALSURFACE_HPP

#include <memory>
#include <vector>
#include <boost/concept/assert.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/geometries/ring.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#include <initializer_list>
#endif

namespace boost { namespace geometry
{
namespace model
{

template
<
typename Ring,
template<typename, typename> class Container = std::vector,
template<typename> class Allocator = std::allocator

>
class polyhedral_surface : public Container<Ring, Allocator<Ring> >
{
BOOST_CONCEPT_ASSERT( (concepts::Ring<Ring>) );

public :

using point_type = model::point<double, 3, boost::geometry::cs::cartesian>;
using ring_type = ring<point_type, true, true>;
using ph = Container<ring_type, Allocator<ring_type> >;

#ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST

/// \constructor_default{polyhedron}
inline polyhedral_surface()
: ph()
{}

/// \constructor_initialized_list{polyhedron}
inline polyhedral_surface(std::initializer_list<ring_type> l)
: ph(l.begin(), l.end())
{}

#endif

};
} // namespace model

#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
namespace traits
{

template
<
typename Ring,
template<typename, typename> class Container,
template<typename> class Allocator
>
struct tag
<
model::polyhedral_surface
<
Ring,
Container, Allocator
>
>
{
using type = polyhedral_surface_tag;
};

template
<
typename Ring,
template<typename, typename> class Container,
template<typename> class Allocator
>
struct poly_ring_type
<
model::polyhedral_surface
<
Ring,
Container, Allocator
>
>
{
using type = typename model::polyhedral_surface
<
Ring,
Container, Allocator
>::ring_type&;
};

} // namespace traits
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS

}} // namespace boost::geometry

#endif
5 changes: 5 additions & 0 deletions include/boost/geometry/io/wkt/detail/prefix.hpp
Original file line number Diff line number Diff line change
@@ -42,6 +42,11 @@ struct prefix_linestring
static inline const char* apply() { return "LINESTRING"; }
};

struct prefix_polyhedral_surface
{
static inline const char* apply() { return "POLYHEDRALSURFACE"; }
};

struct prefix_multipoint
{
static inline const char* apply() { return "MULTIPOINT"; }
45 changes: 45 additions & 0 deletions include/boost/geometry/io/wkt/read.hpp
Original file line number Diff line number Diff line change
@@ -453,6 +453,42 @@ struct polygon_parser
}
};

template<typename PolyhedralSurface>
struct polyhderal_surface_parser
{
using ring_return_type = typename ring_return_type<PolyhedralSurface>::type;
using appender = container_appender<ring_return_type>;

static inline void apply(tokenizer::iterator& it,
tokenizer::iterator const& end,
std::string const& wkt,
PolyhedralSurface& Poly)
{
handle_open_parenthesis(it, end, wkt);
while(it != end && *it != ")")
{
handle_open_parenthesis(it, end, wkt);

typename ring_type<PolyhedralSurface>::type ring;

appender::apply(it, end, wkt, ring);
traits::push_back
<
typename std::remove_reference<PolyhedralSurface>::type
>::apply(Poly, ring);

handle_close_parenthesis(it, end, wkt);
if(it!=end && *it == ",")
{
//skip "," after ring is parsed
++it;
}

}
handle_close_parenthesis(it, end, wkt);
}
};


inline bool one_of(tokenizer::iterator const& it,
std::string const& value,
@@ -844,6 +880,15 @@ struct read_wkt<polygon_tag, Geometry>
>
{};

template <typename Geometry>
struct read_wkt<polyhedral_surface_tag, Geometry>
: detail::wkt::geometry_parser
<
Geometry,
detail::wkt::polyhderal_surface_parser,
detail::wkt::prefix_polyhedral_surface
>
{};

template <typename MultiGeometry>
struct read_wkt<multi_point_tag, MultiGeometry>
37 changes: 37 additions & 0 deletions include/boost/geometry/io/wkt/write.hpp
Original file line number Diff line number Diff line change
@@ -235,6 +235,34 @@ struct wkt_poly

};

template <typename Polyhedral_surface, typename PrefixPolicy>
struct wkt_polyhedral
{
template <typename Char, typename Traits>
static inline void apply(std::basic_ostream<Char, Traits>& os,
Polyhedral_surface const& polyhedral, bool force_closure)
{
using const_polyhedral_type = typename std::remove_const<Polyhedral_surface>::type;
using ring = typename ring_type<const_polyhedral_type>::type;

os << PrefixPolicy::apply();

os << "(";
for(auto it = boost::begin(polyhedral); it != boost::end(polyhedral); ++it)
{
if(it != boost::begin(polyhedral))
{
os << ",";
}
os << "(";

wkt_sequence<ring>::apply(os, *it, force_closure);
os << ")";
}
os << ")";
}
};

template <typename Multi, typename StreamPolicy, typename PrefixPolicy>
struct wkt_multi
{
@@ -409,6 +437,15 @@ struct wkt<Polygon, polygon_tag>
>
{};

template <typename Polyhedral_surface>
struct wkt<Polyhedral_surface, polyhedral_surface_tag>
: detail::wkt::wkt_polyhedral
<
Polyhedral_surface,
detail::wkt::prefix_polyhedral_surface
>
{};

template <typename Multi>
struct wkt<Multi, multi_point_tag>
: detail::wkt::wkt_multi