$include_dir="/home/hyper-archives/geometry/include"; include("$include_dir/msg-header.inc") ?>
Subject: [ggl] Adding support for Curves (and other custom geometry types)
From: Mats Taraldsvik (mats.taraldsvik)
Date: 2011-07-20 15:51:42
Barend,
Fortunately, a simple implementation wasn't that difficult to do.
http://pastebin.com/bQ0Mg5Jd ## circularstring_def.h ## (the definition 
of the circularstring, reusing linestring)
cheers,
Mats
### circularstring_def.h ###
#ifndef CIRCULARSTRING_DEF_H_INCLUDED
#define CIRCULARSTRING_DEF_H_INCLUDED
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/mutable_range.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <memory>
#include <vector>
#include <boost/concept/assert.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/domains/gis/io/wkt/write_wkt.hpp>
namespace boost
{
     namespace geometry
     {
         /// Circularstring identifying tag
         struct circularstring_tag : single_tag {};
//        namespace concept
//
//        {
//            template <typename Geometry>
//            class Circularstring
//            {
//            #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
//                typedef typename point_type<Geometry>::type point_type;
//
//                BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
//                BOOST_CONCEPT_ASSERT( 
(boost::RandomAccessRangeConcept<Geometry>) );
//
//            public :
//
//                BOOST_CONCEPT_USAGE(Circularstring)
//                {
//                    Geometry* ls = 0;
//                    traits::clear<Geometry>::apply(*ls);
//                    traits::resize<Geometry>::apply(*ls, 0);
//                    point_type* point = 0;
//                    traits::push_back<Geometry>::apply(*ls, *point);
//                }
//            #endif
//            };
//        }
         namespace model
         {
             template
<
                 typename Point,
                 template<typename,typename> class Container = std::vector,
                 template<typename> class Allocator = std::allocator
 >
             class circularstring : public Container<Point, 
Allocator<Point> >
             {
                 BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
                 typedef Container<Point, Allocator<Point> > base_type;
             public :
                 /// \constructor_default{circularstring}
                 inline circularstring()
                     : base_type()
                 {}
                 /// \constructor_begin_end{circularstring}
                 template <typename Iterator>
                 inline circularstring(Iterator begin, Iterator end)
                     : base_type(begin, end)
                 {}
             };
         } // namespace model
         #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
         namespace traits
         {
             template
<
                 typename Point,
                 template<typename,typename> class Container,
                 template<typename> class Allocator
 >
             struct tag<model::circularstring<Point, Container, Allocator> >
             {
                 typedef circularstring_tag type;
             };
         } // namespace traits
         #endif
         #ifndef DOXYGEN_NO_DETAIL
         namespace detail
         {
             namespace wkt
             {
                 struct prefix_circularstring_par
                 {
                     static inline const char* apply() { return 
"CIRCULARSTRING("; }
                 };
             }
         } // namespace detail
         #endif
         #ifndef DOXYGEN_NO_DISPATCH
         namespace dispatch
         {
             template <typename Linestring>
             struct wkt<circularstring_tag, Linestring>
                 : detail::wkt::wkt_range
<
                         Linestring,
                         detail::wkt::prefix_circularstring_par,
                         detail::wkt::closing_parenthesis
 >
             {};
         } // namespace dispatch
         #endif
     } //namespace geometry
} // namespace boost
#endif // CIRCULARSTRING_DEF_H_INCLUDED
## END ##
> Hi Mats,
>
> >/  I'm very interested in using Boost.Geometry in my project, as it looks
> />/  like a better fit than GEOS.
> />/
> />/  In GEOS I need to extract the geometry from my internal geometry
> />/  object/class, and create new geos::geom::Geometry objects, while
> />/  Boost.Geometry -- if I have read the docs correctly -- allows me to
> />/  define my internal geometry object as Boost.Geometry compatible (with
> />/  BOOST_GEOMETRY_REGISTER_*), and get all of the Boost.Geometry
> />/  functionality "for free" directly against my internal geometry
> />/  objects/classes, thus eliminating the additional object I have to
> />/  create with GEOS. Is this correct?
> />/
> /
> Yes, this is correct.
>
>
> >/  In addition to the existing Geometry models in Boost.Geometry, I need
> />/  support for Curves (CIRCULARSTRINGs in PostGIS [1]), which are
> />/  basically a start, end and middle point (PostGIS takes care of
> />/  calculating the actual arc).
> />/
> />/  At the moment, I only need support for writing the Curve to EWKT (a
> />/  PostGIS extension to WKT. Currently, EWKT is a superset of WKT.).
> />/  Could you give me pointers on how to achieve this (i.e. defining a
> />/  Curve Geometry model, and extending the io.wkt module to add some EWKT
> />/  features)?
> />/
> /
> That is not trivial. But it should be doable. We do not yet support
> curves indeed. We do have circles and spheres but they are moved to an
> extension, because we first want to concentrate on linear features. And
> in that extension, WKT is not supported.
>
> What you would need to do to support it (more or less the official way):
> 1) define a tag (e.g. "circularstring_tag"), comparable to linestring_tag
> 2) create a concept (so for circular string it would probably be similar
> to a linestring). A concept is a set of traits classes, plus a concept
> checking class
> 3) create a model, or adapt your existing geometries to this concept
> 4) in write_wkt.hpp, add a dispatch for the tag, and implement the WKT
> writing.
>
> You might postpone a step (e.g. the concept checking class). Anyway,
> because it is more or less comparable to a linestring implementation,
> you can look how these steps are done there.
>
> I'm interested in the results!
>
> Regards, Barend
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/ggl/attachments/20110720/584bd2e6/attachment.html