سؤال

I have a SpatialPointsDataFrame in R that looks like this:

              coordinates id order  hole piece group box_id
    326  (-94.4, 27.6586) 47     1 FALSE     1  47.1      1
    327 (-93.64, 27.6232) 47     2 FALSE     1  47.1      1
    328 (-92.04, 27.7649) 47     3 FALSE     1  47.1      1
    329 (-90.36, 27.0903) 47     4 FALSE     1  47.1      1
    330 (-91.12, 25.6929) 47     5 FALSE     1  47.1      1
    331 (-92.92, 25.6569) 47     6 FALSE     1  47.1      1
    332 (-93.44, 26.0169) 47     7 FALSE     1  47.1      1
    333  (-94.4, 25.9809) 47     8 FALSE     1  47.1      1
    334  (-94.4, 27.6586) 47     9 FALSE     1  47.1      1
    335 (-92.04, 27.7649) 48     1 FALSE     1  48.1      2
    336 (-93.64, 27.6232) 48     2 FALSE     1  48.1      2
    337  (-94.4, 27.6586) 48     3 FALSE     1  48.1      2
    338  (-94.4, 27.8356) 48     4 FALSE     1  48.1      2
    339 (-93.64, 27.7649) 48     5 FALSE     1  48.1      2
    340 (-90.28, 28.1182) 48     6 FALSE     1  48.1      2
    341 (-90.56, 27.9417) 48     7 FALSE     1  48.1      2
    342 (-92.04, 27.7649) 48     8 FALSE     1  48.1      2
    100  (-94.4, 27.8356) 20     1 FALSE     1  20.1      3
    101  (-94.4, 28.0829) 20     2 FALSE     1  20.1      3
    102 (-90.28, 28.1182) 20     3 FALSE     1  20.1      3
    103 (-93.64, 27.7649) 20     4 FALSE     1  20.1      3
    104  (-94.4, 27.8356) 20     5 FALSE     1  20.1      3

(row names/numbers are not in order because I sorted by box_id column)

These points are nodes of polygons (identified by box_id). I want to write this as a polygon shape file to read into GIS programs, but I'm having trouble converting it into a SpatialPolygonDataFrame (to then use writeOGR) or to directly write it to a shp file. Any help would be appreciate. I'm new to GIS with R, so apologies if I'm missing something obvious.

هل كانت مفيدة؟

المحلول

So here's another solution, conceptually similar to @JoshO'Brien's. This one accommodates sub-polygons (multiple groups for a given id) and creates an object of class SpatialPolygonsDataFrame, with included data section (e.g., the attributes table). This is fully exportable to an ESRI shapefile.

First, as an example, we create a SpatialPointsDataFrame with the same format as yours. The id column identifies Polygon ID and the group column identifies sub-polygons for a given polygon. In this example we have 3 polygons, two of which have 1 sub-Polygon, and the third which has 3 sub-Polygons. We also create a data frame data (the attributes table) which in this case associates polygon ID with box_id.

# this code just creates a sample SpatialPointsDataFrame 
x <- c(-10,-10,10,10,-10)
y <- c(-10,10,10,-10,-10)
df.1 <- data.frame(x,y,id=47, order=1:5,hole=F,piece=1,group=47.1,box_id=1)
coordinates(df.1)=c("x","y")
x <- c(+15+3*cos(2*pi/5*(0:5)))
y <- c(-15+3*sin(2*pi/5*(0:5)))
df.2 <- data.frame(x,y,id=48, order=1:6,hole=F,piece=1,group=48.1,box_id=2)
coordinates(df.2)=c("x","y")
x <- c(-15+2*cos(2*pi/8*(0:8)))
y <- c(+15+2*sin(2*pi/8*(0:8)))
df.3.1 <- data.frame(x,y,id=20, order=1:9,hole=F,piece=1,group=20.1,box_id=3)
coordinates(df.3.1)=c("x","y")
x <- c(0+2*cos(2*pi/8*(0:8)))
y <- c(+15+2*sin(2*pi/8*(0:8)))
df.3.2 <- data.frame(x,y,id=20, order=1:9,hole=F,piece=1,group=20.2,box_id=3)
coordinates(df.3.2)=c("x","y")
x <- c(+15+2*cos(2*pi/8*(0:8)))
y <- c(+15+2*sin(2*pi/8*(0:8)))
df.3.3 <- data.frame(x,y,id=20, order=1:9,hole=F,piece=1,group=20.3,box_id=3)
coordinates(df.3.3)=c("x","y")
df <- rbind(df.1,df.2,df.3.1,df.3.2,df.3.3)
df
#              coordinates id order  hole piece group box_id
# 1             (-10, -10) 47     1 FALSE     1  47.1      1
# 2              (-10, 10) 47     2 FALSE     1  47.1      1
# 3               (10, 10) 47     3 FALSE     1  47.1      1
# 4              (10, -10) 47     4 FALSE     1  47.1      1
# 5             (-10, -10) 47     5 FALSE     1  47.1      1
# 6              (18, -15) 48     1 FALSE     1  48.1      2
# 7  (15.92705, -12.14683) 48     2 FALSE     1  48.1      2
# 8  (12.57295, -13.23664) 48     3 FALSE     1  48.1      2
# ...
data <- data.frame(box_id=unique(df$box_id),row.names=unique(df$id))

Now, this is the code for points2polygons(...). With your existing SpatialPointsDataFrame, this is all you'd need.

points2polygons <- function(df,data) {
  get.grpPoly <- function(group,ID,df) {
         Polygon(coordinates(df[df$id==ID & df$group==group,]))
         }
  get.spPoly  <- function(ID,df) {
         Polygons(lapply(unique(df[df$id==ID,]$group),get.grpPoly,ID,df),ID)
         }
  spPolygons  <- SpatialPolygons(lapply(unique(df$id),get.spPoly,df))
  SpatialPolygonsDataFrame(spPolygons,match.ID=T,data=data)
}
spDF <- points2polygons(df,data)
plot(spDF,col=spDF$box_id+1)

library(rgdal)
writeOGR(spDF,dsn=".",layer="myShapefile", driver="ESRI Shapefile")

نصائح أخرى

Check this one:

From: SpatialPointsDataFrame --> SpatialPolygons --> SpatialPolygonsDataFrame

https://stackoverflow.com/a/66565985/14361772

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top