生成有箭头的流向Line.shp 并通过ArcMap绘制带箭头的图,根据D8算法,输入Flow Direction

该代码示例展示了如何使用C++结合GDAL库读取流向数据(ASC文件),并利用ArcGIS的D8算法处理,最后将处理结果保存为ESRI Shapefile(.shp)矢量图。主要涉及GDAL的环境配置、数据读取、流向计算和形状文件创建。
摘要由CSDN通过智能技术生成

简单说明:代码C++,配置GDAL环境(必须),ArcMap
附一个配置GDAL环境的教程,感谢这位大佬
VS2017编译配置GDAL库

输入流向数据的 asc文件,附网盘测试链接
链接:https://pan.baidu.com/s/1-Q35OktO8dOPbjdkI1XC8w
提取码:p2ap

代码如下:

#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <sstream>
#include "ogrsf_frmts.h"
#include "gdal.h"
#include "gdal_priv.h"
#include "gdal_alg.h"
using namespace std;

//ToString该函数转载自他人
template<typename T> string toString(const T& t)
{
	ostringstream oss;  //创建一个格式化输出流
	oss << t;             //把值传递如流中
	return oss.str();
}
void Draw_arrow(int fd, int row, int col, int fd_row, int fd_col, double fd_xll, double fd_yll, double fd_res, double &x1, double &x2, double &y1, double &y2);

void main()
{
	int i, j, k;
	int fd_row = 359;
	int fd_col = 719;
	double fd_xll = 112.6;
	double fd_yll = 32.500277777778;
	double fd_res = 0.00027777777799999;
	string flow_path_file = "E:\\arcgis\\fdr.asc";
	string line_shp_path = "E:\\arcgis\\fdr.shp";
	string flow_file_path;
	int **fd_value = new int*[fd_row*fd_col];
	for (i = 0; i < fd_row*fd_col; i++)
	{
		fd_value[i] = new int[8];
	}
	int **order = new int*[fd_row*fd_col];
	for (i = 0; i < fd_row; i++)
	{
		order[i] = new int[fd_col];
	}
	for (i = 0; i < fd_row*fd_col; i++)
		for (j = 0; j < 8; j++)
			fd_value[i][j] = 0;

	ifstream FDR(flow_path_file.c_str());
	if (!FDR)
	{
		cout << "no in FDR" << endl;
		system("pause");
	}
	string str;
	for (i = 0; i < 6; i++)
		getline(FDR, str);
	//cout << "1" << endl;
	//system("pause");
	int tmp;
	for (i = 0; i < fd_row; i++)
	{
		for (j = 0; j < fd_col; j++)
		{
			FDR >> tmp;
			if (tmp == -9999 || tmp == 0)
			{
				continue;
			}
			// 这里根据ArcGIS的D8算法流向修改了一下,不过问题不大,个人比较喜欢这么计算
			if (tmp == 32)
			{
				fd_value[i*fd_col + j][0] = 1;
			}
			else if (tmp == 64)
			{
				fd_value[i*fd_col + j][1] = 1;
			}
			else if (tmp == 128)
			{
				fd_value[i*fd_col + j][2] = 1;
			}
			else if (tmp == 16)
			{
				fd_value[i*fd_col + j][3] = 1;
			}
			else if (tmp == 1)
			{
				fd_value[i*fd_col + j][4] = 1;
			}
			else if (tmp == 8)
			{
				fd_value[i*fd_col + j][5] = 1;
			}
			else if (tmp == 4)
			{
				fd_value[i*fd_col + j][6] = 1;
			}
			else if (tmp == 2)
			{
				fd_value[i*fd_col + j][7] = 1;
			}
		}
	}
	GDALAllRegister();
	const char * pFileName = line_shp_path.c_str();
	const char * pszDriverName = "ESRI Shapefile";
	GDALDriver * poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName);
	if (poDriver == NULL)
		return;
	GDALDataset * poDs = poDriver->Create(pFileName, 0, 0, 0, GDT_Unknown, NULL);
	if (poDs == NULL)
		return;
	//wkbPolygon表示绘制多边形;wkbLinearRing表示绘制线环
	OGRLayer * poLayer = poDs->CreateLayer("ring", NULL, wkbLineString, NULL);//不删
	if (poLayer == NULL)
	{
		return;
	}
	int line_num;
	int count_line;
	double x1, x2, y1, y2;
	//	system("pause");
	for (i = 0; i < fd_row; i++)
	{
		for (j = 0; j < fd_col; j++)
		{
			count_line = 0;
			for (k = 0; k < 8; k++)
			{
				if (fd_value[i*fd_col + j][k] == 1)
					count_line++;

			}
			if (count_line == 0)
				continue;
			if (count_line == 1)
			{
				for (k = 0; k < 8; k++)
				{
					if (fd_value[i*fd_col + j][k] == 1)
					{
						Draw_arrow(k + 1, i, j, fd_row, fd_col, fd_xll, fd_yll, fd_res, x1, x2, y1, y2);
						OGRFeature * poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
						OGRLineString line;

						line.setNumPoints(2);
						line.setPoint(0, x1, y1, 0);//第一个输入变量是序号,第二、三、四分别是线XYZ坐标
						line.setPoint(1, x2, y2, 0);
						poFeature->SetGeometry(&line);
						if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
						{
							return;
						}
						OGRFeature::DestroyFeature(poFeature);
					}
				}
			}
			else if (count_line > 1)
			{
				for (k = 0; k < 8; k++)
				{
					if (fd_value[i*fd_col + j][k] == 1)
					{	// k+1
						Draw_arrow(k + 1 + 8, i, j, fd_row, fd_col, fd_xll, fd_yll, fd_res, x1, x2, y1, y2);
						OGRFeature * poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
						OGRLineString line;
						line.setNumPoints(2);
						line.setPoint(0, x1, y1, 0);//第一个输入变量是序号,第二、三、四分别是线XYZ坐标
						line.setPoint(1, x2, y2, 0);
						poFeature->SetGeometry(&line);
						if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
						{
							return;
						}
						OGRFeature::DestroyFeature(poFeature);
					}
				}
			}
		}
	}
	GDALClose(poDs);
	OGRCleanupAll();
	for (i = 0; i < fd_row; i++)
		delete[]fd_value[i];
	delete[]fd_value;
	cout << "***** Finished *****" << endl;
	//system("pause");
}

void Draw_arrow(int fd, int row, int col, int fd_row, int fd_col, double fd_xll, double fd_yll, double fd_res, double &x1, double &x2, double &y1, double &y2)
{
	int i = row;
	int j = col;
	if (fd == 1)
	{
		x1 = fd_xll + (j + 1)* fd_res;
		x2 = fd_xll + (j)*fd_res;
		y1 = fd_yll + (fd_row - i - 1)*fd_res;
		y2 = fd_yll + (fd_row - i) * fd_res;
	}
	else if (fd == 2)
	{
		x1 = fd_xll + (2 * j + 1)* fd_res / 2.0;
		x2 = fd_xll + (2 * j + 1)*fd_res / 2.0;
		y1 = fd_yll + (fd_row - i - 1)*fd_res;
		y2 = fd_yll + (fd_row - i) * fd_res;
	}
	else if (fd == 3)
	{
		x1 = fd_xll + (j)* fd_res;
		x2 = fd_xll + (j + 1)*fd_res;
		y1 = fd_yll + (fd_row - i - 1)*fd_res;
		y2 = fd_yll + (fd_row - i) * fd_res;
	}
	else if (fd == 4)
	{
		x1 = fd_xll + (j)*fd_res;
		x2 = fd_xll + (j + 1)* fd_res;
		y1 = fd_yll + (fd_row - (2 * i + 1) / 2.0)*fd_res;
		y2 = fd_yll + (fd_row - (2 * i + 1) / 2.0) * fd_res;
	}
	else if (fd == 8)
	{
		x1 = fd_xll + (j + 1)* fd_res;
		x2 = fd_xll + (j)*fd_res;
		y1 = fd_yll + (fd_row - (2 * i + 1) / 2.0)*fd_res;
		y2 = fd_yll + (fd_row - (2 * i + 1) / 2.0) * fd_res;
	}

	else if (fd == 5)
	{
		x1 = fd_xll + (j)*fd_res;
		x2 = fd_xll + (j + 1)* fd_res;
		y1 = fd_yll + (fd_row - i) * fd_res;
		y2 = fd_yll + (fd_row - i - 1)*fd_res;
	}

	else if (fd == 6)
	{
		x1 = fd_xll + (2 * j + 1)*fd_res / 2.0;
		x2 = fd_xll + (2 * j + 1)* fd_res / 2.0;
		y1 = fd_yll + (fd_row - i) * fd_res;
		y2 = fd_yll + (fd_row - i - 1)*fd_res;
	}

	else if (fd == 7)
	{
		x1 = fd_xll + (j + 1)*fd_res;
		x2 = fd_xll + (j)* fd_res;
		y1 = fd_yll + (fd_row - i) * fd_res;
		y2 = fd_yll + (fd_row - i - 1)*fd_res;
	}

	//以下是别的,可忽略;
	else if (fd == 9)
	{
		x1 = fd_xll + (j + 1)* fd_res - 0.5*fd_res;
		x2 = fd_xll + (j)*fd_res;
		y1 = fd_yll + (fd_row - (i + 1))*fd_res + 0.5*fd_res;
		y2 = fd_yll + (fd_row - i) * fd_res;
	}
	else if (fd == 10)
	{
		x1 = fd_xll + (2 * j + 1)* fd_res / 2.0;
		x2 = fd_xll + (2 * j + 1)*fd_res / 2.0;
		y1 = fd_yll + (fd_row - (i + 1))*fd_res + 0.5*fd_res;
		y2 = fd_yll + (fd_row - i) * fd_res;
	}
	else if (fd == 11)
	{
		x1 = fd_xll + (j)* fd_res + 0.5*fd_res;
		x2 = fd_xll + (j + 1)*fd_res;
		y1 = fd_yll + (fd_row - i - 1)*fd_res + 0.5*fd_res;
		y2 = fd_yll + (fd_row - i) * fd_res;
	}
	else if (fd == 12)
	{
		x1 = fd_xll + (j)*fd_res + 0.5*fd_res;
		x2 = fd_xll + (j + 1)* fd_res;
		y1 = fd_yll + (fd_row - (2 * i + 1) / 2.0)*fd_res;
		y2 = fd_yll + (fd_row - (2 * i + 1) / 2.0) * fd_res;
	}
	else if (fd == 16)
	{
		x1 = fd_xll + (j + 1)* fd_res - 0.5*fd_res;
		x2 = fd_xll + (j)*fd_res;
		y1 = fd_yll + (fd_row - (2 * i + 1) / 2.0)*fd_res;
		y2 = fd_yll + (fd_row - (2 * i + 1) / 2.0) * fd_res;
	}

	else if (fd == 13)
	{
		x1 = fd_xll + (j)*fd_res + 0.5*fd_res;
		x2 = fd_xll + (j + 1)* fd_res;
		y1 = fd_yll + (fd_row - i) * fd_res - 0.5*fd_res;
		y2 = fd_yll + (fd_row - i - 1)*fd_res;
	}

	else if (fd == 14)
	{
		x1 = fd_xll + (2 * j + 1)*fd_res / 2.0;
		x2 = fd_xll + (2 * j + 1)* fd_res / 2.0;
		y1 = fd_yll + (fd_row - i) * fd_res - 0.5*fd_res;
		y2 = fd_yll + (fd_row - i - 1)*fd_res;
	}

	else if (fd == 15)
	{
		x1 = fd_xll + (j + 1)*fd_res - 0.5*fd_res;
		x2 = fd_xll + (j)* fd_res;
		y1 = fd_yll + (fd_row - i) * fd_res - 0.5*fd_res;
		y2 = fd_yll + (fd_row - i - 1)*fd_res;
	}
}

将代码生成的fdr.shp加载入ArcMap
在这里插入图片描述

对其形状标志选择向右的箭头
在这里插入图片描述
放大看就完成了
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇天y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值