河流溯源分析
需求: 基于水系分析河流溯源路径
输入: 河流数据
实现思路: 基于网络模型, 根据 河流交点打断生成河流网数据, 这跟路网不同, 河流一般都是单向流向, 所以是有向图.
基于GDAL gnm算法数据结构有以下实现:
/// \brief 顶点对象, 顶点内不带几何,方便算法运行,要查询几何可以直接去Storage根据ID查询
struct Vertex
{
public:/// \brief 顶点IDlong long VertexID = 0;/// \brief 是否阻碍bool bIsBloked = false;/// \brief bIsBloked为true参与计算/// 阻抗值 要么无限大就是无法通的点, 要么是来源一个字段的值,会累加权值消耗double ImpedanceCost = 0;/// \brief 此点对应的原始边的IDlong long SourcePathID = 0;/// 图中下几条边ID, 默认vector anOutEdgeFIDs = {};vector anInEdgeFIDs = {};Vertex(){}Vertex(long long vid){VertexID = vid;}Vertex(const Vertex & o);bool IsValid();
};/// \brief 边对象
struct Edge
{
public:/// \brief 起始点IDlong long nSrcVertexFID = 0;/// \brief 结束点IDlong long nTgtVertexFID = 0;/// \brief 唯一权值, 此权值对于不同模型可以动态从不同字段取double dfDirCost = 0.;/// \brief 逆向权值double dfInvCost = 0.;/// \brief 图的边ID,经过打断处理的边ID 必须字段,long long EdgeID = 0;/// \brief 未打断前的数据边ID, 非必需的, 如果为0, 说明是通过规则构建的虚拟边, 比如换乘边long long SourcePathID = 0;/// \brief 是否双向bool bIsBidir = false;/// \brief 是否阻碍bool bIsBloked = false;Edge();Edge(long long innSrcVertexFID, long long innTgtVertexFID, double dfDirCost = 0., long long EdgeID = 0);Edge(const Edge& o);bool IsValid();
};std::map m_mstVerticesCache;
std::map m_mstEdgesCache;
查找溯源河流边得函数如下:
#define GNMGFID long long
typedef std::pair EDGEVERTEXPAIR;
typedef std::vector< EDGEVERTEXPAIR > GNMPATH;void gnm_algorithm::TraceSources(std::queue& vertexQueue, std::set& markedVertIds, GNMPATH & connectedIds)
{GNMCONSTVECTOR::const_iterator it;std::queue neighbours_queue;while (!vertexQueue.empty()){GNMGFID nCurVertID = vertexQueue.front();if (markedVertIds.find(nCurVertID) == markedVertIds.end()){markedVertIds.insert(nCurVertID);LPGNMCONSTVECTOR panOutcomeEdgeIDs = QueryStartVID(nCurVertID);if (nullptr != panOutcomeEdgeIDs){for (it = panOutcomeEdgeIDs->begin(); it != panOutcomeEdgeIDs->end(); ++it){GNMGFID nCurStartID = *it;connectedIds.push_back(GsPair(nCurStartID, nCurVertID ));if ((markedVertIds.find(nCurStartID) == markedVertIds.end()))neighbours_queue.push(nCurStartID);}}}vertexQueue.pop();}if (!neighbours_queue.empty())TraceTargets(neighbours_queue, markedVertIds, connectedIds);
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
