[ Disclaimer: This is a crosspost; a similar question has been posted on
stackoverflow.com: <http://stackoverflow.com/questions/27767656/howtoregisteraboostgeometrydistancestrategyforogrpointandogrlinestrin> ] Hello list! I am a firsttime user of Boost.Geometry. My goal is to use Boost.Geometry's rtree implementation with OGRGeometry instances [0]. To that end, I've adapted the necessary OGR classes (OGRPoint, OGRLineString, OGRLinearRing and OGRPolygon) to Boost.Geometry's model. Iterating, etc. works good. However, the current version of Boost.Geometry has no support for different map projections, which is why I'm forced to stick with OGRGeometry in general. Also, the existing codebase makes heavy use of the OGR* interfaces. What I am looking for is to use Boost.Geometry's tag/dispatch feature to call OGRGeometry::Distance() whenever I (or rtree) uses bg::distance(), OGRGeometry::Crosses() when bg::crosses() is used, and so an. Basically, the Boost.Geometry predicates are then nothing more than wrappers around the corresponding OGR* counterparts. I've begun with bg::distance for OGRPoint to OGRPoint, and it worked. However, I'm stuck with bg::distance(OGRPoint &, OGRLineString &), with a compile error. My guess is that it stems from Boost.Geometry's concept of a linestring, which is nothing more than an ordered collection of points. Is there any kind of template specialisation I can use so that a call to bg::distance(OGRGeometry const&, OGRGeometry const&) is dispatched to OGRGeometry::Distance(...)? What follows is the template instanciation that makes me believe that my dispatching does not work due to a Boost.Geometry linestring being a collection of points, the full error message, and my current code: %< struct boost::geometry::strategy::distance::services::default_strategy< boost::geometry::point_tag, boost::geometry::segment_tag, OGRPoint, // NOTE: Twice OGRPoint! OGRPoint, MyCode::OGRCoordinateSystemTag, MyCode::OGRCoordinateSystemTag, void> >% The full error message is: >% In file included from /usr/include/boost/geometry/strategies/strategies.hpp:30:0, from /usr/include/boost/geometry/geometry.hpp:43, from /usr/include/boost/geometry.hpp:17, from ../../../winzent/test/simulation/OGRLineStringAdapterTest.cpp:7: /usr/include/boost/geometry/strategies/distance.hpp: In instantiation of 'struct boost::geometry::strategy::distance::services::default_strategy<boost::geometry::point_tag, boost::geometry::segment_tag, OGRPoint, OGRPoint, Winzent::Simulation::boost::OGRCoordinateSystemTag, Winzent::Simulation::boost::OGRCoordinateSystemTag, void>': /usr/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp:57:8: required from 'struct boost::geometry::detail::distance::default_strategy<OGRPoint, OGRLineString, boost::geometry::pointlike_tag, boost::geometry::linestring_tag, false>' /usr/include/boost/geometry/algorithms/detail/distance/default_strategies.hpp:73:8: required from 'struct boost::geometry::detail::distance::default_strategy<OGRLineString, OGRPoint, boost::geometry::linestring_tag, boost::geometry::pointlike_tag, true>' /usr/include/boost/geometry/strategies/distance_result.hpp:60:8: required from 'struct boost::geometry::resolve_strategy::distance_result<OGRLineString, OGRPoint, boost::geometry::default_strategy>' /usr/include/boost/geometry/strategies/distance_result.hpp:79:8: required from 'struct boost::geometry::resolve_variant::distance_result<OGRLineString, OGRPoint, boost::geometry::default_strategy>' /usr/include/boost/geometry/strategies/distance_result.hpp:199:8: required from 'struct boost::geometry::distance_result<OGRLineString, OGRPoint, boost::geometry::default_strategy>' /usr/include/boost/geometry/strategies/distance_result.hpp:205:8: required from 'struct boost::geometry::distance_result<OGRLineString, OGRPoint, void>' /usr/include/boost/geometry/strategies/default_distance_result.hpp:35:8: required from 'struct boost::geometry::default_distance_result<OGRLineString, OGRPoint>' /usr/include/boost/geometry/algorithms/detail/distance/interface.hpp:392:1: required by substitution of 'template<class Geometry1, class Geometry2> typename boost::geometry::default_distance_result<Geometry1, Geometry2>::type boost::geometry::distance(const Geometry1&, const Geometry2&) [with Geometry1 = OGRLineString; Geometry2 = OGRPoint]' ../../../winzent/test/simulation/OGRLineStringAdapterTest.cpp:71:62: required from here /usr/include/boost/geometry/strategies/distance.hpp:97:456: error: no matching function for call to 'assertion_failed(mpl_::failed************ (boost::geometry::strategy::distance::services::default_strategy<boost::geometry::point_tag, boost::geometry::segment_tag, OGRPoint, OGRPoint, Winzent::Simulation::boost::OGRCoordinateSystemTag, Winzent::Simulation::boost::OGRCoordinateSystemTag, void>::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE_COMBINATION::************) (mpl_::assert_::types<OGRPoint, OGRPoint, Winzent::Simulation::boost::OGRCoordinateSystemTag, Winzent::Simulation::boost::OGRCoordinateSystemTag>))' BOOST_MPL_ASSERT_MSG %< And this is my current attempt on a distance strategy: %< namespace boost { namespace geometry { namespace detail { namespace distance { template <> struct default_strategy< OGRPoint, OGRLineString, pointlike_tag, linestring_tag, false> { typedef OGRPointToLineStringDistanceStrategy type; }; } // namespace distance } // namespace detail } // namespace geometry } // namespace boost >% Thanks a lot in advance for any hints! Kind Regards, Eric [0] http://www.gdal.org/classOGRGeometry.html _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hi Eric,
Eric Msp Veith wrote: > [ Disclaimer: This is a crosspost; a similar question has been posted on > stackoverflow.com: <http://stackoverflow.com/questions/27767656/howtoregisteraboostgeometrydistancestrategyforogrpointandogrlinestrin> ] > > Hello list! > > I am a firsttime user of Boost.Geometry. My goal is to use Boost.Geometry's > rtree implementation with OGRGeometry instances [0]. To that end, I've adapted > the necessary OGR classes (OGRPoint, OGRLineString, OGRLinearRing and > OGRPolygon) to Boost.Geometry's model. Iterating, etc. works good. > > However, the current version of Boost.Geometry has no support for different > map projections, which is why I'm forced to stick with OGRGeometry in general. > Also, the existing codebase makes heavy use of the OGR* interfaces. > > What I am looking for is to use Boost.Geometry's tag/dispatch feature to call > OGRGeometry::Distance() whenever I (or rtree) uses bg::distance(), > OGRGeometry::Crosses() when bg::crosses() is used, and so an. Basically, the > Boost.Geometry predicates are then nothing more than wrappers around the > corresponding OGR* counterparts. > > I've begun with bg::distance for OGRPoint to OGRPoint, and it worked. However, > I'm stuck with bg::distance(OGRPoint &, OGRLineString &), with a compile > error. My guess is that it stems from Boost.Geometry's concept of a > linestring, which is nothing more than an ordered collection of points. If you have problems with this function this probably mean that you're using geographic CS. Is that right? Boost.Geometry supports Point/Point, Point/Linestring, and Point/Box distance in cartesian and spherical_equatorial. Couldn't you just switch to e.g. spherical equatorial? Btw, during any operation Boost.Geometry is not doing any projections, and probably will never do, at least in 2D. In particular the distance in a specific coordinate system (defined by the Pointtype of a geometry) is calculated (or approximated) using a method/algorithm/formula designed for this coordinate system. If the user wanted to perform some projection and then some operation for a projected geometry, that's ok. But the library will probably always try to calculate the "correct" result. This is why for example to calculate the distance between the Points the library is using or could use:  in cartesian  wellknown cartesian distance  in spherical  haversine formula or a formula derived from spherical law of cosines*  in geographic  formulas of Vincenty**, AndoyerLambert**, AndoyerLambertThomas* etc. *  currently not implemented **  planned for release in 1.58 > Is there any kind of template specialisation I can use so that a call to > bg::distance(OGRGeometry const&, OGRGeometry const&) is dispatched to > OGRGeometry::Distance(...)? Why not overload the bg::distance() directly? namespace boost { namespace geometry { template <> struct default_distance_result<OGRPoint, OGRLineString> { typedef /*some_type*/ type; }; /*some_type*/ distance(OGRPoint const& g1, OGRLineString const& g2) { // some implementation } }} And probably the same for bg::comparable_distance() and bg::default_distance_result<> since it's the function and trait used by the rtree. The rest if you have much time to spare :) TL; DR; > > What follows is the template instanciation that makes me believe that my > dispatching does not work due to a Boost.Geometry linestring being a > collection of points, the full error message, and my current code: > > > %< > struct boost::geometry::strategy::distance::services::default_strategy< > boost::geometry::point_tag, > boost::geometry::segment_tag, > OGRPoint, // NOTE: Twice OGRPoint! > OGRPoint, > MyCode::OGRCoordinateSystemTag, > MyCode::OGRCoordinateSystemTag, void> > >% https://github.com/boostorg/geometry/blob/develop/include/boost/geometry/strategies/distance.hpp line 85. Those are Point types from which the algorithm can for instance extract coordinate types. > > The full error message is: > <snip> In Boost.Geometry operations are divided into 2 parts  an algorithm and a strategy. The strategy defines some critical parts of the calculation and the algorithms knows how to use the strategies to get the result. So in order to support some combination of geometries there must be an algorithm and a strategy adapted to a concept which this algorithm can use. E.g. distance(Point, Point) requires a strategy calculating the distance between 2 points, obviously. But in the case of distance(Point, Linestring) it requires a strategy calculating the distance between a Point and a Segment, not Point and Linestring. It's because the strategy defines only the most critical part of the calculation and the algorithm does the rest. So the default distance(Point, Linestring) algorithm knows how to use a strategy calculating the distance between a Point and a Segment. In order to support your strategy calculating the distance between a Point and a Linestring you'd be forced to implement an algorithm that knows how to use it. > And this is my current attempt on a distance strategy: > > > %< > namespace boost { > namespace geometry { > namespace detail { > namespace distance { > > > template <> > struct default_strategy< > OGRPoint, > OGRLineString, > pointlike_tag, > linestring_tag, > false> > { > typedef OGRPointToLineStringDistanceStrategy type; > }; > } // namespace distance > } // namespace detail > } // namespace geometry > } // namespace boost > >% So you could try to implement Point/Segment strategy instead for your coordinate system (geographic?), and e.g. arbitrary geometries, not only OGRPoint and OGRLineString. A distance strategy also requires a lot of various traits. See this file defining the default Point/Segment strategy for spherical_equatorial CS: https://github.com/boostorg/geometry/blob/develop/include/boost/geometry/strategies/spherical/distance_cross_track.hpp At the beginning of the file the strategies (comparable::cross_track and cross_track) are defined, and then at line 545 there are various traits which must be specialized for a distance strategy. They're for errors detaction, conversion between comparable and direct distance, etc. Then at the very end the default_strategy is specialized in line 716. Or here the same for Point/Point strategy in spherical_equatorial CS: https://github.com/boostorg/geometry/blob/develop/include/boost/geometry/strategies/spherical/distance_haversine.hpp in line 179. Those files are from develop branch, Boost1.57.0 version may be slightly different. Regards, Adam _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hi Adam,
thank you for your extensive reply! It already helped me a lot. I guess that there are actually two topics that are covered by my problem and your answer. First, the simple question of how to overwrite bg::distance() with OGRGeometry::Distance, and second, the underlying question of why the results of bg::distance() and OGRGeometry::Distance actually differ. Since my data source is a PostGIS database, and PostGIS relies on GEOS just as OGR does, I'll go for the lowhangig fruit first before diving deeper into the actual problem, if that's OK with you. I've tried overloading bg::distance(), and tried to overload it for all instances of OGRGeometry's derived classes. OGRPoint is derived from OGRGeometry, OGRLineString, too, and all the over ones (OGRPolygon, OGRLinearRing, ...) the same. C++11 templates are not (yet) my league, so I've run into problems using enable_if<> and is_base_of<>. What I tried is the following: %< namespace boost { namespace geometry { template <> struct default_distance_result<OGRGeometry, OGRGeometry> { typedef qreal type; }; template < typename Geometry1, typename Geometry2, typename std::enable_if< std::is_base_of<OGRGeometry, Geometry1>::value and std::is_base_of< OGRGeometry, Geometry2>::value, int>::type = 0> inline typename default_distance_result<Geometry1, Geometry2>::value distance(Geometry1 const &geometry1, Geometry2 const &geometry2) { return geometry1.Distance(&geometry2); } } } >% Replacing the specialization's parameters with, e.g. <OGRPoint, OGRLineString> does what I want, but it also means I need to create a specialized struct for every possible combination of OGRGeometryderived classes, i.e., <OGRLineString, OGRPoint>, <OGRLineString, OGRPolygon>, <OGRPolygon, OGRLineString>, and so on. Do you know a more general way of doing it for all of OGR's geometry classes? Now to the deeperlying root cause: On Thursday 08 January 2015, 19:08:56, Adam Wulkiewicz wrote: > If you have problems with this function this probably mean that you're > using geographic CS. Is that right? Yes, that is right. > Boost.Geometry supports Point/Point, Point/Linestring, and Point/Box > distance in cartesian and spherical_equatorial. Couldn't you just switch > to e.g. spherical equatorial? I've tried using different coordinate systems, because adapting the OGRGeometry classes to Boost's range concept was not that hard. To make things easier to explain, I've set up a github.com repository that contains the adapter code at <https://github.com/eveith/ogrboostadapter>. Perhaps there's just an error hidden somewhere in my adapter code. ;) However, I'm presented with different results for OGRGeometry::Distance() and bg::distance(). For example, consider the following geometries: ST_GeomFromText('LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)', 4326), ST_GeomFromText('LINESTRING(15.0 15.0, 16.0 16.0)', 4326) ST_GEomFromText('POINT(15.0 15.0)', 4326) For this, the database gives: %< db=# SELECT ST_Distance( ST_GeomFromText('LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)', 4326), ST_GeomFromText('POINT(15.0 15.0)', 4326)); st_distance  15.556349186104 db=# SELECT ST_Distance( ST_GeomFromText('LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)', 4326), ST_GeomFromText('LINESTRING(15.0 15.0, 16.0 16.0)', 4326)); st_distance  15.556349186104 >% The 15.556... is of course the same result OGR gives me, since both PostGIS and OGR use GEOS. Using cs::cartesian yields 16.9706 on bg::distance for the very same geometries. When using cs::geographic, 0.294082 is returned. I'm at loss for an explanation why. That was the point where I decided to just use OGRGeometry::Distance. Since I'm not under time pressure (and relatively new to anything GIS), I'd like to learn about the backgrounds and hope to come up with an actually useable wrapper for OGRGeometry/GEOS classes, using Boost.Geometry's facilities the right way  just resorting to template specialization seems like a bad hack to me. :) > Btw, during any operation Boost.Geometry is not doing any projections, > and probably will never do, at least in 2D. In particular the distance > in a specific coordinate system (defined by the Pointtype of a > geometry) is calculated (or approximated) using a > method/algorithm/formula designed for this coordinate system. If the > user wanted to perform some projection and then some operation for a > projected geometry, that's ok. But the library will probably always try > to calculate the "correct" result. This is why for example to calculate > the distance between the Points the library is using or could use: >  in cartesian  wellknown cartesian distance >  in spherical  haversine formula or a formula derived from spherical > law of cosines* >  in geographic  formulas of Vincenty**, AndoyerLambert**, > AndoyerLambertThomas* etc. > > *  currently not implemented > **  planned for release in 1.58 Perhaps I'm mistaken, but the obvious conclusion seems to be that as long as I use the same projection for all geometries I apply predicates to, e.g. force WGS84 for all geometries, and choose the right algorithm, I'm on the safe side? At least that's how I always understood it. From what I could find out, GEOS uses the Discrete Hausdorff Distance algorithm? But that doesn't make much sense, given that the Hausdorff Distance is the longest distance one has to travel to a Geometry G1 if a point P is chosen on another Geometry G0. But again, I lack the knowledge to be sure and am most probably mistaken. > The rest if you have much time to spare :) Yes, I have. :) > Everything is ok here, see. e.g. > https://github.com/boostorg/geometry/blob/develop/include/boost/geometry/str > ategies/distance.hpp line 85. > Those are Point types from which the algorithm can for instance extract > coordinate types. Like boost::model::point? > In Boost.Geometry operations are divided into 2 parts  an algorithm and > a strategy. The strategy defines some critical parts of the calculation > and the algorithms knows how to use the strategies to get the result. I'm sorry, I cannot wrap my head around it. The AndoyerLambert formula, for example, would be part of ... the strategy? I.e., the algorithm is bg::distance() and the strategy is chosen according to the actual geometries and the coordinate system, arriving at, for example, the Pythagoras strategy for cs::cartesian or the haversine strategy for cs::geographic? > So in order to support some combination of geometries there must be an > algorithm and a strategy adapted to a concept which this algorithm can use. > > E.g. distance(Point, Point) requires a strategy calculating the distance > between 2 points, obviously. But in the case of distance(Point, > Linestring) it requires a strategy calculating the distance between a > Point and a Segment, not Point and Linestring. It's because the strategy > defines only the most critical part of the calculation and the algorithm > does the rest. > > So the default distance(Point, Linestring) algorithm knows how to use a > strategy calculating the distance between a Point and a Segment. > In order to support your strategy calculating the distance between a > Point and a Linestring you'd be forced to implement an algorithm that > knows how to use it. So, in order to use OGRLineString::Distance(OGRPoint const&), I'd have to implement my own bg::distance()? If so, that sounds like "back to square one, specialize that template"? > So you could try to implement Point/Segment strategy instead for your > coordinate system (geographic?), and e.g. arbitrary geometries, not only > OGRPoint and OGRLineString. Yes, geographic. But from that paragraph I fear I got the idea of strategy/algorithm wrong. :( Thank you very much for the help and the background info. I currently try to understand why there are different distance algorithms and when they are employed. If you can suggest sources to read up on this, I'll happily consume them. Thanks!  Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hi Eric,
Eric Msp Veith wrote: > Hi Adam, > > thank you for your extensive reply! It already helped me a lot. > > I guess that there are actually two topics that are covered by my problem and > your answer. First, the simple question of how to overwrite bg::distance() > with OGRGeometry::Distance, and second, the underlying question of why the > results of bg::distance() and OGRGeometry::Distance actually differ. > > Since my data source is a PostGIS database, and PostGIS relies on GEOS just as > OGR does, I'll go for the lowhangig fruit first before diving deeper into the > actual problem, if that's OK with you. > > I've tried overloading bg::distance(), and tried to overload it for all > instances of OGRGeometry's derived classes. OGRPoint is derived from > OGRGeometry, OGRLineString, too, and all the over ones (OGRPolygon, > OGRLinearRing, ...) the same. > > C++11 templates are not (yet) my league, so I've run into problems using > enable_if<> and is_base_of<>. What I tried is the following: > > %< > > namespace boost { > namespace geometry { > > template <> > struct default_distance_result<OGRGeometry, OGRGeometry> > { > typedef qreal type; > }; > > > template < > typename Geometry1, > typename Geometry2, > typename std::enable_if< > std::is_base_of<OGRGeometry, Geometry1>::value > and std::is_base_of< > OGRGeometry, > Geometry2>::value, int>::type = 0> > inline typename default_distance_result<Geometry1, Geometry2>::value > distance(Geometry1 const &geometry1, Geometry2 const &geometry2) > { > return geometry1.Distance(&geometry2); > } > } > } > > >% It looks good. Well, your default_distance_result<> specialization wouldn't be instantiated since it's specialized for base type. But it probably isn't needed really, the default one should probably work. It creates the type the distance taking into account coordinate types of both geometries. The function overload looks ok, if you can use C++11 function default template parameters. In C++98 you could use Boost.Core (enable_if), Boost.MPL (and_), Boost.TypeTraits (is_base_of) and implement a return type as enable_if<...>::type. Anyway, the problem is that it's ambiguous since there are 2 overloads of bg::distance(), both taking 2 arbitrary types, the original and yours. So this can't be done this way or at least I don't have any idea. > Replacing the specialization's parameters with, e.g. <OGRPoint, OGRLineString> > does what I want, but it also means I need to create a specialized struct for > every possible combination of OGRGeometryderived classes, i.e., > <OGRLineString, OGRPoint>, <OGRLineString, OGRPolygon>, <OGRPolygon, > OGRLineString>, and so on. > > Do you know a more general way of doing it for all of OGR's geometry classes? I could think about some hacks but you'd be forced to mess with the internals of the library so I'd discourage that. You could implement some convenient macro and then use it like this: DEFINE_DISTANCE(OGRPoint,OGRPoint) DEFINE_DISTANCE(OGRPoint,OGRLinestring) DEFINE_DISTANCE(OGRPoint,OGRBox) /*...*/ > Now to the deeperlying root cause: > > On Thursday 08 January 2015, 19:08:56, Adam Wulkiewicz wrote: >> If you have problems with this function this probably mean that you're >> using geographic CS. Is that right? > Yes, that is right. >> Boost.Geometry supports Point/Point, Point/Linestring, and Point/Box >> distance in cartesian and spherical_equatorial. Couldn't you just switch >> to e.g. spherical equatorial? > I've tried using different coordinate systems, because adapting the > OGRGeometry classes to Boost's range concept was not that hard. To make things > easier to explain, I've set up a github.com repository that contains the > adapter code at <https://github.com/eveith/ogrboostadapter>. Perhaps there's > just an error hidden somewhere in my adapter code. ;) Well, I see now that you've defined your own coordinate system tag. In this case you should support it by implementation of a set of strategies and maybe more. In general, it's playing with the internals of the library which is something that a user shouldn't do. But if you're interested below is more information about the strategies and how algorithms use them. > However, I'm presented with different results for OGRGeometry::Distance() and > bg::distance(). > > For example, consider the following geometries: > > ST_GeomFromText('LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)', > 4326), > ST_GeomFromText('LINESTRING(15.0 15.0, 16.0 16.0)', 4326) > ST_GEomFromText('POINT(15.0 15.0)', 4326) > > For this, the database gives: > > %< > > db=# SELECT ST_Distance( > ST_GeomFromText('LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)', > 4326), > ST_GeomFromText('POINT(15.0 15.0)', 4326)); > > st_distance >  > 15.556349186104 (Below BG means Boost.Geometry) In BG, using cartesian CS, the result is 15.556349186104 so the same. AFAIR if you're using PostGIS like in your example all calculations are done using cartesian CS. Instead of ST_GeomFromText you could try to use ST_GeogFromText (http://postgis.net/docs/ST_GeogFromText.html). But in this case you should notice that the functionality is limited. Furthermore, I'm not sure if it's possible to calculate distances (or perform other operations) in other coordinate systems than cartesian in GEOS. I'd guess that they probably support SRIDs somehow (store?), but besides that all calculations are done in cartesian. Note that GEOS =/= PostGIS, AFAIR in PostGIS there are additional things implemented. Some time ago I checked PostGIS code and I found some functions for the Point/Point distance calculation in geographic CS, maybe there are other like Point/Segment but I didn't see them. It's possible that they calculate the closest distance between the Points of geometries, not the "true"/"correct" one. You could easily check it defining some very long segment and a Point very close to it somewhere near the middle. In BG, in spherical_equatorial<degree> the result is 0.26942677292131906 [radians] for a unit sphere, or 1716517.97 [meters] for spherical Earth with radius 6371000 [meters]. To get the distance in meters you may multiply the resulting radians by the radius or pass the strategy explicitly into the distance() function specifying the radius. FYI, in 1.57, distance(Point, Linestring) or even distance(Point, Point) doesn't compile for geographic CS. However in develop branch (probably 1.58) the distance(POINT(4, 4), POINT(15, 15)) does compile and the result is 1712939.35 meters for WGS84 ellipsoid. Currently by default AndoyerLambert formula is used. If Vincenty strategy is passed explicitly, the result is 1712955.94 meters. You can verify the results e.g. using this form: http://www.ga.gov.au/geodesy/datums/vincenty_direct.jsp > db=# SELECT ST_Distance( > ST_GeomFromText('LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)', > 4326), > ST_GeomFromText('LINESTRING(15.0 15.0, 16.0 16.0)', 4326)); > st_distance >  > 15.556349186104 > > >% > > The 15.556... is of course the same result OGR gives me, since both PostGIS > and OGR use GEOS. And Boost.Geometry returns the same distances as the ones mentioned above. However distance(Linestring, Linestring) doesn't compile for spherical_equatorial in 1.57 but it compiles in develop so probably expect the same in 1.58. > > Using cs::cartesian yields 16.9706 on bg::distance for the very same > geometries. When using cs::geographic, 0.294082 is returned. I'm at loss for > an explanation why. That was the point where I decided to just use > OGRGeometry::Distance. Since I'm not under time pressure (and relatively new > to anything GIS), I'd like to learn about the backgrounds and hope to come up > with an actually useable wrapper for OGRGeometry/GEOS classes, using > Boost.Geometry's facilities the right way  just resorting to template > specialization seems like a bad hack to me. :) So I guess the answer is already above. First you should probably check if you really need this workadound. The right way would be to properly implement missing elements in Boost.Geometry :) What bothers me is why your results are slightly different than mine. Do you get the same for the following program? #include <iostream> #include <boost/geometry.hpp> #include <boost/geometry/geometries/geometries.hpp> #include <boost/geometry/io/wkt/wkt.hpp> namespace bg = boost::geometry; namespace bgi = boost::geometry::index; int main() { typedef bg::model::point<double, 2, bg::cs::cartesian> point; typedef bg::model::linestring<point> linestring; point pt; linestring ls, ls2; bg::read_wkt("LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)", ls); bg::read_wkt("POINT(15.0 15.0)", pt); bg::read_wkt("LINESTRING(15.0 15.0, 16.0 16.0)", ls2); std::cout << std::setprecision(24) << bg::distance(pt, ls) << std::endl; std::cout << std::setprecision(24) << bg::distance(ls, ls2) << std::endl; } >> Btw, during any operation Boost.Geometry is not doing any projections, >> and probably will never do, at least in 2D. In particular the distance >> in a specific coordinate system (defined by the Pointtype of a >> geometry) is calculated (or approximated) using a >> method/algorithm/formula designed for this coordinate system. If the >> user wanted to perform some projection and then some operation for a >> projected geometry, that's ok. But the library will probably always try >> to calculate the "correct" result. This is why for example to calculate >> the distance between the Points the library is using or could use: >>  in cartesian  wellknown cartesian distance >>  in spherical  haversine formula or a formula derived from spherical >> law of cosines* >>  in geographic  formulas of Vincenty**, AndoyerLambert**, >> AndoyerLambertThomas* etc. >> >> *  currently not implemented >> **  planned for release in 1.58 > Perhaps I'm mistaken, but the obvious conclusion seems to be that as long as I > use the same projection for all geometries I apply predicates to, e.g. force > WGS84 for all geometries, and choose the right algorithm, I'm on the safe > side? At least that's how I always understood it. Yes, as long as one coordinate system is used and the distances calculated for various geometries are compatible you should be safe. You probably shouldn't mix 2 libraries calculating similar things in a different way, e.g. Boost.Geometry using one formula for Point/Point and GEOS/GDAL/XXX for Point/Linestring calculating the distance differently, e.g. using different formula or using cartesian CS, etc. I'm not sure how this library does it. I'm guessing that if you used GEOS/GDAL/XXX for all distance calculations the rtree should work properly, probably... I can't really guarantee anything. Furthermore assuming that this library uses cartesian CS (I'm not sure) it really doesn't have sense to replace Boost.Geometry. So this probably needs some testing. If you plan to perform them could you please share the results? > >From what I could find out, GEOS uses the Discrete Hausdorff Distance > algorithm? But that doesn't make much sense, given that the Hausdorff Distance > is the longest distance one has to travel to a Geometry G1 if a point P is > chosen on another Geometry G0. But again, I lack the knowledge to be sure and > am most probably mistaken. It's a different algorithm, it measures how two geometries are similar to each other. >> The rest if you have much time to spare :) > Yes, I have. :) Ok :) > >> Everything is ok here, see. e.g. >> https://github.com/boostorg/geometry/blob/develop/include/boost/geometry/str >> ategies/distance.hpp line 85. >> Those are Point types from which the algorithm can for instance extract >> coordinate types. > Like boost::model::point? This, or OGRPoint, every type adapted to the Point concept. In Boost.Geometry a Point bound with some geometry like Linestring or Polygon defines the coordinate type, dimension and coordinate system. This Point can be retrieved from a Geometry by bg::point_type<Geometry>::type internally using bg::traits::point_type<> specialized by you when you were adapting your legacy geometries to Boost.Geometry Concepts. > >> In Boost.Geometry operations are divided into 2 parts  an algorithm and >> a strategy. The strategy defines some critical parts of the calculation >> and the algorithms knows how to use the strategies to get the result. > I'm sorry, I cannot wrap my head around it. The AndoyerLambert formula, for > example, would be part of ... the strategy? I.e., the algorithm is > bg::distance() and the strategy is chosen according to the actual geometries > and the coordinate system, arriving at, for example, the Pythagoras strategy > for cs::cartesian or the haversine strategy for cs::geographic? Yes, the AndoyerLambert formula is a part of a Strategy. This particular Strategy defines how a distance between 2 points is calculated in geographic CS. The algorithm is the distance(), but internally there are many versions of it, dispatched for various pairs of input Geometries, by using the tags of those Geometries. Each dispatched version requires some specific kind of strategy. For instance, algorithm dispatched for Point/Point or MultiPoint/MultiPoint requires PointPoint Strategy. It knows how to use only this kind of Strategy. For example, Point/Point version calls the strategy once for a pair of Points. MultiPoint/MultiPoint version could for instance check all possible pairs of Points and return the smallest distance found (this is just an example, actually different algorithm is used since this'd have complexity O(N^2)). Version for Point/Linestring or Point/Polygon requires Point/Segment strategy. The former checks all segments in a Linestring, the latter checks the exterior ring and all interior rings, etc. For the algorithm it doesn't matter what is the coordinate system, the required operation is defined in the Strategy. > >> So in order to support some combination of geometries there must be an >> algorithm and a strategy adapted to a concept which this algorithm can use. >> >> E.g. distance(Point, Point) requires a strategy calculating the distance >> between 2 points, obviously. But in the case of distance(Point, >> Linestring) it requires a strategy calculating the distance between a >> Point and a Segment, not Point and Linestring. It's because the strategy >> defines only the most critical part of the calculation and the algorithm >> does the rest. >> >> So the default distance(Point, Linestring) algorithm knows how to use a >> strategy calculating the distance between a Point and a Segment. >> In order to support your strategy calculating the distance between a >> Point and a Linestring you'd be forced to implement an algorithm that >> knows how to use it. > So, in order to use OGRLineString::Distance(OGRPoint const&), I'd have to > implement my own bg::distance()? If so, that sounds like "back to square one, > specialize that template"? what you planned to do. Of course this'd be needed assuming that using cartesian or spherical_equatorial CS wouldn't be enough. >> So you could try to implement Point/Segment strategy instead for your >> coordinate system (geographic?), and e.g. arbitrary geometries, not only >> OGRPoint and OGRLineString. > Yes, geographic. But from that paragraph I fear I got the idea of > strategy/algorithm wrong. :( > > Thank you very much for the help and the background info. I currently try to > understand why there are different distance algorithms and when they are > employed. If you can suggest sources to read up on this, I'll happily consume > them. > Sorry, I should be more clear before. I already described above what a strategy and algorithm is. So what an already implemented algorithm (e.g. distance(Point, Point) or distance(Point, Linestring)) needs is a Strategy defined for some coordinate system. E.g. to support distance(PointLike, PointLike) the Point/Point strategy is required (this is already done in develop for geographic CS as mentioned above). To support distance(PointLike, LinearOrAreal) we'd need a strategy calculating the distance between a Point and a Segment on ellipsoid. This would be required to support all combinations like Point/Linestring, Point/Polygon, MultiPoint/MultiPolygon etc. to calculate the "true" distance. Well, actually we'd need more things but that's another story. Regards, Adam _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hi Adam,
On Sunday 11 January 2015 03:47:01, Adam Wulkiewicz <[hidden email]> wrote: > [...] > > You could implement some convenient macro and then use it like this: > > DEFINE_DISTANCE(OGRPoint,OGRPoint) > DEFINE_DISTANCE(OGRPoint,OGRLinestring) > DEFINE_DISTANCE(OGRPoint,OGRBox) all right; good to know that there's a lastresort hackedyhack possible. > Well, I see now that you've defined your own coordinate system tag. [...] Yes, that was because I wanted to ensure that none of the BG strategies was used, because I though the deviation comes from different formulae being used. That's, of course, neither a problem of BG nor OGR, because I assume that both libraries implement their corresponding formulae correctly  I just needed consistency between the two. However, I fear that neither Boost nor OGR are to blame, but simply my very own code, because with your test code, I get the correct result. > What bothers me is why your results are slightly different than mine. Do > you get the same for the following program? > > #include <iostream> > > #include <boost/geometry.hpp> > #include <boost/geometry/geometries/geometries.hpp> > #include <boost/geometry/io/wkt/wkt.hpp> > > namespace bg = boost::geometry; > namespace bgi = boost::geometry::index; > > int main() > { > typedef bg::model::point<double, 2, bg::cs::cartesian> point; > typedef bg::model::linestring<point> linestring; > > point pt; > linestring ls, ls2; > > bg::read_wkt("LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 > 4.0)", ls); > bg::read_wkt("POINT(15.0 15.0)", pt); > bg::read_wkt("LINESTRING(15.0 15.0, 16.0 16.0)", ls2); > > std::cout << std::setprecision(24) << bg::distance(pt, ls) << > std::endl; > std::cout << std::setprecision(24) << bg::distance(ls, ls2) << > std::endl; > } [eveith@basileia:~/tmp/boosttest]% ./bgtest 15.5563491861040450459086 15.5563491861040450459086 Exactly what I was looking for. So I cut all the custom CS/strategy stuff I implemented over the last few days and went back to cs::cartesian. This is my current testcase: >% OGRGeometry *ls3 = nullptr, *p2 = nullptr; char wktLS[] = "LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)"; char wktP[] = "POINT(15.0 15.0)"; char *wktLSp = static_cast<char *>(wktLS); char *wktPp = static_cast<char *>(wktP); OGRGeometryFactory::createFromWkt(&wktLSp, sref, &ls3); OGRGeometryFactory::createFromWkt(&wktPp, sref, &p2); QCOMPARE( bg::distance( *(dynamic_cast<OGRPoint *>(p2)), *(dynamic_cast<OGRLineString *>(ls3))), ls3>Distance(p2)); >% The result, however, is: %< FAIL! : OGRLineStringAdapterTest::testGeometry() Compared doubles are not the same (fuzzy compare) Actual (bg::distance( *(dynamic_cast<OGRPoint *>(p2)), *(dynamic_cast<OGRLineString *>(ls3)))): 16,9706 Expected (ls3>Distance(p2)): 15,5563 >% Meh. Oh, and the distance between the two linestrings is 0.0, according to my code. > So I guess the answer is already above. First you should probably check > if you really need this workadound. > The right way would be to properly implement missing elements in > Boost.Geometry :) So, yes, it seems I've made a mistake somewhere in my adapter code, and all workarounds are unnecessary. The iterator itself seems to work, though, because I can iterate over all points on a given OGRLineString using range_begin(ls) and range_end(ls). Hope I can find my bug. Thank you for the extensive amount of background info. I really appreciate it! Have a nice sunday evening!  Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry signature.asc (853 bytes) Download Attachment 
Hi,
did I say "implementing the Iterator for OGRLineString wasn't that hard"? Well, I guess it actually is. bg::model::linestring<OGRPoint> delivers the correct results for any bg::distance() call. However, when my OGRLineString iterator_facade is being used, the wrong points are selected. In the example containing the LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0) and POINT(15.0 15.0), using my own iterator_facade meant that bg::distance always calculated the distance between the n1th point on the linestring and the single point. I.e., my iterator_facade is at fault. I don't know yet what's exactly wrong, but I'll find it! :) Thanks for all the help so far!  Eric On Sunday 11 January 2015 17:42:46, Eric MSP Veith <[hidden email]> wrote: > Hi Adam, > > On Sunday 11 January 2015 03:47:01, Adam Wulkiewicz > > <[hidden email]> wrote: > > [...] > > > > You could implement some convenient macro and then use it like this: > > > > DEFINE_DISTANCE(OGRPoint,OGRPoint) > > DEFINE_DISTANCE(OGRPoint,OGRLinestring) > > DEFINE_DISTANCE(OGRPoint,OGRBox) > > all right; good to know that there's a lastresort hackedyhack possible. > > > Well, I see now that you've defined your own coordinate system tag. [...] > > Yes, that was because I wanted to ensure that none of the BG strategies was > used, because I though the deviation comes from different formulae being > used. That's, of course, neither a problem of BG nor OGR, because I assume > that both libraries implement their corresponding formulae correctly  I > just needed consistency between the two. > > However, I fear that neither Boost nor OGR are to blame, but simply my very > own code, because with your test code, I get the correct result. > > > What bothers me is why your results are slightly different than mine. Do > > you get the same for the following program? > > > > #include <iostream> > > > > #include <boost/geometry.hpp> > > #include <boost/geometry/geometries/geometries.hpp> > > #include <boost/geometry/io/wkt/wkt.hpp> > > > > namespace bg = boost::geometry; > > namespace bgi = boost::geometry::index; > > > > int main() > > { > > > > typedef bg::model::point<double, 2, bg::cs::cartesian> point; > > typedef bg::model::linestring<point> linestring; > > > > point pt; > > linestring ls, ls2; > > > > bg::read_wkt("LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 > > > > 4.0)", ls); > > > > bg::read_wkt("POINT(15.0 15.0)", pt); > > bg::read_wkt("LINESTRING(15.0 15.0, 16.0 16.0)", ls2); > > > > std::cout << std::setprecision(24) << bg::distance(pt, ls) << > > > > std::endl; > > > > std::cout << std::setprecision(24) << bg::distance(ls, ls2) << > > > > std::endl; > > } > > This outputs: > > [eveith@basileia:~/tmp/boosttest]% ./bgtest > 15.5563491861040450459086 > 15.5563491861040450459086 > > Exactly what I was looking for. So I cut all the custom CS/strategy stuff I > implemented over the last few days and went back to cs::cartesian. This is > my current testcase: > > >% > > OGRGeometry *ls3 = nullptr, *p2 = nullptr; > char wktLS[] = "LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)"; > char wktP[] = "POINT(15.0 15.0)"; > char *wktLSp = static_cast<char *>(wktLS); > char *wktPp = static_cast<char *>(wktP); > OGRGeometryFactory::createFromWkt(&wktLSp, sref, &ls3); > OGRGeometryFactory::createFromWkt(&wktPp, sref, &p2); > > QCOMPARE( > bg::distance( > *(dynamic_cast<OGRPoint *>(p2)), > *(dynamic_cast<OGRLineString *>(ls3))), > ls3>Distance(p2)); > > >% > > The result, however, is: > > %< > > FAIL! : OGRLineStringAdapterTest::testGeometry() Compared doubles are not > the same (fuzzy compare) > Actual (bg::distance( *(dynamic_cast<OGRPoint *>(p2)), > *(dynamic_cast<OGRLineString *>(ls3)))): 16,9706 > Expected (ls3>Distance(p2)): 15,5563 > > >% > > Meh. Oh, and the distance between the two linestrings is 0.0, according to > my code. > > > So I guess the answer is already above. First you should probably check > > if you really need this workadound. > > The right way would be to properly implement missing elements in > > Boost.Geometry :) > > So, yes, it seems I've made a mistake somewhere in my adapter code, and all > workarounds are unnecessary. The iterator itself seems to work, though, > because I can iterate over all points on a given OGRLineString using > range_begin(ls) and range_end(ls). Hope I can find my bug. > > Thank you for the extensive amount of background info. I really appreciate > it! > > Have a nice sunday evening! > >  Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry signature.asc (853 bytes) Download Attachment 
Hi Eric,
Eric Msp Veith wrote: > Hi, > > did I say "implementing the Iterator for OGRLineString wasn't that hard"? > Well, I guess it actually is. > > bg::model::linestring<OGRPoint> delivers the correct results for any > bg::distance() call. However, when my OGRLineString iterator_facade is being > used, the wrong points are selected. In the example containing the > LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0) and POINT(15.0 15.0), > using my own iterator_facade meant that bg::distance always calculated the > distance between the n1th point on the linestring and the single point. > > I.e., my iterator_facade is at fault. I don't know yet what's exactly wrong, > but I'll find it! :) Good luck! > Thanks for all the help so far! No problem. Now when everything is clear and you decided to use cartesian CS. Note that the distance between geographical points calculated as if they were cartesian points will not be the "correct" one. By correctness I have in mind being in line with the definition of a geodesic, the shortest path between two points on the surface of the Earth. Depending on the points configuration and actual position on the globe for a pair of geographic coordinates treated as cartesian coordinates you will get the same or greater distance than you should if you represented the points in spherical or geographic CS. For instance, in cartesian CS the result of distance(POINT(15 15), POINT(4 4)) is 15.556349186104045, but in spherical (assuming that the coordinates are degrees) 15.43701697622119 degrees (0.26942677292131906 radians). For the spherical Earth with radius 6371000 meters the difference between those distances is around 13 kilometers. And for geographic CS the distance will be different than in the above cases. Of course this kind of error may be acceptable for you. I'm just pointing out this aspect in case you find it important/interesting. And AFAIU you must also deal with it when you're using GEOS or ST_GeomFromText in PostGIS no matter what SRID you passed. However I'm not entirely sure if this is true, feel free to proove me wrong. Regards, Adam _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hi Adam,
thanks to your help, I've finally been able to integrate OGR and Boost.Geometry. Thank you very much for your patience and explanations. They also helped me alot in understanding the underlying concepts and connected knowledge.
I'd like to give something back and thus have updated the GitHub repository where I've stored the adapter code: <https://github.com/eveith/ogrboostadapter>
Perhaps that helps somebody else in the future!
Cheers, Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry signature.asc (836 bytes) Download Attachment 
Administrator

20150121 22:38 GMT+01:00 Eric MSP Veith <[hidden email]>:
> Hi Adam, > > thanks to your help, I've finally been able to integrate OGR and > Boost.Geometry. Thank you very much for your patience and explanations. They > also helped me alot in understanding the underlying concepts and connected > knowledge. > > I'd like to give something back and thus have updated the GitHub repository > where I've stored the adapter code: > <https://github.com/eveith/ogrboostadapter> > > Perhaps that helps somebody else in the future! Eric, Sweet, thanks for sharing! Best regards,  Mateusz Loskot, http://mateusz.loskot.net _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hello list,
earlier this year I adapted the OGRGeometry subclasses to the boost.Geometry models. My adapter code is available at <https://github.com/eveith/ogrboostadapter>. Everything was done on the basis of boost 1.56.0, where tests ran successfully. I've now upgraded my Linux distribution, which also pulled boost 1.57.0. I recompiled everything, but much to my surprise, my adapter code stopped working! At first I thought the iterator code somehow had a bug lurking in it that caused the failure, but I can successfully retrieve all points on an OGRLineString without problems. However, bg::distance() between two OGRLineStrings returns 0 instead of the proper result. Is anybody aware of a change in bg::distance or Boost.Range that might cause the failure? After having checked that the iterator works forwards and backwards, I'm unsure where to begin with the debugging. Here's the test code that I use. bg::distance(OGRLineString &, OGRLineString &) always returns 0.0: %< void BoostOGRLineStringAdapterTest::testGeometryMultiLineString() { typedef bg::model::linestring<OGRPoint> boostLinestring; boostLinestring bls1, bls2; OGRLineString *ls1 = new OGRLineString(), *ls2 = new OGRLineString(), *ls3 = new OGRLineString(); auto distantPoint = new OGRPoint(15.0, 15.0); OGRSpatialReference *sref = new OGRSpatialReference(); OGRErr rc = sref>importFromEPSG(4326); QVERIFY(OGRERR_NONE == rc); ls1>assignSpatialReference(sref); ls2>assignSpatialReference(sref); ls3>assignSpatialReference(sref); distantPoint>assignSpatialReference(sref); ls1>addPoint(0.0, 0.0); ls1>addPoint(1.0, 1.0); ls1>addPoint(2.0, 2.0); ls1>addPoint(3.0, 3.0); ls1>addPoint(4.0, 4.0); bls1.push_back(OGRPoint(0.0, 0.0)); bls1.push_back(OGRPoint(1.0, 1.0)); bls1.push_back(OGRPoint(2.0, 2.0)); bls1.push_back(OGRPoint(3.0, 3.0)); bls1.push_back(OGRPoint(4.0, 4.0)); ls2>addPoint(17.0, 17.0); ls2>addPoint(21.0, 21.0); ls2>addPoint(33.0, 33.0); ls2>addPoint(76.0, 56.0); bls2.push_back(OGRPoint(17.0, 17.0)); bls2.push_back(OGRPoint(21.0, 21.0)); bls2.push_back(OGRPoint(33.0, 33.0)); bls2.push_back(OGRPoint(76.0, 56.0)); ls3>addPoint(42.0, 34.2); ls3>addPoint(72.0, 14.2); ls3>addPoint(67.0, 34.2); ls3>addPoint(82.0, 2.2); ls3>addPoint(5.0, 17.2); QCOMPARE( bg::crosses(*ls1, *distantPoint), ls1>Crosses(distantPoint)); QCOMPARE( bg::intersects(*ls1, *distantPoint), ls1>Intersects(distantPoint)); for (int i = 0; i != ls1>getNumPoints(); ++i) { auto p = new OGRPoint(); ls1>getPoint(i, p); QCOMPARE( bg::distance(*p, *distantPoint), p>Distance(distantPoint)); } QCOMPARE( bg::distance(*ls1, *distantPoint), ls1>Distance(distantPoint)); QCOMPARE( bg::distance(*ls3, *distantPoint), ls3>Distance(distantPoint)); QCOMPARE( bg::distance(*ls2, *distantPoint), ls2>Distance(distantPoint)); QCOMPARE( bg::distance(bls1, bls2), ls1>Distance(ls2)); QCOMPARE( bg::distance(bls1, bls2), bg::distance(*ls1, *ls2)); QCOMPARE( bg::distance(*ls1, *ls2), ls1>Distance(ls2)); delete sref; } >% Thanks alot in advance for any hints!  Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hello Eric.
On 21/05/2015 06:35 μμ, Eric MSP Veith wrote: > Hello list, > > earlier this year I adapted the OGRGeometry subclasses to the boost.Geometry > models. My adapter code is available at <https://github.com/eveith/ogrboostadapter>. > > Everything was done on the basis of boost 1.56.0, where tests ran > successfully. I've now upgraded my Linux distribution, which also pulled boost > 1.57.0. I recompiled everything, but much to my surprise, my adapter code > stopped working! > > At first I thought the iterator code somehow had a bug lurking in it that > caused the failure, but I can successfully retrieve all points on an > OGRLineString without problems. I cannot really tell what the problem is but there is one thing that I think needs investigation: Please make sure that you have correctly defined the specializations required by Boost.Range. It seems that you are missing the range_mutable_iterator specialization. See http://www.boost.org/doc/libs/1_58_0/libs/range/doc/html/range/reference/extending.html for the details. I do not know is this the root cause of your problem, but it seems to be that you need to have this specialization anyway. Another thing: would it be possible to also try with boost 1.58? It would be helpful to know if the problem persists there. > However, bg::distance() between two OGRLineStrings returns 0 instead of the > proper result. Is anybody aware of a change in bg::distance or Boost.Range > that might cause the failure? After having checked that the iterator works > forwards and backwards, I'm unsure where to begin with the debugging. > > Here's the test code that I use. bg::distance(OGRLineString &, OGRLineString > &) always returns 0.0: > > %< > void BoostOGRLineStringAdapterTest::testGeometryMultiLineString() > { > typedef bg::model::linestring<OGRPoint> boostLinestring; > boostLinestring bls1, bls2; > > OGRLineString *ls1 = new OGRLineString(), > *ls2 = new OGRLineString(), > *ls3 = new OGRLineString(); > auto distantPoint = new OGRPoint(15.0, 15.0); > OGRSpatialReference *sref = new OGRSpatialReference(); > > OGRErr rc = sref>importFromEPSG(4326); > QVERIFY(OGRERR_NONE == rc); > ls1>assignSpatialReference(sref); > ls2>assignSpatialReference(sref); > ls3>assignSpatialReference(sref); > distantPoint>assignSpatialReference(sref); > > ls1>addPoint(0.0, 0.0); > ls1>addPoint(1.0, 1.0); > ls1>addPoint(2.0, 2.0); > ls1>addPoint(3.0, 3.0); > ls1>addPoint(4.0, 4.0); > > bls1.push_back(OGRPoint(0.0, 0.0)); > bls1.push_back(OGRPoint(1.0, 1.0)); > bls1.push_back(OGRPoint(2.0, 2.0)); > bls1.push_back(OGRPoint(3.0, 3.0)); > bls1.push_back(OGRPoint(4.0, 4.0)); > > ls2>addPoint(17.0, 17.0); > ls2>addPoint(21.0, 21.0); > ls2>addPoint(33.0, 33.0); > ls2>addPoint(76.0, 56.0); > > bls2.push_back(OGRPoint(17.0, 17.0)); > bls2.push_back(OGRPoint(21.0, 21.0)); > bls2.push_back(OGRPoint(33.0, 33.0)); > bls2.push_back(OGRPoint(76.0, 56.0)); > > ls3>addPoint(42.0, 34.2); > ls3>addPoint(72.0, 14.2); > ls3>addPoint(67.0, 34.2); > ls3>addPoint(82.0, 2.2); > ls3>addPoint(5.0, 17.2); > > QCOMPARE( > bg::crosses(*ls1, *distantPoint), > ls1>Crosses(distantPoint)); > QCOMPARE( > bg::intersects(*ls1, *distantPoint), > ls1>Intersects(distantPoint)); > > > for (int i = 0; i != ls1>getNumPoints(); ++i) { > auto p = new OGRPoint(); > ls1>getPoint(i, p); > > QCOMPARE( > bg::distance(*p, *distantPoint), > p>Distance(distantPoint)); > } > > QCOMPARE( > bg::distance(*ls1, *distantPoint), > ls1>Distance(distantPoint)); > QCOMPARE( > bg::distance(*ls3, *distantPoint), > ls3>Distance(distantPoint)); > QCOMPARE( > bg::distance(*ls2, *distantPoint), > ls2>Distance(distantPoint)); > QCOMPARE( > bg::distance(bls1, bls2), > ls1>Distance(ls2)); > QCOMPARE( > bg::distance(bls1, bls2), > bg::distance(*ls1, *ls2)); > QCOMPARE( > bg::distance(*ls1, *ls2), > ls1>Distance(ls2)); > Which one(s) of the three tests above fail? All of them? Just the second? Please let me know of your findings. Best,  m. > delete sref; > } > >% > > Thanks alot in advance for any hints! > >  Eric > _______________________________________________ > Geometry mailing list > [hidden email] > http://lists.boost.org/mailman/listinfo.cgi/geometry _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hello Menelaos,
thanks for your reply! On Friday 22 May 2015, 08:42:58, Menelaos Karavelas wrote: > I cannot really tell what the problem is but there is one thing that I > think needs investigation: > > Please make sure that you have correctly defined the specializations > required by Boost.Range. It seems that you are missing the > range_mutable_iterator specialization. See > http://www.boost.org/doc/libs/1_58_0/libs/range/doc/html/range/reference/ext > ending.html for the details. Doesn't range_mutable_iterator mean that the return type of the iterator's dereference operator is a modifiable reference? If so, I cannot do this due to the OGRLineString's API. :/ Please correct me if I'm mistaken here; I'm by no means an expert in C++ STL conformant iterator design. > Another thing: would it be possible to also try with boost 1.58? It > would be helpful to know if the problem persists there. Just upgraded to Boost 1.58.0. I used a different machine to make sure there are no leftovers that interfer on the original machine. Same problem, sadly. > > QCOMPARE( > > > > bg::distance(bls1, bls2), > > bg::distance(*ls1, *ls2)); > > > > QCOMPARE( > > > > bg::distance(*ls1, *ls2), > > ls1>Distance(ls2)); > > Which one(s) of the three tests above fail? All of them? Just the second? These two both fail. From that I conclude that (a) the OGRPoint adapter to Boost.Geometry works, since I can successfully use bg::distance with my `typedef bg::model::linestring<OGRPoint> boostLinestring` linestring. However, the OGRLineString version uses my iterator code and fails. So the only bug that can be found here is most probably in my own iterator code. Thanks Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hello again,
On Friday 22 May 2015 10:39:41, Eric MSP Veith <[hidden email]> wrote: > > Please make sure that you have correctly defined the specializations > > required by Boost.Range. It seems that you are missing the > > range_mutable_iterator specialization. See > > http://www.boost.org/doc/libs/1_58_0/libs/range/doc/html/range/reference/e > > xt ending.html for the details. > > Doesn't range_mutable_iterator mean that the return type of the iterator's > dereference operator is a modifiable reference? If so, I cannot do this due > to the OGRLineString's API. :/ > > Please correct me if I'm mistaken here; I'm by no means an expert in C++ > STL conformant iterator design. added the following specialization to my code: namespace boost { template <> struct range_mutable_iterator<OGRLineString> { typedef Winzent::Simulation::boost::OGRLineStringIterator type; }; } From what I can see, this will make the range_mutable_iterator concept usable with my adapter. I checked that BOOST_FOREACH (...) { ... } works for an OGRLineString; it successfully iterates over all points. However... > > Another thing: would it be possible to also try with boost 1.58? It > > would be helpful to know if the problem persists there. > > Just upgraded to Boost 1.58.0. I used a different machine to make sure there > are no leftovers that interfer on the original machine. Same problem, > sadly. > > > QCOMPARE( > > > > > > bg::distance(bls1, bls2), > > > bg::distance(*ls1, *ls2)); > > > > > > QCOMPARE( > > > > > > bg::distance(*ls1, *ls2), > > > ls1>Distance(ls2)); > > > > Which one(s) of the three tests above fail? All of them? Just the second? > > These two both fail. From that I conclude that (a) the OGRPoint adapter to > Boost.Geometry works, since I can successfully use bg::distance with my > `typedef bg::model::linestring<OGRPoint> boostLinestring` linestring. > However, the OGRLineString version uses my iterator code and fails. So the > only bug that can be found here is most probably in my own iterator code. yields the same result, just with other parameters): FAIL! : BoostOGRLineStringAdapterTest::testGeometryMultiLineString() Compared doubles are not the same (fuzzy compare) Actual (bg::distance(*ls1, *ls2)): 0 Expected (ls1>Distance(ls2)) : 18,3848 Any ideas on how I can start debugging...? Thanks, Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry signature.asc (836 bytes) Download Attachment 
Hi Eric.
On 22/05/2015 02:08 μμ, Eric MSP Veith
wrote:
Hello again, On Friday 22 May 2015 10:39:41, Eric MSP Veith [hidden email] wrote:Please make sure that you have correctly defined the specializations required by Boost.Range. It seems that you are missing the range_mutable_iterator specialization. See http://www.boost.org/doc/libs/1_58_0/libs/range/doc/html/range/reference/e xt ending.html for the details.Doesn't range_mutable_iterator mean that the return type of the iterator's dereference operator is a modifiable reference? If so, I cannot do this due to the OGRLineString's API. :/ Please correct me if I'm mistaken here; I'm by no means an expert in C++ STL conformant iterator design.while I'm still not clear on the implications of range_mutable_iterator, I added the following specialization to my code: namespace boost { template <> struct range_mutable_iterator<OGRLineString> { typedef Winzent::Simulation::boost::OGRLineStringIterator type; }; } From what I can see, this will make the range_mutable_iterator concept usable with my adapter. I checked that BOOST_FOREACH (...) { ... } works for an OGRLineString; it successfully iterates over all points. However...Another thing: would it be possible to also try with boost 1.58? It would be helpful to know if the problem persists there.Just upgraded to Boost 1.58.0. I used a different machine to make sure there are no leftovers that interfer on the original machine. Same problem, sadly.QCOMPARE( bg::distance(bls1, bls2), bg::distance(*ls1, *ls2)); QCOMPARE( bg::distance(*ls1, *ls2), ls1>Distance(ls2));Which one(s) of the three tests above fail? All of them? Just the second?These two both fail. From that I conclude that (a) the OGRPoint adapter to Boost.Geometry works, since I can successfully use bg::distance with my `typedef bg::model::linestring<OGRPoint> boostLinestring` linestring. However, the OGRLineString version uses my iterator code and fails. So the only bug that can be found here is most probably in my own iterator code.I'm still getting this error (copied from the second QCOMPARE, the first one yields the same result, just with other parameters): FAIL! : BoostOGRLineStringAdapterTest::testGeometryMultiLineString() Compared doubles are not the same (fuzzy compare) Actual (bg::distance(*ls1, *ls2)): 0 Expected (ls1>Distance(ls2)) : 18,3848 Any ideas on how I can start debugging...? Could you please try the attached program with your geometries? Basically, what I am asking is that you change the typedefs for point_type and linestring_type to indicate your geometries. Then give it a try. I want to make sure that point and segment iterator for your linestrings work correctly. If they do then we can see what needs to be done next.  m. Thanks, Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry linestring_iterators.cpp (1K) Download Attachment 
Hi Menelaos,
On Friday 22 May 2015 15:24:32, Menelaos Karavelas <[hidden email]> wrote: > Could you please try the attached program with your geometries? > Basically, what I am asking is that you change the typedefs for > point_type and linestring_type to indicate your geometries. Then give it > a try. > > I want to make sure that point and segment iterator for your linestrings > work correctly. If they do then we can see what needs to be done next. I've changed the typedefs and added the required headers: //... #include <boost/geometry.hpp> #include <gdal/ogr_geometry.h> #include "boost/OGRPointAdapter.h" #include "boost/OGRLineStringAdapter.h" #include "boost/OGRPointCollectionIterator.h" namespace bg = boost::geometry; typedef OGRPoint point_type; typedef OGRLineString linestring_type; typedef bg::point_iterator<linestring_type const> point_iterator_type; typedef bg::segment_iterator<linestring_type const> segment_iterator_type; int main() { //... But the code doesn't compile. I'm quoting only the first few lines: %< In file included from /usr/include/boost/geometry/algorithms/detail/distance/iterator_selector.hpp:16:0, from /usr/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp:48, from /usr/include/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp:17, from /usr/include/boost/geometry/strategies/strategies.hpp:48, from /usr/include/boost/geometry/geometry.hpp:50, from /usr/include/boost/geometry.hpp:17, from t.cpp:3: /usr/include/boost/geometry/iterators/point_iterator.hpp: In instantiation of ‘boost::geometry::point_iterator<Geometry>::point_iterator(const boost::geometry::point_iterator<G>&) [w ith OtherGeometry = OGRLineString; Geometry = const OGRLineString]’: t.cpp:29:62: required from here /usr/include/boost/geometry/iterators/point_iterator.hpp:268:57: error: no matching function for call to ‘boost::iterators::iterator_adaptor<boost::geometry::point_iterator<const OGR LineString>, Winzent::Simulation::boost::OGRPointCollectionIter<const OGRLineString, OGRPoint>, boost::iterators::use_default, boost::iterators::use_default, boost::iterators::use_de fault, boost::iterators::use_default>::iterator_adaptor(const Winzent::Simulation::boost::OGRPointCollectionIter<OGRLineString, OGRPoint>&)’ : point_iterator::iterator_adaptor_(other.base()) ^ /usr/include/boost/geometry/iterators/point_iterator.hpp:268:57: note: candidates are: In file included from /usr/include/boost/iterator/reverse_iterator.hpp:12:0, from /usr/include/boost/range/reverse_iterator.hpp:21, from /usr/include/boost/range/rbegin.hpp:19, from /usr/include/boost/range/functions.hpp:23, from /usr/include/boost/range/iterator_range_core.hpp:38, from /usr/include/boost/lexical_cast.hpp:30, from /usr/include/boost/math/constants/constants.hpp:18, from /usr/include/boost/geometry/util/math.hpp:28, from /usr/include/boost/geometry/core/radian_access.hpp:28, from /usr/include/boost/geometry/geometry.hpp:43, from /usr/include/boost/geometry.hpp:17, from t.cpp:3: /usr/include/boost/iterator/iterator_adaptor.hpp:265:16: note: boost::iterators::iterator_adaptor<Derived, Base, Value, Traversal, Reference, Difference>::iterator_adaptor(const Base &) [with Derived = boost::geometry::point_iterator<const OGRLineString>; Base = Winzent::Simulation::boost::OGRPointCollectionIter<const OGRLineString, OGRPoint>; Value = boost::iter ators::use_default; Traversal = boost::iterators::use_default; Reference = boost::iterators::use_default; Difference = boost::iterators::use_default] explicit iterator_adaptor(Base const &iter) ^ /usr/include/boost/iterator/iterator_adaptor.hpp:265:16: note: no known conversion for argument 1 from ‘const Winzent::Simulation::boost::OGRPointCollectionIter<OGRLineString, OGRPoint>’ to ‘const Winzent::Simulation::boost::OGRPointCollectionIter<const OGRLineString, OGRPoint>&’ /usr/include/boost/iterator/iterator_adaptor.hpp:263:7: note: boost::iterators::iterator_adaptor<Derived, Base, Value, Traversal, Reference, Difference>::iterator_adaptor() [with Derived = boost::geometry::point_iterator<const OGRLineString>; Base = Winzent::Simulation::boost::OGRPointCollectionIter<const OGRLineString, OGRPoint>; Value = boost::iterators::use_default; Traversal = boost::iterators::use_default; Reference = boost::iterators::use_default; Difference = boost::iterators::use_default] iterator_adaptor() {} ^ /usr/include/boost/iterator/iterator_adaptor.hpp:263:7: note: candidate expects 0 arguments, 1 provided >% My OGRPointCollectionIterator is both default and copy constructible: %< OGRPointCollectionIter(): m_currentPointIndex(0) { } OGRPointCollectionIter(const OGRPointCollectionIter &other): m_currentPointIndex(other.m_currentPointIndex), m_collection(other.m_collection.get()) { } >%  Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry signature.asc (836 bytes) Download Attachment 
Hi Eric.
On 22/05/2015 04:06 μμ, Eric MSP Veith
wrote:
Hi Menelaos, On Friday 22 May 2015 15:24:32, Menelaos Karavelas [hidden email] wrote:Could you please try the attached program with your geometries? Basically, what I am asking is that you change the typedefs for point_type and linestring_type to indicate your geometries. Then give it a try. I want to make sure that point and segment iterator for your linestrings work correctly. If they do then we can see what needs to be done next.I've changed the typedefs and added the required headers: //... #include <boost/geometry.hpp> #include <gdal/ogr_geometry.h> #include "boost/OGRPointAdapter.h" #include "boost/OGRLineStringAdapter.h" #include "boost/OGRPointCollectionIterator.h" namespace bg = boost::geometry; typedef OGRPoint point_type; typedef OGRLineString linestring_type; typedef bg::point_iterator<linestring_type const> point_iterator_type; typedef bg::segment_iterator<linestring_type const> segment_iterator_type; int main() { //... But the code doesn't compile. I'm quoting only the first few lines: %< In file included from /usr/include/boost/geometry/algorithms/detail/distance/iterator_selector.hpp:16:0, from /usr/include/boost/geometry/algorithms/detail/distance/point_to_geometry.hpp:48, from /usr/include/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp:17, from /usr/include/boost/geometry/strategies/strategies.hpp:48, from /usr/include/boost/geometry/geometry.hpp:50, from /usr/include/boost/geometry.hpp:17, from t.cpp:3: /usr/include/boost/geometry/iterators/point_iterator.hpp: In instantiation of ‘boost::geometry::point_iterator<Geometry>::point_iterator(const boost::geometry::point_iterator<G>&) [w ith OtherGeometry = OGRLineString; Geometry = const OGRLineString]’: t.cpp:29:62: required from here /usr/include/boost/geometry/iterators/point_iterator.hpp:268:57: error: no matching function for call to ‘boost::iterators::iterator_adaptor<boost::geometry::point_iterator<const OGR LineString>, Winzent::Simulation::boost::OGRPointCollectionIter<const OGRLineString, OGRPoint>, boost::iterators::use_default, boost::iterators::use_default, boost::iterators::use_de fault, boost::iterators::use_default>::iterator_adaptor(const Winzent::Simulation::boost::OGRPointCollectionIter<OGRLineString, OGRPoint>&)’ : point_iterator::iterator_adaptor_(other.base()) ^ /usr/include/boost/geometry/iterators/point_iterator.hpp:268:57: note: candidates are: In file included from /usr/include/boost/iterator/reverse_iterator.hpp:12:0, from /usr/include/boost/range/reverse_iterator.hpp:21, from /usr/include/boost/range/rbegin.hpp:19, from /usr/include/boost/range/functions.hpp:23, from /usr/include/boost/range/iterator_range_core.hpp:38, from /usr/include/boost/lexical_cast.hpp:30, from /usr/include/boost/math/constants/constants.hpp:18, from /usr/include/boost/geometry/util/math.hpp:28, from /usr/include/boost/geometry/core/radian_access.hpp:28, from /usr/include/boost/geometry/geometry.hpp:43, from /usr/include/boost/geometry.hpp:17, from t.cpp:3: /usr/include/boost/iterator/iterator_adaptor.hpp:265:16: note: boost::iterators::iterator_adaptor<Derived, Base, Value, Traversal, Reference, Difference>::iterator_adaptor(const Base &) [with Derived = boost::geometry::point_iterator<const OGRLineString>; Base = Winzent::Simulation::boost::OGRPointCollectionIter<const OGRLineString, OGRPoint>; Value = boost::iter ators::use_default; Traversal = boost::iterators::use_default; Reference = boost::iterators::use_default; Difference = boost::iterators::use_default] explicit iterator_adaptor(Base const &iter) ^ /usr/include/boost/iterator/iterator_adaptor.hpp:265:16: note: no known conversion for argument 1 from ‘const Winzent::Simulation::boost::OGRPointCollectionIter<OGRLineString, OGRPoint>’ to ‘const Winzent::Simulation::boost::OGRPointCollectionIter<const OGRLineString, OGRPoint>&’ /usr/include/boost/iterator/iterator_adaptor.hpp:263:7: note: boost::iterators::iterator_adaptor<Derived, Base, Value, Traversal, Reference, Difference>::iterator_adaptor() [with Derived = boost::geometry::point_iterator<const OGRLineString>; Base = Winzent::Simulation::boost::OGRPointCollectionIter<const OGRLineString, OGRPoint>; Value = boost::iterators::use_default; Traversal = boost::iterators::use_default; Reference = boost::iterators::use_default; Difference = boost::iterators::use_default] iterator_adaptor() {} ^ /usr/include/boost/iterator/iterator_adaptor.hpp:263:7: note: candidate expects 0 arguments, 1 provided >% My OGRPointCollectionIterator is both default and copy constructible: I think the question is whether your mutable iterator is convertible to your const iterator, or to pose it differently, whether your const iterator is constructible from your mutable iterator (which should be the case).  m. %< OGRPointCollectionIter(): m_currentPointIndex(0) { } OGRPointCollectionIter(const OGRPointCollectionIter &other): m_currentPointIndex(other.m_currentPointIndex), m_collection(other.m_collection.get()) { } >%  Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hello Menelaos,
On Friday 22 May 2015 17:33:35, Menelaos Karavelas <[hidden email]> wrote: > > My OGRPointCollectionIterator is both default and copy constructible: > I think the question is whether your mutable iterator is convertible to > your const iterator, or to pose it differently, whether your const > iterator is constructible from your mutable iterator (which should be > the case). I'm still puzzled. I've checked my iterator code and updated some of it in order to have it adhere to the Boost iterator_facade howto as closeley as possible. Specifically, I made sure that `MyConstIterator iter = boost::begin(someNonConstLineString);` works, which would cause the iterator to be converted to the const iterator. So I assume that it is not the iterator that is at fault. Checking your example and investigating the Boost.Geometry headers, I see that the bg::model::linestring<...> trait relies on several functions via dispatching that are present in std::vector and other container types, but not in OGRLineString. This includes, as seen from the compiler error I posted previously, clear(), push_back(), and resize(). I'd now open up the boost::geometry::traits namespace and provide dispatch structures for these operations along the lines of... template <> struct clear<OGRLineString> { static inline void apply( typename rvalue_type<OGRLineString>::type range) { range.empty(); } }; Would that be the correct approach or merely a hack? Thanks Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry signature.asc (836 bytes) Download Attachment 
Hi Eric.
On 26/05/2015 02:43 μμ, Eric MSP Veith
wrote:
Hello Menelaos, On Friday 22 May 2015 17:33:35, Menelaos Karavelas [hidden email] wrote:My OGRPointCollectionIterator is both default and copy constructible:I think the question is whether your mutable iterator is convertible to your const iterator, or to pose it differently, whether your const iterator is constructible from your mutable iterator (which should be the case).I'm still puzzled. I've checked my iterator code and updated some of it in order to have it adhere to the Boost iterator_facade howto as closeley as possible. Specifically, I made sure that `MyConstIterator iter = boost::begin(someNonConstLineString);` works, which would cause the iterator to be converted to the const iterator. So I assume that it is not the iterator that is at fault. Checking your example and investigating the Boost.Geometry headers, I see that the bg::model::linestring<...> trait relies on several functions via dispatching that are present in std::vector and other container types, but not in OGRLineString. This includes, as seen from the compiler error I posted previously, clear(), push_back(), and resize(). I'd now open up the boost::geometry::traits namespace and provide dispatch structures for these operations along the lines of... template <> struct clear<OGRLineString> { static inline void apply( typename rvalue_type<OGRLineString>::type range) { range.empty(); } }; Would that be the correct approach or merely a hack? Yes, this IS the correct way. You need to specialize various metafunctions in bg::traits namespace so that things work. Please keep us posted about this.  m. Thanks Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Hello Menelaos,
On Tuesday 26 May 2015 14:47:20, Menelaos Karavelas <[hidden email]> wrote: > Yes, this IS the correct way. You need to specialize various > metafunctions in bg::traits namespace so that things work. > Please keep up posted about this. ok, good to know. I've followed this path and provided template specializations for clear, resize, and push_back. The test program you supplied now compiles, but gives a rather surprising result: geometry: LINESTRING(1 1,2 2,3 3,4 4,9 9) points: (1, 1) (2, 2) (3, 3) (4, 4) (9, 9) segments: ((2.0872e317, 6.95257e310), (6.91222e310, 6.91222e310)) ((2.0872e317, 6.95257e310), (6.91222e310, 6.91222e310)) ((2.0872e317, 6.95257e310), (6.91222e310, 6.91222e310)) ((2.0872e317, 6.95257e310), (6.91222e310, 6.91222e310)) The values of the last line change with each run, but never much, i.e., the value left to the dot remains the same. Do I need to provide a separate segment iterator...? Thanks Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry signature.asc (836 bytes) Download Attachment 
Hi Eric.
On 26/05/2015 03:00 μμ, Eric MSP Veith
wrote:
Hello Menelaos, On Tuesday 26 May 2015 14:47:20, Menelaos Karavelas [hidden email] wrote:Yes, this IS the correct way. You need to specialize various metafunctions in bg::traits namespace so that things work. Please keep up posted about this.ok, good to know. I've followed this path and provided template specializations for clear, resize, and push_back. The test program you supplied now compiles, but gives a rather surprising result: geometry: LINESTRING(1 1,2 2,3 3,4 4,9 9) points: (1, 1) (2, 2) (3, 3) (4, 4) (9, 9) segments: ((2.0872e317, 6.95257e310), (6.91222e310, 6.91222e310)) ((2.0872e317, 6.95257e310), (6.91222e310, 6.91222e310)) ((2.0872e317, 6.95257e310), (6.91222e310, 6.91222e310)) ((2.0872e317, 6.95257e310), (6.91222e310, 6.91222e310)) The values of the last line change with each run, but never much, i.e., the value left to the dot remains the same. My understanding is that something is left uninitialized, hence the strange values. Do I need to provide a separate segment iterator...? You should not need to. The implementation of the segment iterator is rather generic, but quite tricky, as it is not the typical kind of iterator (for example, dereferrencing returns a value rather than a reference). What is your linestring's value type and reference type? In the implementation of the segment iterator it is assumed that, when dereferrencing an iterator on the points of the linestring, a reference (or const reference) is returned. If your linestring iterator returns point values then this could indeed be a problem.  m. Thanks Eric _______________________________________________ Geometry mailing list [hidden email] http://lists.boost.org/mailman/listinfo.cgi/geometry 
Free forum by Nabble  Edit this page 