パスワードを忘れた? アカウント作成
418606 journal

j3259の日記: 地形 (terrain)

日記 by j3259

脳味噌ぶら~ん link集/GIS系というページを見つける。モデルのファイルフォーマットでもお世話になったけど、地形データもカバーしてる。この管理人の You&I という人はなんかすごい人だ。

USGS(米地質調査所)の DEM という高度地図のファイルフォーマットを使って地形をレンダリングするのにGDALというのが使えそうだなと思ってます。Windows でのバイナリが vterrain.org で配布されてる。libpng13.dll も一緒にダウンロードする必要あり。

データには10-meter DEM files in Victoriaを使ってみる。

USGS DEM の仕様は概要仕様を一応目を通した。10-meter DEM は幸い "north up" だったけど、目の粗い普通の DEM は地球の北と UTM(ユニバーサル横メルカトル)地図の北がずれるので注意。あと、-32767 というのは void もしくはエラー容疑の値。地面の真ん中だとフィルタかけて補正する必要があると思うけど、海面っぽい場合は 0。
チュートリアルに従って DEM を読み込んでみたコード

    HeightMap * DEMLoader::load(const string& a_fileName)
    {
        GDALDataset * dataset;
        GDALAllRegister();
        dataset = (GDALDataset *) GDALOpen(a_fileName.c_str(), GA_ReadOnly);
 
        cout << "Driver: "
            << dataset->GetDriver()->GetDescription() << "/"
            << dataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME) << endl;
        cout << "Size is "
            << dataset->GetRasterXSize() << "x"
            << dataset->GetRasterYSize() << "x"
            << dataset->GetRasterCount() << endl;
        if (dataset->GetProjectionRef() != NULL) {
            cout << "Projection is " << dataset->GetProjectionRef() << endl;
        } // if
        double geoTransform[6];
        if (dataset->GetGeoTransform(geoTransform) == CE_None) {
            cout << "Origin = ("
                << geoTransform[0] << ", " << geoTransform[3] << ")" << endl;
            cout << "Pixel Size = ("
                << geoTransform[1] << ", " << geoTransform[5] << ")" << endl;
            cout << "Incline = ("
                << geoTransform[2] << ", " << geoTransform[4] << ")" << endl;
        } // if
 
        GDALRasterBand  * band;
        band = dataset->GetRasterBand(1);
        int xSize = band->GetXSize();
        int ySize = band->GetYSize();
        cout << "Band Type: " << GDALGetDataTypeName(GDALGetRasterDataType(band)) << endl;
 
        HeightMap * retval = new HeightMap();
        retval->setSize(xSize, ySize);
 
        cout << "Reading... ";
        for (int i = 0; i < xSize; i++) {
            band->RasterIO(GF_Read, i, 0, 1, ySize,
                retval->getColumn(i), 1, ySize, GDT_Float32,
                0, 0);
        } // for i
        cout << "Done" << endl;
 
        for (int i = 0; i < 12; i++) {
            cout << "(";
            for (int j = 0; j < 100; j++) {
                cout << retval->getHeight(i, j) << ", ";
            } // for j
            cout << ")," << endl;
        } // for i
 
        GDALClose(dataset);
 
        return retval;
    }

戻り値の HeightMap というクラスは float の二次元配列をクラスにしただけの簡単なもの。
DEMLoader はファイル読み込みに専念して LOD は別クラスで実装する。

#ifndef HEIGHT_MAP_H_
#define HEIGHT_MAP_H_
 
#include <iostream>
#include <string>
#include <cmath>
 
using namespace std;
 
namespace eed3si9n
{
class HeightMap
{
public:
    HeightMap();
    ~HeightMap();
    void setSize(int a_xSize, int a_ySize);
    float * getColumn(int a_xOffset);
    float getHeight(int a_xOffset, int a_yOffset);
private:
    float ** m_heights;
    int m_xSize;
    int m_ySize;
};
 
inline HeightMap::HeightMap():
    m_heights(NULL),
    m_xSize(0),
    m_ySize(0)
{
}
 
inline HeightMap::~HeightMap()
{
    if (m_heights == NULL) {
        return;
    } // if
 
    for (int i = 0; i < m_xSize; i++) {
        float * buffer = m_heights[i];
        delete buffer;
    } // for i
 
    delete [] m_heights;
}
 
inline void HeightMap::setSize(int a_xSize, int a_ySize)
{
    m_xSize = a_xSize;
    m_ySize = a_ySize;
 
    m_heights = new float *[m_xSize];
    for (int i = 0; i < m_xSize; i++) {
        m_heights[i] = new float[m_ySize];
    } // for i
}
 
inline float * HeightMap::getColumn(int a_xOffset)
{
    return m_heights[a_xOffset];
}
 
inline float HeightMap::getHeight(int a_xOffset, int a_yOffset)
{
    return m_heights[a_xOffset][a_yOffset];
}
 
//-------------------------------------------------
}
 
#endif /*HEIGHT_MAP_H_*/

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

弘法筆を選ばず、アレゲはキーボードを選ぶ -- アレゲ研究家

読み込み中...