现阶段DEM数据的来源不再仅仅局限于原来保存的纸质地形图的跟踪数字化,可能是采用激光测距仪配合地面控制点生成,由此产生的DEM格网数据可能需要生成等高线图,以作为基础地理数据或底图。此工艺流程与原来跟踪等高线来生产DEM的目标刚好相反,是在拥有DEM数据后反而希望生成等高线。下面介绍具体的流程和参考代码:

1)     针对格网中每个基本单元,创建一个参考变量,即YuanSu[i][j](0<=i<=Row; 0<=j<=Column)同时分配内存。此参考变量赋值0或1,其中1代表此位置处的邻域高程数值将发生变化,那么此位置将绘制等高线。

colchar **)calloc(m_iRows, sizeof(char *));                           //指向指针的指针初始化
row     = (char **)calloc(m_iRows, sizeof(char *));                           //指向指针的指针初始化
for(y=0; y<m_iRows; y++)                                                      //m_iRows:格网的行数
    {
col[y] = (char *)calloc(m_iColumns, sizeof(char));        //每个单元分配内存,m_iColumns : 格网的列数
row[y] = (char *)calloc(m_iColumns, sizeof(char));         //每个单元分配内存
    }

2)在以高程数值从最小值开始依次递增的最外部一层循开始,接着对整个格网数据进行循环,在给参考变量YuanSu[i][j]赋数值0或1之后,然后以YuanSu[i][j] == 1为判断条件,寻找并记录等高线。

for(zValue=zMin, ID=0; zValue<=zMax; zValue+=zStep)           //从最小Z数值计算起,知道最大Z数值
    {
//-------------------------------------------------
// Step1: Find Border Cells                //找到边界单元,边界:高度趋势发生改变的地方。
for(y=0; y<m_iRows-1; y++)
for(x=0; x<m_iColumns-1; x++)
if( m_p3dDEMPoints[y*m_iColumns+x][2] >= zValue
                 {
row[y][x]   = m_p3dDEMPoints[y*m_iColumns+(x+1)][2] < zValue ? 1 : 0;            //‘’就代表边界
col[y][x]   = m_p3dDEMPoints[(y+1)*m_iColumns+x][2] < zValue
                 }
else
                 {
row[y][x]   = m_p3dDEMPoints[y*m_iColumns+(x+1)][2] >= zValue ? 1 : 0;            //‘’就代表边界
col[y][x]   = m_p3dDEMPoints[(y+1)*m_iColumns+x][2] >= zValue
                 }
//-------------------------------------------------
// Step2: Interpolation + Delineation
for(y=0; y<m_iRows-1; y++)
for(x=0; x<m_iColumns-1; x++)
            {
if(row[y][x])                                 //如果数值为
                 {                
for(i=0; i<2; i++)                         //两次调用函数,ID值增加
                     {
if(i==0) m_iCountourfind
else m_iCountourfind
ContourFind(x, y, zValue, true, ID++);
                     }
row[y][x]   = 0;                          //代表已经处理过
                 
                 }
if(col[y][x])                                 //如果数值为
                 {                
for(i=0; i<2; i++)                       //两次调用函数,ID值继续增加
                     {
if(i==0) m_iCountourfind
else m_iCountourfind
ContourFind(x, y, zValue, false, ID++);
                     }
col[y][x]   = 0;                        //代表已经处理过
                 }
        }
    }

3)寻找等高线的过程,是在本位置的高程数值,本条等高线的高程ZValue和邻近位置的高程数值做插值处理后,得到X、Y位置并做记录。

do
    {
//-------------------------------------------------
// Interpolation...
d       = m_p3dDEMPoints[y*m_iColumns+x][2];            //取本位置的高程数值
d       = (d - z) / (d - m_p3dDEMPoints[zy*m_iColumns+zx][2]);    //以本位置的高程数值,ZValue和邻近位置的高程数值做插值处理
xPos    = m_dXMin + m_iXCellSize * (x + d * (zx - x));       //通过高度差的比例,线性插值求得X、Y位置
yPos    = m_dYMin + m_iYCellSize * (y + d * (zy - y));            //
        
if(m_iCountourfind
        {
if (m_iPointNum_one >= m_iBufferSize_one)                             
            {
m_iBufferSize_one
m_point3dtmp_one = (POINT3d *)realloc(m_point3dtmp_one,m_iBufferSize_one * sizeof(POINT3d));            //为顶点增加新的内存分配                                  
            }
if(m_point3dtmp_one!=NULL)
            {
m_point3dtmp_one[m_iPointNum_one][0] = xPos;                          //记录下X位置
m_point3dtmp_one[m_iPointNum_one][1] = yPos;                          //记录下Y位置
m_point3dtmp_one[m_iPointNum_one][2] = z+0.2;                         //此处高度为ZValue,增加.2个单位的目的是为了显示时抬高一些,便于观察。
m_iPointNum_one++;
            }
        }
else
        {
if (m_iPointNum_two >= m_iBufferSize_two)                             
            {
m_iBufferSize_two
m_point3dtmp_two = (POINT3d *)realloc(m_point3dtmp_two,m_iBufferSize_two * sizeof(POINT3d));            //为顶点增加新的内存分配                                  
            }
if(m_point3dtmp_two!=NULL)
            {
m_point3dtmp_two[m_iPointNum_two][0] = xPos;                          //记录下X位置
m_point3dtmp_two[m_iPointNum_two][1] = yPos;                          //记录下Y位置
m_point3dtmp_two[m_iPointNum_two][2] = z+0.2;                         //此处高度为ZValue,增加.2个单位的目的是为了显示时抬高一些,便于观察。
m_iPointNum_two++;
            }
        }
        
//-------------------------------------------------
// Naechstes (x/y) (col/row) finden...
if( !ContourFindNext(Dir, x ,y ,doRow) )              //x、y将发生增或减的变化,doRow也改变数值
doContinue = ContourFindNext(Dir, x, y, doRow);
Dir     = (Dir
//-------------------------------------------------
// Loeschen und initialisieren...
if(doRow)
        {
row[y][x]   = 0;                                                   //表示已经处理过
zx         = x + 1;                                                 //重新计算数值
zy          = y;
        }
else
        {
col[y][x]   = 0;                                                          //表示已经处理过
zx          = x;                                                          //重新计算数值
zy          = y
        }
    }
while(doContinue);

4)寻找等高线过程结束的条件:

booldoContinue;
if(doRow)
    {
switch(Dir)                              //邻域上个方向的判断
        {
case 0:// Norden
if(row[y+1][x
y++;                     Dir=0; doContinue=true; break; }
case 1:// Nord-Ost
if(col[y ][x+1])
x++;             doRow=false;Dir=1; doContinue=true; break; }
case 2:// Osten ist nicht...
case 3:// Sued-Ost
if(y-1>=0) if(col[y-1][x+1])
x++;    y--;    doRow=false;Dir=3; doContinue=true; break; }
case 4:// Sueden
if(y-1>=0) if(row[y-1][x
y--;                     Dir=4; doContinue=true; break; }
case 5:// Sued-West
if(y-1>=0) if(col[y-1][x
y--;    doRow=false;Dir=5; doContinue=true; break; }
case 6:// Westen ist nicht...
case 7:// Nord-West
if(col[y ][x
doRow=false;Dir=7; doContinue=true; break; }
default:
Dir=0; doContinue=false;
        }
    }
else
    {
switch(Dir)                                   //邻域上个方向的判断
        {
case 0:// Norden ist nicht...
case 1:// Nord-Ost
if(row[y+1][x
y++;    doRow=true;      Dir=1; doContinue=true; break; }
case 2:// Osten
if(col[y ][x+1])
x++;                             Dir=2; doContinue=true; break; }
case 3:// Sued-Ost
if(row[y ][x
doRow=true;      Dir=3; doContinue=true; break; }
case 4:// Sueden ist nicht...
case 5:// Sued-West
if(x-1>=0) if(row[y ][x-1])
x--;             doRow=true;      Dir=5; doContinue=true; break; }
case 6:// Westen
if(x-1>=0) if(col[y ][x-1])
x--;                             Dir=6; doContinue=true; break; }
case 7:// Nord-West
if(x-1>=0) if(row[y+1][x-1])
x--;    y++;    doRow=true;      Dir=7; doContinue=true; break; }
default:
Dir=0; doContinue=false;
        }
    }
return(doContinue);


原始DEM显示图:

dem数据怎么转换为png dem数据如何生成_数据



生成的等高线图:

dem数据怎么转换为png dem数据如何生成_邻域_02