Is it only me who have the problem with extracting coordinates of a polygon from SpatialPolygonsDataFrame
object? I am able to extract other slots of the object
This question was also addressed on gis.stackexchange, here. I made an example below testing all the options mentioned here by @mdsumner. Also have a look here
library(sp)
library(sf)
#> Warning: package 'sf' was built under R version 3.5.3
#> Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
library(raster)
library(spbabel)
#> Warning: package 'spbabel' was built under R version 3.5.3
library(tmap)
library(microbenchmark)
library(ggplot2)
# Prepare data
data(World)
# Convert from sf to sp objects
atf_sf <- World[World$iso_a3 == "ATF", ]
atf_sp <- as(atf_sf, "Spatial")
atf_sp
#> class : SpatialPolygonsDataFrame
#> features : 1
#> extent : 5490427, 5660887, -6048972, -5932855 (xmin, xmax, ymin, ymax)
#> coord. ref. : +proj=eck4 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
#> variables : 15
#> # A tibble: 1 x 15
#> iso_a3 name sovereignt continent area pop_est pop_est_dens economy
#> <fct> <fct> <fct> <fct> <S3:> <dbl> <dbl> <fct>
#> 1 ATF Fr. ~ France Seven se~ 7257~ 140 0.0193 6. Dev~
#> # ... with 7 more variables: income_grp <fct>, gdp_cap_est <dbl>,
#> # life_exp <dbl>, well_being <dbl>, footprint <dbl>, inequality <dbl>,
#> # HPI <dbl>
# Try various functions:
raster::geom(atf_sp)
#> object part cump hole x y
#> [1,] 1 1 1 0 5550200 -5932855
#> [2,] 1 1 1 0 5589907 -5964836
#> [3,] 1 1 1 0 5660887 -5977490
#> [4,] 1 1 1 0 5656160 -5996685
#> [5,] 1 1 1 0 5615621 -6042456
#> [6,] 1 1 1 0 5490427 -6048972
#> [7,] 1 1 1 0 5509148 -5995424
#> [8,] 1 1 1 0 5536900 -5953683
#> [9,] 1 1 1 0 5550200 -5932855
ggplot2::fortify(atf_sp)
#> Regions defined for each Polygons
#> long lat order hole piece id group
#> 1 5550200 -5932855 1 FALSE 1 8 8.1
#> 2 5589907 -5964836 2 FALSE 1 8 8.1
#> 3 5660887 -5977490 3 FALSE 1 8 8.1
#> 4 5656160 -5996685 4 FALSE 1 8 8.1
#> 5 5615621 -6042456 5 FALSE 1 8 8.1
#> 6 5490427 -6048972 6 FALSE 1 8 8.1
#> 7 5509148 -5995424 7 FALSE 1 8 8.1
#> 8 5536900 -5953683 8 FALSE 1 8 8.1
#> 9 5550200 -5932855 9 FALSE 1 8 8.1
spbabel::sptable(atf_sp)
#> # A tibble: 9 x 6
#> object_ branch_ island_ order_ x_ y_
#> <int> <int> <lgl> <int> <dbl> <dbl>
#> 1 1 1 TRUE 1 5550200. -5932855.
#> 2 1 1 TRUE 2 5589907. -5964836.
#> 3 1 1 TRUE 3 5660887. -5977490.
#> 4 1 1 TRUE 4 5656160. -5996685.
#> 5 1 1 TRUE 5 5615621. -6042456.
#> 6 1 1 TRUE 6 5490427. -6048972.
#> 7 1 1 TRUE 7 5509148. -5995424.
#> 8 1 1 TRUE 8 5536900. -5953683.
#> 9 1 1 TRUE 9 5550200. -5932855.
as.data.frame(as(as(atf_sp, "SpatialLinesDataFrame"),"SpatialPointsDataFrame"))
#> iso_a3 name sovereignt continent
#> 8 ATF Fr. S. Antarctic Lands France Seven seas (open ocean)
#> 8.1 ATF Fr. S. Antarctic Lands France Seven seas (open ocean)
#> 8.2 ATF Fr. S. Antarctic Lands France Seven seas (open ocean)
#> 8.3 ATF Fr. S. Antarctic Lands France Seven seas (open ocean)
#> 8.4 ATF Fr. S. Antarctic Lands France Seven seas (open ocean)
#> 8.5 ATF Fr. S. Antarctic Lands France Seven seas (open ocean)
#> 8.6 ATF Fr. S. Antarctic Lands France Seven seas (open ocean)
#> 8.7 ATF Fr. S. Antarctic Lands France Seven seas (open ocean)
#> 8.8 ATF Fr. S. Antarctic Lands France Seven seas (open ocean)
#> area pop_est pop_est_dens economy
#> 8 7257.455 [km^2] 140 0.01929051 6. Developing region
#> 8.1 7257.455 [km^2] 140 0.01929051 6. Developing region
#> 8.2 7257.455 [km^2] 140 0.01929051 6. Developing region
#> 8.3 7257.455 [km^2] 140 0.01929051 6. Developing region
#> 8.4 7257.455 [km^2] 140 0.01929051 6. Developing region
#> 8.5 7257.455 [km^2] 140 0.01929051 6. Developing region
#> 8.6 7257.455 [km^2] 140 0.01929051 6. Developing region
#> 8.7 7257.455 [km^2] 140 0.01929051 6. Developing region
#> 8.8 7257.455 [km^2] 140 0.01929051 6. Developing region
#> income_grp gdp_cap_est life_exp well_being footprint
#> 8 2. High income: nonOECD 114285.7 NA NA NA
#> 8.1 2. High income: nonOECD 114285.7 NA NA NA
#> 8.2 2. High income: nonOECD 114285.7 NA NA NA
#> 8.3 2. High income: nonOECD 114285.7 NA NA NA
#> 8.4 2. High income: nonOECD 114285.7 NA NA NA
#> 8.5 2. High income: nonOECD 114285.7 NA NA NA
#> 8.6 2. High income: nonOECD 114285.7 NA NA NA
#> 8.7 2. High income: nonOECD 114285.7 NA NA NA
#> 8.8 2. High income: nonOECD 114285.7 NA NA NA
#> inequality HPI Lines.NR Lines.ID Line.NR coords.x1 coords.x2
#> 8 NA NA 1 8 1 5550200 -5932855
#> 8.1 NA NA 1 8 1 5589907 -5964836
#> 8.2 NA NA 1 8 1 5660887 -5977490
#> 8.3 NA NA 1 8 1 5656160 -5996685
#> 8.4 NA NA 1 8 1 5615621 -6042456
#> 8.5 NA NA 1 8 1 5490427 -6048972
#> 8.6 NA NA 1 8 1 5509148 -5995424
#> 8.7 NA NA 1 8 1 5536900 -5953683
#> 8.8 NA NA 1 8 1 5550200 -5932855
# What about speed? raster::geom is the fastest
res <- microbenchmark(raster::geom(atf_sp),
ggplot2::fortify(atf_sp),
spbabel::sptable(atf_sp),
as.data.frame(as(as(atf_sp, "SpatialLinesDataFrame"),
"SpatialPointsDataFrame")))
ggplot2::autoplot(res)
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.
Created on 2019-03-23 by the reprex package (v0.2.1)
ggplot2's fortify() function may be deprecated at some point so the broom package is now suggested
library(broom)
broom::tidy(atf_sp)
This took me a while to figure out too. The following function I wrote worked for me. sp.df should be SpatialPolygonsDataFrame.
extractCoords <- function(sp.df)
{
results <- list()
for(i in 1:length(sp.df@polygons[[1]]@Polygons))
{
results[[i]] <- sp.df@polygons[[1]]@Polygons[[i]]@coords
}
results <- Reduce(rbind, results)
results
}
Use the coordinates()
function from the sp
package. It should give you the values in a list format.
You can also get the Polygon attribute from the shapefile.
mfile = readOGR(dsn=dsn,layer=layername)
polys = attr(mfile,'polygons')
npolys = length(polys)
for (i in 1:npolys){
poly = polys[[i]]
polys2 = attr(poly,'Polygons')
npolys2 = length(polys2)
for (j in 1:npolys2){
#do stuff with these values
coords = coordinates(polys2[[j]])
}
}
Finally, I figured out that I didn't parse the output correctly. The correct way to do is bdryData@polygons[[2]]@Polygons[[1]]@coords
. Mind the difference in command polygons
(Polygons
and polygons
) and it took me ages to find out.