这一点是否在多边形内?

时间:2017-08-31 02:25:48

标签: r polygon geospatial sp

非常简单的情况:一个多边形定义了一个地理区域,我想知道一个由gps坐标给出的点是否位于该多边形内。

我经历了很多SO问题,并尝试过像sp这样的各种函数和软件包,但无法弄清楚它失败的原因。

我试过这个非常简单的功能: https://www.rdocumentation.org/packages/SDMTools/versions/1.1-221/topics/pnt.in.poly

install.packages("SDMTools v1.1-221")
library(SDMTools v1.1-221)

## Coordinates of the polygon corners
lat <- c(48.43119, 48.43119, 48.42647, 48.400031, 48.39775, 48.40624, 48.42060, 48.42544, 48.42943 ) 
lon <- c(-71.06970, -71.04180, -71.03889, -71.04944, -71.05991, -71.06764, -71.06223, -71.06987, -71.07004)
pol = cbind(lat=lat,lng=lon)

## Point to be tested
x <- data.frame(lng=-71.05609, lat=48.40909)

## Visualization, this point clearly stands in the middle of the polygon
plot(rbind(pol, x))
polygon(pol,col='#99999990')

## Is that point in the polygon? 
out = pnt.in.poly(x,poly)

## Well, no (pip=0)
print(out)

这个函数给出的例子对我有用,但是这个简单的例子没有......为什么会这样?

2 个答案:

答案 0 :(得分:3)

我没有使用过你正在使用的方法,但是我在sp中有一个方法可以在你的点和多边形上完美运行。

我挑选了你的代码并将latlon作为向量,将点坐标作为值来满足函数要求。

但你可以很容易地创建一个数据框并明确地将列用作lat / lon值。

以下是它的要点:

require(sp)
## Your polygon
lat <- c(48.43119, 48.43119, 48.42647, 48.400031, 48.39775, 48.40624, 48.42060, 48.42544, 48.42943 ) 
lon <- c(-71.06970, -71.04180, -71.03889, -71.04944, -71.05991, -71.06764, -71.06223, -71.06987, -71.07004)


## Your Point
lng=-71.05609
lt=48.40909

# sp function which tests for points in polygons

point.in.polygon(lt, lng, lat, lon, mode.checked=FALSE)

这是输出:

[1] 1  

文档中对此的解释:

整数数组值为:

  • 0点严格地在多边形外部
  • 1点严格地在多边形内部
  • 2点位于多边形边缘的相对内部
  • 3点是多边形的顶点

由于你的观点是基于此的1,它应该完全在你的地图显示的多边形内!使用这些类型的数据获得良好输出的关键是以正确的格式提供变量。

您可以轻松地将数据框dfdf$latdf$lon作为两个多边形变量以及带test的测试框test$lat }和test$lon作为一系列要点。您只需将等式中的每一个替换为等式:

point.in.polygon(df$lat, df$lon, test$lat, test$lon, mode.checked=FALSE)

它将返回0,1的2和3的向量

请确保先使用正确的格式! Here is a link to the function page:

答案 1 :(得分:2)

我无法在?pnt.in.poly的文档中明确说明,但lnglat列的排序似乎很重要。您需要在pol中交换列顺序,它才有效。

pol = cbind(lat=lat, lng=lon)
pnt.in.poly(x, pol)
#          lng      lat pip
# 1 -71.05609 48.40909   0

pol = cbind(lng=lon, lat=lat)
pnt.in.poly(x, pol)
#          lng      lat pip
# 1 -71.05609 48.40909   1

在空间测量中,lng通常被认为是x-axislat y-axisplot(),你会看到compile "com.android.support:support-emoji:26.0.1" }