|
Geometry : |
Subject: [ggl] RE: A few Boost.Geometry questions
From: Bruno Lalande (bruno.lalande)
Date: 2010-09-24 08:40:11
> Anyone else that may be able to answer my previous questions?
Hi Bill,
Sorry for such a late reply, I'll try to address your pending questions.
1/ Documentation => you're right, since the requirements of a
Boost.Range are not likely to change much, it might make sense to
summarize them within the Boost.Geometry documentation. Alternatively,
we could point directly to the Boost.Range doc
(http://www.boost.org/doc/libs/1_44_0/libs/range/doc/html/index.html).
Also it might make sense to try to specify a more precise Range
concept the passed type must follow : Single Pass Range, Forward
Range, Bidirectional Range, Random Access Range.
As you can see in the Boost.Range doc (section "Range Concepts")
adapting a type to the Range concept is not exactly about adding
methods to it, but more generally making a precise set of expressions
valid. If you take for example the Single Pass Range, what the
documentation says in the "Valid Expressions" section is basically
that there must exist an overload of boost::begin() for your range
type, and it must return an iterator to the beginning of your range.
2/ About multiple geometries => I don't see any mean to handle that
out-of-the-box (no compile-time equivalent to GEOMETRYCOLLECTION), but
you should be able to obtain what you want by using Boost.Variant. As
mentioned by Luke earlier, geometry types in Boost.Geometry are
defined at compile-time. As such, you have to find a way to constitute
a heterogeneous set of gometries, that is something that can contain
instances of different types. That's exactly what Boost.Variant is
made for. Once you've created the wrappers around your multiple
geometry type (for instance MyLineString and MyPolygon) you can create
a boost::variant<MyLineString, MyPolygon>, which is an object that can
either be one or the other of those types. Then, you will define a
static visitor as described in the Boost.Variant tutorial (see
http://www.boost.org/doc/libs/1_43_0/doc/html/variant/tutorial.html)
for each of the algorithms you want to use. This static visitor has
the responsibility of dispatching to the right overload of the
algorithm, depending on the actual type of the geometry (reminder =>
all this occurs at compile-time).
Just one note about inheritence/wrapping. I'm under the impression
that none of them is actually necessary. All we want is to get several
distinct types out of your unique type, in order to transform your
runtime world into our compile-time world. As such, simple typedefs
sound entirely sufficient to me:
typedef GeometryPath MyLineString;
typedef GeometryPath MyPolygon;
Then, adapt MyLineString to the LineString concept, MyPolygon to the
Polygon concept, etc... And always instanciate a MyLineString or a
MyPolygon instead of a GeometryPath, so that all the compile-time
mechanisms Boost.Geometry relies on can do their job. Am I missing
something?
3/ Z-value => I'm not sure to understand the issue here. What you seem
to need is adapting a 3D point (which is actually a 2D point with an
additional coordinate that you don't want to take into account in the
algorithms you call) to a 2D point. This is possible, you will simply
be discarding your Z-value when adapting your point. For instance if
your Point3D class has .x .y .z attributes, just adapting it the way
you mentioned above should do:
BOOST_GEOMETRY_REGISTER_POINT_2D(Point3D, Float, cs::geographic<degree>, x, y)
The library "believes" that your point is only a 2D points and just
ignores the rest. But maybe I've misunderstood your need?
Sorry for such long explanations, hope they're not too unclear. Please
tell me if you need more precise guidelines about the solutions
proposed here, or if they're not adapted to what you need.
Thanks
Bruno
Geometry list run by mateusz at loskot.net