第05章 09 使用Lookup绘制地形数据高程着色图

在VTK(Visualization Toolkit)中,可以使用颜色查找表(Lookup Table,简称LUT)来根据高程数据对地形进行着色。以下是一个示例代码,展示了如何使用VTK和C++来读取地形数据,并使用颜色查找表根据高程进行着色。

示例代码

cpp 复制代码
#include <vtkSmartPointer.h>
#include <vtkDEMReader.h>
#include <vtkImageData.h>
#include <vtkPolyData.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkColorTransferFunction.h>
#include <vtkLookupTable.h>
#include <vtkProperty.h>
#include <vtkCamera.h>

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        std::cerr << "Usage: " << argv[0] << " <DEMFileName>" << std::endl;
        return EXIT_FAILURE;
    }

    // 读取DEM数据
    vtkSmartPointer<vtkDEMReader> reader = vtkSmartPointer<vtkDEMReader>::New();
    reader->SetFileName(argv[1]);
    reader->Update();

    // 获取ImageData
    vtkSmartPointer<vtkImageData> imageData = reader->GetOutput();

    // 创建颜色查找表
    vtkSmartPointer<vtkLookupTable> lookupTable = vtkSmartPointer<vtkLookupTable>::New();
    lookupTable->SetTableRange(imageData->GetScalarRange());
    lookupTable->SetNumberOfTableValues(256);
    lookupTable->Build();

    // 设置颜色映射,例如从低到高依次为蓝色到绿色到黄色到红色
    for (int i = 0; i < 256; i++)
    {
        double value = lookupTable->GetTableValue(i)[0];
        double h = (value - lookupTable->GetTableRange()[0]) / (lookupTable->GetTableRange()[1] - lookupTable->GetTableRange()[0]);
        double r, g, b;
        if (h < 0.25)
        {
            r = 0.0;
            g = 4 * h;
            b = 1.0;
        }
        else if (h < 0.5)
        {
            r = 0.0;
            g = 1.0;
            b = 1.0 - 4 * (h - 0.25);
        }
        else if (h < 0.75)
        {
            r = 4 * (h - 0.5);
            g = 1.0;
            b = 0.0;
        }
        else
        {
            r = 1.0;
            g = 1.0 - 4 * (h - 0.75);
            b = 0.0;
        }
        lookupTable->SetTableValue(i, r, g, b, 1.0);
    }

    // 创建几何表示
    double bounds[6];
    imageData->GetBounds(bounds);
    double dx = (bounds[1] - bounds[0]) / imageData->GetDimensions()[0];
    double dy = (bounds[3] - bounds[2]) / imageData->GetDimensions()[1];

    vtkSmartPointer<vtkImageDataGeometryFilter> geometryFilter = vtkSmartPointer<vtkImageDataGeometryFilter>::New();
    geometryFilter->SetInputData(imageData);
    geometryFilter->Update();

    // 创建mapper和actor
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(geometryFilter->GetOutputPort());
    mapper->SetLookupTable(lookupTable);
    mapper->SetScalarRange(imageData->GetScalarRange());

    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    // 创建renderer, renderWindow, interactor
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);
    renderer->SetBackground(0.1, 0.2, 0.4);

    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(800, 600);

    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);

    // 设置相机
    renderer->GetActiveCamera()->SetPosition(0, 0, 1);
    renderer->GetActiveCamera()->SetFocalPoint(0, 0, 0);
    renderer->GetActiveCamera()->SetViewUp(0, 1, 0);
    renderer->ResetCamera();

    // 开始渲染和交互
    renderWindow->Render();
    interactor->Start();

    return EXIT_SUCCESS;
}

代码说明

  1. 读取DEM数据 :使用 vtkDEMReader 读取地形数据文件(如DEM文件)。
  2. 创建颜色查找表 :使用 vtkLookupTable 创建一个颜色查找表,根据高程数据的范围设置颜色映射。
  3. 设置颜色映射:通过循环设置查找表的每个条目的颜色,实现从低到高的颜色渐变。
  4. 创建几何表示 :使用 vtkImageDataGeometryFilter 将ImageData转换为PolyData,以便进行渲染。
  5. 创建mapper和actor :使用 vtkPolyDataMapper 映射PolyData,并将颜色查找表应用到mapper上。
  6. 设置渲染器、渲染窗口和交互器:创建渲染器、渲染窗口和交互器,并设置相机视角。
  7. 渲染和交互:渲染窗口并启动交互循环。

编译和运行

确保你已经安装了VTK库,并正确配置了开发环境。编译和运行代码时,需要提供DEM数据文件作为命令行参数。

复制代码
g++ -std=c++11 -o terrain_rendering terrain_rendering.cpp -lvtkCommonCore -lvtkCommonDataModel -lvtkIOImage -lvtkRenderingCore -lvtkRenderingOpenGL2 -lvtkInteractionStyle
./terrain_rendering /path/to/dem/file

注意事项

  • 需要根据具体的DEM文件格式选择合适的读取器,例如 vtkDEMReader 适用于某些DEM格式。
  • 颜色映射可以根据需求自定义,这里示例中使用了从蓝色到绿色到黄色到红色的渐变。
  • 根据数据的大小和复杂度,可能需要调整渲染设置以获得更好的性能和视觉效果。
相关推荐
界面开发小八哥8 分钟前
数据可视化图表库LightningChart JS v8.0上线:全新图例系统 + 数据集重构
javascript·信息可视化·数据可视化·lightningchart
THMAIL17 分钟前
深度学习从入门到精通 - AutoML与神经网络搜索(NAS):自动化模型设计未来
人工智能·python·深度学习·神经网络·算法·机器学习·逻辑回归
金古圣人25 分钟前
hot100 滑动窗口
数据结构·c++·算法·leetcode·哈希算法
kebeiovo28 分钟前
算法-二叉树的序列化与反序列化
算法
蒹葭玉树30 分钟前
【C++上岸】C++常见面试题目--算法篇(第二十期)
c++·算法·面试
JJJJ_iii34 分钟前
【左程云算法03】对数器&算法和数据结构大致分类
数据结构·算法·分类
轮到我狗叫了44 分钟前
牛客.小红的子串牛客.kotori和抽卡牛客.循环汉诺塔牛客.ruby和薯条
java·开发语言·算法
高山有多高1 小时前
详解文件操作
c语言·开发语言·数据库·c++·算法
乌萨奇也要立志学C++1 小时前
【洛谷】队列相关经典算法题详解:模板队列、机器翻译、海港
算法
YuTaoShao2 小时前
【LeetCode 热题 100】49. 字母异位词分组
算法·leetcode·哈希算法