我有一个使用相机陷阱观察到的物种的数据点,并希望使用R测量每个相机陷阱位置(CameraStation)到国家公园边缘的距离。我有公园的shapefile (shp),并希望将一个标准应用于距离边缘<5 5km的CameraStation(s)。我的数据帧(df)由每个CameraStation的多个事件/观察值(EventID)组成。目的是分析当公园边缘附近的事件最频繁的时候,考虑到其他环境因素,如季节,月相和DayNight (也是DF中的列)。
我在R中找到了一个名为distance的包,但这是用于距离采样的,而不是我想要做的。在这种情况下,哪个包是相关的?
我预计会有以下结果:
EventID CameraStation Distance(km) Within 5km
0001 Station 1 4.3 Yes
0002 Station 1 4.3 Yes
0003 Station 2 16.2 No
0004 Station 3 0.5 Yes
...发布于 2019-09-07 13:23:29
这是一个通用的解决方案,改编自Spacedman对this question at gis.stackexchange的回答。注意:此解决方案需要在投影坐标系中工作。如果需要,您可以使用spTransform转换为投影的CRS。
rgeos包的gDistance函数计算几何图形之间的距离,但对于多边形内部的点,距离为零。诀窍是创建一个新的“遮罩”多边形,其中原始多边形是从遮罩中切出的一个洞。然后我们可以测量洞中的点和蒙版之间的距离,这是我们真正关心的到原始多边形边缘的距离。
我们将使用在this page上找到的黄石国家公园边界的形状文件。
library(sp) # for SpatialPoints and proj4string
library(rgdal) # to read shapefile with readOGR
library(rgeos) # for gDistance, gDifference, and gBuffer
# ab67 was the name of the shape file I downloaded.
yellowstone.shp <- readOGR("ab67")
# gBuffer enlarges the boundary of the polygon by the amount specified by `width`.
# The units of `width` (meters in this case) can be found in the proj4string
# for the polygon.
yellowstone_buffer <- gBuffer(yellowstone.shp, width = 5000)
# gDifference calculates the difference between the polygons, i.e. what's
# in one and not in the other. That's our mask.
mask <- gDifference(yellowstone_buffer, yellowstone.shp)
# Some points inside the park
pts <- list(x = c(536587.281264245, 507432.037861251, 542517.161278414,
477782.637790409, 517315.171218198),
y = c(85158.0056377799, 77251.498952222, 15976.0721391485,
40683.9055315169, -3790.19457474617))
# Sanity checking the mask and our points.
plot(mask)
points(pts)

# Put the points in a SpatialPointsDataFrame with camera id in a data field.
spts.df <- SpatialPointsDataFrame(pts, data = data.frame(Camera = ordered(1:length(pts$x))))
# Give our SpatialPointsDataFrame the same spatial reference as the polygon.
proj4string(spts.df) <- proj4string(yellowstone.shp)
# Calculate distances (km) from points to edge and put in a new column.
spts.df$km_to_edge <- apply(gDistance(spts.df, difference, byid=TRUE),2,min)/1000
# Determine which records are within 5 km of an edge and note in new column.
spts.df$edge <- ifelse(spts.df$km_to_edge < 5, TRUE, FALSE)
# Results
spts.df
# coordinates Camera km_to_edge edge
# 1 (536587.3, 85158.01) 1 1.855010 TRUE
# 2 (507432, 77251.5) 2 9.762755 FALSE
# 3 (542517.2, 15976.07) 3 11.668700 FALSE
# 4 (477782.6, 40683.91) 4 4.579638 TRUE
# 5 (517315.2, -3790.195) 5 8.211961 FALSE发布于 2019-09-07 06:35:23
这里有一个快速的解决方案。
将shapefile的轮廓简化为N个点。然后计算每个相机陷阱到国家公园轮廓中每个点的最小距离。
library(geosphrere)
n <- 500 ##The number of points summarizing the shapefile
NPs <- ##Your shapefile goes here
NP.pts <- spsample(NPs, n = n, type = "regular")
CP.pts <- ## Coordinates for a single trap
distances<-distm(coordinates(CP.pts), coordinates(NP.pts), fun = distHaversine)/1000
##Distance in Km between the trap to each point in the perimeter of the shapefile:
distances使用distances查找shapefile和给定陷印之间的最小距离。对于loops或apply函数,这种方法很容易推广。
发布于 2019-09-10 00:38:42
我在投影点数据框和形状文件时遇到问题,因此我使用此链接中的示例来回答我的问题
基本上,我使用了以下代码;
df # my data frame with points
shp # my shapefile (non-projected)
dist.mat <- geosphere::dist2Line(p = df2, line = shp)
coordinates(df2)<-~Longitude+Latitude # Longitude and Latitude are columns in my df
dmat<-data.frame(dist.mat) # turned it into a data frame
dmat$km5 <- ifelse(dmat$distance < 5000, TRUE, FALSE) # in meters (5000)
coordinates(dmat)<-~lon+lat
df2$distance <- dmat$distance # added new Distance column to my dfhttps://stackoverflow.com/questions/57820969
复制相似问题