R语言实战——一些批量对地理数据进行操作的方法

news2024/11/24 6:17:56

各位朋友在进行数据处理时,当有多张栅格影像时,如果我们都要进行同一操作时,一张一张做很繁琐,用ArcGIS模型构建器是一种比较好的方法。当然,今天小编新学了R语言上面进行批量裁剪,一起来学习一下吧!

一、批量裁剪

当我们有一张栅格数据时,需要按照特定的空间范围进行矢量数据裁剪时,应该怎么办?

话不多说,直接上代码:

裁剪
library(terra)
# 定义栅格文件和矢量数据路径
raster_file <- "H:/TEMData/Result/mean_output.tif"  # 栅格文件路径
vector_file <- "H:/shpfile"  # 矢量数据路径
output_file <- "H:/TEMData/Result/cropped_output.tif"    # 输出文件路径

# 读取栅格数据
raster_data <- rast(raster_file)

# 读取矢量数据
vector_data <- vect(vector_file)

# 设置栅格数据的坐标系(如果需要)
if (is.na(crs(raster_data))) {
  crs(raster_data) <- crs(vector_data)
}

# 使用 crop 和 mask 函数进行裁剪
masked_data <- crop(raster_data, vector_data) %>% 
  mask(., vector_data)

# 写入裁剪后的数据到输出文件
writeRaster(masked_data, output_file, overwrite = TRUE)

cat("Cropped raster saved to:", output_file, "\n")

# 可选:显示裁剪后的栅格
plot(masked_data, main = "Cropped Raster", col = terrain.colors(20))

 上面是单张栅格影像的处理,那如果我有20张,有50张呢?那我们来写个循环吧。

library(terra)
library(magrittr)  # 加载管道操作符

# 批量读取tif
folder <- "F:/shiyan1/"
# 输出文件夹路径,保存裁剪后的数据
output_folder <- "F:/result1/"

# 创建输出文件夹
if (!dir.exists(output_folder)) { 
  dir.create(output_folder)
}

# 获取所有TIF文件
tiff_files <- list.files(path = folder, pattern = "\\.tif$", full.names = TRUE)

# 读取 Shapefile 数据
shp_data <- vect("F:/hlbe")

# 循环处理每个TIF文件
for (tiff_file in tiff_files) { 
  # 从文件名中提取文件名(不包括路径和扩展名) 
  output_name <- tools::file_path_sans_ext(basename(tiff_file)) 
  
  # 读取 GeoTIFF 数据
  raster_data <- rast(tiff_file) 
  
  # 使用 mask 函数进行按照 Shapefile 进行的遮罩
  masked_data <- crop(raster_data, shp_data) %>% 
    mask(., shp_data) 
  
  # 构建输出文件路径
  output_path <- file.path(output_folder, paste0(output_name, ".tif")) 
  
  # 写入裁剪后的数据到输出文件 
  writeRaster(masked_data, output_path, overwrite = TRUE) 
  
  cat("File", tiff_file, "processed and saved to", output_path, "\n")
}

# 加载显示裁剪后的数据
output_rasters <- list.files(path = output_folder, pattern = "\\.tif$", full.names = TRUE)
if (length(output_rasters) > 0) {
  plot(rast(output_rasters))
} else {
  cat("No raster files found in the output folder.\n")
}

上面写了一个for循环,用mask函数进行掩膜处理,这样子就可以实现批量裁剪啦。

不过大家要注意,在进行代码梳理的时候,一定要注意,矢量空间范围和栅格数据的坐标系要统一,不然可能因为空间范围不同,没有重叠,或者坐标系冲突,从而产生错误结果。代码可以直接用,要改的地方就是文件夹的读取和导出,大家要复制自己所在数据地址哈!

二、定义坐标系

既然上面讲到了坐标系要统一,那么我们想到,怎么样对一张栅格影像进行坐标系定义呢?

我们上代码:

library(terra)

# 定义输入文件夹和输出文件夹
folder <- "F:/shiyan1/"
output_folder <- "F:/result1/"

# 创建输出文件夹
if (!dir.exists(output_folder)) {
  dir.create(output_folder)
}

# 获取所有TIF文件
tiff_files <- list.files(path = folder, pattern = "\\.tif$", full.names = TRUE)

# 循环处理每个TIF文件
for (tiff_file in tiff_files) {
  # 读取 GeoTIFF 数据
  raster_data <- rast(tiff_file)
  
  # 设置坐标系为 WGS 1984
  crs(raster_data) <- "EPSG:4326"
  
  # 构建输出文件路径
  output_path <- file.path(output_folder, basename(tiff_file))
  
  # 写入设置坐标系后的数据到输出文件 
  writeRaster(raster_data, output_path, overwrite = TRUE) 
  
  cat("File", tiff_file, "processed and saved with WGS 1984 coordinate system to", output_path, "\n")
}

这里我们将栅格数据定义为WGS1984坐标系,大家找到要定义的坐标系的EPSG代码,改一改就行啦。

三、批量转换数据格式

在进行数据处理时,tif格式的数据是常用的数据格式,我们从一些网站下面下载的数据可能是GRID格式或者其他格式,小编在处理多年风速数据的时候就遇到了这个问题,如果你需要将多张其他格式的数据转换成tif格式,应该怎么做?

我们上代码:

# 加载必要的包
library(terra)

# 设置输入和输出文件夹
input_folder <- "H:/VData/"  # 输入 ADF 文件夹路径
output_folder <- "H:/tem/output/"  # 输出 TIFF 文件夹路径

# 创建输出文件夹(如果不存在)
if (!dir.exists(output_folder)) {
  dir.create(output_folder)
}

# 获取所有 ADF 文件夹
adf_dirs <- list.dirs(path = input_folder, full.names = TRUE, recursive = FALSE)

# 循环处理每个 ADF 文件夹
for (adf_dir in adf_dirs) {
  # 检查是否存在 ADF 文件
  adf_files <- list.files(adf_dir, pattern = "\\.adf$", full.names = TRUE)
  if (length(adf_files) > 0) {
    # 读取 ADF 数据
    raster_data <- rast(adf_dir)
    
    # 从文件夹名中提取输出 TIFF 文件名
    output_name <- tools::file_path_sans_ext(basename(adf_dir))  # 不包括后缀
    output_file <- file.path(output_folder, paste0(output_name, ".tif"))
    
    # 将 ADF 数据保存为 TIFF 格式
    writeRaster(raster_data, output_file, overwrite = TRUE)  # 不需要指定 format
    
    cat("Converted:", adf_dir, "to", output_file, "\n")
  } else {
    cat("No ADF files found in:", adf_dir, "\n")
  }
}

通过上述代码,我们可以实现对数据的格式转换,中间我们用if函数检查了一下我们的文件夹里面是否存在我们需要转换的数据格式文件,如果没有会报出,这时我们需要对文件夹重新整理。小编在处理的时候,一开始有info文件夹在里头,R语言读不了,后面吧info文件删除之后,就能够开始读取了。

四、栅格计算

当我们有连续20年的数据,如果需要进行均值计算时,怎么办?

library(terra)

# 定义输入文件夹
input_folder <- "H:/TEMData/Data"

# 获取所有 TIF 文件
tiff_files <- list.files(path = input_folder, pattern = "\\.tif$", full.names = TRUE)

# 读取第一个栅格数据以获取参考范围和分辨率
reference_raster <- rast(tiff_files[1])

# 创建一个空的列表来存储对齐后的栅格数据
aligned_rasters <- list(reference_raster)

# 循环处理其他栅格文件
for (tiff_file in tiff_files[-1]) {
  # 读取栅格数据
  raster_data <- rast(tiff_file)
  
  # 对齐栅格数据到参考栅格的范围和分辨率
  aligned_raster <- project(raster_data, reference_raster)
  
  # 添加对齐后的栅格到列表
  aligned_rasters <- c(aligned_rasters, list(aligned_raster))
}

# 将对齐后的栅格合并为一个栅格堆栈
raster_stack <- rast(aligned_rasters)

# 计算均值
mean_raster <- app(raster_stack, fun = mean, na.rm = TRUE)

# 构建输出文件路径
output_path <- "H:/TEMData/Result/mean_output.tif"

# 写入均值栅格数据到输出文件
writeRaster(mean_raster, output_path, overwrite = TRUE)

# 显示均值栅格
plot(mean_raster, main = "Mean Raster", col = terrain.colors(20))

cat("Mean raster saved to:", output_path, "\n")

这里是结果:

如果是要进行求和呢?

我们以逐月日照数据为例,来看看怎么实现?

library(terra)

# 设置输入文件夹路径
input_folder <- "H:/ssd/2013"
output_file <- "H:/ssd/result/annual_sum_raster.tif"

# 获取所有 TIF 文件
raster_files <- list.files(path = input_folder, pattern = "\\.tif$", full.names = TRUE)

if (length(raster_files) == 0) {
  stop("No TIF files found in the specified folder.")
}

annual_sum_raster <- NULL

# 循环处理每个栅格影像
for (raster_file in raster_files) {
  current_raster <- rast(raster_file)
  
  if (is.null(annual_sum_raster)) {
    annual_sum_raster <- current_raster
  } else {
    annual_sum_raster <- annual_sum_raster + current_raster
  }
  
  gc()  # 垃圾回收
}

writeRaster(annual_sum_raster, output_file, overwrite = TRUE)
cat("Annual sum raster saved to:", output_file, "\n")
plot(annual_sum_raster, main = "Annual Sum Raster")

需要注意的是年度合成数据因为计算量比较大,如果你的栅格有多张,可能算不出来,我们就需要设计一个垃圾回收的机制,来减少不必要的内存消耗,这里是月日照数据合成年总和数据的结果:

好了,今天我们的学习就到这里结束了,希望对大家有帮助!

我们是梧桐GIS,致力于分享数据处理的优质教程,谢谢大家关注!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

详解如何创建SpringBoot项目

目录 点击New Project 选择依赖 简单使用SpringBoot 前面已经讲解了如何获取IDEA专业版&#xff0c;下面将以此为基础来讲解如何创建SpringBoot项目。 点击New Project 选择依赖 注意&#xff0c;在选择SpringBoot版本时&#xff0c;不要选择带SNAPSHOT的版本。 这样&#…

点云分割总结

点云分割总结 point transformerbackground 标量自注意力和向量自注意力&#xff08;可参考论文&#xff09;标量自注意力向量注意力 Point Transformer Layer下采样上采样整体结构 point transformer v2group vector attentionPosition Encoding MultiplerPartition-based Poo…

智象未来(HiDream.ai):从科技创新启程,绘制智能未来新篇章

在人工智能领域飞速演进的当下&#xff0c;智象未来&#xff08;HiDream.ai&#xff09;作为全球领先的多模态生成式人工智能技术供应商&#xff0c;正以其独树一帜的视觉多模态大模型及创新应用&#xff0c;推动行业趋势的前进。智象未来&#xff08;HiDream.ai&#xff09;自…

CSP/信奥赛C++刷题训练:经典例题 - 栈(2):洛谷P1981 :[NOIP2013 普及组] 表达式求值

CSP/信奥赛C刷题训练&#xff1a;经典例题 - 栈&#xff08;2&#xff09;&#xff1a;洛谷P1981 &#xff1a;[NOIP2013 普及组] 表达式求值 题目背景 NOIP2013 普及组 T2 题目描述 给定一个只包含加法和乘法的算术表达式&#xff0c;请你编程计算表达式的值。 输入格式 …

LVGL加入外围字库

一、首先lvgl是有自带字库的 lvgl/src/font 如下图 二、但如果这个字库不能满足我们的需求我们就要外建字库。 1、字库生成软件LVGL官网&#xff0c;字体转换器 — LVGL如下图&#xff1a; 最后按“提交”就可以看到有一个字体被下载到你电脑里。他是以.c文件的型式&#xff0…

创新引领,模块化微电网重塑能源格局

根据QYResearch调研团队最新发布的《全球模块化微电网市场报告2023-2029》显示&#xff0c;预计到2029年&#xff0c;全球模块化微电网市场的规模将扩大至33.1亿美元&#xff0c;且在未来几年内&#xff0c;其年复合增长率&#xff08;CAGR&#xff09;将达到8.8%。 如下图所示…

FPGA 第4讲 初识Verilog HDL

时间&#xff1a;2024.11.9 一、学习内容 1.Verilog HDL简介 1.1语言简介 Verilog HDL是一种硬件描述语言&#xff0c;以文本的形式来描述数字系统硬件的结构和行为的语言&#xff0c;用它可以表示逻辑电路图、逻辑表达式&#xff0c;还可以表示数字逻辑系统所完成的逻辑功能…

【51单片机】LED点阵屏 原理 + 使用

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 LED点阵屏显示原理74HC595 编码LED点阵屏显示笑脸LED点阵屏显示动画 LED点阵屏 点阵屏在开发板的右上角&#xff0c;注意使用前需要…

Chrome扩展是程序员做独立开发的绝佳入场机会

一、开发成本低&#xff0c;难度低 简便灵活&#xff1a;相比开发移动应用&#xff0c;浏览器扩展的开发过程更加简便灵活&#xff0c;更适合初学者。省时省力&#xff1a;通过扩展&#xff0c;你可以修改现有网站的功能&#xff0c;无需从零开始搭建应用&#xff0c;大大节省…

记录一下最近遇到的两个问题

问题1 网友问&#xff1a;一个数据同步的程序之前运行正常&#xff0c;突然数据有问题了&#xff0c;俺的回答是退出杀毒软件 问题是很快解决了&#xff0c;但是网友后来说&#xff0c;客户觉得程序很不稳定。俺不清楚这算不算背锅。 问题2 今天下午&#xff0c;调试着程序蓝…

30.1 时序数据库TSDB的典型特点

本节重点介绍 : db-ranking网站对db进行排名时序数据特点时序数据库特点时序数据库遇到的挑战开源时间序列数据库 db-ranking 一个神奇的网站 https://db-engines.com/en/ranking 时序数据ranking https://db-engines.com/en/ranking/timeseriesdbms 排名方法 https://db-en…

Linux SSH私钥认证结合cpolar内网穿透安全高效远程登录指南

文章目录 前言1. Linux 生成SSH秘钥对2. 修改SSH服务配置文件3. 客户端秘钥文件设置4. 本地SSH私钥连接测试5. Linux安装Cpolar工具6. 配置SSHTCP公网地址7. 远程SSH私钥连接测试8. 固定SSH公网地址9. 固定SSH地址测试 前言 开发人员在工作中经常需要远程访问服务器和数据中心…

vscode摸鱼学习插件开发

不知道大家在摸鱼的时候&#xff0c;会不会想要学习&#xff1f; 或者有没有考公人&#xff0c;下班要学习的&#xff1f; 上班时间摸鱼&#xff0c;下班时间不够学习&#xff1f; 为此&#xff0c;我决定开发一个vscode插件&#xff0c;来刷粉笔题 粉笔插件名称&#xff1a;…

深入浅出WebSocket(实践聊天室demo)

文章目录 什么是WebSocket?WebSocket连接过程WebSocket与Http的区别重连机制完整代码使用方法心跳机制实现聊天室demo(基于Socket.io)参考文章、视频小广告~什么是WebSocket? WebSocket 是一种在单个TCP连接上进行全双工通信的协议(计算机网络应用层的协议) 在 WebSocket A…

[ Linux 命令基础 7 ] Linux 命令详解-磁盘管理相关命令

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

ElasticSearch 添加IK分词器

ElasticSearch 添加IK分词器 前言一、IK分词器的算法二、Ik分词器的下载安装&#xff08;Winows 版本&#xff09;三、Ik分词器的下载安装&#xff08;Linux 版本&#xff09;四、验证测试&#xff08;postman工具&#xff09;测试 ik_smart 分词算法测试 ik_max_word 分词算法…

aws(学习笔记第十一课) 使用AWS的EFS,以及AWS Storage Gateway

aws(学习笔记第十一课) 使用AWS的EFS和AWSStorage Gateway 学习内容&#xff1a; 使用AWS的EFS使用AWS Storage Gateway 1. 使用AWS的EFS 什么是EFS EFS是 Elastic File System的缩写。前面练习的实例存储和EBS都是同时只能一个EC2实例进行挂载&#xff0c;不能实现多个EC2实…

Diffusion Policy——斯坦福刷盘机器人UMI所用的扩散策略(含Diff-Control、ControlNet详解)

前言 本文一开始是属于此文《UMI——斯坦福刷盘机器人&#xff1a;从手持夹持器到动作预测Diffusion Policy(含代码解读)》的第三部分&#xff0c;考虑后Diffusion Policy的重要性很高&#xff0c;加之后续还有一系列基于其的改进工作 故独立成本文&#xff0c;且把原属于另一…

计算机毕业设计 | SpringBoot慈善公益平台 爱心互助活动发布管理系统(附源码)

1&#xff0c;项目介绍 爱慈善公益平台&#xff08;love-charity&#xff09;是一个基于 SpringBoot 开发的标准 Java Web 项目。整体页面非常的简约大气&#xff0c;项目的完整度较高&#xff0c;是一个偏向公益论坛的系统。非常适合刚刚接触学习 SpringBoot 的技术小白学习&…

【深入浅出】之Linux进程(二)

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…