已经在工程中使用特化来扩展boost的rtree,用于处理自定义数据结构。
boost里有rtree这个数据结构,主要用于空间检索。
它已经提供了std::pair(如下),也
/*!
\brief The function object extracting Indexable from Value.
This specialization translates from std::pair<Indexable, T2>.
\tparam Indexable The Indexable type.
\tparam Second The second type.
*/
template <typename Indexable, typename Second>
struct indexable<std::pair<Indexable, Second>, false>
{
typedef std::pair<Indexable, Second> value_type;
BOOST_GEOMETRY_STATIC_ASSERT(
(detail::is_indexable<Indexable>::value),
"The first type of std::pair has to be an Indexable.",
Indexable);
/*! \brief The type of result returned by function object. */
typedef Indexable const& result_type;
/*!
\brief Return indexable extracted from the value.
\param v The value.
\return The indexable.
*/
inline result_type operator()(value_type const& v) const
{
return v.first;
}
/*!
\brief Return indexable extracted from compatible type different than value_type.
\param v The value.
\return The indexable.
*/
template <typename I, typename S>
inline result_type operator()(std::pair<I, S> const& v) const
{
BOOST_GEOMETRY_STATIC_ASSERT(
(is_referencable<I, result_type>::value),
"Unexpected type.",
std::pair<I, S>);
return v.first;
}
/*!
\brief Prevent reference to temporary for types convertible to Value.
*/
template <typename V>
inline result_type operator()(V const& v) const
{
return indexable_prevent_any_type<Indexable>(v);
}
};
利用特化,可以检索自己的自定义数据,如下面的Point2CisdiCurveList,里面的key用于检索,剩下的两个成员变量作为携带的数据。
/*--------------------------------------------------------------------------------------**//**
* 通过空间点,来查询空间曲线
* Created by Simon.Zou on 7/2021
+---------------+---------------+---------------+---------------+---------------+-----------*/
struct Point2CisdiCurveList
{
// typedef PointFindCurve::BDPoint BDPoint; //双精度的点
using BDPoint = boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian> ; //双精度的点
using BoostDBox = boost::geometry::model::box<BDPoint> ; //立方体
using Value = std::pair<BoostDBox, CurveVectorPtr> ;
using MyRTree = boost::geometry::index::rtree<PointFindCurve::Value, boost::geometry::index::quadratic<16>> ; //双精度的点
//typedef boost::geometry::model::point<double, 3, boost::geometry::cs::cartesian> BoostPoint3d; //双精度的点
BDPoint key;
std::list<CurveVectorPtr> cisdiCurve2DLst;
std::list<CurveVectorPtr> cisdiCurve3DLst;
};
/*--------------------------------------------------------------------------------------**//**
* 特化
* Point2CisdiCurveList里定义了key和对应的数据
* Created by Simon.Zou on 9/2021
+---------------+---------------+---------------+---------------+---------------+-----------*/
template <>
struct boost::geometry::index::indexable<Point2CisdiCurveList>
{
typedef Point2CisdiCurveList::BDPoint result_type; //这个不能缺少
//boostPoint2d operator()(const CityRef& c) const { return c.location; }
const Point2CisdiCurveList::BDPoint& operator()(const Point2CisdiCurveList& c) const {
return c.key;
}
};
/*--------------------------------------------------------------------------------------**//**
* 点找到线的list
* Created by Simon.Zou on 8/2021
+---------------+---------------+---------------+---------------+---------------+-----------*/
struct PointFindCurveList
{
typedef Point2CisdiCurveList::BDPoint BDPoint; //双精度的点
typedef boost::geometry::index::rtree<Point2CisdiCurveList, boost::geometry::index::linear<16> > MyRTree;
// static BoostDBox CreateBoostDBox(DPoint3dR pt, //IN
// double dDis = 1 * UOR_PER_MM //IN
// ){return PointFindCurve::CreateBoostDBox(pt, dDis);}
static bool Add1Point1Curve(PointFindCurveList::MyRTree& rtree, //IN
DPoint3dR pt, //IN
CurveVectorPtr curve2d, //IN
CurveVectorPtr curve3d, //IN
//bool bAllow3dPointDuplicate = false, //IN 是否允许通过空间点查到多个数据
double dDis = 1 * UOR_PER_MM //IN
)
{
PointFindCurve::BoostDBox b = PointFindCurve::CreateBoostDBox(pt, dDis);
/*--------------------------------------------------------------------------------------**//**
* 如果能找到,则更新:
* 删除唯一记录,然后插入记录 Commented by Simon.Zou on 7/2021
+---------------+---------------+---------------+---------------+---------------+-----------*/
bool bFind = false;
for (PointFindCurveList::MyRTree::const_query_iterator
it = rtree.qbegin(boost::geometry::index::intersects(b));
it != rtree.qend();
++it)
{
bFind = true;
Point2CisdiCurveList& lst = const_cast<Point2CisdiCurveList&>(*it);
lst.cisdiCurve2DLst.push_back(curve2d);
lst.cisdiCurve3DLst.push_back(curve3d);
}
if (!bFind)
{
std::list<CurveVectorPtr> cisdiCurveLst;
Point2CisdiCurveList o;
o.key.set<0>(pt.x);
o.key.set<1>(pt.y);
o.key.set<2>(pt.z);
o.cisdiCurve2DLst.push_back(curve2d);
o.cisdiCurve3DLst.push_back(curve3d);
rtree.insert(o);//r树插入外包围矩形 i为索引
return true;
}
return true;
}
static bool FindByPoint(std::list<Point2CisdiCurveList>& result_s, //OUT
PointFindCurveList::MyRTree& rtree, //IN
DPoint3dR pt, //IN
double dDis = 1 * UOR_PER_MM //IN
)
{
PointFindCurve::BoostDBox b = PointFindCurve::CreateBoostDBox(pt, dDis);
//std::vector<Value> result_s;
int size = (int)rtree.query(boost::geometry::index::intersects(b), std::back_inserter(result_s));
if (size == 0)
return false;
//if (result_s.size() == 0)
// m_rtree.query(boost::geometry::index::nearest(BDPoint(ptRes.x, ptRes.y, ptRes.z), 2), std::back_inserter(result_s));
return !result_s.empty();
}
};
下面代码运行结果是:0
说明“共同类型”(在被特化后)是Ex0
struct Ex0 {
int a = 0;
};
struct Ex1 {
int a = 1;
};
//没错,这个std就是stl的那个std
//就是为了对stl的common_type进行特化。
//否则的话,光用stl的肯定是编译不过。因为Ex0和Ex1不是一个类型,没法转换
namespace std {
template <>
struct common_type<Ex0, Ex1>
{
using type = Ex0; //说明:decltype(true? Ex0:Ex1)的结果就是Ex0
};
}
void testOwner() {
using type = std::common_type_t<Ex0, Ex1>;
type m;
std::cout << "cur class value:" << m.a << std::endl;
}
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.youkuaiyun.com/fpcc/article/details/136000816