3DGIS

研究OpenGL,GPU和GIS

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  41 随笔 :: 1 文章 :: 68 评论 :: 8 引用
    美国USGS的DEM数据读取的程序代码已经提供,关键是对文件头的处理要注意每个字段的含义,到数据部分需要注意XY轴的最大和最小数值,Z轴的最大最小数值提取的时候,要防止NodataValue数据的干扰,因为部分数据是NodataValue,会非常小或大。
    

读取美国USGS的DEM数据程序

string quadName,processInfo;
    double seGeoCornerX,seGeoCornerY;
    long processCode;
    string sectionIndicator, mapCenterCode;
       long levelCode,elevPattern,groundRefSysCode,groundRefSysZone,groundRefSysUnits;
       long elevUnits, numPolySides;
       DEMPointVector demCorners;
    double counterclockAngle;
    long elevAccuracyCode;
      
       double spatialResX,spatialResY,spatialResZ;
       long profileRows,profileColumns;
    long largeContInt,maxSourceUnits,smallContInt,minSourceUnits;
    long sourceDate, inspRevDate;
    string inspFlag;
    long valFlag;
    long suspectVoidFlg;
    long vertDatum,horizDatum;
    long dataEdition;
    long perctVoid;
    long westEdgeFlag,northEdgeFlag,eastEdgeFlag,southEdgeFlag;
    double vertDatumShift;               //通过文件流得到DEM文件头信息
   
   
    char bufstr[1024];
    char temp[1024];
    long i;

     DEMUtil::getRecord(dem,bufstr);             //从文件流中获得信息

     strncpy(temp, bufstr, 40);              //从获得信息中拷贝到临时变量
     temp[40] = '\0';
     quadName = temp;

     strncpy(temp,bufstr+40,40);              //从获得信息中拷贝到临时变量
     temp[40] = '\0';
     processInfo = temp;
    
     DEMUtil::getDouble(bufstr, 109, 13, seGeoCornerX);
     DEMUtil::getDouble(bufstr, 122, 13, seGeoCornerY);
     processCode = DEMUtil::getLong(bufstr, 135, 1);         //135 = 122 + 13

     strncpy(temp,bufstr+137,3);
     temp[3] = '\0';
     sectionIndicator = temp;

     strncpy(temp,bufstr+140,4);
     temp[4] = '\0';
     mapCenterCode = temp;
     
     levelCode = DEMUtil::getLong(bufstr, 144, 6);         //level编码
     elevPattern = DEMUtil::getLong(bufstr, 150, 6);
     groundRefSysCode = DEMUtil::getLong(bufstr, 156, 6);
     groundRefSysZone = DEMUtil::getLong(bufstr, 162, 6);
     groundRefSysUnits = DEMUtil::getLong(bufstr, 528, 6);       //得到平面上使用的度量单位
     elevUnits = DEMUtil::getLong(bufstr, 534, 6);         //得到Z轴上的度量单位
     numPolySides = DEMUtil::getLong(bufstr, 540, 6);

     for (i = 0; i < 4; i++)
     {
     double x,y;
     long pos = 546 + (i * 48);
     DEMUtil::getDouble(bufstr, pos, 24, x);
     DEMUtil::getDouble(bufstr, pos + 24, 24, y);
     demCorners.push_back(DEMPoint(x,y));          //各角部顶点数据
     }

     DEMUtil::getDouble(bufstr, 738, 24, m_dminElevation);       //得到最小高程数值
     DEMUtil::getDouble(bufstr, 762, 24, m_dmaxElevation);       //得到最大高程数值
     DEMUtil::getDouble(bufstr, 786, 24, counterclockAngle );
     elevAccuracyCode = DEMUtil::getLong(bufstr, 810, 6);
     DEMUtil::getDouble(bufstr, 816, 12, spatialResX);        //X轴分辨率
     DEMUtil::getDouble(bufstr, 828, 12, spatialResY);        //Y轴分辨率
     DEMUtil::getDouble(bufstr, 840, 12, spatialResZ);        //Z轴分辨率
     profileRows = DEMUtil::getLong(bufstr, 852, 6);         //得到行数
     profileColumns = DEMUtil::getLong(bufstr, 858, 6);        //得到列数
     largeContInt = DEMUtil::getLong(bufstr, 864, 5);
     maxSourceUnits = DEMUtil::getLong(bufstr, 869, 1);
     smallContInt = DEMUtil::getLong(bufstr, 870, 5);
     minSourceUnits = DEMUtil::getLong(bufstr, 875, 1);
     sourceDate = DEMUtil::getLong(bufstr, 876, 4);
     inspRevDate = DEMUtil::getLong(bufstr, 880, 4);
    
     strncpy(temp, bufstr+884,1);
     temp[1]='\0';
     inspFlag = temp;

     valFlag = DEMUtil::getLong(bufstr, 885, 1);
     suspectVoidFlg = DEMUtil::getLong(bufstr, 886, 2);
     vertDatum = DEMUtil::getLong(bufstr, 888, 2);   //垂直
     horizDatum = DEMUtil::getLong(bufstr, 890, 2);      //水平
     dataEdition = DEMUtil::getLong(bufstr, 892, 4);
     perctVoid = DEMUtil::getLong(bufstr, 896, 4);
     westEdgeFlag = DEMUtil::getLong(bufstr, 900, 2);   //西部
     northEdgeFlag = DEMUtil::getLong(bufstr, 902, 2); //北部
     eastEdgeFlag = DEMUtil::getLong(bufstr, 904, 2);   //东部
     southEdgeFlag = DEMUtil::getLong(bufstr, 906, 2); //南部
     DEMUtil::getDouble(bufstr, 908, 7, vertDatumShift);

     m_p3dDEMGrid->SetXMin( demCorners[0].getX() );
     m_p3dDEMGrid->SetYMin( demCorners[0].getY() );
     m_p3dDEMGrid->SetXCellSize( spatialResX );
     m_p3dDEMGrid->SetYCellSize( spatialResY );
     m_p3dDEMGrid->SetColumns( profileColumns );
   
     long retval;

    retval = FillGeographic(dem,incrementalRead);

long ImportDEMDataUSGS::FillGeographic(istream& dem,bool incrementalRead)
{
if (m_bReadingFileHeadOnlyOnce)
{
   m_lCurProfile = 0;
}

    while (m_lCurProfile < m_p3dDEMGrid->GetColumns())          //断面数据还没有读完
    {
          m_vecProfiles.push_back(DEMProfile());
          dem >> m_vecProfiles.back();              //存储断面数据
          m_lCurProfile++;
          if (incrementalRead)                //倘若采用增量读法,则马上返回
             return m_p3dDEMGrid->GetColumns() - m_lCurProfile + 1;
    }
   
    int width = m_p3dDEMGrid->GetColumns();
    int height = m_vecProfiles[0].getNumberOfElevations();         //假设所有的断面和第一个断面有一样的一连串高程数值
    m_p3dDEMGrid->SetRows( height );

    m_ppt3dPoint = new POINT3d[width * height];            //added

    double dXMin = m_p3dDEMGrid->GetXMin();
    double dYMin = m_p3dDEMGrid->GetYMin();
    double dXCellSize = m_p3dDEMGrid->GetXCellSize();
    double dYCellSize = m_p3dDEMGrid->GetYCellSize();
    int i,j;
    long Index;
    for (i = 1; i < width; i++)
    {
         DEMElevationVector const& elev = m_vecProfiles[i].getElevations();     //得到这个断面的一连串高程数值
   for (j = 0; j < height; j++)
   {
             Index = width * j + i;
    m_ppt3dPoint[Index][0]=dXMin + i*dXCellSize;            
    m_ppt3dPoint[Index][1]=dYMin + j*dYCellSize;     
    m_ppt3dPoint[Index][2]=elev[j]/m_dPlaneHeightRadio;       //保证三轴单位统一
   }
    }

i=0;                     //为了填充数组第一列
DEMElevationVector const& elev_1 = m_vecProfiles[1].getElevations();
for(j = 0; j < elev_1.size();j++)
{
    Index = width * j + i;
    m_ppt3dPoint[Index][0]=dXMin + i*dXCellSize;        
    m_ppt3dPoint[Index][1]=dYMin + j*dYCellSize;
    m_ppt3dPoint[Index][2]=elev_1[j]/m_dPlaneHeightRadio;    
  
}
m_vecProfiles.erase(m_vecProfiles.begin(), m_vecProfiles.end());
return 0;
}

posted on 2007-10-31 20:32 武汉侯涛 阅读(828) 评论(7)  编辑 收藏

评论

#1楼  2008-04-19 15:34 wss [未注册用户]
请问这是用JAVA还是VC++写的代码?
  回复  引用    

是在VC 2005 平台下写的,用C++语言.
  回复  引用    

#3楼  2008-04-20 19:28 wss [未注册用户]
有没有用VC++,OpenGL环境写的读取的代码啊?
  回复  引用    

#4楼  2008-04-20 21:51 wss [未注册用户]
因为我的毕业设计做的东西要用到这个,而且必须用VC来做。看到你的代码很兴奋,只是我对编程不熟,不知道怎么把它转成VC++.如果你有VC++的代码,能不能麻烦你传到我邮箱?不管怎样,谢谢你把这段代码发到你的博客。
  回复  引用    

#5楼 [楼主] 2008-04-21 20:38 武汉侯涛      
To wss,你还可以参考USGS早期的代码:http://www.cnblogs.com/Files/wuhanhoutao/dem3d.rar
  回复  引用  查看    

#6楼  2008-04-22 18:49 wss [未注册用户]
非常的感谢你,你真的是非常热心的人。
  回复  引用    

#7楼  2008-08-09 12:59 sharper [未注册用户]
你好,看到了你关于几种格式DEM数据的读取,深受启发,十分感谢!
我毕业设计主要思路就是读取USGSDEM数据实现三维地形可视化,并进行交互操作,但我对vc++不是很熟,现在正在学习中,你能否在百忙之中解释一下那个代码中各个模块实现的功能,以及运行方式,谢谢了!
可以直接给我发邮件!

  回复  引用    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      


相关链接: