简体   繁体   English

从shapefile计算覆盖率

[英]Calculating percent cover from shapefiles

I normally do not work with shapefiles, so I am a bit lost here. 我通常不使用shapefile,所以我在这里有点迷路。 I have two shapefiles each with multiple objects. 我有两个shapefile,每个都有多个对象。 The first is a set of 32 polygons (each one is a plot). 第一个是一组32个多边形(每个都是一个图)。 The second shapefile has >10,000 objects which represent vegetation clusters of different sizes within each plot. 第二个shapefile具有> 10,000个对象,这些对象代表每个图中不同大小的植被簇。 I am trying to figure out. 我想弄清楚。

1) How do I calculate percent cover of total vegetation cover within each site? 1)如何计算每个站点内植被覆盖的百分比?

2) What percentage of each the vegetation cover is less than 5 meters in area in each plot? 2)在每个样地中,每个植被覆盖面积小于5米的百分比是多少?

This is what my data looks like in ArcGIS for a single plot. 这是我的数据在ArcGIS中单个图的样子。

在此处输入图片说明

The following code will do what you want, I think. 我认为以下代码可以完成您想要的工作。

NB: This uses the area information stored in the shapefile polygons (as explained below). 注意:这使用存储在shapefile多边形中的区域信息(如下所述)。 It does not use the Area column in your vegetation shapefile data section. 使用Area在植被shapefile数据部分列。 In most cases, your Area is identical to the area stored in the shapefile, but in some cases your Area is much larger. 在大多数情况下,您的Area与shapefile中存储的区域相同,但是在某些情况下,您的Area要大得多。 Since I don't know where your Area data came from, it seemed safer to use the information stored with the shapefile polygons. 由于我不知道您的Area数据来自何处,因此使用与shapefile多边形一起存储的信息似乎更安全。

library(rgdal)
library(ggplot2)

setwd("<directory containing all your shapefiles>")
plt.map <- readOGR(dsn=".",layer="plots")
veg.map <- readOGR(dsn=".",layer="veg_in_plots")
# associate LocCode with polygon IDs
plt.data <- cbind(id=rownames(plt.map@data), LocCode=plt.map@data$LocCode)
veg.data <- cbind(id=rownames(veg.map@data), LocCode=veg.map@data$LocCode)
# function to extract area from polygon data
get.area <- function(polygon) {
  row <- data.frame(id=polygon@ID, area=polygon@area, stringsAsFactors=F)
  return(row)
}
# area of each plot polygon
plt.areas <- do.call(rbind,lapply(plt.map@polygons, get.area))
plt.data  <- merge(plt.data,plt.areas, by="id")  # append area column to plt.data
# area of each vegetation polygon
veg.areas <- do.call(rbind,lapply(veg.map@polygons, get.area))
veg.data  <- merge(veg.data,veg.areas, by="id")  # append area column to veg.data
# total area of vegetation polygons by LocCode
veg.smry  <- aggregate(area~LocCode,data=veg.data,sum)
smry      <- merge(plt.data,veg.smry,by="LocCode")
smry$coverage <- with(smry,100*area.y/area.x)    # coverage percentage
# total area for vegetation object with A < 5 msq
veg.lt5   <- aggregate(area~LocCode,data=veg.data[veg.data$area<5,],sum)
smry      <- merge(smry, veg.lt5, by="LocCode") 
# fraction of covered area coming from veg. obj. with A < 5 msq
smry$pct.lt5 <- with(smry, 100*area/area.y)

Produces this: 产生这个:

# head(smry)
#   LocCode id   area.x   area.y coverage      area  pct.lt5
# 1       1  3 1165.916 259.2306 22.23408  60.98971 23.52720
# 2      10 11 1242.770 366.3222 29.47626  88.21827 24.08216
# 3      11 12 1181.366 213.2105 18.04779 129.21612 60.60496
# 4      12 13 1265.352 577.6037 45.64767 236.83946 41.00380
# 5      13 14 1230.662 226.2686 18.38593  48.09509 21.25575
# 6      14 15 1274.538 252.0577 19.77640  46.94874 18.62619

Explanation: 说明:

Shapefiles can be imported into R using readOGR(...) in the rgdal package. 可以使用rgdal包中的rgdal readOGR(...)将Shapefile导入到R中。 When importing a polygon shapefile, the result is a "SpatialPolygonDataFrame" object. 导入多边形shapefile时,结果是“ SpatialPolygonDataFrame”对象。 These objects basically have two sections: a polygon section, which has the coordinates needed to plot each polygon, and a data section, which has data for each polygon (so, one row per polygon). 这些对象基本上有两个部分:一个多边形部分,它具有绘制每个多边形所需的坐标;一个数据部分,它具有每个多边形的数据(因此,每个多边形一行)。 If the shapefile is imported as, eg, map , 如果shapefile是作为map导入的,

map <- readOGR(dsn=".",layer="myShapeFile")

then the polygon and data sections can be accessed as map@polygon and map@data . 然后可以通过map@polygonmap@data访问多边形和数据部分。 It turns out that the polygon areas are stored in the polygon section. 事实证明,多边形区域存储在多边形部分中。 To get the areas, we define a function, get.area(...) that extracts the area and polygon ID from a polygon. 要获取区域,我们定义一个函数get.area(...) ,该函数从多边形中提取区域和多边形ID。 Then we call that function for all polygons using lapply(...) , and bind all the returned values together row-wise using rbind(...) : 然后,我们使用lapply(...)为所有多边形调用该函数,并使用rbind(...)将所有返回值按行绑定在一起:

plt.areas <- do.call(rbind,lapply(plt.map@polygons, get.area))
veg.areas <- do.call(rbind,lapply(veg.map@polygons, get.area))

Now we need to associate vegetation areas with plot polygons. 现在我们需要将植被区域与绘图多边形相关联。 This is done through column LocCode , which is present in the data section of each shapefile. 这是通过LocCodeLocCode ,该列存在于每个shapefile的data部分中。 So we first associate polygon ID's with LocCode for both plots and vegetation areas: 因此,我们首先将图和植被区域的多边形ID与LocCode关联:

plt.data <- cbind(id=rownames(plt.map@data), LocCode=plt.map@data$LocCode)
veg.data <- cbind(id=rownames(veg.map@data), LocCode=veg.map@data$LocCode)

Then we append the area column based on polygon ID: 然后,我们根据多边形ID附加面积列:

plt.data  <- merge(plt.data,plt.areas, by="id")  # append area column to plt.data
veg.data  <- merge(veg.data,veg.areas, by="id")  # append area column to veg.data

Then we need to sum the vegetation areas by LocCode: 然后我们需要通过LocCode对植被面积求和:

veg.smry  <- aggregate(area~LocCode,data=veg.data,sum)

And finally merge this with the plot polygon areas: 最后将其与绘图多边形区域合并:

smry      <- merge(plt.data,veg.smry,by="LocCode")

In the smry dataframe, area.x is the area of the plot, and area.y is the total area covered by vegetation in that plot. smry据帧, area.x是小区的面积, area.y是植被在情节覆盖的总面积。 Since, for both shapefiles, the projection is: 因为对于这两个shapefile,投影都是:

 +proj=utm +zone=13 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0

the units are in meters and the areas are in msq. 单位为米,面积为msq。 To determine how much of the vegetation is coming from areas < 5 msq, we total the vegetation areas with area < 5 and merge that result with smry : 为了确定有多少植被来自面积小于5 msq的区域,我们将面积小于5的植被面积总计,并将结果与smry合并:

veg.lt5   <- aggregate(area~LocCode,data=veg.data[veg.data$area<5,],sum)
smry      <- merge(smry, veg.lt5, by="LocCode") 

Finally, with the data we have it's straightforward to render maps for each plot area: 最后,有了数据,我们可以很容易地为每个绘图区域渲染地图:

cols   <- c("id","LocCode")
plt.df <- fortify(plt.map)
plt.df <- merge(plt.df,plt.data[cols],by="id")
veg.df <- fortify(veg.map)
veg.df <- merge(veg.df,veg.data[cols],by="id")
ggp <- ggplot(plt.df, aes(x=long, y=lat, group=group))
ggp <- ggp + geom_path()
ggp <- ggp + geom_polygon(data=veg.df, fill="green")
ggp <- ggp + facet_wrap(~LocCode,scales="free")
ggp <- ggp + theme(axis.text=element_blank())
ggp <- ggp + labs(x="",y="")
ggp <- ggp + coord_fixed()
ggp

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

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