是否有更好的方法来处理穿过反子午线(日界线)的空间多边形?

2023-12-25

TL;DR

R中处理在纬度+/-180°处与反子午线相交/重叠的空间多边形并将其沿该子午线切割成两部分的最佳方法是什么?

Preface

这将是一篇很长的文章,但只是因为我将包含大量代码和图形来进行说明。我将向您展示我的目标是什么以及我通常如何实现该目标,然后演示这一切如何在字面上的边缘情况下分解在一起。正如标题所示,我已经找到了解决我的问题的一种可能的解决方案,因此我也将其包括在内。但它并不是 100% 干净,我想看看是否有人能想出更优雅的东西。无论如何,我认为这是一个有趣的问题,因为就在几天前,我在最疯狂的梦想中都不会怀疑这甚至可能成为 2019 年的一个问题。

R 中的常规工作流程

首先,创建一个有效的示例数据集

library(sp)
library(rgdal)
library(rgeos)
library(dismo)
library(maptools) # this is just for plotting a simple world map in the background
data("wrld_simpl")


# create a set of locations
locations <- SpatialPoints(coords=cbind(c(50,0,0,0), c(10, 30, 50, 70)), proj4string = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))
plot(wrld_simpl, border="grey50")
points(locations, pch=19, col="blue")

Looks like this: locations on a world map Then, I use circles() from the dismo package to create circular buffers around those locations. I use this function, because it takes into account that the Earth is not flat:

buffr <- circles(p = locations, d = 1500000, lonlat=TRUE, dissolve=FALSE)
plot(wrld_simpl, border="grey50")
plot(buffr, add=TRUE, border="red", lwd=2)
points(locations, pch=19, col="blue")

That looks like this: locations with their individual buffers

然后,将单个缓冲区合并为一个大(多)多边形:

buffr <- buffr@polygons # extract the SpatialPolygons object from the "CirclesRange" object
buffr <- gUnaryUnion(buffr) # merge

plot(wrld_simpl, border="grey50")
plot(buffr, add=TRUE, border="red", lwd=2)
points(locations, pch=19, col="blue")

This is exactly what I need: points with merged buffers

问题

现在观察当我们引入非常接近反子午线(经度+/-180°)以至于缓冲区必须穿过该线的位置时会发生什么:

locations <- SpatialPoints(coords=cbind(c(50,0,0,0, 175, -170), c(10, 30, 50, 70,0,-10)), proj4string = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))
buffr <- circles(p = locations, d = 1500000, lonlat=TRUE, dissolve=FALSE)

plot(wrld_simpl, border="grey50")
plot(buffr, add=TRUE, border="red", lwd=2)
points(locations, pch=19, col="blue")

Circles() 命令确实设法在反子午线的另一侧创建多边形线段(如果溶解 = FALSE):

但多边形穿过整个地球,而不是正确环绕(与 0° 相交而不是 180° 相交)。这会导致自相交和

buffr <- gUnaryUnion(buffr@polygons)

将会失败

gUnaryUnion(buffr@polygons) 中的错误:TopologyException:输入 geom 0 无效:在点或点附近自相交 170.08604674698876 12.562175561621103 在 170.08604674698876 12.562175561621103

快速但有点脏的解决方案

首先,我们需要检测多边形是否穿过反子午线。然而,它们实际上都没有相交 +/-180°。相反,我使用两条伪反子午线,它们靠近真实子午线,但距离东部和西部足够远,可能与所讨论的多边形相交。如果一个多边形与它们两者相交,它也必须穿过反子午线。

antimeridian <- SpatialLines(list(Lines(slinelist=list(Line(coords=cbind(c(179,179), c(90,-90)))), ID="1"),
              Lines(slinelist=list(Line(coords=cbind(c(-179,-179), c(90,-90)))), ID="2")),
                                   proj4string = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))
intrscts <- gIntersects(antimeridian, buffr, byid = TRUE)
any(intrscts[,1] & intrscts[,2])
intrscts <- which(intrscts[,1] & intrscts[,2])
buffr.bad <- buffr[intrscts,]
buffr.good <- buffr[-intrscts,]

plot(wrld_simpl)
plot(buffr.good, border="blue", add=TRUE)
plot(buffr.bad, border="red", add=TRUE)

在检测并分离“坏”多边形后,我只需通过查看纵向坐标将它们分成两个单独的部分。每个具有负值的坐标对进入新的西部多边形,正值进入东部多边形。然后我将它们全部合并在一起,执行我的 gUnaryUnion 并得到几乎我需要的东西:

buffr.fixed <- buffr.good
for(i in 1:length(buffr.bad)){
  thispoly <- buffr.bad[i,]                              # select first problematic polygon
  crds <- thispoly@polygons[[1]]@Polygons[[1]]@coords   # extract coordinates
  crds.west <- subset(crds, crds[,1] < 0)               # western half of the polygon
  crds.east<- subset(crds, crds[,1] > 0)
  # turn into Spatial*, merge back together, re-add original crs
  sppol.east <- SpatialPolygons(list(Polygons(list(Polygon(crds.east)), paste0("east_", i))))
  sppol.west <- SpatialPolygons(list(Polygons(list(Polygon(crds.west)), paste0("west_", i))))
  sppol <- spRbind(sppol.east, sppol.west)
  proj4string(sppol) <- proj4string(thispoly)

  buffr.fixed <- spRbind(buffr.fixed, sppol)
}
buffr.final <- gUnaryUnion(buffr.fixed)
plot(wrld_simpl, border="grey50")
points(locations, pch=19, col="blue")
plot(buffr.final, add=TRUE, border="red", lwd=2)

The final outcome: merged buffers, problem solved?

实际问题

因此,这个解决方案适用于我当前的用例,但它有一些问题:

  • 一旦其中一个缓冲区同时穿过反子午线和本初子午线,它可能就会完全破坏(如果原始点位置靠近两极,则这种情况不太可能发生)。
  • 它并不十分精确,因为两个多边形部分不是以 +/-180° 切割,而是以原始多边形中存在的最高负/正纬度值切割。
  • 我很难相信没有“正确”的方法可以做到这一点。

所以这一切归结起来的问题是:有更好的方法吗?

当我试图弄清楚这一点时,我遇到了nowrapRecenter() and nowrapSpatialPolygons() https://rdrr.io/cran/maptools/man/nowrapRecenter.html函数从maptools包装,乍一看似乎完全符合我的要求。经过仔细检查,它们的目标几乎是相反的用例(将地图以反子午线为中心,从而沿着本初子午线切割多边形)。我和他们一起玩,但没能让他们为我工作——事实上,他们只会让事情变得更糟。

感谢您的关注!


你是对的,今年是你的问题的解决方案。这sf- 包有功能st_wrap_dateline(),这正是您所需要的。

library(dismo)
library(sf)


locations <- SpatialPoints(coords=cbind(c(50,0,0,0, 175, -170), c(10, 30, 50, 70,0,-10)), proj4string = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))
buffr <- circles(p = locations, d = 1500000, lonlat=TRUE, dissolve=FALSE)

buffr2 <- as(buffr@polygons, Class = "sf") %>%
            st_wrap_dateline(options = c("WRAPDATELINE=YES")) %>%
             st_union()


plot(wrld_simpl, border="grey50")
plot(buffr2, add=TRUE, border="red", lwd=2)
points(locations, pch=19, col="blue")

st_wrap_dateline将跨越国际日期变更线或“反子午线”的多边形转换为MULTIPOLYGON。就是这样。

这能解决你的问题吗?至少它缩短了你到达现在所在位置的路程。 ^^

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否有更好的方法来处理穿过反子午线(日界线)的空间多边形? 的相关文章

  • ggplot堆叠条 - 隐藏标签但保留标签位置

    我在 ggplot 中有一个堆积条形图 其中 geom text 标签位于每个条形的中心 我想隐藏小条上的标签 以便图表看起来不会过于拥挤 我可以使用下面的代码来完成此操作 但它会弄乱标签的位置 正如您在下面的链接图片中看到的那样 它们不再
  • Plotly 绘图不会在 RMarkdown 文档的 for 循环内渲染

    我正在尝试动态构建一个需要运行循环的报告 并为每次迭代打印一些消息 表格和绘图 我可以让一切正常运转except为了情节 示例 rmd r echo FALSE results asis fig keep all message FALSE
  • 使用pivot_longer将R中的多列变成一列[重复]

    这个问题在这里已经有答案了 我有一个dfpopulation看起来像这样 未列出所有列和行 Region X1975 X1976 X1977 X2008 National Total 942420 93717 94974 132802 Be
  • R:如何根据规范更改数据框中的列名称

    我有一个数据框 它的开头如下 SM H1455 SM V1456 SM K1457 SM X1461 SM K1462 ENSG00000000419 8 290 270 314 364 240 ENSG00000000457 8 252
  • 当测试集中不存在响应变量时,h2o 预测有时会失败

    当在不存在响应变量的测试集上进行预测时 如果在训练中对因子变量使用一种热编码 则 h2o 会以各种不同的方式失败 无论是在训练 GLM 时隐式指定还是在其他方法中显式指定时 R 3 4 0 和 h2o 3 12 0 1 中存在此错误 我们还
  • 使用 stargazer 分析包含时间序列的数据帧

    我有一个面板数据集共 10 个观测值和 3 个变量 观测值 30 的数量 10 行 国家 地区 2 列 迁移参数 相应年份的 1 列 可以这么说 我的数据框由 3 个年度数据框组成 我该如何申请观星者考虑到它是一个面板数据集 所以最大 N
  • 在ggplotly散点图中添加自定义数据标签

    我想显示Species对于每个数据点 当光标位于该点上方而不是 x 和 y 值时 我用iris数据集 另外 我希望能够单击数据点以使标签持久存在 并且当我在图中选择新位置时标签不会消失 如果可能的话 最基本的是标签 持久性问题是一个优点 这
  • 编写健壮的 R 代码:命名空间、屏蔽和使用 `::` 运算符

    简洁版本 对于那些不想阅读我的 案例 的人来说 这就是本质 最小化新包破坏现有代码 即编写您编写的代码 的机会的推荐方法是什么尽可能坚固 充分利用该功能的推荐方法是什么 命名空间机制 when a just using贡献的软件包 比如在一
  • 有没有一种简单的方法可以根据多个标准进行排名,从而保留 R 中的联系?

    当单个标准排序良好时 rank 函数会返回明显的结果 rank c 2 4 1 3 5 1 2 4 1 3 5 当单个标准具有联系时 排名函数 默认情况下 将平均排名分配给联系 rank c 2 4 1 1 5 1 3 0 4 0 1 5
  • ggplot2 - 添加具有不同中断和标签的辅助 y 轴

    是否可以使用 ggplot2 手动向辅助 y 轴添加中断和标签 see bottom right 我希望在右侧 y 轴上有更紧凑的中断 代表条形 该图将作为基本情况 然后我将展示如何更改辅助 y 轴上的分隔符和标签 sapply c pip
  • 使用starts_with() 将 NA 替换为 0

    我正在尝试替换我的一组特定列的 NA 值tibble 这些列都以相同的前缀开头 所以我想知道是否有一种简洁的方法来使用starts with 函数从dplyr包可以让我做到这一点 我已经看到了有关 SO 的其他几个问题 但是它们都需要使用特
  • 在 R 中将时间间隔数据扩展为天数

    假设我有如下所示的数据 interval id indiv id role start date end date 1 1 A 2006 05 01 2006 06 16 2 1 B 2006 06 16 2006 10 16 3 1 A
  • 使用 data.table 进行分组并选择最短日期

    My Data df1 lt structure list ID c A A A B B C c1 1 6 c2 1 6 myDate c 01 01 2015 02 02 2014 03 01 2014 09 09 2009 10 10
  • R:根据元素长度从向量中删除元素

    如何根据字符串的字符数或长度从字符串向量中删除元素 df lt c asdf fweafewwf af aewfawefwef awefWEfawefawef gt df 1 asdf fweafewwf af aewfawefwef aw
  • Django 中的 Rpy2 错误 - 未为“”类型的对象定义转换“py2rpy”

    我以前从未使用过 R 并且正在尝试使用 rpy2 从 python 调用 R 函数 它可以在独立的 python 终端上运行 但不能在 Django 中运行 但rpy2似乎无法将python字符串转换为r对象 我正在使用同事提供的自定义库
  • R闪亮主面板显示样式和字体

    我正在学习闪亮的应用程序 并且有一些关于调整布局的基本问题 特别是样式和字体 希望得到指点或明确的答案 谢谢 考虑一个基本的输入输出应用程序 用户在 sidebarPanel 中输入数据 然后在 mainPanel 中反应性地输出结果 如何
  • 从 data.frame 中提取时用 NA 填充缺失的列

    我有一个函数 它将具有某些列的数据框作为输入 columns a b z 现在我有一个数据框DF只有很少的这些列DF columns f u z 如果列不在其中 如何创建一个包含所有值为 NA 的列的数据框DF这与DF在柱子上 f u z
  • 美人鱼图:调整图表周围的空白

    我在用 Rstudio 编译的 Rmd 报告中使用了美人鱼图 在 HTML PDF 输出中 图表上方和下方有大量空白 请参见下面的示例 Header Text r library DiagrammeR mermaid graph TD cl
  • 如何有效地将多个光栅 (.tif) 文件导入 R

    我是 R 新手 尤其是在空间数据方面 我正在尝试找到一种方法来有效地将多个 600 单波段栅格 tif 文件导入到 R 中 所有文件都存储在同一文件夹中 不确定这是否重要 但请注意 在我的 Mac 和 Windows 并行 VM 上的文件夹
  • 将所有分号替换为空格 pt2

    我尝试对 2000 多行关键字的列表运行文本分析 但它们的列出方式如下 战略 管理风格 组织 所以当我使用 tm 删除标点符号时 它就变成了 组织的战略管理风格 我认为这在某种程度上破坏了我常用术语的分析 我尝试过使用 vector lt

随机推荐

  • 如何以编程方式指定replyUrlsWithType

    我想设置replyUrlsWithType以编程方式在应用程序上manifest https learn microsoft com en us azure active directory develop reference app ma
  • Eclipse 在调试 java 时跳过断点

    我使用 Eclipse 已经很多年了 并且一直使用调试器 但最近我知道它可以在调试时跳过断点 我什至已经在 println 上设置了一个断点 我会看到文本出来 但不会到达断点 另外 有时我会在代码的一个区域一致地遇到断点 但在其他区域却不会
  • default(Type) 的编程等效项

    我正在使用反射来循环Type的属性并将某些类型设置为其默认值 现在 我可以切换类型并设置default Type 明确地 但我宁愿在一行中完成 是否存在与默认值等效的编程方式 如果是值类型使用激活器 CreateInstance http
  • SET NOCOUNT ON 使用情况

    灵感来自这个问题 https stackoverflow com questions 1483383 is this stored procedure thread safe or whatever the equiv is on sql
  • 如果数据包含撇号,如何插入?

    实际上 我的任务是使用 C 将 csv 文件加载到 sql server 中 所以我用逗号将其拆分 我的问题是某些字段的数据包含撇号 并且我正在触发插入查询以将数据加载到 sql 中 所以它给出了我的编码错误 using System us
  • 如何按列对文本文件进行排序并保持原始顺序

    我有一个非常大的数据文件 有 15 列 我需要根据特定列 例如第 11 列 对所有行进行排序 我在 Linux 中使用以下命令 sort k11 d myfile txt gt sortedfile 问题是排序命令不保留文件的原始顺序 例如
  • FILTER_VALIDATE 与 Preg_match。使用哪一个?

    要验证输入日期 无论是表单 URL 还是表单 您通常使用哪种技术 我一直在看PHP 过滤器 http www w3schools com php php ref filter asp但我很少在任何代码上看到它们 我平时见过preg mach
  • PHP大量内存用于SQL查询

    我在优化 Apache PHP 内存使用时偶然发现了一个奇怪的问题 基本上 当尝试绑定 MySQLi 查询的结果时 代码会崩溃 并显示错误消息 致命错误 允许的内存大小 16777216 字节耗尽 试图分配 50331646 字节 相关表格
  • 我什么时候可以激活/停用布局约束?

    我在 IB 中设置了多组约束 并且我想根据某些状态以编程方式在它们之间切换 有一个constraintsA所有出口集合均标记为从 IB 安装 并且constraintsB出口集合全部在IB中卸载 我可以通过编程方式在两组之间切换 如下所示
  • Spring Boot 中用于模块化应用程序的插件系统

    我在编译后寻找在 Spring Boot 中动态加载 jar 例如 我将 jar 放在某个文件夹中 当 Spring Boot 启动时 该文件夹中的所有 jar 将被注入到 Spring Boot 应用程序中 我不知道如何使用 Spring
  • 从powershell执行msbuild任务

    我正在关注这个博客 http sedodream com 2010 04 26 ConfigTransformationsOutsideOfWebAppBuilds aspx http sedodream com 2010 04 26 Co
  • Microsoft onedrive:无需登录即可使用 API 密钥创建文件夹

    我可以使用以下命令在 onedrive 中创建文件夹和文件Graph API 但是第一次我必须登录微软帐户 以下是我需要登录的链接 https login microsoftonline com common oauth2 v2 0 aut
  • Angular 2 (keydown.enter) 无法阻止Default()

    the event preventDefault 我使用时不起作用 keydown enter 在模板中 这是演示 https plnkr co edit GZrVt7l6BEO2uHfWFoTQ p preview https plnkr
  • Spring-data-cassandra 1.3.4 与 Cassandra 3.x 不兼容

    我尝试使用 Spring data cassandra 1 3 4 以及最新的 cassandra driver core 3 0 0 在 Cassandra 2 1 12 作为 DSE 4 8 4 的一部分 上 一切正常 因为相同的 sp
  • React 是否保证“props”对象引用保持稳定?

    最近我看到类似于以下人为示例的代码 const MyComp props gt const prevProps setPrevProps useState props if props prevProps setPrevProps prop
  • 编写一个监听 USB 端口的小实用工具,需要建议

    我有一个可以循环工作的硬件 它配备了专有的软件工具 让用户可以通过 USB 从 PC 控制它 用户定义每个周期的长度 在每个周期开始时 软件工具通过 USB 快速向硬件发出一系列命令 然后进入空闲模式 等待下一个周期 还有第二个硬件需要与第
  • 通过静态类访问 HttpContext 可以“正确”处理不同的请求

    I found 本文 https www quickdevnotes com better approach to use httpcontext outside a controller in net core 2 1 在尝试解决需要非控
  • 图片上传:iPhone客户端-Django-S3

    我有一个关于从客户端 在本例中为 iPhone 应用程序 上传到 S3 的一般性问题 我正在使用 Django 在 EC2 实例上编写 Web 服务 以下方法是将文件上传到 S3 的最低限度方法 对于较小的文件 jpg 或 png def
  • 判断手机是否重启过

    我正在尝试检测自上次设置首选项值以来 Android 设备是否已重新启动 理想情况下 我想在没有android permission RECEIVE BOOT COMPLETED允许 我考虑的一种方法是存储另一个包含某种会话 ID 的首选项
  • 是否有更好的方法来处理穿过反子午线(日界线)的空间多边形?

    TL DR R中处理在纬度 180 处与反子午线相交 重叠的空间多边形并将其沿该子午线切割成两部分的最佳方法是什么 Preface 这将是一篇很长的文章 但只是因为我将包含大量代码和图形来进行说明 我将向您展示我的目标是什么以及我通常如何实