首页 > 其他分享 >使用ChatGPT写一个GDALDatasetRasterIOEx功能增强函数

使用ChatGPT写一个GDALDatasetRasterIOEx功能增强函数

时间:2023-04-10 14:56:16浏览次数:43  
标签:函数 int nBufXSize GDALDatasetRasterIOEx nPixelBytes nYOff ++ pLineData ChatGPT

GDALDatasetRasterIOEx函数是GDAL用来读取栅格数据文件像素数据的函数,默认是不支持参数传入的读取窗口范围超出栅格的实际范围的,但是很多时候,需要按照地理范围读取,就会有超出栅格范围的情况。
之前我常用的做法,就是创建一个 基于 MemVRT(虚拟栅格),VRT的地理范围取自己想要读取的范围即可,这种做法实际上是使用了GDAL自身的功能进行的一些简单的组合应用。
ChatGPT出来之后,简单尝试了一下,用它来写代码确实可以减少很大的工作量,也解决不少变量起名的问题。

下面是使用 ChatGPT 来编写一个函数,解决这个问题的记录。

写一个C++代码程序,封装一下GDALDatasetRasterIOEx 函数,使其支持访问范围超出影像大小,超出部分使用nodata值填充

以下是一个示例代码,封装了GDALDatasetRasterIOEx函数,支持访问范围超出影像大小,超出部分使用nodata值填充。在代码中,我们首先获取影像的nodata值和像素宽高等信息,然后再根据读取范围对应的实际影像坐标进行判断,判断是否超出影像范围。如果超出影像范围,则填充nodata值。

下面是 ChatGPT 写出来的代码,这个代码整体结构很清晰,变量命名也非常切意,不过还需要进行一下优化。

#include "gdal_priv.h"
#include "cpl_conv.h" // for CPLMalloc()

// 封装GDALDatasetRasterIOEx函数
CPLErr customGDALDatasetRasterIOEx(GDALDataset *pDataset, GDALRWFlag eRWFlag,
                                   int nXOff, int nYOff, int nXSize, int nYSize,
                                   void *pData, int nBufXSize, int nBufYSize,
                                   GDALDataType eBufType, int nBandCount,
                                   int *panBandMap, int nPixelSpace, int nLineSpace, int nBandSpace,
                                   const char* pszOrder, int nCompeletedPixels, int nCompeletedLines)
{
    if (pDataset == NULL) {
        return CE_Failure;
    }

    CPLErr eErr = CE_None;

    // 获取像素和行之间的字节偏移量
    int nPixelBytes = GDALGetDataTypeSize(eBufType) / 8;
    int nLineBytes = nPixelBytes * nBufXSize;

    // 获取影像的像素、行数和波段数等信息
    int nRasterXSize = pDataset->GetRasterXSize();
    int nRasterYSize = pDataset->GetRasterYSize();
    int nBands = pDataset->GetRasterCount();

    // 获取nodata值
    double dfNoDataValue;
    int bGotNoData = false;
    if (nBandCount == 1) {
        GDALRasterBand *pBand = pDataset->GetRasterBand(panBandMap[0]);
        dfNoDataValue = pBand->GetNoDataValue(&bGotNoData);
    }

    // 计算读取范围对应的实际影像坐标
    int nActualXOff = nXOff < 0 ? 0 : nXOff;
    int nActualYOff = nYOff < 0 ? 0 : nYOff;
    int nActualXEnd = nXOff + nXSize > nRasterXSize ? nRasterXSize : nXOff + nXSize;
    int nActualYEnd = nYOff + nYSize > nRasterYSize ? nRasterYSize : nYOff + nYSize;

    // 计算超出部分的长度和宽度
    int nExceedXStart = nXOff < 0 ? -nXOff : 0;
    int nExceedYStart = nYOff < 0 ? -nYOff : 0;
    int nExceedXEnd = nXOff + nXSize > nRasterXSize ? nXOff + nXSize - nRasterXSize : 0;
    int nExceedYEnd = nYOff + nYSize > nRasterYSize ? nYOff + nYSize - nRasterYSize : 0;

    // 实际要读取的像素宽度和高度
    int nActualXSize = nActualXEnd - nActualXOff;
    int nActualYSize = nActualYEnd - nActualYOff;

    // 创建一个临时数组存储影像数据
    char *pTempData = (char*)CPLMalloc(nPixelBytes * nBufXSize * nBufYSize * nBands);

    // 读取实际部分
    if (nActualXSize > 0 && nActualYSize > 0) {
        eErr = pDataset->RasterIO(eRWFlag, nActualXOff, nActualYOff, nActualXSize, nActualYSize,
                                   pTempData + (nExceedXStart + nExceedYStart * nBufXSize) * nPixelBytes * nBands,
                                   nBufXSize, nBufYSize, eBufType, nBandCount, panBandMap,
                                   nPixelSpace, nLineSpace, nBandSpace);
    }

    // 填充超出部分的nodata值
    for (int i = 0; i < nExceedYStart; i++) {
        char *pLineData = pTempData + i * nLineBytes;
        for (int j = 0; j < nBufXSize; j++) {
            for (int k = 0; k < nBands; k++) {
                if (bGotNoData) {
                    GDALCopyWords(&dfNoDataValue, GDT_Float64, 0,
                                  pLineData + (j + k * nBufXSize) * nPixelBytes, eBufType, 0,
                                  1);
                } else {
                    memset(pLineData + (j + k * nBufXSize) * nPixelBytes, 0,
                           nPixelBytes);
                }
            }
        }
    }

    for (int i = nExceedYStart; i < nBufYSize - nExceedYEnd; i++) {
        char *pLineData = pTempData + i * nLineBytes;
        for (int j = 0; j < nExceedXStart; j++) {
            for (int k = 0; k < nBands; k++) {
                if (bGotNoData) {
                    GDALCopyWords(&dfNoDataValue, GDT_Float64, 0,
                                  pLineData + (j + k * nBufXSize) * nPixelBytes, eBufType, 0,
                                  1);
                } else {
                    memset(pLineData + (j + k * nBufXSize) * nPixelBytes, 0,
                           nPixelBytes);
                }
            }
        }

        for (int j = nActualXOff; j < nActualXEnd; j++) {
            char *pPixelData = pLineData + (j - nActualXOff + nExceedXStart) * nPixelBytes * nBands;
            eErr = pDataset->RasterIO(eRWFlag, j, i, 1, 1,
                                       pPixelData, 1, 1, eBufType, nBandCount, panBandMap,
                                       nPixelSpace, nLineSpace, nBandSpace);
        }

        for (int j = nBufXSize - nExceedXEnd; j < nBufXSize; j++) {
            for (int k = 0; k < nBands; k++) {
                if (bGotNoData) {
                    GDALCopyWords(&dfNoDataValue, GDT_Float64, 0,
                                  pLineData + (j + k * nBufXSize) * nPixelBytes, eBufType, 0,
                                  1);
                } else {
                    memset(pLineData + (j + k * nBufXSize) * nPixelBytes, 0,
                           nPixelBytes);
                }
            }
        }
    }

    for (int i = nBufYSize - nExceedYEnd; i < nBufYSize; i++) {
        char *pLineData = pTempData + i * nLineBytes;
        for (int j = 0; j < nBufXSize; j++) {
            for (int k = 0; k < nBands; k++) {
                if (bGotNoData) {
                    GDALCopyWords(&dfNoDataValue, GDT_Float64, 0,
                                  pLineData + (j + k * nBufXSize) * nPixelBytes, eBufType, 0,
                                  1);
                } else {
                    memset(pLineData + (j + k * nBufXSize) * nPixelBytes, 0,
                           nPixelBytes);
                }
            }
        }
    }

    // 将临时数组中的数据写入到输出指针所指向的空间中
    memcpy(pData, pTempData, nPixelBytes * nBufXSize * nBufYSize * nBands);

    CPLFree(pTempData);

    return eErr;
}

标签:函数,int,nBufXSize,GDALDatasetRasterIOEx,nPixelBytes,nYOff,++,pLineData,ChatGPT
From: https://www.cnblogs.com/oloroso/p/17302914.html

相关文章

  • C++派生类里析构函数和构造函数的调用顺序
    C++派生类里析构函数和构造函数的调用顺序1.定义一个哺乳类Mammal,在由此派生出狗类Dog,定义一个Dog类的对象,观察基类和派生类的构造函数与析构函数的调用顺序。#include<bits/stdc++.h>usingnamespacestd;classMammal{public: Mammal(){ cout<<"constructedM"<<e......
  • ES_ChatGPT问答
    Q1:springboot项目,如何使用elasticsearch的api增删改查?查询中有哪些方式,如果模糊查询、排序查询、分页查询?分别阐述下这些查询方式的用法?最后举一个完整的例子答:在SpringBoot项目中使用Elasticsearch的API增删改查,需要引入spring-boot-starter-data-elasticsearch依赖。该依赖会......
  • Go 语言函数闭包
    Go语言支持匿名函数,可作为闭包。匿名函数是一个"内联"语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。以下实例中,我们创建了函数getSequence(),返回另外一个函数。该函数的目的是在闭包中递增i变量,代码如下:实例package mainimport "fmt"func ge......
  • ChatGPT垂直行业私有数据知识库功能-咨询接口采用流式响应输出-JS和Golang实现流式响
    近期开发私有数据知识库功能,想要实现和ChatGPT聊天效果类似的逐字流式输出展示效果。GPT3.5本身就有流式聊天补全接口,后端Golang对接后,也需要能流式输出。下面就介绍下前端JS后端Golang来实现这种输出效果 大部分介绍是使用EventStream来实现,我现在不使用EventStream也来实现......
  • 【ACM博弈论】SG函数入门(1):从巴什博奕到尼姆游戏
    在我小时候以前做题的时候,遇到博弈题往往都是漫无目的地打表找规律,或者找一些特殊情况但是没有很好的分析方法。其实博弈题是有比较套路的解题方法的,那就是利用SG函数,第一节不会讲到SG函数的具体用法,我们先来博弈入个门,学习一下最基本的博弈类型:Nim游戏。......
  • 命令式编程\声明式编程\函数式编程
    命令式编程(Imperative):详细的命令机器怎么(How)去处理一件事情以达到你想要的结果(What);声明式编程(Declarative):只告诉你想要的结果(What),机器自己摸索过程(How)。命令式编程是我们一步一步告诉机器需要怎么做,机器按部就班地执行命令。声明式编程是我们告诉机器我想要这样的结果,而不管他是怎......
  • SQL获取年月日时分秒的函数
    1.GETDATE()返回当前的时间和日期。语法:getdate()selectgetdate()2.CONVERT()把日期转换为新数据类型的通用函数,可以用不同的格式显示日期/时间数据。说明:此样式一般在时间类型(datetime,smalldatetime)与字符串类型(nchar,nvarchar,char,varchar)相互转换的时候才......
  • CH32V系列——关于指定函数在RAM中运行
     注意:以下修改,都只是在原来基础上添加,不做删减在启动文件做修改,增加下列代码:2:/*LoaddatasectionfromflashtoRAM*/laa0,_highcode_lmalaa1,_highcode_vma_startlaa2,_highcode_vma_endbgeua1,a2,2f1:lwt0,(a0)swt0,(a1)addia0,a0,4addia1,......
  • 全网最详细中英文ChatGPT-GPT-4示例文档-食谱智能生成从0到1快速入门——官网推荐的48
    目录Introduce简介setting设置Prompt提示Sampleresponse回复样本APIrequest接口请求python接口请求示例node.js接口请求示例curl命令示例json格式示例其它资料下载ChatGPT是目前最先进的AI聊天机器人,它能够理解图片和文字,生成流畅和有趣的回答。如果你想跟上AI时代的潮流......
  • 全网最详细中英文ChatGPT-GPT-4示例文档-文章大纲智能生成器从0到1快速入门——官网推
    目录Introduce简介setting设置Prompt提示Sampleresponse回复样本APIrequest接口请求python接口请求示例node.js接口请求示例curl命令示例json格式示例其它资料下载ChatGPT是目前最先进的AI聊天机器人,它能够理解图片和文字,生成流畅和有趣的回答。如果你想跟上AI时代的潮流......