# librerias requeridas
library(sf)
library(mapview)
library(dplyr)
SIG con R: Vectores part 2
SIG
R
Apuntes de la escuela ambiental
Continuación de apuntes con manipulación y operación con vectores
Crear polígonos mínimos convexos
En ecología y biología nos ayuda para determinar hábitos hogareños, es decir, encontrar el área en el que se desplaza una especie.
# Cargamos el dataframe con los puntos
<-read.csv("Registros.csv", header = T) %>% st_as_sf(coords=c("Longitude","Latitude"), crs=4326)
registrosmapview(registros)
# Observar solo la sp1
<-filter(registros, Species=="sp1")
sp1mapview(sp1)
# Generar PMC para una sola especie
<- sp1 %>% group_by(Species) %>%
pmc1summarise(geometry= st_combine(geometry)) |> st_convex_hull()
mapview(list(pmc1, sp1))
# Generar poligonos para todas las especies
<- registros %>% group_by(Species) %>%
pmc_sppsummarise(geometry= st_combine(geometry)) %>%
st_convex_hull()
mapview(list(pmc_spp, registros))
Crear polígonos alpha hull
#install.packages("alphahull")
#instalar maptools
#("maptools", repos = "https://packagemanager.posit.co/cran/2023-10-13")
library(maptools)
library(alphahull)
library(sp)
#library(rgdal)
# Funcion para convertir los a-hull en shp (https://stat.ethz.ch/pipermail/r-sig-geo/2012-March/014409.html)
<- function(x, increment=360, rnd=10, proj4string=CRS(as.character(NA))){
ah2sp require(alphahull)
require(maptools)
if (class(x) != "ahull"){
stop("x needs to be an ahull class object")
}# Extract the edges from the ahull object as a dataframe
<- as.data.frame(x$arcs)
xdf # Remove all cases where the coordinates are all the same
<- subset(xdf,xdf$r > 0)
xdf <- NULL
res if (nrow(xdf) > 0){
# Convert each arc to a line segment
<- list()
linesj <-NULL
prevx<-NULL
prevy<-1
jfor(i in 1:nrow(xdf)){
<- xdf[i,]
rowi <- c(rowi$v.x, rowi$v.y)
v <- rowi$theta
theta <- rowi$r
r <- c(rowi$c1, rowi$c2)
cc # Arcs need to be redefined as strings of points. Work out the number of points to allocate in this arc segment.
<- 2 + round(increment * (rowi$theta / 2),0)
ipoints # Calculate coordinates from arc() description for ipoints along the arc.
<- anglesArc(v, theta)
angles <- seq(angles[1], angles[2], length = ipoints)
seqang <- round(cc[1] + r * cos(seqang),rnd)
x <- round(cc[2] + r * sin(seqang),rnd)
y # Check for line segments that should be joined up and combine their coordinates
if (is.null(prevx)){
<-x
prevx<-y
prevyelse if (x[1] == round(prevx[length(prevx)],rnd) && y[1] ==
} round(prevy[length(prevy)],rnd)){
if (i == nrow(xdf)){
#We have got to the end of the dataset
<-append(prevx,x[2:ipoints])
prevx<-append(prevy,y[2:ipoints])
prevylength(prevx)]<-prevx[1]
prevx[length(prevy)]<-prevy[1]
prevy[<-cbind(prevx,prevy)
coordsjcolnames(coordsj)<-NULL
# Build as Line and then Lines class
<- Line(coordsj)
linej <- Lines(linej, ID = as.character(j))
linesj[[j]] else {
} <-append(prevx,x[2:ipoints])
prevx<-append(prevy,y[2:ipoints])
prevy
}else {
} # We have got to the end of a set of lines, and there are several such sets, so convert the whole of this one to a line segment and reset.
length(prevx)]<-prevx[1]
prevx[length(prevy)]<-prevy[1]
prevy[<-cbind(prevx,prevy)
coordsjcolnames(coordsj)<-NULL
# Build as Line and then Lines class
<- Line(coordsj)
linej <- Lines(linej, ID = as.character(j))
linesj[[j]] <-j+1
j<-NULL
prevx<-NULL
prevy
}
}# Promote to SpatialLines
<- SpatialLines(linesj)
lspl # Convert lines to polygons
# Pull out Lines slot and check which lines have start and end points that are the same
<- slot(lspl, "lines")
lns <- sapply(lns, function(x) {
polys <- slot(slot(x, "Lines")[[1]], "coords")
crds identical(crds[1, ], crds[nrow(crds), ])
}) # Select those that do and convert to SpatialPolygons
<- lspl[polys]
polyssl <- slot(polyssl, "lines")
list_of_Lines <- SpatialPolygons(list(Polygons(lapply(list_of_Lines, function(x)
sppolys Polygon(slot(slot(x, "Lines")[[1]], "coords")) }), ID = "1")),
{ proj4string=proj4string)
# Create a set of ids in a dataframe, then promote to SpatialPolygonsDataFrame
<- sapply(slot(sppolys, "polygons"), function(x) slot(x, "ID"))
hid <- sapply(slot(sppolys, "polygons"), function(x) slot(x, "area"))
areas <- data.frame(hid,areas)
df names(df) <- c("HID","Area")
rownames(df) <- df$HID
<- SpatialPolygonsDataFrame(sppolys, data=df)
res <- res[which(res@data$Area > 0),]
res
} return(res)
}
<- read.csv("Registros.csv", header=TRUE)
puntos<-puntos %>% filter(Species=="sp1") sp1
Defino Alfa y creo el poligono (el valor de alfa debe variar segun los puntos). En los datos NO deben haber x, y duplicados, sino la funcion saca ERROR. Los datos ya deben estar limpios
# Alfa hull
=4.5 # ancho de poligono
alpha1<-ahull(x=sp1$Longitude, y=sp1$Latitude, alpha=alpha)
alfa_sp1plot(alfa_sp1)
- 1
- Comando del paquete alphahull
class(alfa_sp1)
[1] "ahull"
# transformo de ashape a spatial polygon
<-ah2sp(alfa_sp1)
ob_shapeplot(ob_shape)
class(ob_shape)
[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"
# Exporto shape. Debo configurar el dsn.
# write_sf(obs_shp, "alpha_hull.shp")
Búferes
¿ Cómo dibujar un área sobre sobre un polígono ?
# librerias requeridas
library(sf)
library(mapedit)
library(mapview)
library(tidyverse)
# para dibujar los shapefile
<-mapview() %>% editMap()
poligono <-mapview() %>% editMap()
puntos <-mapview() %>% editMap()
lineas
mapview(poligono$drawn)
#transformar sistemas de coordenadas
<- poligono$finished %>% st_transform(crs=32618)
polig<- puntos$finished %>% st_transform(crs=32618)
point<- lineas$finished %>% st_transform(crs=32618)
rutas
mapview(list(polig, point, rutas))
# write_sf(poligono$drawn, "polig.shp")
Tengan en cuenta que el sistema de coordenadas de referencia nos marca las unidades de distancia (En este caso el sistema de coordenadas esta en UTM y trabaja las distancias en metros). Si quieren que las unidades sean metros deben reproyectar su capa. 1 km equivale a aproximadamente 0.0083333 grados
# creando buffer
1<-st_buffer(polig, dist= 10000)
polibuffmapview(list(polig, polibuff))
<-st_buffer(point, dist= 5000)
puntbuffmapview(list(point, puntbuff))
<-st_buffer(rutas, dist= 500)
linbuffmapview(list(rutas, linbuff))
- 1
- la distancia este en metros 😀 que equivalen a 10 km
# buffer negativo
<-st_buffer(polig, dist= -10000)
polibuff2mapview(list(polig, polibuff, polibuff2))
Calculando áreas
# Calculo de areas
1<-st_area(polig)/1000000
a_po<-st_area(polibuff)/1000000
a_pb<-st_area(polibuff2)/1000000 a_pb2
- 1
- Se divide entre un millón para pasar de \(m^2\) a \(km^2\)
<-c(a_po, a_pb, a_pb2)
areakm2# calculando diferencias entre los poligonos
1]-areakm2[2]
areakm2[1]-areakm2[3] areakm2[
<- read_sf("COL_adm1.shp")
col<-st_area(col)/1000000
area_col
#calculo de areas de departamentos
<- col %>% mutate(AREAKM=st_area(col)/1000000) areas_depa