简体   繁体   English

我如何确保 spatstat::owin(poly=<polygon> ) 没有“负区域”

[英]How do I ensure that the polygon in spatstat::owin(poly=<polygon>) does not have “negative area”

I am a new user of the R spatstat package and am having problems creating a polygonal observation window with owin().我是 R spatstat 包的新用户,在使用 owin() 创建多边形观察窗口时遇到问题。 Code follows:代码如下:

library("maps")
library ("sp")` 
library("spatstat")
mass.map <- map("state", "massachusetts:main", fill=T) # This returns a data frame includding x and y components that form a polygon of massachusetts mainland`

mass.win <- owin(poly=data.frame(x=mass.map$x, y=mass.map$y)

Error in if (w.area < 0) stop(paste("Area of polygon is negative -", "maybe traversed in >wrong direction?")) : missing value where TRUE/FALSE needed if (w.area < 0) stop(paste("Area of​​多边形为负 -", "maybe traversed in > wrong direction?")) 中的错误:需要 TRUE/FALSE 的缺失值

I tried things like reversing the order of the polygon and got same error.我尝试了诸如颠倒多边形顺序之类的方法,但得到了同样的错误。

 mass.win <- owin(poly=data.frame(x=rev(mass.map$x), y=rev(mass.map$y)))

Polygon contains duplicated vertices多边形包含重复的顶点

Polygon is self-intersecting Error in owin(poly = data.frame(x = rev(mass.map$x), y = rev(mass.map$y))) : Polygon data contain duplicated vertices and self-intersection Polygon is self-intersecting Error in owin(poly = data.frame(x = rev(mass.map$x), y = rev(mass.map$y))) :多边形数据包含重复的顶点和自相交

Then I figured that maybe the polygon returned by map() is not meant to be fed to owin().然后我想也许 map() 返回的多边形并不意味着要馈送给 owin()。 So I tried loading a massachusetts shape file (I am totally taking guesses at this point).:所以我尝试加载马萨诸塞州的形状文件(此时我完全猜测)。:

x <- readShapePoly("../Geog/OUTLINE25K_POLY") ## The shape file for MASS, loaded from MassGIS website
mass.poly <- x <- readShapePoly("../Geog/OUTLINE25K_POLY", force_ring=T, delete_null_obj=T) ## I got following error whether or not I used force_ring

mass.owin <- as(mass.poly, "owin") Checking 1006 polygons...1, Polygon 1 contains duplicated vertices [Checking polygon with 91844 edges...] 2, 3, .. [etd 1:21:52] ....10 [etd 36:12] ..... [etd 23:10] ....20 [etd 16:59] ..... [etd 13:22] ....30 [etd 11:01] ..... [etd 9:21] ....40 [etd 8:06] ..... [etd 7:09] ....50 [etd 6:23] ..... [etd 5:46] ....60 [etd 5:15] ...[Checking polygon with 2449 edges...] .. [etd 4:49] ....70 [etd 4:27] ..... [etd 4:07] ....80 [etd 3:50] ..... [etd 3:36] ....90 [etd 3:22] ..... [etd 3:11] ....100 [ etc. mass.owin <- as(mass.poly, "owin") 检查 1006 个多边形...1,多边形 1 包含重复的顶点 [检查具有 91844 条边的多边形...] 2, 3, .. [etd 1:21: 52] ....10 [etd 36:12] ..... [etd 23:10] ....20 [etd 16:59] ..... [etd 13:22] .... 30 [etd 11:01] ..... [etd 9:21] ....40 [etd 8:06] ..... [etd 7:09] ....50 [etd 6:23] ] ..... [etd 5:46] ....60 [etd 5:15] ...[检查具有 2449 条边的多边形...] .. [etd 4:49] ....70 [ etd 4:27] ..... [etd 4:07] ....80 [etd 3:50] ..... [etd 3:36] ....90 [etd 3:22] . .... [etd 3:11] ....100 [等。

I got messages complaining about intersecting vertices, etc. and it failed to build the polygon.我收到了抱怨相交顶点等的消息,但它无法构建多边形。

Some context on problem: I am trying to use functions in spatstat for spatial relative risk calculations, ie, the spatial ratio of denstity of cases vs. controls.关于问题的一些背景:我正在尝试使用 spatstat 中的函数进行空间相对风险计算,即案例与控件密度的空间比率。 For that I need an observation window and point plot within that window.为此,我需要一个观察窗口和该窗口内的点图。 I could cheat and make the observation window a rectangle around massachusetts but that would presumably distort values near the coast.我可以作弊,使观察窗口成为围绕马萨诸塞州的矩形,但这可能会扭曲海岸附近的值。 In any case, I'd like to learn how to do this right for any future work I do with this package.无论如何,我想学习如何为我使用此软件包所做的任何未来工作正确地做到这一点。 Thanks for any help you can provide.感谢您的任何帮助,您可以提供。

EDIT 2021-02-04: I had this clockwise/anti-clockwise problem again and found my own answer the only one addressing the issue for spatstat.编辑 2021-02-04:我再次遇到了这个顺时针/逆时针问题,并找到了我自己的答案,这是唯一一个解决 spatstat 问题的答案。 The answer was not very helpful.答案不是很有帮助。 Have improved it to make it useful for a wider range of applications.对其进行了改进,使其可用于更广泛的应用。

spatstat package wants owin object coordinates specified anticlockwise . spatstat包要owin对象坐标指定逆时针 A quote from the documentation of version 1.36-0:引用自 1.36-0 版文档:

single polygon: If poly is a matrix or data frame with two columns, or a structure with two component vectors x and y of equal length, then these values are interpreted as the cartesian coordinates of the vertices of a polygon circumscribing the window.单多边形:如果 poly 是具有两列的矩阵或数据框,或者是具有两个相等长度的分量向量 x 和 y 的结构,则这些值被解释为外接窗口的多边形顶点的笛卡尔坐标。 The vertices must be listed anticlockwise.顶点必须逆时针列出。 No vertex should be repeated (ie do not repeat the first vertex).不应重复任何顶点(即不重复第一个顶点)。

library("maps")
library ("sp")
library("spatstat")
mass.map <- map("state", "massachusetts:main", fill=T)

在此处输入图片说明

First, you'll need to find out whether your polygon is running clockwise or anticlock-wise.首先,您需要确定多边形是顺时针运行还是逆时针运行。 The approach here can be used to find out the answer. 这里的方法可以用来找出答案。 Formulate it as a function:将其公式化为函数:

#' @title Check whether points for an owin are clockwise
#' @param x a dataframe with x coordinates in the first column and y coordinates in the second. 
#' @details Similarly to owin, the polygon should not be closed
#' @return A logical telling whether the polygon is arranged clockwise.
#' @author The idea has been scavenged from https://stackoverflow.com/a/1165943/1082004

clockwise <- function(x) {
    
  x.coords <- c(x[[1]], x[[1]][1])
  y.coords <- c(x[[2]], x[[2]][1])
  
  double.area <- sum(sapply(2:length(x.coords), function(i) {
    (x.coords[i] - x.coords[i-1])*(y.coords[i] + y.coords[i-1])
  }))
  
  double.area > 0
} 

Now, see whether the coordinates in mass.map are clockwise:现在,查看mass.map中的坐标是否为顺时针:

clockwise(data.frame(x=mass.map$x, y=mass.map$y))
#> TRUE

They are.他们是。 Turn the coordinates anti-clockwise by usingrev function, which reverses vectors for x and y :使用rev函数逆时针旋转坐标,该函数反转xy向量:

mass.win <- owin(poly=data.frame(x=rev(mass.map$x), y=rev(mass.map$y)))
plot(mass.win)

在此处输入图片说明

I'm quite familiar with the problem you have.我对你遇到的问题很熟悉。 If I understood right, you desire to get a polygonal object of class owin.如果我理解正确,您希望获得 owin 类的多边形对象。 Following codes will help you to acquire what you wanted.以下代码将帮助您获得您想要的东西。

#Loading the required packages
library (sp)
library(maps)

# Reading the dataset
mass.map <- map("state", "massachusetts:main", fill=T)

IDs <- sapply(strsplit(mass.map$names, ":"), function(x) x[1])
# converting can be done by loading the powerful package "maptools"
library(maptools)
# Converting into SpatialPolygons-object
mass.poly <- map2SpatialPolygons(mass.map, IDs = IDs)

# Converting by coercing into owin-object
mass.owin <- as.owin.SpatialPolygons(mass.poly)

The original question was posted 7 years ago (2014).最初的问题是在 7 年前(2014 年)发布的。 The spatstat package has changed vastly since then. spatstat起, spatstat包发生了巨大的变化。

The error messages about duplicated vertices and self-intersecting polygons do not occur anymore , because the code now automatically corrects these flaws in the polygon data.不再出现关于重复顶点和自相交多边形的错误消息,因为代码现在会自动更正多边形数据中的这些缺陷。

The error message Area of polygon is negative - maybe traversed in wrong direction?错误消息Area of polygon is negative - maybe traversed in wrong direction? still occurs .仍然发生 This is because owin requires polygon vertices to be listed in anticlockwise order around an outer boundary (and clockwise order around the boundary of a hole).这是因为owin要求多边形顶点围绕外部边界按逆时针顺序(以及围绕孔边界的顺时针顺序)列出。 If your window is a single polygon rather than a collection of polygons, the fix is to simply reverse the order of the coordinate vectors using rev :如果您的窗口是单个多边形而不是多边形集合,则解决方法是使用rev简单地反转坐标向量的顺序:

library(maps)
library(sp)
library(spatstat)
mass.map <- map("state", "massachusetts:main", fill=TRUE)
mass.win <- owin(poly=lapply(mass.map, rev))

We can't make this happen automatically because it is not always what the user wanted.我们不能让这自动发生,因为它并不总是用户想要的。

For more information, see Chapter 3 of the spatstat book , which you can download for free from here .有关详细信息,请参阅spatstat 书籍的第 3 章,您可以从此处免费下载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM