Как зарегистрировать стратегию расстояния Boost.Geometry для OGRPoint и OGRLineString?

Я создаю оболочку, которая позволяет использовать классы OGR с Boost.Geometry. До сих пор я создал этот необходимый фасад итератора и зарегистрировал классы геометрии OGR (OGRPoint, OGRLineString, OGRLinearRing а также OGRPolygon) с Boost.Geometry.

Теперь я хотел бы использовать предикаты классов OGR, такие как OGRGeometry::Distance() с надбавкой вместо тех, что используются в 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

Как я могу «перехватить» экземпляр шаблона, который приводит к использованию концепции итератора / диапазона и использования OGRGeometry::Distance() напрямую?

1

Решение

Оказалось, что проблема не связана с OGR и Boost с использованием двух разных алгоритмов. Вместо этого виноват был мой код адаптера. Более конкретно, фасад итератора, который я написал для адаптации OGRLineString, OGRLinearRing и в конечном итоге OGRPolygon к коду Boost.Geometry. Я отправил вопрос, как только узнал проблему: Создать корректный итератор для API записи в указатель.

Моя текущая (и окончательная) версия доступна как проект GitHub. Возможно, кто-то найдет это полезным.

1

Другие решения


По вопросам рекламы [email protected]