河流溯源分析

需求:  基于水系分析河流溯源路径

输入: 河流数据

实现思路:  基于网络模型,  根据 河流交点打断生成河流网数据,  这跟路网不同, 河流一般都是单向流向, 所以是有向图.

基于GDAL  gnm算法数据结构有以下实现:


/// \brief 顶点对象, 顶点内不带几何,方便算法运行,要查询几何可以直接去Storage根据ID查询
struct Vertex
{
public:
	/// \brief 顶点ID
	long long VertexID = 0;
	/// \brief		是否阻碍
	bool bIsBloked = false;
	/// \brief  bIsBloked为true参与计算
	///  阻抗值  要么无限大就是无法通的点,  要么是来源一个字段的值,会累加权值消耗
	double ImpedanceCost = 0;

	/// \brief 此点对应的原始边的ID
	long long SourcePathID = 0;

	/// 图中下几条边ID, 默认
	vector<long long> anOutEdgeFIDs = {};
	vector<long long> anInEdgeFIDs = {};

	Vertex()
	{

	}
	Vertex(long long vid)
	{
		VertexID = vid;
	}
	Vertex(const Vertex & o);
	bool IsValid();
};

/// \brief 边对象
struct Edge
{
public:
	/// \brief		起始点ID
	long long		nSrcVertexFID = 0;
	/// \brief		结束点ID
	long 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<long long, Vertex> m_mstVerticesCache;
std::map<long long, Edge>   m_mstEdgesCache;

查找溯源河流边得函数如下:

#define GNMGFID long long
typedef std::pair<long long, long long> EDGEVERTEXPAIR;
typedef std::vector< EDGEVERTEXPAIR > GNMPATH;

void gnm_algorithm::TraceSources(std::queue<long long>& vertexQueue, std::set<long long>& markedVertIds, GNMPATH & connectedIds)
{
	GNMCONSTVECTOR::const_iterator it;
	std::queue<GNMGFID> 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<long long, long long>(nCurStartID, nCurVertID ));
					if ((markedVertIds.find(nCurStartID) == markedVertIds.end()))
						neighbours_queue.push(nCurStartID);
				}
			}
		}

		vertexQueue.pop();
	}

	if (!neighbours_queue.empty())
		TraceTargets(neighbours_queue, markedVertIds, connectedIds);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值