如何为 OGRPoint 和 OGRLineString 注册 Boost.Geometry 距离策略?

How to register a Boost.Geometry distance strategy for OGRPoint and OGRLineString?

我正在创建一个允许将 OGR 类与 Boost.Geometry 一起使用的包装器。到目前为止,我已经创建了必要的迭代器外观并使用 Boost.Geometry.[= 注册了 OGR 的几何类(OGRPointOGRLineStringOGRLinearRingOGRPolygon)。 23=]

现在,我想使用 OGR 类谓词,例如 OGRGeometry::Distance() 和 boost,而不是 Boost.Geometry 使用的谓词(因为,例如,股票 Boost.Geometry 1.57。 0 没有任何地图投影的概念)。它适用于 boost::geometry::distance(OGRPoint, OGRPoint),但不适用于 bg::distance(OGRPoint, OGRLineString) 或任何其他点集合。我的猜测是因为 Boost.Geometry 将线串、环和多边形视为要迭代的点的有序集合,因为编译器会尝试实例化以下模板:

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>

完整错误信息如下:

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

所以我尝试专门为 struct boost::geometry::detail::distance::default_strategy<OGRPoint, OGRLineString, boost::geometry::pointlike_tag, boost::geometry::linestring_tag, false> 提供模板专业化,但没有成功 --- 出现相同的错误消息。

这是我的代码:

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

如何"intercept" 导致使用 iterator/range 概念的模板实例化并直接使用 OGRGeometry::Distance()

事实证明,问题与使用两种不同算法的 OGR 和 Boost 无关。相反,应该归咎于我的适配器代码。更具体地说,我编写的迭代器外观是为了使 OGRLineStringOGRLinearRing 并最终使 OGRPolygon 适应 Boost.Geometry 代码。我一发现这个问题就发布了一个问题:.

我当前的工作(和最终)版本可用 a GitHub project。也许有人觉得有用。