Saltar al contenido

Cómo calcular centroides de polígono en R (para formas no contiguas)

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') 

ingrese la descripción de la imagen aquí

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *