GDAL:Warning 1: All options related to creation ignored in update mode

01 警告说明

首先贴出相关代码:

out_file_name = 'Rs_{:4.0f}{:02.0f}.tiff'.format(year, month)
out_path = os.path.join(out_dir, out_file_name)
mem_driver = gdal.GetDriverByName('MEM')
mem_ds = mem_driver.Create('', len(lon), len(lat), 1, gdal.GDT_Float32)
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
mem_ds.SetProjection(srs.ExportToWkt())
mem_ds.SetGeoTransform(geo_transform)
mem_ds.GetRasterBand(1).WriteArray(cur_Rs)
mem_ds.GetRasterBand(1).SetNoDataValue(-9999)  # 设置无效值
driver = gdal.GetDriverByName('GTiff')
ds = driver.Create(out_path, len(lon), len(lat), 1, gdal.GDT_Float32)
ds.SetGeoTransform(geo_transform)
ds.SetProjection(srs.ExportToWkt())
gdal.Warp(ds, mem_ds, cropToCutline=True, cutlineDSName=mask_path, xRes=out_res, yRes=out_res,
          resampleAlg=gdal.GRA_Cubic, srcNodata=-9999, dstNodata=-9999)

警告代码在gdal.Warp函数中产生。

警告: All options related to creation ignored in update mode,很明显,正如它所说,所有和创建相关的options将会在更新模式下忽略。

这里的options根据gdal源代码中:

在这里插入图片描述

02 解决

应该可以理解为gdal.Warp函数中的相关参数,换言之,我们指定的参数例如前面代码中的:

gdal.Warp(ds, mem_ds, cropToCutline=True, cutlineDSName=mask_path, xRes=out_res, yRes=out_res,
          resampleAlg=gdal.GRA_Cubic, srcNodata=-9999, dstNodata=-9999)

也就是说参数应该发生了某种冲突,导致有些参数无法起作用而忽略了,下面是该警告导致的输出影像显示:

在这里插入图片描述

可以发现,至少cropToCutlinedstNodata两个参数是没有正常作用的,掩膜似乎是作用的。周围黑色背景均为0,说明dstNodata没有起作用,而且似乎不应该是0,因为我确定我的栅格数据中不存在0值,无效值也是赋值的是-65535。另外影像周围很多多余黑色背景,说明它没有将shp矩形范围外的栅格矩阵丢弃,因此cropToCutline也是失效的。

调试发现,确实自己该的。gdal.Warp的参数和前面的代码存在矛盾导致的警告,进而导致错误影像产生。

在代码中:

ds = driver.Create(out_path, len(lon), len(lat), 1, gdal.GDT_Float32)
ds.SetGeoTransform(geo_transform)
ds.SetProjection(srs.ExportToWkt())

一开始我是不存在传入仿射参数和投影信息的,但是命令行警告:

ERROR 1: Unable to compute a transformation between pixel/line and georeferenced coordinates for E:\FeaturesTargets\uniform\Rs\Rs_198307.tiff. There is no affine transformation and no GCPs. Specify transformation option DST_METHOD=NO_GEOTRANSFORM to bypass this check.

于是我顺手给加上了,但是投影信息是正常的,而传入的geo_transform却是和后面的掩膜相矛盾,掩膜后的栅格矩阵必不可能是这个仿射参数。于是我想起来了,原来只需要传入输出路径即可,如下:

out_file_name= 'Rs_{:4.0f}{:02.0f}.tiff'.format(year, month)
out_path = os.path.join(out_dir, out_file_name)
mem_driver = gdal.GetDriverByName('MEM')
mem_ds = mem_driver.Create('', len(lon), len(lat), 1, gdal.GDT_Float32)
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
mem_ds.SetProjection(srs.ExportToWkt())
mem_ds.SetGeoTransform(geo_transform)
mem_ds.GetRasterBand(1).WriteArray(cur_Rs)
mem_ds.GetRasterBand(1).SetNoDataValue(-9999)  # 设置无效值
gdal.Warp(out_path, mem_ds, cropToCutline=True, cutlineDSName=mask_path, xRes=out_res, yRes=out_res,
          resampleAlg=gdal.GRA_Cubic, srcNodata=-9999, dstNodata=-9999)

无需建立两个ds对象出来。

但是在调试过程中,我一开始认为是在MEM中创建影像导致的问题,于是将代码修改为:

mem_driver = gdal.GetDriverByName('GTiff')
mem_ds = mem_driver.Create(os.path.join(out_dir, 'temp.tiff'), len(lon), len(lat), 1, gdal.GDT_Float32)

结果发现输出的temp.tiff文件在GIS中显示异常:

在这里插入图片描述

对的,就是完全空的状态,我在代码中使用matplotlib显示如下:

在这里插入图片描述

说明应该是gdal在存入的时候导致的错误,最后找了很久没有发现原因,本来不打算研究了,因为虽然中间数据虽然存在显示问题,但是由于最后的输出还是正常的如下(我已经修改了此前的错误关于geo_transform):

在这里插入图片描述

当然,结局是好的,最后发现的原因应该是python的垃圾回收机制这方面的原因,换句话就是代码执行到这里时

mem_ds.GetRasterBand(1).SetNoDataValue(-9999)

我们想当然理解为数据集应该传入到了硬盘中,但实际上它还在内存中。这是很正常的,我以为它会在代码结束后自动将内存中的数据写入到硬盘,但是实际上并没有。

往常我是一般会写:

mem_ds = None

或者

mem_ds.FlushCache()

前者通过python的垃圾回收机制将内存中的东西写入到硬盘后再进行回收,后者则是gdal自带方法有相关写入内存的函数。

但是由于有时我发现写不写似乎并没有导致一些异常发生,且就算有异常一般是发生在命令行/jupyter/调试过程中,这个过程我认为是因为写入数据实际上还在内存,当我结束或者关闭时它会自动写入,事实上它确实如我所想这么实现了。因此我误以为所有数据集写入其实无需进行写入硬盘操作,因为当程序结束等会自动进行,但是事实证明我错了,或许在更为复杂的情况会导致没有来得及写入硬盘导致输出结果错误的情况发生。

所以,养成习惯,显式调用它们吧,这些错误有时非常致命当你不清楚它时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/607944.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

掌握用户全生命周期数据,Xinstall让App投放更科学

在数字化时代,App已成为企业与用户互动的重要窗口。然而,想要让App在众多竞争者中脱颖而出,吸引并留住用户,有效的广告投放策略至关重要。这就需要对广告投放效果进行精准分析,以便及时调整策略,实现最大化…

Kubernetes的基本概念

目录 一.基本内容 1.定义 2.作用 二.特性 1.弹性伸缩 2.自我修复 3.服务发现和负载均衡 4.自动发布(默认滚动发布模式)和回滚 5.集中化配置管理和密钥管理 6.存储编排,支持外挂存储并对外挂存储资源进行编排 7.任务批处理运行 三…

clickhouse mergeTree表引擎解析

参照 https://clickhouse.com/docs/zh/engines/table-engines/mergetree-family/mergetree https://clickhouse.com/docs/en/optimize/skipping-indexes Clickhouse中最强大的表引擎当属MergeTree(合并树)引擎及该系列(*MergeTree&#xff…

Springboot项目使用redis实现session共享

1.安装redis,并配置密码 这里就不针对于redis的安装约配置进行说明了,直接在项目中使用。 redis在windows环境下安装:Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)_redis安装-CSDN博客 2…

图片公式识别@文档公式识别@表格识别@在线和离线OCR工具

文章目录 abstract普通文字识别本地软件识别公式扩展插件下载小结 在线识别网站/API👺Quicker整合(推荐)可视化编辑和识别公式其他多模态大模型识别图片中的公式排版 开源模型 abstract 本文介绍免费图片文本识别(OCR)工具,包括普通文字识别,公式识别,甚至是手写公…

Linux网络——自定义序列化与反序列化

前言 之前我们学习过socket之tcp通信,知道了使用tcp建立连接的一系列操作,并通过write与read函数能让客户端与服务端进行通信,但是tcp是面向字节流的,有可能我们write时只写入了部分数据,此时另一端就来read了&#x…

ZYNQ MPSoC zcu102 PS端运行helloworld

文章目录 一、参考资料二、需要注意的步骤三、运行结果 一、参考资料 1.zcu102 zynq Mpsoc uart hello world——CSDN博客 2.zcu102自学 —— 第一个实验 (纯PS 串口打印 Hello world)——CSDN博客 3.【02】ALINX Zynq MPSoC XILINX FPGA视频教程 SDK 裸…

Linux:进程信号(一)信号的产生

目录 一、信号是什么? 二、Linux信号 三、信号处理方式 四、信号的产生 1、 通过终端按键产生信号 2、调用系统函数向进程发信号 3、 硬件异常产生信号 一、信号是什么? 在生活中,有许多信号,比如红绿灯,下课铃声…

如何使用Transformer-TTS语音合成模型

1、技术原理及架构图 ​ Transformer-TTS主要通过将Transformer模型与Tacotron2系统结合来实现文本到语音的转换。在这种结构中,原始的Transformer模型在输入阶段和输出阶段进行了适当的修改,以更好地处理语音数据。具体来说,Transformer-TT…

【Docker】新手教程的第一个demo:Wordpress

1 任务简单介绍 WordPress是什么: 是一个常用博客软件简单易部署,只需要两个容器(业务容器 数据库容器) 本文借鉴博客,使用自建 WordPress 容器方法在Docker上部署Wordpress,本地环境为Mac时使用该博客…

C语言leetcode刷题笔记2

C语言leetcode刷题笔记2 第4题:283.移动零互换直接移动 第5题:122.买卖股票的最佳时机‖递归(超时)动态规划贪心算法 第6题:49.字母异位词分组优化 第4题:283.移动零 给定一个数组 nums,编写一…

分布式事务Seata使用

我们要学习seata,首先需要具备如下技术储备: 数据库事务的基本知识;maven工具的使用;熟悉SpringCloudAlibaba技术栈;掌握SpringDataJPA简单使用; 一. Seata基本概念 1.seata是什么 Seata是阿里巴巴中间…

C++ 动态内存管理

例如:动态内存和释放单个数据的存储区 一 用new运算符初始化单个数据的存储区 举例

pytest + yaml 框架 - 参数化读取文件路径优化

针对小伙伴提出参数化时读取外部文件,在项目根路径运行没问题,但是进入到项目下子文件夹运行用例,就会找不到文件问题做了优化。 关于参数化读取外部文件相关内容参考前面这篇pytest yaml 框架 -25.参数化数据支持读取外部文件txt/csv/json/…

LeetCode 257. 二叉树的所有路径

LeetCode 257. 二叉树的所有路径 1、题目 题目链接:257. 二叉树的所有路径 给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root…

C++:内存管理

C:内存管理 一、C/C内存分布二、C语言中动态内存管理方式:malloc/calloc/realloc/free三、C内存管理方式1.new/delete操作内置类型2.new和delete操作自定义类型 四、operator new与operator delete函数(重点)五、new和delete的实现原理1.内置…

Unity曲线插件Dreamteck Splines生成曲线Mesh

一、需求 脱离编辑器,运行时添加点,动态生成管道、线缆等曲线Mesh。 二、Dreamteck Splines简单运用 这方面资料不多,只有官方文档全英参考,而且又介绍得不详细。 2个重要组件介绍: SplineComputer: 最…

系统运维(虚拟化)

1.VLAN VLAN(Virtual Local Area Network)即虚拟局域网,是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。 每个VLAN是一个广播域,VLAN内的主机间可以直接通信,而VLAN间则不能直接互通。这样,广播报…

987: 输出用先序遍历创建的二叉树是否为完全二叉树的判定结果

解法: 一棵二叉树是完全二叉树的条件是: 对于任意一个结点,如果它有右子树而没有左子树,则这棵树不是完全二叉树。 如果一个结点有左子树但是没有右子树,则这个结点之后的所有结点都必须是叶子结点。 如果满足以上条…

1010: 折半查找的实现

解法&#xff1a; #include<iostream> #include<vector> using namespace std; void solve() {int n;cin >> n;vector<int> vec(n);for (int& x : vec) cin >> x;int x;cin >> x;int l 0, r n-1, cnt 0;while (l < r) {cnt;int…
最新文章