阅读:2666回复:0
由DEM格网数据生成等高线
现阶段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> |
|
|