gisempire100
捉鬼专家
捉鬼专家
  • 注册日期2004-08-13
  • 发帖数552
  • QQ
  • 铜币2462枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:2500回复:0

由DEM格网数据生成等高线

楼主#
更多 发布于:2008-01-15 23:25
现阶段DEM数据的来源不再仅仅局限于原来保存的纸质地形图的跟踪数字化,可能是采用激光测距仪配合地面控制点生成,由此产生的DEM格网数据可能需要生成等高线图,以作为基础地理数据或底图。此工艺流程与原来跟踪等高线来生产DEM的目标刚好相反,是在拥有DEM数据后反而希望生成等高线。下面介绍具体的流程和参考代码:
<P >1)     针对格网中每个基本单元,创建一个参考变量,即YuanSu[j](0<=i<=Row; 0<=j<=Column)同时分配内存。此参考变量赋值0或1,其中1代表此位置处的邻域高程数值将发生变化,那么此位置将绘制等高线。</P>
<P  align=left>col      = (char **)calloc(m_iRows, sizeof(char *));                           //指向指针的指针初始化</P>
<P  align=left>    row     = (char **)calloc(m_iRows, sizeof(char *));                           //指向指针的指针初始化</P>
<P  align=left>    for(y=0; y<m_iRows; y++)                                                      //m_iRows:格网的行数</P>
<P  align=left>    {</P>
<P  align=left>        col[y] = (char *)calloc(m_iColumns, sizeof(char));        //每个单元分配内存,m_iColumns : 格网的列数</P>
<P  align=left>        row[y] = (char *)calloc(m_iColumns, sizeof(char));         //每个单元分配内存</P>
<P  align=left>    }</P>
<P>2)在以高程数值从最小值开始依次递增的最外部一层循开始,接着对整个格网数据进行循环,在给参考变量YuanSu[j]赋数值0或1之后,然后以YuanSu[j] == 1为判断条件,寻找并记录等高线。</P>
<P  align=left>       for(zValue=zMin, ID=0; zValue<=zMax; zValue+=zStep)           //从最小Z数值计算起,知道最大Z数值</P>
<P  align=left>    {</P>
<P  align=left>        //-------------------------------------------------</P>
<P  align=left>        // Step1: Find Border Cells                //找到边界单元,边界:高度趋势发生改变的地方。</P>
<P  align=left>        for(y=0; y<m_iRows-1; y++)</P>
<P  align=left>            for(x=0; x<m_iColumns-1; x++)</P>
<P  align=left>                 if( m_p3dDEMPoints[y*m_iColumns+x][2] >= zValue )</P>
<P  align=left>                 {</P>
<P  align=left>                     row[y][x]   = m_p3dDEMPoints[y*m_iColumns+(x+1)][2] < zValue ? 1 : 0;            //‘’就代表边界</P>
<P  align=left>                     col[y][x]   = m_p3dDEMPoints[(y+1)*m_iColumns+x][2] < zValue ? 1 : 0;</P>
<P  align=left>                 }</P>
<P  align=left>                 else</P>
<P  align=left>                 {</P>
<P  align=left>                     row[y][x]   = m_p3dDEMPoints[y*m_iColumns+(x+1)][2] >= zValue ? 1 : 0;            //‘’就代表边界</P>
<P  align=left>                     col[y][x]   = m_p3dDEMPoints[(y+1)*m_iColumns+x][2] >= zValue ? 1 : 0;</P>
<P  align=left>                 }</P>
<P  align=left>        //-------------------------------------------------</P>
<P  align=left>        // Step2: Interpolation + Delineation</P>
<P  align=left>        for(y=0; y<m_iRows-1; y++)</P>
<P  align=left>            for(x=0; x<m_iColumns-1; x++)</P>
<P  align=left>            {</P>
<P  align=left>                 if(row[y][x])                                 //如果数值为</P>
<P  align=left>                 {                </P>
<P  align=left>                     for(i=0; i<2; i++)                         //两次调用函数,ID值增加</P>
<P  align=left>                     {</P>
<P  align=left>                         if(i==0) m_iCountourfind = 0;</P>
<P  align=left>                         else m_iCountourfind = 1;</P>
<P  align=left>                         ContourFind(x, y, zValue, true, ID++);</P>
<P  align=left>                     }</P>
<P  align=left>                     row[y][x]   = 0;                          //代表已经处理过</P>
<P  align=left>                 </P>
<P  align=left>                 }</P>
<P  align=left>                 if(col[y][x])                                 //如果数值为</P>
<P  align=left>                 {                </P>
<P  align=left>                     for(i=0; i<2; i++)                       //两次调用函数,ID值继续增加</P>
<P  align=left>                     {</P>
<P  align=left>                         if(i==0) m_iCountourfind = 0;</P>
<P  align=left>                         else m_iCountourfind = 1;</P>
<P  align=left>                         ContourFind(x, y, zValue, false, ID++);</P>
<P  align=left>                     }</P>
<P  align=left>                     col[y][x]   = 0;                        //代表已经处理过</P>
<P  align=left>                 }</P>
<P  align=left>        }</P>
<P>    }</P>
<P>3)寻找等高线的过程,是在本位置的高程数值,本条等高线的高程ZValue和邻近位置的高程数值做插值处理后,得到X、Y位置并做记录。</P>
<P  align=left>       do</P>
<P  align=left>    {</P>
<P  align=left>        //-------------------------------------------------</P>
<P  align=left>        // Interpolation...</P>
<P  align=left>        d       = m_p3dDEMPoints[y*m_iColumns+x][2];            //取本位置的高程数值</P>
<P  align=left>        d       = (d - z) / (d - m_p3dDEMPoints[zy*m_iColumns+zx][2]);    //以本位置的高程数值,ZValue和邻近位置的高程数值做插值处理</P>
<P  align=left>        xPos    = m_dXMin + m_iXCellSize * (x + d * (zx - x));       //通过高度差的比例,线性插值求得X、Y位置</P>
<P  align=left>        yPos    = m_dYMin + m_iYCellSize * (y + d * (zy - y));            //</P>
<P  align=left>        </P>
<P  align=left>        if(m_iCountourfind == 0)</P>
<P  align=left>        {</P>
<P  align=left>            if (m_iPointNum_one >= m_iBufferSize_one)                             </P>
<P  align=left>            {</P>
<P  align=left>                 m_iBufferSize_one += 1024;</P>
<P  align=left>                 m_point3dtmp_one = (POINT3d *)realloc(m_point3dtmp_one,m_iBufferSize_one * sizeof(POINT3d));            //为顶点增加新的内存分配                                  </P>
<P  align=left>            }</P>
<P  align=left>            if(m_point3dtmp_one!=NULL)</P>
<P  align=left>            {</P>
<P  align=left>                 m_point3dtmp_one[m_iPointNum_one][0] = xPos;                          //记录下X位置</P>
<P  align=left>                 m_point3dtmp_one[m_iPointNum_one][1] = yPos;                          //记录下Y位置</P>
<P  align=left>                 m_point3dtmp_one[m_iPointNum_one][2] = z+0.2;                         //此处高度为ZValue,增加.2个单位的目的是为了显示时抬高一些,便于观察。</P>
<P  align=left>                 m_iPointNum_one++;</P>
<P  align=left>            }</P>
<P  align=left>        }</P>
<P  align=left>        else</P>
<P  align=left>        {</P>
<P  align=left>            if (m_iPointNum_two >= m_iBufferSize_two)                             </P>
<P  align=left>            {</P>
<P  align=left>                 m_iBufferSize_two += 1024;</P>
<P  align=left>                 m_point3dtmp_two = (POINT3d *)realloc(m_point3dtmp_two,m_iBufferSize_two * sizeof(POINT3d));            //为顶点增加新的内存分配                                  </P>
<P  align=left>            }</P>
<P  align=left>            if(m_point3dtmp_two!=NULL)</P>
<P  align=left>            {</P>
<P  align=left>                 m_point3dtmp_two[m_iPointNum_two][0] = xPos;                          //记录下X位置</P>
<P  align=left>                 m_point3dtmp_two[m_iPointNum_two][1] = yPos;                          //记录下Y位置</P>
<P  align=left>                 m_point3dtmp_two[m_iPointNum_two][2] = z+0.2;                         //此处高度为ZValue,增加.2个单位的目的是为了显示时抬高一些,便于观察。</P>
<P  align=left>                 m_iPointNum_two++;</P>
<P  align=left>            }</P>
<P  align=left>        }</P>
<P  align=left>        </P>
<P  align=left>        //-------------------------------------------------</P>
<P  align=left>        // Naechstes (x/y) (col/row) finden...</P>
<P  align=left>        if( !ContourFindNext(Dir, x ,y ,doRow) )              //x、y将发生增或减的变化,doRow也改变数值</P>
<P  align=left>            doContinue = ContourFindNext(Dir, x, y, doRow);</P>
<P  align=left>        Dir     = (Dir + 5) % 8;</P>
<P  align=left>        //-------------------------------------------------</P>
<P  align=left>        // Loeschen und initialisieren...</P>
<P  align=left>        if(doRow)</P>
<P  align=left>        {</P>
<P  align=left>            row[y][x]   = 0;                                                   //表示已经处理过</P>
<P  align=left>            zx         = x + 1;                                                 //重新计算数值</P>
<P  align=left>            zy          = y;</P>
<P  align=left>        }</P>
<P  align=left>        else</P>
<P  align=left>        {</P>
<P  align=left>            col[y][x]   = 0;                                                          //表示已经处理过</P>
<P  align=left>            zx          = x;                                                          //重新计算数值</P>
<P  align=left>            zy          = y + 1;</P>
<P  align=left>        }</P>
<P  align=left>    }</P>
<P>    while(doContinue);   </P>
<P>4)寻找等高线过程结束的条件:</P>
<P  align=left>bool    doContinue;</P>
<P  align=left>    if(doRow)</P>
<P  align=left>    {</P>
<P  align=left>        switch(Dir)                              //邻域上个方向的判断</P>
<P  align=left>        {</P>
<P  align=left>        case 0:// Norden</P>
<P  align=left>            if(row[y+1][x ])</P>
<P  align=left>            {           y++;                     Dir=0; doContinue=true; break; }</P>
<P  align=left>        case 1:// Nord-Ost</P>
<P  align=left>            if(col[y ][x+1])</P>
<P  align=left>            {   x++;             doRow=false;Dir=1; doContinue=true; break; }</P>
<P  align=left>        case 2:// Osten ist nicht...</P>
<P  align=left>        case 3:// Sued-Ost</P>
<P  align=left>            if(y-1>=0) if(col[y-1][x+1])</P>
<P  align=left>            {   x++;    y--;    doRow=false;Dir=3; doContinue=true; break; }</P>
<P  align=left>        case 4:// Sueden</P>
<P  align=left>            if(y-1>=0) if(row[y-1][x ])</P>
<P  align=left>            {           y--;                     Dir=4; doContinue=true; break; }</P>
<P  align=left>        case 5:// Sued-West</P>
<P  align=left>            if(y-1>=0) if(col[y-1][x ])</P>
<P  align=left>            {           y--;    doRow=false;Dir=5; doContinue=true; break; }</P>
<P  align=left>        case 6:// Westen ist nicht...</P>
<P  align=left>        case 7:// Nord-West</P>
<P  align=left>            if(col[y ][x ])</P>
<P  align=left>            {                    doRow=false;Dir=7; doContinue=true; break; }</P>
<P  align=left>        default:</P>
<P  align=left>            Dir=0; doContinue=false;</P>
<P  align=left>        }</P>
<P  align=left>    }</P>
<P  align=left>    else</P>
<P  align=left>    {</P>
<P  align=left>        switch(Dir)                                   //邻域上个方向的判断</P>
<P  align=left>        {</P>
<P  align=left>        case 0:// Norden ist nicht...</P>
<P  align=left>        case 1:// Nord-Ost</P>
<P  align=left>            if(row[y+1][x ])</P>
<P  align=left>            {           y++;    doRow=true;      Dir=1; doContinue=true; break; }</P>
<P  align=left>        case 2:// Osten</P>
<P  align=left>            if(col[y ][x+1])</P>
<P  align=left>            {   x++;                             Dir=2; doContinue=true; break; }</P>
<P  align=left>        case 3:// Sued-Ost</P>
<P  align=left>            if(row[y ][x ])</P>
<P  align=left>            {                    doRow=true;      Dir=3; doContinue=true; break; }</P>
<P  align=left>        case 4:// Sueden ist nicht...</P>
<P  align=left>        case 5:// Sued-West</P>
<P  align=left>            if(x-1>=0) if(row[y ][x-1])</P>
<P  align=left>            {   x--;             doRow=true;      Dir=5; doContinue=true; break; }</P>
<P  align=left>        case 6:// Westen</P>
<P  align=left>            if(x-1>=0) if(col[y ][x-1])</P>
<P  align=left>            {   x--;                             Dir=6; doContinue=true; break; }</P>
<P  align=left>        case 7:// Nord-West</P>
<P  align=left>            if(x-1>=0) if(row[y+1][x-1])</P>
<P  align=left>            {   x--;    y++;    doRow=true;      Dir=7; doContinue=true; break; }</P>
<P  align=left>        default:</P>
<P  align=left>            Dir=0; doContinue=false;</P>
<P  align=left>        }</P>
<P  align=left>    }</P>
<P>    return(doContinue);<BR><BR>原始DEM显示图:<BR><IMG src="http://www.cnblogs.com/images/cnblogs_com/wuhanhoutao/120009/r_DEM_Original.jpg" border=0><BR><BR>生成的等高线图:<BR><IMG src="http://www.cnblogs.com/images/cnblogs_com/wuhanhoutao/120009/r_To_Countour.jpg" border=0><BR></P>
喜欢0 评分0
A friend is never known till a man has need. ...CL
游客

返回顶部