// Boost.Geometry (aka GGL, Generic Geometry Library) // // Copyright (c) 2010 Barend Gehrels, Amsterdam, the Netherlands. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Experiment using Proto to construct geometries #include #include #include #include #include #include #include #include #include #include namespace bg = boost::geometry; namespace proto = boost::proto; using proto::_; struct proto_geometry_tag {}; // Add a coordinate to a ring or linestring struct append_point : proto::callable { template struct result; template struct result : boost::add_reference {}; template Geometry& operator()(Geometry& geometry, T1 const& x, T2 const& y) const { typedef typename boost::geometry::point_type::type point; point p; boost::geometry::set<0>(p, x); boost::geometry::set<1>(p, y); geometry.push_back(p); return geometry; } }; // The grammar for valid geometry expressions, // and a transform that populates the geometry struct geometry_grammar : proto::or_ < proto::when < proto::function < proto::terminal , proto::terminal > , proto::terminal > > , append_point ( proto::_data , proto::_value(proto::_child1) , proto::_value(proto::_child2) ) > , proto::when < proto::function < geometry_grammar , proto::terminal > , proto::terminal > > , append_point ( geometry_grammar(proto::_child0) , proto::_value(proto::_child1) , proto::_value(proto::_child2) ) > > {}; template struct proto_geometry_expression; struct proto_geometry_domain : proto::domain, geometry_grammar> {}; // An expression wrapper that provides a conversion to a // ring, that uses the geometry_grammar template struct proto_geometry_expression { BOOST_PROTO_BASIC_EXTENDS(Expr, proto_geometry_expression, proto_geometry_domain) BOOST_PROTO_EXTENDS_FUNCTION() template operator T () const { BOOST_MPL_ASSERT((proto::matches)); T geometry; return geometry_grammar()(*this, 0, geometry); } // NOT finished, need more knowledge about Proto template inline T inner() const { BOOST_MPL_ASSERT((proto::matches)); T geometry; return geometry_grammar()(*this, 0, geometry); } inline void inner() { } }; int main() { proto_geometry_expression::type> const geometry_of = {{{}}}; // Initialize a ring: typedef bg::model::ring > ring_type; ring_type ring = geometry_of(16, 1)(15,2)(14, 3)(13,4)(12, 3.14)(1,6); std::cout << bg::wkt(ring) << std::endl; // Initialize a line typedef bg::model::linestring > line_type; line_type line = geometry_of(1, 1)(2, 2)(3, 3); std::cout << bg::wkt(line) << std::endl; // For Polygon (not finished) it should be something like: typedef bg::model::polygon > polygon_type; //polygon_type polygon = geometry_of(0, 0)(0, 10)(10, 10)(10, 0)(0, 0).inner(2, 2)(2, 5)(5, 5)(5, 2)(2, 2); //std::cout << bg::wkt(polygon) << std::endl; return 0; }