
Hi Alfredo,
as I told you, my implementation is a total mock up and I am not sure I am doing it with the right philosophy. I added the code of boost_geometry_units.hpp file at the end of this post. I guess it works for me because I specialised the class model::point<double, 3, cs::units_cartesian<...> > and its constructor.
Thanks for this code.
The logic is that once you introduce units, the types of the coordinates are not uniform types, for example, a real space vector can have its cartesian coordinates in meters, but in spherical coordinates, only the radial part is in meters, (the others are angles).
I see, good point.
But maybe you are right the coordinates should be double upon constructions and the metric and units is only contained in the type.
I understand that integrations with Boost.Units is not planned and even not desirable. But making the implicit assumption that typeof(sqrt(s)) == typeof(s) or that typeof(s*s)==type(s) makes it incompatible with Boost.units. Those assumptions are good as defaults but there should be a way to tell Boost.Geometry that sometimes it is not the case.
I see what you mean. Yesterday in other answer I already referred to this. This would mean a total rework of all calculations, which is impossible, at least with respect to the time available for it. Look e.g. here: http://bit.ly/gOT5Yk and try to give them a physical meaning with quantities etc... Besides the amount of work, with many calculations such as the dot product and the determinant, the physical meaning is there but normally not used in this context. Dot product and determinant just returns a value, AFAIK normally not expressed in square meters. Determinant (and "side" which is similar) are e.g. used in segment intersection; those calculations are just steps in between; the end product are coordinates again. Having units applied there would be a burden nobody expects there (I think)...
So Boost.Geometry is not dependant on Boost.Units. I think the way to go is define a point type using a coordinate system using Boost.Units, like you did, and also add quantities there. yes. Even at the interface level I am not sure for example if constructors should carry units or not. I added the units to my constructors to make it more dimensionally type safe. Maybe the boost.units people will have clearer idea.
OK, I'm curious.
boost::geometry::units::area(a) -> returns a quantity e.g. in square_meters from a polygon
So I added two of these functions as well, giving:
std::cout<< units::get<0>(p2)<< std::endl; quantity<si::length> d = units::distance(p1, p2); std::cout<< d<< std::endl;
reporting all quantities including units. It required some small additional metafunctions as well.
yes, I the same thing in my first implementation, with a namespace boost::geometry::units that have all the overloaded functions but then I though it would have a lot a repeated code.
Yes, it would, but on the other hand, it makes a lot of things much and much simpler. Besides that, there are not so many functions like this: area, length, perimeter, distance are quantified values, but many others as intersection, union, simplify; and boolean predicates as within, intersects, all can do without any overload.
I just committed it, for the moment as a new example (including definitions), here:http://bit.ly/dEip8s (...) below the "mock up" code for boost_geometry_units.hpp. It is not good code, it is just barely enough to make it work with (...)
template<class T, std::size_t Dimension, class Unit> boost::units::quantity<Unit, T> distance( model::point<T, Dimension, cs::units_cartesian<Unit> > const& p1, model::point<T, Dimension, cs::units_cartesian<Unit> > const& p2 ){ return boost::units::quantity<Unit, T>::from_value( boost::geometry::distance( (model::point<T, Dimension, cs::cartesian> const&)p1, (model::point<T, Dimension, cs::cartesian> const&)p2 ) ); }
I understand how you got this working now. It is similar to my solution (forwarding to distance) but here you have the need to many casts, and many additional metafunctions and specializations implemented...
namespace strategy{namespace distance{namespace services{
template<class Unit> struct return_type<boost::geometry::units_cartesian_tag<Unit> >{ typedef boost::units::quantity<Unit> type; }; (...)
This, and the other code, is necessary here, but not in the proposal I sent... So there are more than one approaches, you can write an own distance strategy, correctly handling x*x and sqrt(x) w.r.t. Boost.Units. This might be doable for distance, but for huge algorithms as intersections, where you actually do not have any profit from units (input = coordinates, output = coordinates), I personally think it is way too much. I'm actually curious to know, is does the solution (that example) work for you? Regards, Barend