sempr-tk / sempr

SEMPR - Semantic Environment Mapping, Processing and Reasoning
BSD 3-Clause "New" or "Revised" License
7 stars 1 forks source link

Boost Geometry and GOES::Geom conflict in Spatialindex #55

Open ctieben opened 5 years ago

ctieben commented 5 years ago

Hi,

currently if you try to add a 2D Geometry to the core with an active SpatialIndex module you will receive following runtime error from the Boost rtree: [ctest] sempr_spatial_conclusion_tests: /usr/include/boost/geometry/index/rtree.hpp:1445: void boost::geometry::index::rtree<Value, Options, IndexableGetter, EqualTo, Allocator>::raw_insert(const value_type&) [with Value = std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 3ul, boost::geometry::cs::cartesian> >, std::shared_ptr<sempr::entity::Geometry> >; Parameters = boost::geometry::index::quadratic<16ul>; IndexableGetter = boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 3ul, boost::geometry::cs::cartesian> >, std::shared_ptr<sempr::entity::Geometry> > >; EqualTo = boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 3ul, boost::geometry::cs::cartesian> >, std::shared_ptr<sempr::entity::Geometry> > >; Allocator = std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 3ul, boost::geometry::cs::cartesian> >, std::shared_ptr<sempr::entity::Geometry> > >; boost::geometry::index::rtree<Value, Options, IndexableGetter, EqualTo, Allocator>::value_type = std::pair<boost::geometry::model::box<boost::geometry::model::point<double, 3ul, boost::geometry::cs::cartesian> >, std::shared_ptr<sempr::entity::Geometry> >]: Assertion(detail::is_valid(m_members.translator()(value)))&&("Indexable is invalid")' failed. `

The reason for this is, that geos::geom coordinates stores X, Y, NaN for 2D coordinate and the boost rtree expect valid 3D points without a NaN value.

So how to handle 2D and 3D in the same context? ( set z to 0 instead of NaN)?

niniemann commented 5 years ago

So you say that findEnvelope(min, max) returns NaN in the min.zand max.z? This is something we can check for in the SpatialIndex, and overwrite it. No big deal.

The only real question is: What to overwrite it with? Project everything that is 2D into the x-y plane (i.e., set it to 0)? Or make the z value "arbitrary, everything matches", and thus set the bounds to +/- max double?

ctieben commented 5 years ago

Yes also the findEnvelope method will set Z to NaN if there are no Z values to compare. So its comform with geos::geom. I think the most correct way in the SpatialIndex for 2D surfaces is to set the max. possible height ( [- max double; + max double] ). If there is a 2D surface it will define a region and the height will not matter. Otherwise its possible to define a surface in 3D space with a specific height information.

niniemann commented 5 years ago

Yes, but in some cases this might be unintuitve: E.g. If you make a "contains"-query: Given some Volume, return everything that is contained in it. With the min/max values you won't get any 2D-geometries. But since it's basically 2D I'd expect it to be included in the results.

ctieben commented 5 years ago

Mhhh yes even the contains query of one 2D surface to another will be different than expected in this case. see: http://edndoc.esri.com/arcsde/9.1/general_topics/understand_spatial_relations.htm#Contains

ctieben commented 5 years ago

This could be solved by query with min/max vales and storing 2d geometries with min-1 / max-1. But its a bit hacky.

niniemann commented 5 years ago

I think in that case it is better to project all 2D geometries into the x-y plane, which is easily documented and understood.

ctieben commented 5 years ago

As long as we are in a 3D space the within and contains query will not match even if we project the geometry to plane at a specific height (e.g. z=0) because the z coordinate will be checked for this condition.

niniemann commented 5 years ago

Yes. That's the point. Just document the fact that the index assumes 2D geometries to lie in the x-y plane, so if he wants to include them he needs to adjust his query accordingly.

The alternative would be to not add 2D-geometries to the index at all, and implement a 2D variation of it.

ctieben commented 5 years ago

To fix this I have changed the SpatialIndex to contain only 2D or 3D elements. See: 796867f7e014baf3ac6da7960f7b93c5c668a81a

niniemann commented 5 years ago

(Shouldn't the issue only be closed when the branch you fixed this in is merged into master?)

ctieben commented 5 years ago

(yes ok, I had seen this more like a discussion than as a fixing issue)