Рассчитать центроид внутри / внутри пространственного полигона

В таких программах, как ArcMap, можно создавать центроиды для многоугольников внутри многоугольника. В случаях, подобных показанному ниже, это необходимо.

В R можно вычислить центроиды пространственных многоугольников с rgeos::gCentroid(), Однако нет способа форсировать расчет центроидов внутри многоугольника.

library(rgdal)
library(rgeos)

x <- readWKT("POLYGON ((1441727.5096940901130438 6550163.0046194596216083, 
             1150685.2609429201111197 6669225.7427449300885201, 
             975398.4520359700545669 6603079.7771196700632572, 
             866257.6087542800232768 6401334.5819626096636057, 
             836491.9242229099618271 6106985.0349301798269153, 
             972091.1537546999752522 5835786.5758665995672345, 
             1547561.0546945100650191 5782869.8033663900569081, 
             1408654.5268814601004124 5600968.3978968998417258, 
             720736.4843787000281736 5663807.0652409195899963, 
             598366.4479719599476084 6001151.4899297598749399, 
             654590.5187534400029108 6341803.2128998702391982, 
             869564.9070355399744585 6784981.1825891500338912, 
             1451649.4045378800947219 6788288.4808704098686576, 
             1441727.5096940901130438 6550163.0046194596216083))")
plot(x)

Это многоугольник x

gCentroid() создает центроид, который в данном конкретном случае находится за пределами многоугольника. Несмотря на геометрическую правильность, некоторым приложениям требуются центроиды внутри многоугольника, так как они могут быть рассчитаны с помощью ArcMap.

xCent <- gCentroid(x, byid = TRUE)
points(xCent, col = "red", pch = 16)

Желаемый вывод (из ArcMap) выглядит следующим образом:

Есть ли возможность генерировать центроиды как это в R?

РЕДАКТИРОВАТЬ:

После некоторого копания выясняется, что ArcMap выбирает случайную точку внутри полигона:

Msgstr "Для входного многоугольника: выходная точка будет внутри многоугольника."

Таким образом, вопрос должен быть: есть ли функция, которая создает точку в любой случайной позиции внутри многоугольников?

1 ответ

Решение

Как указывалось в обновлениях Вопроса, кажется, что ArcMap просто помещает точку в случайное место внутри многоугольника. Это может быть достигнуто путем gPointsOnSurface(..., n = 1, type = 'random') также.

xCent2 <- gPointOnSurface(x, byid = T)
points(xCent2, col = "blue", pch = 16)

Я написал эту функцию, которая сначала находит центроид, и, если он не находится внутри (то есть не перекрывает / не пересекает многоугольник), он заменяется точкой на поверхности. Кроме того, он возвращает новый столбец, который указывает, является ли точка настоящим центроидом или нет.

gCentroidWithin <- function(pol) {
  require(rgeos)

  pol$.tmpID <- 1:length(pol)
  # initially create centroid points with gCentroid
  initialCents <- gCentroid(pol, byid = T)

  # add data of the polygons to the centroids
  centsDF <- SpatialPointsDataFrame(initialCents, pol@data)
  centsDF$isCentroid <- TRUE

  # check whether the centroids are actually INSIDE their polygon
  centsInOwnPoly <- sapply(1:length(pol), function(x) {
    gIntersects(pol[x,], centsDF[x, ])
  })
  # substitue outside centroids with points INSIDE the polygon
  newPoints <- SpatialPointsDataFrame(gPointOnSurface(pol[!centsInOwnPoly, ], 
                                                      byid = T), 
                                      pol@data[!centsInOwnPoly,])
  newPoints$isCentroid <- FALSE
  centsDF <- rbind(centsDF[centsInOwnPoly,], newPoints)

  # order the points like their polygon counterpart based on `.tmpID`
  centsDF <- centsDF[order(centsDF$.tmpID),]

  # remove `.tmpID` column
  centsDF@data <- centsDF@data[, - which(names(centsDF@data) == ".tmpID")]

  cat(paste(length(pol), "polygons;", sum(centsInOwnPoly), "actual centroids;", 
            sum(!centsInOwnPoly), "Points corrected \n"))

  return(centsDF)
}
Другие вопросы по тегам