Cannot open shapefile in R - r

I am not sure why but I cant read shapefiles at all in r!
On a MacOS Mojave,
I have tried:
afg <- readOGR("afg.shp")
afg <- readOGR(dsn = ".", layer = "afg")
The shapefiles are from this website: http://www.diva-gis.org/gdata, Afghanistan roads.
This same error keeps occuring:
Error in ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv, :
Cannot open layer
However, this code works:
countries <- readOGR("countries.geojson")
Can someone figure out why?

I'm on Mojave and this works fine:
httr::GET(
url = "http://biogeo.ucdavis.edu/data/diva/rds/AFG_rds.zip",
httr::write_disk("AFG_rds.zip"),
httr::progress()
) -> res
fils <- unzip("AFG_rds.zip", exdir = "afg-roads")
fils
## [1] "afg-roads/AFG_roads.dbf" "afg-roads/AFG_roads.prj"
## [3] "afg-roads/AFG_roads.shp" "afg-roads/AFG_roads.shx"
rgdal::readOGR("afg-roads/AFG_roads.shp")
## OGR data source with driver: ESRI Shapefile
## Source: "/Users/bob/Development/afg-roads/AFG_roads.shp", layer: "AFG_roads"
## with 1409 features
## It has 5 fields
## class : SpatialLinesDataFrame
## features : 1409
## extent : 60.6075, 74.67168, 29.38582, 38.48983 (xmin, xmax, ymin, ymax)
## coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
## variables : 5
## names : MED_DESCRI, RTT_DESCRI, F_CODE_DES, ISO, ISOCOUNTRY
## min values : Unknown, Primary Route, Road, AFG, AFGHANISTAN
## max values : Without Median, Unknown, Trail, AFG, AFGHANISTAN

I faced the same problem too. Don't try renaming the file. After unzipping, you will get a number of files, one of which will be a shapefile. In my case, all those files had the same name but different extensions. Then just do what you were already doing:
afg <- readOGR(dsn = ".", layer = "AFG_roads")
Hopefully this will work.

Related

Save raster to USGS DEM Format in R

Similar to this question:
I would like to know how to do the reverse and save an .img raster image into a USGS DEM format.
Based on GDAL docs, it seems like it would be possible but when I run rgdal::getGDALDriverNames() in R I get the following:
name long_name create copy isRaster
139 USGSDEM USGS Optional ASCII DEM (and CDED) FALSE TRUE TRUE
which seems to imply that it won't create these files?
I was hoping to do something like:
library(raster)
# read
img <- raster("Raster_100ft_2022_10_18.img")
# convert to DEM
writeRaster(img, 'test.dem')
But raster doesn't seem to recognize that output format.
Is there some other method to save as USGS DEM files?
Thanks
For me it works with terra. If that's proper "USGSDEM" file, that's another question. From gdal reference it should save the file as well: https://gdal.org/drivers/raster/usgsdem.html
f <- system.file("ex/elev.tif", package="terra")
r <- terra::rast(f)
terra::writeRaster(r, filename = "test.dem", filetype = "USGSDEM", overwrite = TRUE)
raster::raster("test.dem")
#> class : RasterLayer
#> dimensions : 90, 95, 8550 (nrow, ncol, ncell)
#> resolution : 0.008333333, 0.008333333 (x, y)
#> extent : 5.741667, 6.533333, 49.44167, 50.19167 (xmin, xmax, ymin, ymax)
#> crs : +proj=longlat +datum=WGS84 +no_defs
#> source : test.dem
#> names : elevation
#> values : 141, 547 (min, max)
Created on 2022-10-20 with reprex v2.0.2

Projecting points with terra package R

I need to project longitude/latitude coordinates in the terra package, but I don't believe it is working correctly, as I am trying to extract data from a raster with this projection, but the data is not being extracted correctly.
Here's my lon/lat points and the code I am using to try to project them.
latlon_df <- structure(list(Lon = c(-103.289, -96.6735, -96.9041, -96.76864,
-102.4694, -96.6814, -97.7504, -99.6754, -96.4802, -103.0007,
-96.8897, -101.8539, -103.9717, -101.253, -99.1134, -96.5849,
-98.0301, -99.9537, -99.4601, -99.7122, -103.8278, -98.931, -102.1081,
-101.7162, -100.115, -101.3448, -100.7805, -103.5606, -96.5302,
-99.4156, -103.281, -100.0063, -97.9928, -100.7208, -98.5289,
-96.762, -96.9218, -97.1024, -103.3793, -101.0841, -102.6745,
-96.9188, -97.5154, -100.7435, -98.6938), Lat = c(45.5194, 44.3099,
43.0526, 44.3252, 45.5183, 43.7316, 45.6796, 45.4406, 44.7154,
44.0006, 43.7687, 43.9599, 43.4737, 44.9875, 45.0292, 44.0867,
45.5735, 44.9895, 44.5256, 43.5938, 43.7343, 45.7163, 45.9189,
43.1672, 45.6716, 45.9154, 45.7963, 44.6783, 44.5073, 43.7982,
43.3784, 44.2912, 43.3841, 43.2002, 44.8579, 43.5048, 43.5033,
45.1055, 44.4245, 45.4167, 44.5643, 44.304, 45.2932, 43.5601,
43.7321)), class = "data.frame", row.names = c(NA, -45L))
latlons <- terra::vect(latlon_df,geom=c('Lon','Lat'),crs="+proj=longlat")
lcc <- terra::project(latlons,"+proj=lcc +lat_0=38.5 +lon_0=262.5 +lat_1=38.5 +lat_2=38.5 +x_0=0 +y_0=0 +R=6371229 +units=m +no_defs")
var_df <- terra::extract(grib_data,lcc)[,-1]
The raster data (grib_data) I am using comes from here (it is way too big for me to put on here). https://nomads.ncep.noaa.gov/pub/data/nccf/com/hrrr/prod/hrrr.20210612/conus/hrrr.t00z.wrfsubhf00.grib2
I am not sure what I am doing wrong here, as I have used this method previously, and it seemed to work fine. Any help would be wonderful.
EDIT: The specific problem I am having is that I am not getting any different values for each lon/lat pair. The value for each variable is different, but all the values for the stations (different lon/lats are the same).
Why do you think it has to do with the projection? Either way, it appears to work for me.
url <- "https://nomads.ncep.noaa.gov/pub/data/nccf/com/hrrr/prod/hrrr.20210612/conus/hrrr.t00z.wrfsubhf00.grib2"
if (!file.exist(basename(url))) download.file(url, basename(url), mode="wb")
url <- paste0(url, ".idx")
if (!file.exist(basename(url))) download.file(url, basename(url), mode="wb")
library(terra)
r <- rast("hrrr.t00z.wrfsubhf00.grib2")
r
#class : SpatRaster
#dimensions : 1059, 1799, 49 (nrow, ncol, nlyr)
#resolution : 3000, 3000 (x, y)
#extent : -2699020, 2697980, -1588806, 1588194 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=lcc +lat_0=38.5 +lon_0=262.5 +lat_1=38.5 +lat_2=38.5 +x_0=0 +y_0=0 +R=6371229 +units=m +no_defs
#source : hrrr.t00z.wrfsubhf00.grib2
#names : 0[-] ~here", 0[-] ~tops", 0[-] ~here", 0[-] ~here", 0[-] ~face", 1000[~ound", ...
You can check of the points overlap with the raster data
plot(r, 1)
points(lcc)
And extract. It takes very long with grib files, but it does appear to work
e <- extract(r, lcc)
head(e[,c(1,6,9)])
# ID 0[-] SFC="Ground or water surface" 0[-] SFC="Ground or water surface".1
#1 1 85100 11.775471
#2 2 54400 11.087971
#3 3 79300 9.900471
#4 4 49200 10.712971
#5 5 70800 9.212971
#6 6 56600 11.400471
Make sure you have the current (CRAN) version, or perhaps the development version that you can install like this:
install.packages('terra', repos='https://rspatial.r-universe.dev')
You can speed things up a lot by doing a single read from disk (by adding zero in this example)
e <- extract(r+0, lcc)
That is not always possible and I need to do some optimization behind the scences.

stack and brick function error despite all of the rasters have been

Good day everyone..
I have 13 bioclimatic variables (in .tiff format) that I will used to perform sdm by using dismo package.
I followed the tutorial written by Robert J. Hijmans and Jane Elith.
However, when I tried to stack all of the variables, I got the following error
Error in .local(.Object, ...) :
Error in .rasterObjectFromFile(x, band = band, objecttype = "RasterLayer", :
Cannot create a RasterLayer object from this file.
All of my file's coordinate system, extent, and cell size have been adjusted so they are all the same..
when I tried to used the alternative brick function, I got the following error :
Error in .rasterObjectFromFile(x, objecttype = "RasterBrick", ...) :
Cannot create a RasterLayer object from this file.
In addition: There were 12 warnings (use warnings() to see them)
I used the warning() message but it was empty..
do any of you have any hints regarding what may be the cause of such errors?
i've tried to google it, but unfortunately, no answer can solve it.
Thank you in advance..
Here presented is the fraction of the transcript
#setting the workspace
setwd("D:/Riset/MaxentSelaginella/newpaperproject_part2/MakalahVI/Workspace_R")
#Loading Libraries
library("sp")
library("raster")
library("maptools")
library("rgdal")
library("dismo")
library("rJava")
#open the csv file
obs.data <- read.csv(file = "data3/Selaginella_plana.csv", sep = ",")
#open Environmental Data
files <- list.files(path = "data3/tif/", pattern = ".tif", full.names=TRUE)
#stacking all the files
predictors <- brick(files)
I guess you need to use stack instead of brick. As per brick help, in fact:
A RasterBrick is a multi-layer raster object. They are typically created from
a multi-layer (band) file; but they can also exist entirely in memory.
They are similar to a RasterStack (that can be created with stack), but processing
time should be shorter when using a RasterBrick. Yet they are less flexible as they can only point to a single file.
So, if we try to “stack” multiple files:
library(raster)
r <- raster(ncols = 100, nrows = 100, vals = 1:10000)
rfile1 <- tempfile(fileext = ".tif")
writeRaster(r, filename = rfile1)
rfile2 <- tempfile(fileext = ".tif")
writeRaster(r, filename = rfile2)
files_to_stack <- c(rfile1, rfile2)
This fails:
brick(files_to_stack)
#> Warning in if (x == "" | x == ".") {: the condition has length > 1 and only
#> the first element will be used
#> Warning in if (!start %in% c("htt", "ftp")) {: the condition has length > 1
#> and only the first element will be used
#> Warning in if (fileext %in% c(".GRD", ".GRI")) {: the condition has length
#> > 1 and only the first element will be used
#> Warning in if (!file.exists(x)) {: the condition has length > 1 and only
#> the first element will be used
.....
#> Error in .rasterObjectFromFile(x, objecttype = "RasterBrick", ...): Cannot create a RasterLayer object from this file.
While this works:
stack(files_to_stack)
#> class : RasterStack
#> dimensions : 100, 100, 10000, 2 (nrow, ncol, ncell, nlayers)
#> resolution : 3.6, 1.8 (x, y)
#> extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#> coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
#> names : file46e41bcd78e3, file46e43ea75bad
#> min values : 1, 1
#> max values : 10000, 10000
If you want to have a brick to get some gain in “efficiency” in further
processing, you can save the different "layers" as a multiband tiff, and then open using brick:
rfile_multi <- tempfile(fileext = ".tif")
writeRaster(stack(files_to_stack), filename = rfile_multi)
brick(rfile_multi)
#> class : RasterBrick
#> dimensions : 100, 100, 10000, 2 (nrow, ncol, ncell, nlayers)
#> resolution : 3.6, 1.8 (x, y)
#> extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#> coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
#> data source : D:\RTemp\RtmpacXztJ\file4808784f268c.tif
#> names : file4808784f268c.1, file4808784f268c.2
#> min values : 1, 1
#> max values : 10000, 10000
Created on 2018-11-10 by the reprex package (v0.2.1)

Very likely bug in the R raster package intersect function when intersecting 1 polygon with 1 point

Through attempting to get an intersect result from a single point and a single polygon I have found what I believe can only be a bug in the R raster package intersect function.
I have 1 polygon and 1 point, and use intersect as follows:
intersect(a_point, a_polygon)
Where a_point contains an id attribute. This fails with the error:
Error in j[, 2] : incorrect number of dimensions
However, if I reverse the arguments and do:
intersect(a_polygon, a_point)
It works fine, but doesn't return the id from the point shape file as part of the result which I require. This is expected behaviour, so fine but I need it to work the other way around.
To rule out there being some peculiarity with my polygon or point data, I created a single polygon and single point spatial object and tested the same hypothesis, and the same result occurred as above with these 'raw' objects.
The following is the code for generating these two 'fake' objects for completeness and so that it can be reproduced:
test_list_x = list(530124, 530125) #For when I use 2 points
test_list_y = list(176949, 176950) #For when I use 2 points
data_frame_object = data.frame(530124, 176950)
names(data_frame_object) = c("Longitude", "Latitude")
coordinates(data_frame_object)=~Longitude+Latitude
proj4string(data_frame_object)=CRS("+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +datum=OSGB36 +units=m +no_defs +ellps=airy +towgs84=446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894")
fake_point_shape_object=SpatialPointsDataFrame(data_frame_object, data.frame(id=1:length(data_frame_object)))
coords = matrix( nrow=5, ncol=2)
coords[1,1] = 530106.8
coords[1,2] = 176953.3
coords[2,1] = 530127.5
coords[2,2] = 176953.3
coords[3,1] = 530127.5
coords[3,2] = 176933.3
coords[4,1] = 530106.8
coords[4,2] = 176933.3
coords[5,1] = 530106.8
coords[5,2] = 176953.3
my_fake_polygon = Polygon(coords)
polygon_list = list(my_fake_polygon)
polygon_set <- lapply(seq_along(polygon_list), function(i) Polygons(list(polygon_list[[i]]), i ))
new_polygons <- SpatialPolygons(polygon_set)
new_polygons#proj4string = CRS("+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +datum=OSGB36 +units=m +no_defs +ellps=airy +towgs84=446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894")
df <- data.frame("1")
names(df) = "id"
my_fake_polygon <- SpatialPolygonsDataFrame(new_polygons,df)
Now here's the thing, if I create 2 points next to each other (so they are both within the polygon) instead of just one, it works fine, no error. Suggesting there is a bug associated with intersection between 1 point and 1 polygon, WHEN the point carries an attribute to be returned in the intersection process.
You might ask why do you actually need to have the attribute returned if there is just one point, this is because it is an iterative process in which it may not be just one point, it could be none or many.
I would appreciate somebody explaining this error or confirming my findings.
Here are your example data in a more concise way.
library(raster)
pnt <- SpatialPoints(cbind(530124, 176950))
pol <- spPolygons(matrix(c(530106.8, 530127.5, 530127.5, 530106.8, 530106.8, 176953.3, 176953.3, 176933.3, 176933.3, 176953.3), ncol=2))
Now illustrate the problem.
intersect(pol, pnt)
#class : SpatialPolygons
#features : 1
#extent : 530106.8, 530127.5, 176933.3, 176953.3 (xmin, xmax, ymin, ymax)
#coord. ref. : NA
# this fails
intersect(pnt, pol)
#Loading required namespace: rgeos
#Error in j[, 2] : incorrect number of dimensions
# but it works with two points!
intersect(bind(pnt, pnt), pol)
#class : SpatialPoints
#features : 2
#extent : 530124, 530124, 176950, 176950 (xmin, xmax, ymin, ymax)
#coord. ref. : NA
This was another drop=TRUE bug caused by the R default of "dropping" matrices to vectors when a single row is selected. This was fixed in raster version 2.6-11 (not on CRAN yet).
Sorry i can't answer your intersect bug question, but it might be simpler for now to use sp::over to return polygon attributes to points
# dummy polygon
xym <- as.matrix(data.frame(x=c(16.48438,17.49512,24.74609,22.59277,16.48438),
y=c(59.73633,55.12207,55.03418,61.14258,59.73633)))
# make into SpatialPolygon
p = Polygon(xym)
ps = Polygons(list(p),1)
sps = SpatialPolygons(list(ps))
# Promote to SPDF and give an attribute
SPDF = SpatialPolygonsDataFrame(sps, data.frame(N = "hello", row.names = 1))
# make 2 points, one inside the polygon and one outside
p <- data.frame(x=c(16,18),y=c(58,58))
coordinates(p) <- ~x + y
# plot to check
plot(sps)
plot(p,add=T)
# perform the over, returns a named vector for every point in the SpatialPoints
res <- unname(over(p,SPDF))
# promote points to SpatialPointsDataFrame and put in new polygon attribute
data <- data.frame(ID=row.names(p),pol=res)
sp <- SpatialPointsDataFrame(p, data)

readOGR point shapefile and plot using Leaflet > NULL values in LON/LAT

Could someone please advise me on how to proceed in the following: I have a ESRI shapefile from a town in the Netherlands (Urk) and what to plot every housenummer on a map with a marker. Leaflet provides an error saying the file has NULL values, but I can't seem to find them.
# what does this file look like
> ogrInfo("WGS1984_Urk/nummer.shp", "nummer")
Source: "WGS1984_Urk/nummer.shp", layer: "nummer"
Driver: ESRI Shapefile; number of rows: 7792
Feature type: wkbPoint with 2 dimensions
Extent: (5.591987 52.64994) - (170059.4 518956.2)
LDID: 87
Number of fields: 18
name type length typeName
1 NUMMER_ID 4 16 String
2 STRAATNAAM 4 80 String
3 HUISNUMMER 0 8 Integer
......
# Read ESRI shapefiles into R
> huisnummers_Urk <-readOGR(dsn="WGS1984_Urk/nummer.shp",
layer="nummer", verbose = TRUE,
dropNULLGeometries= TRUE,
p4s = "+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs")
# Info from spdplyr package
> huisnummers_Urk
class : SpatialPointsDataFrame
features : 7792
extent : 5.591987, 170059.4, 52.64994, 518956.2 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs
variables : 18
# A tibble: 7,792 × 18
# Plot house in Leaflet
> leaflet(huisnummers_Urk) %>%
addTiles() %>%
addMarkers(lng = huisnummers_Urk$x1, lat = huisnummers_Urk$x2)
Error in validateCoords(lng, lat, funcName) :
addMarkers requires non-NULL longitude/latitude values
# Where are the missing values?
> huisnummers_Urk#coords[!complete.cases(huisnummers_Urk#coords),]
coords.x1 coords.x2
Where should I start to see what I am doing wrong here? I've put all the coords in a matrix for inspection and see no NA's / NULL's.
I've found two errors: one in the code and one in the dataset.
1) The Leaflet command for lng and lat should point to "huisnummers_Urk$coords.x1". The name of the coordinates slot is also "coords" and this is repeated in de column. So I made the mistake of leaving this part out.
2) There are lng / lat values of the chart, you can filter them by using the spdplyr package:
huisnummer_urk <- huisnummer_urk %>%
filter(huisnummer_urk$coords.x1 >= -90,
huisnummer_urk$coords.x1 <= 90, huisnummer_urk$coords.x2 >= -180, huisnummer_urk$coords.x2 <= 180)

Resources