Recabamos en distintos sitios para así tener para ti la respuesta a tu problema, si continúas con alguna difcultad déjanos tu duda y te respondemos con gusto, porque estamos para servirte.
Solución:
En primer lugar, no puedo encontrar ninguna documentación que diga que coordinates
o getSpPPolygonsLabptSlots
devuelve el centroide del centro de masa. De hecho, la última función ahora aparece como ‘Desaprobada’ y debería emitir una advertencia.
Lo que desea para calcular el centroide como el centro de masa de una característica es el gCentroid
función de la rgeos
paquete. Haciendo help.search("centroid")
habrá encontrado esto.
trueCentroids = gCentroid(sids,byid=TRUE)
plot(sids)
points(coordinates(sids),pch=1)
points(trueCentroids,pch=2)
debería mostrar la diferencia y ser igual que los centroides de Qgis.
aquí hay un enfoque que utiliza sf. Como demuestro, los resultados de sf :: st_centroid y rgeos :: gCentroid son los mismos.
library(sf)
library(ggplot2)
# I transform to utm because st_centroid is not recommended for use on long/lat
nc <- st_read(system.file('shape/nc.shp', package = "sf")) %>%
st_transform(32617)
# using rgeos
sp_cent <- gCentroid(as(nc, "Spatial"), byid = TRUE)
# using sf
sf_cent <- st_centroid(nc)
# plot both together to confirm that they are equivalent
ggplot() +
geom_sf(data = nc, fill = 'white') +
geom_sf(data = sp_cent %>% st_as_sf, color = 'blue') +
geom_sf(data = sf_cent, color = 'red')
Lo que hice para superar este problema fue generar una función que amortigua negativamente el polígono hasta que sea lo suficientemente pequeño como para esperar un polígono convexo. La función a utilizar escentroid(polygon)
#' find the center of mass / furthest away from any boundary
#'
#' Takes as input a spatial polygon
#' @param pol One or more polygons as input
#' @param ultimate optional Boolean, TRUE = find polygon furthest away from centroid. False = ordinary centroid
require(rgeos)
require(sp)
centroid <- function(pol,ultimate=TRUE,iterations=5,initial_width_step=10)
if (ultimate)
new_pol <- pol
# For every polygon do this:
for (i in 1:length(pol))
width <- -initial_width_step
area <- gArea(pol[i,])
centr <- pol[i,]
wasNull <- FALSE
for (j in 1:iterations)
if (!wasNull) # stop when buffer polygon was alread too small
centr_new <- gBuffer(centr,width=width)
# if the buffer has a negative size:
substract_width <- width/20
while (is.null(centr_new)) #gradually decrease the buffer size until it has positive area
width <- width-substract_width
centr_new <- gBuffer(centr,width=width)
wasNull <- TRUE
# if (!(is.null(centr_new)))
# plot(centr_new,add=T)
#
new_area <- gArea(centr_new)
#linear regression:
slope <- (new_area-area)/width
#aiming at quarter of the area for the new polygon
width <- (area/4-area)/slope
#preparing for next step:
area <- new_area
centr<- centr_new
#take the biggest polygon in case of multiple polygons:
d <- disaggregate(centr)
if (length(d)>1)
biggest_area <- gArea(d[1,])
which_pol <- 1
for (k in 2:length(d))
if (gArea(d[k,]) > biggest_area)
biggest_area <- gArea(d[k,])
which_pol <- k
centr <- d[which_pol,]
#add to class polygons:
[email protected]
[[i]] <- remove.holes([email protected][[i]])
[email protected][[i]]@Polygons[[1]]@coords <- [email protected][[1]]@Polygons[[1]]@coords
centroids <- gCentroid(new_pol,byid=TRUE)
else
centroids <- gCentroid(pol,byid=TRUE)
return(centroids)
#Given an object of class Polygons, returns
#a similar object with no holes
remove.holes <- function(Poly)
# remove holes
is.hole <- lapply([email protected],function(P)[email protected])
is.hole <- unlist(is.hole)
polys <- [email protected][!is.hole]
Poly <- Polygons(polys,[email protected])
# remove 'islands'
max_area <- largest_area(Poly)
is.sub <- lapply([email protected],function(P)[email protected][email protected][!is.sub]
Poly <- Polygons(polys,[email protected])
Poly
largest_area <- function(Poly)
total_polygons <- length([email protected])
max_area <- 0
for (i in 1:total_polygons)
max_area <- max(max_area,[email protected][[i]]@area)
max_area
Calificaciones y reseñas
Eres capaz de reafirmar nuestro cometido poniendo un comentario y dejando una valoración te damos las gracias.