简单说明:代码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
对其形状标志选择向右的箭头
放大看就完成了