I am trying to calculate the centroids of a set of polygons.
My dataset, geodata, contains five columns including one geometry column of class sfc_GEOMETRY, with 45759 rows.
When I run sf::st_centroid(geodata), I get the following message
Error in CPL_geos_op("centroid", x, numeric(0), integer(0), numeric(0), : Evaluation error: IllegalArgumentException: Points of LinearRing do not form a closed linestring.
In addition: Warning messages:
1: In st_centroid.sf(geodata) :
st_centroid assumes attributes are constant over geometries of x
2: In st_centroid.sfc(st_geometry(x), of_largest_polygon = of_largest_polygon) :
st_centroid does not give correct centroids for longitude/latitude data
Should I run a loop to detect which geometry is not closed?
Is this a problem with the class of my geometry? Should it be sfc_MULTIPOLYGON?
Possible solution:
I was encountering this problem when reading in a list of files through a loop. The loop would read in the files and then rbind them together into geodata, and then calculate the centroid:
for(i in 1:length(list)){
file <- st_read(list[i])
geodata <- rbind(geodata, file) #geodata is here a void sf object
}
geocent <- st_centroid(geodata)
When I calculated the centroids within the loop (for each file in the list), the error disappeared.
for(i in 1:length(list)){
file <- st_read(list[i])
file <- st_centroid(file)
geocent <- rbind(geodata, file) #geodata is here a void sf object
}
Hence, I think the problem lay in the binding operation.
Perhaps I had not defined my void sf object in the right manner.
Perhaps rbind was not the appropriate function, or I should have specified its parameters.
There's no need to run a loop to find which geometry is bad. The st_is_valid() function should tell you which row(s) have the problem.
It looks like one of your geometries might be made up of an incorrect number of points.
More info about finding and fixing the problem at r-spatial: https://www.r-spatial.org/r/2017/03/19/invalid.html
Related
I have 14 raster files from each year of land use. I would like to crop these rasters using my shapefile area of interest. With these cut rasters I would like to create a list where each element represents each year cut by the shapefile.
I tried in a very simple and fast way using the for, crop and mask commands, but without success.
my data exemplo:
raster and shape files : https://drive.google.com/file/d/1IOGWZ3_ckKj3UoZVd7ikR5l9n04xd6He/view?usp=sharing
my code
library(raster)
library(rgdal)
library(sf)
setwd('dir')
raster_solo_2005<-raster('utm-50-2005.tif')
raster_solo_2006<-raster('utm-50-2006.tif')
raster_solo_2007<-raster('utm-50-2007.tif')
raster_solo_2008<-raster('utm-50-2008.tif')
raster_solo_2009<-raster('utm-50-2009.tif')
raster_solo_2010<-raster('utm-50-2010.tif')
raster_solo_2011<-raster('utm-50-2011.tif')
raster_solo_2012<-raster('utm-50-2012.tif')
raster_solo_2013<-raster('utm-50-2013.tif')
raster_solo_2014<-raster('utm-50-2014.tif')
raster_solo_2015<-raster('utm-50-2015.tif')
raster_solo_2016<-raster('utm-50-2016.tif')
raster_solo_2017<-raster('utm-50-2017.tif')
raster_solo_2018<-raster('utm-50-2018.tif')
#list raster
list_raster<-as.list(raster_solo_2005, raster_solo_2006, raster_solo_2007, raster_solo_2008, raster_solo_2009, raster_solo_2010, raster_solo_2011, raster_solo_2012, raster_solo_2013, raster_solo_2014, raster_solo_2015, raster_solo_2016, raster_solo_2017, raster_solo_2018)
#shapefile
shp_area<-sf::st_read('500m_utm.shp')
#creat list empity
list_raster_cut<-list()
#loop operation
for(i in 1:10){
# crop e mask
list_raster_cut[[i]] <- list_raster %>%
raster::crop(shp_area)%>%
raster::mask(shp_area)
}
Update: exit error
Error in h(simpleError(msg, call)) : error evaluating argument 'x' when selecting method for function 'mask': 'unable to find an inherited method for function 'crop' for signature '"list" , "sf"''
The problem is that you need to also subset the list_raster object inside the for loop.
list_raster_cut[[i]] <- list_raster[[i]] %>%
raster::crop(shp_area)%>%
raster::mask(shp_area)
I am struggling to convert an object of class SpatialCollections to a SpatialPolygonsDataFrame object.
My input files are both shapefiles and SpatialPolygonsDataFrame objects. They can be accessed here.
I do an intersection of both objects:
SPDF_A <- shapefile("SPDF_A")
SPDF_B <- shapefile("SPDF_B")
intersection <- gIntersection(gBuffer(SPDF_A, width=0), gBuffer(SPDF_B, width=0))
The result is:
> intersection
class : SpatialCollections
Setting gBuffer(... , byid=T) or gBuffer(... , byid=F) seems to make no difference.
I use gIntersection and gBuffer(... , width=0) insetead of intersect in order to avoid geometrical problems (Self-intersection).
This is part of a larger loop. I need to get the intersection as SpatialPolygonsDataFrame because it will be saved as shp file in a following step.
writeOGR(intersection, ".", layer=paste0("Int_SPDF_A-SPDF_B"), driver="ESRI Shapefile")
This is not possible from a SpatialCollections object. In order to convert this to a SpatialPolygonsDataFrame I tried:
intersection <- as(intersection ,"SpatialPolygonsDataFrame")
intersection <- SpatialPolygonsDataFrame(intersection)
intersection <- readOGR(intersection, layer = "intersection")
Nothing works. Does anybody have a solution? Thanks a lot!
First of all, according to the documentation SpatialCollections is kind of a container format that can "hold SpatialPoints, SpatialLines, SpatialRings, and SpatialPolygons (without attributes)". If you need the data frame part of your SpatialPolygonsDataFrame ("attribute table" in GIS language), you'll have to work around that somehow. If, on the other hand, you're only interested in the spatial information (the polygons without the data attached to them) try the following:
str(intersection, max.level = 3)
suggests that the #polyobj is nothing but a SpatialPolygons object. Hence
mySpoly <- intersection#polyobj
should do the trick and
class(mySpoly)
suggests that we indeed now have a SpatialPolygons.
You need to convert that to a SpatialPolygonsDataFrame before exporting:
mySpolyData <- as(mySpoly, "SpatialPolygonsDataFrame")
writeOGR(mySpolyData, ".", layer=paste0("Int_SPDF_A-SPDF_B"), driver="ESRI Shapefile")
I have a dataset contains lines and I have imported them into R. I want to take a close look at the coordinates of them and define the identical first and last coordinate of each point if there is some -->(looking for polygon). Therefore, I am using Slot which makes me able to have a close look at the details of the desired object.
My final goal is to define the number of identical point coordinates(First and last) for each line in order to discover the number of the potential polygon in my data.
recapping my difficulty is the following question:
How many of lines objects have potential to be a polygon?
To do so, I have done several steps:
In the first step, I read my data into R.
The second step, I have used slot to have a close look at the coordinate of each point(Sequence of points represent line object).
the third step: I have tried to define the number of identical points but I have faced with an error says CRDs not found
at the following, you can tack a look at the codes
enter library(maptools)
#Read data directly from National Geophysical Data Center (NGDC) coastline
#extractor.
shorelinedat="http://www.asdar-book.org/RC1/datasets/auckland_mapgen.dat"
#Assign CRS
llCRS <- CRS("+proj=longlat +ellps=WGS84")
#Read data from mapgen into a SpatialLines object.
auck_shore <- MapGen2SL("auckland_mapgen.dat", llCRS)
#Required code to identify the lines.
lns <- slot(auck_shore, "lines")
table(sapply(lns, function(x) length(slot(x, "Lines"))))
Here is the code in which I faced with the error
#identifying the number of identical coordinates
islands_auck <- sapply(lns, function(x) {
+ crds <- slot(slot(x, "Lines")[[1]], "coords")
+ identical(crds[1, ], crds[nrow(crds), ])
+ })
This is the error
Error in +crds <- slot(slot(x, "Lines")[[1]], "coords") :
object 'crds' not found
I would appreciate if anyone can give a hint.
This is just a guess, are those +s actually in your code? If I try to assign to a variable with a + before it (as you do in the code example you posted), I get the same error you got:
+ crds <- 5
Error in +crds <- 5 : object 'crds' not found
When you run a multi-line block of code, R inserts + in the console to show continuing lines, but that's just a visual effect and they are illegal in your actual code.
The problem I had was related to the syntax in the final code which I modified them in below
islands_auck <- sapply(lns, function(x) {
crds <- slot(slot(x, "Lines")[[1]], "coords")
identical(crds[1, ], crds[nrow(crds), ])
})
table(islands_auck)
so the final result will be
islands_auck
FALSE TRUE
16 64
16 lines without equal first and last coordinate (Closed polygon)
64 lines with closed polygon
I have a shape file of 200 counties. How should I sample in order to subset counties from the existing 200? I have tried using the below R code:
library(maptools)
TXcounties <- readShapePoly("C:/Users/Rvg296/Downloads/TXCountiesShapeFiles/TXCounties.shp")
idx <- sample(1:250, 25, replace = FALSE)
df.TXcounties <- as.data.frame(TXcounties)
SpatialPolygonsDataFrame(idx, df.TXcounties).
But this is throwing an error like:
Error in SpatialPolygonsDataFrame(idx, df.TXcounties) : trying to get slot "polygons" from an object of a basic class ("integer") with no slots
The problem is that you are using idx, an integer vector, as the first argument for SpatialPolygonsDataFrame(), but this function needs a spatial polygons object as its first argument. In any case, you should be able to do the whole thing a lot more easily with something like this:
result <- TXcounties[idx,]
I am relatively new to R so i apologize if I have trouble expressing what I'm attempting to do. I have a 'spatial' panel dataset in long form and a shapefile. The long form table is a data.frame and it includes a column of dates (that have been converted to dates using 'as.date') and an ID column that is the same as that in the shapefile used to identify the different polygons (thus my long form dataset has no long lat values just an ID field that corresponds to the polygon features in the shapefile). I want to construct a spatiotemporal object of class ST out of these two objects (the shapefile and the long form dataset). To do this I have tried using stcontruct() and STFDF() but with absolutely not luck. stcontruct() gives me this error:
stConstruct(x, x$ID, x$date, SpatialObj = pol, TimeObj = NULL, interval=FALSE)
Error in stConstruct(x, x$ID, x$date, SpatialObj = pol, TimeObj = NULL, :
unknown parameter combination
and STFDF() gives me this error:
STFDF(shapefile, x$date, x)
Error: nrow(object#data) == length(object#sp) * nrow(object#time) is not TRUE
I've been stuck on this for days reading everything I can about the spacetime package in forums, etc. but to no avail. Any help is greatly appreciated.
thanks!
About STFDF error
From:
http://r-sig-geo.2731867.n2.nabble.com/Error-with-STFDF-td7584461.html
"If you don't have every time value at every spatial point, then you can't
have an STFDF object, as by definition STFDF is a full space by time grid.
The equation in the error is part of the definition/requirement for an
STFDF object.
SDIDF objects don't have that requirement of all times at all locations..."