高程DEM文件操作

1 下载高程DEM文件网站

在这里插入图片描述

在这里插入图片描述

  • 注册邮箱,即可登录下载

在这里插入图片描述

  • 选择对应的经纬度文件下载即可
  • 直接高级检索,下载对应区域
    在这里插入图片描述

2 查找安徽池州高程数据

在这里插入图片描述
在这里插入图片描述

3 高程文件合并与读取

  • 高程文件合并,gdal_merge 安装gdal库时自带的脚步程序
xhome@ubuntu:~/dem$ gdal_merge.py -o merged_dem.tif ./dem_chizhou/ASTGTMV003_*_dem.tif
0...10...20...30...40...50...60...70...80...90...100 - done.
#include <iostream>
#include <gdal/gdal_priv.h>
#include <gdal/ogr_spatialref.h>
#include <iomanip>  // 用于控制输出格式


// g++ gdal_demo.cpp -o gdal_demo -lgdal
int main(int argc, char* argv[]) {
    // 检查命令行参数
    if (argc != 2) {
        std::cerr << "用法: " << argv[0] << " <输入TIFF文件路径>" << std::endl;
        return 1;
    }

    const char* tifFilePath = argv[1];

    // 注册GDAL驱动
    GDALAllRegister();

    // 打开TIFF文件
    GDALDataset* dataset = (GDALDataset*)GDALOpen(tifFilePath, GA_ReadOnly);
    if (dataset == nullptr) {
        std::cerr << "错误:无法打开文件 " << tifFilePath << std::endl;
        return 1;
    }

    // 获取地理变换参数
    double geoTransform[6];
    if (dataset->GetGeoTransform(geoTransform) != CE_None) {
        std::cerr << "错误:无法获取地理变换参数" << std::endl;
        GDALClose(dataset);
        return 1;
    }

    // 获取图像尺寸
    int width = dataset->GetRasterXSize();
    int height = dataset->GetRasterYSize();

    // 获取高程数据波段(假设是第一个波段)
    GDALRasterBand* band = dataset->GetRasterBand(1);
    if (band == nullptr) {
        std::cerr << "错误:无法获取高程数据波段" << std::endl;
        GDALClose(dataset);
        return 1;
    }

    // 获取坐标参考系统
    const char* proj = dataset->GetProjectionRef();
    OGRSpatialReference srcSRS;
    if (proj != nullptr && strlen(proj) > 0) {
        if (srcSRS.importFromWkt(&proj) != OGRERR_NONE) {
            std::cerr << "警告:无法解析坐标参考系统,默认使用WGS84" << std::endl;
            srcSRS.SetWellKnownGeogCS("WGS84");
        }
    } else {
        std::cerr << "警告:未找到坐标参考系统,默认使用WGS84" << std::endl;
        srcSRS.SetWellKnownGeogCS("WGS84");
    }

    // 准备目标坐标系(WGS84)
    OGRSpatialReference dstSRS;
    dstSRS.SetWellKnownGeogCS("WGS84");

    // 创建坐标转换对象
    OGRCoordinateTransformation* coordTrans = 
        OGRCreateCoordinateTransformation(&srcSRS, &dstSRS);
    if (coordTrans == nullptr) {
        std::cerr << "警告:无法创建坐标转换对象,将输出原始坐标" << std::endl;
    }

    // 分配行缓冲区
    float* pafScanline = new float[width];
    if (pafScanline == nullptr) {
        std::cerr << "错误:无法分配内存" << std::endl;
        if (coordTrans) OCTDestroyCoordinateTransformation(coordTrans);
        GDALClose(dataset);
        return 1;
    }

    // 遍历所有像素
    for (int y = 0; y < height; y++) {
        // 读取一行高程数据
        if (band->RasterIO(GF_Read, 0, y, width, 1, pafScanline, width, 1, GDT_Float32, 0, 0) != CE_None) {
            std::cerr << "警告:第" << y << "行读取失败" << std::endl;
            continue;
        }

        for (int x = 0; x < width; x++) {
            // 计算像素坐标对应的地理坐标
            double pixelX = geoTransform[0] + x * geoTransform[1] + y * geoTransform[2];
            double pixelY = geoTransform[3] + x * geoTransform[4] + y * geoTransform[5];

            // 如果需要坐标转换
            if (coordTrans) {
                // 创建临时变量用于转换
                double tmpX = pixelX;
                double tmpY = pixelY;
                if (!coordTrans->Transform(1, &tmpX, &tmpY)) {
                    std::cerr << "警告:坐标转换失败,使用原始坐标" << std::endl;
                } else {
                    pixelX = tmpX;
                    pixelY = tmpY;
                }
            }

            // 获取高程值
            float elevation = pafScanline[x];

            // 输出结果(经度、纬度、高程)
            std::cout << std::fixed << std::setprecision(6) 
                      << pixelX << "," << pixelY << "," 
                      << std::setprecision(2) << elevation << std::endl;
        }
    }

    // 释放资源
    delete[] pafScanline;
    if (coordTrans) OCTDestroyCoordinateTransformation(coordTrans);
    GDALClose(dataset);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

guangshui516

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值