AdehabitatHR::kernelUD error, geographical CRS given to non-conformant data - r

I am trying to perform the simple task of estimating a kernel density utilisation distribution across the foraging tracks of all females in my data set (just a visualisation exercise), and have opted for the kernelUD function within the adehabitatHR package in R.
I can set up a simple example of the SpatialPoints object I have been working with, which is formatted in long-lat format.
female <- filter(tracks, Sex == "Female")
# check the range of the longitude and latitude
range(female[,c("Latitude")])
[1] 20.71389 84.20619
range(female[,c("Longitude")])
[1] -23.85262 105.20330
# make the SpatialPoints object
sp.female <- SpatialPoints(coords = female[,c("Longitude", "Latitude")],
proj4string = CRS("+proj=longlat +ellps=WGS84"))
So no points are outside of the expected range for either longitude or latitude, but when I then try and perform the kernelUD:
kd.female <- kernelUD(sp.female, h = "href")
Error in `proj4string<-`(`*tmp*`, value = CRS(pfs1)) :
Geographical CRS given to non-conformant data: -105.076705907
This data point does not appear in the object I am working with, so I am at a loss as to how to troubleshoot the error.
I'm running the following package versions on R v3.6.3
> packageVersion('adehabitatHR')
[1] ‘0.4.19’
> packageVersion('rgdal')
[1] ‘1.5.23’
> packageVersion('sp')
[1] ‘1.4.5’
Thanks in advance for any help.

I have found that transforming to UTM appears to fix the problem, but I would be keen to know why the kernelUD function does not work on data where the coordinates are formatted in classic longitude and latitude.

Related

How to calculate the distance of a centroid to a polygon in a shape file? R

I have this, and I am trying to use gDistance to calculate the distance between each centroid and the city of Baghdad. I am trying to do it like this:
gDistance(districts_centroids, districts#data$ADM3NAME %in% c("Baghdad"), byid=TRUE)
Where district_centroids are Formal Class SpatialPoints, and the districts#data... is basically the city of Baghdad in the shp file.
I get an error saying the following:
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘is.projected’ for signature ‘"logical"’
In addition: Warning message:
In RGEOSDistanceFunc(spgeom1, spgeom2, byid, "rgeos_distance") :
Spatial object 1 is not projected; GEOS expects planar coordinates
I am completely new to R and I don't really know what's going on.
Any help would be appreciated
Thank you!
This is a great question. After taking a look at things, it was decided the best way to answer this question was using simple feature objects rather than spatial objects.
The map in question looks familiar. I used the IRQ_2_sf.rds map which is probably the same map used and shown above. There are other alternative ways to achieve the solution to this question. Jupyter Lab is the IDE used.
Using the Google API and the geocode function, the coordinates for Baghdad were retrieved.
baghdad <- geocode("Baghdad, Iraq", source = c("google") )
A tibble: 1 × 2
lon lat
<dbl> <dbl>
44.36607 33.31524
Then sf functions were used to create the sf column object.
baghdad.sfg <- st_point(c(lon, lat), dim = "XY")
baghdad.sfc <- st_sfc(baghdad.sfg, crs = 4326)
Then, using the sf map named iraq, the centroids were created.
Note: warning message - st_centroid does not give correct centroids for longitude/latitude data. For this answer, the centroids will be close
enough.
iraq.c <- st_centroid(iraq)
The distance from each centroid to Baghdad gets determined in kilometers.
head(dist <- data.frame(c(st_distance(iraq.c$geom[], baghdad.sfc)/1000)))
Units: [m]
[1] 28.63250 59.61553 215.43354 323.06418 259.14509 113.55356
And then create a date frame that includes the names, the centroid geometry and the distance values. Requires some cleaning and binding.
distance <- c(dist$c.st_distance.iraq.c.geom....baghdad.sfc..1000.)
x <- distance[]
d_Bdad_Km <- as.numeric(str_extract(x, "[0-9]*.[0-9]."))
iraq2 <- iraq[-c(5, 8,9,10,11,12,13)]
df_dist <- cbind(iraq2, d_Bdad_Km) # df as desired
And then the outputs gets plotted.
plot(iraq$geom)
plot(iraq.c$geom, add = TRUE, col = "red")
plot(baghdad.sfc, add = TRUE, pch = 19, col = "blue")
Please ask if there are any follow-up questions. The plot can be viewed at this link:

How can I overlay Sentinal 2 data with shapefiles in R?

I need to extract Sentinal 2 data for NDVI for specific study sites. I used RGIS tools and followed the reference manual https://cran.r-project.org/web/packages/RGISTools/RGISTools.pdf . I was able to obtain and plot the time series for NDVI.
Now I have to do the same procedure for my study area. I have a shapefile for my area which is accessible here, https://gis.utah.gov/data/boundaries/zip-codes/. It looks like that the shapefile needs to be converted into raster or sf type object before using it. I used st_as_sf to convert shapefile to sf but I receive the following error in senSearch function,
Error in if (as.integer(json$feed$opensearch:totalResults) > 0) { :
argument is of length zero
It is my first time working with such data, any help is appreciated.
It looks like you try to search using the extent argument. This argument only accepts spatial objects projected as lonlat projections. You can use the region argument with any spatial obj (sp, sf, or raster).
Here you have an example with your region:
library(RGISTools)
library(rgdal)
shp<-readOGR("ZipCodes_shp/ZipCodes")
plot(shp)
senres<-senSearch(startDate = as.Date("2018210", "%Y%j"),
endDate = as.Date("2018215", "%Y%j"),
platform = "Sentinel-2",
region = shp,
product = "S2MSI1C",
username="user",
password="pass")

Intersect in R - miss one polygon

1. The problem
I'm trying to extract the intersection of two polygons shapes in R. The first is the watershed polygon "ws_polygon_2", and the second is the Voronoi polygons of 5 rain gauges which was constructed from the Excel sheet "DATA.xlsx", both available here: link.
The code is the following:
#[1] Montagem da tabela de coordenadas dos postos pluviométricos
library(sp)
library(readxl)
dados_precipitacao_1985 <- read_excel(path="C:/Users/.../DATA.xlsx")
coordinates(dados_precipitacao_1985) <- ~ x + y
proj4string(dados_precipitacao_1985) <- CRS("+proj=longlat +datum=WGS84")
d_prec <- spTransform(dados_precipitacao_1985, CRSobj = "+init=epsg:3857")
#[2] Coleta dos dados espaciais da bacia hidrográfica
library(rgdal)
bacia_Caio_Prado <- readOGR(dsn="C:/Users/...", layer="ws_polygon_2")
bacia_WGS <- spTransform(bacia_Caio_Prado, CRSobj = "+proj=longlat +datum=WGS84")
bacia_UTM <- spTransform(bacia_Caio_Prado, CRSobj = "+init=epsg:3857")
#[3] Poligonos de Thiessen - 1 INTERPOLAÇÃO
library(dismo)
library(rgeos)
library(raster)
library(mapview)
limits_voronoi_WGS <- c(-40.00,-38.90,-5.00,-4.50)
v_WGS <- voronoi(dados_precipitacao_1985, ext=limits_voronoi_WGS)
bc <- aggregate(bacia_WGS)
u_WGS_1 <- gIntersection(spgeom1 = v_WGS, spgeom2 = bc,byid=TRUE)
u_WGS_2 <- intersect(bc, v_WGS)
When I apply the intersect function, the variable returned u_WGS_2 is a spatial polygon data frame with only 4 features, instead of 5. The Voronoi object v_WGS has 5 features as well.
By other hand, when I apply the gIntesection function, I get 5 features. However, the u_WGS_1 object is a spatial polygon only and I loss the rainfall data.
I'd like to know if I am committing any mistake or if there is any way to get the 5 features aggregated with the rainfall data in a spatial polygon data frame through the intersect function.
My objective is to transform this spatial polygon data frame with the rainfall data for each Voronoi polygon in a raster through the rasterize function later to compare with other interpolating results and satellite data.
Look these results. The first one is when I get the SPDF (Spatial Polygon Data Frame) I want, but missing the 5º feature. The second is the one I get with all the features I want, but missing the rainfall data.
spplot(u_WGS_2, 'JAN')
plot(u_WGS_1)
2. What I've tried
I look into the ws_polygon_2 shape searching for any other unwanted polygon who would pollute the shape and guide to this results. The shape is composed by only one polygon feature, the correct watershed feature.
I tried to use the aggregate function, as above, and as I saw in this tutorial. But I got the same result.
I tried to create a SPDF with de u_WGS_1 and the d_precSpatial Point Data Frame object. Actually, I'm working on it. And if it is the correct answer to my trouble, please help me with some code.
Thank you!
This is not an issue when using st_intersection() from sf, which retains the data from both data sets. Mind that dismo::voronoi() is compatible with sp objects only, so the precipitation data needs to be available in that format, at least temporarily. If you do not feel comfortable with sf and prefer to continue working with Spatial* objects after the actual intersection, simply invoke the as() method upon the output sf object as shown below.
library(sf)
#[1] Montagem da tabela de coordenadas dos postos pluviométricos
dados_precipitacao_1985 <- readxl::read_excel(path="data/DATA.xlsx")
dados_precipitacao_1985 <- st_as_sf(dados_precipitacao_1985, coords = c("x", "y"), crs = 4326)
dados_precipitacao_1985_sp <- as(dados_precipitacao_1985, "Spatial")
#[2] Coleta dos dados espaciais da bacia hidrográfica
bacia_Caio_Prado <- st_read(dsn="data/SHAPE_CORRIGIDO", layer="ws_polygon_2")
#[3] Poligonos de Thiessen - 1 INTERPOLAÇÃO
limits_voronoi_WGS <- c(-40.00,-38.90,-5.00,-4.50)
v_WGS <- dismo::voronoi(dados_precipitacao_1985_sp, ext=limits_voronoi_WGS)
v_WGS_sf <- st_as_sf(v_WGS)
u_WGS_3 <- st_intersection(bacia_Caio_Prado, v_WGS_sf)
plot(u_WGS_3[, 6], key.pos = 1)
The missing polygon is removed because it is invalid
library(raster)
bacia <- shapefile("SHAPE_CORRIGIDO/ws_polygon_2.shp")
rgeos::gIsValid(bacia)
#[1] FALSE
#Warning message:
#In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
# Ring Self-intersection at or near point -39.070555560000003 -4.8419444399999998
The self-intersection is here:
zoom(bacia, ext=extent(-39.07828, -39.06074, -4.85128, -4.83396))
points(cbind( -39.070555560000003, -4.8419444399999998))
Invalid polygons are removed as they are assumed to have been produced by intersect. In this case, the invalid data was already there and should have been retained. I will see if I can fix that.

Unable to properly use autokrige from automap package (R cannot read the prediction locations well)

I'm trying to use R to perform a map of interpolated frequencies of data collected from Iberian Peninsula. (something like this https://gis.stackexchange.com/questions/147660/strange-spatial-interpolation-results-from-ordinary-kriging )
My problem is that the plot is not showing the interpolated data, due to some kind of error in the atributte new_data of the autokrige function.
https://cran.r-project.org/web/packages/automap/automap.pdf
new_data:
A sp object containing the prediction locations. new_data can be a points set, a
grid or a polygon. Must not contain NA’s. If this object is not provided a default is calculated. This is done by taking the convex hull of input_data and placing around 5000 gridcells in that convex hull.
I think the problem is that R is not reading well the map transformed to poligons because if I avoid this new_data attribute I get a propper plot of the krigging values. but I do not obtain a good shape of the iberian peninsula.
Can someone help me please? I would be truly grateful
here you can see my data: http://pastebin.com/QHjn4qjP
Actual code:
now since I transform my data coordinates to UTM projection i do not get error messages but the last plot is not interpolated, the whole map appear of one single color :(
setwd("C:/Users/Ruth/Dropbox/R/pruebas")
#Libraries
library(maps)
library(mapdata)
library(automap)
library(sp)
library(maptools)
library(raster)
library(rgdal)
####################MAPA#############
#obtain the grid of the desired country
map<-getData('GADM', country='ESP', level=0)
#convert the grid to projected data
mapa.utm<-spTransform(mapa3,CRSobj =CRS(" +proj=utm +zone=29 +zone=30 +zone=31 +ellps=WGS84"))
###############################Datos#######################
#submit the data
data1<-read.table("FRECUENCIASH.txt",header=T)
head(data1)
attach(data1)
#convert longlat coordinates to UTM
coordinates(data1)<-c("X","Y")
proj4string(data1) = CRS("+proj=longlat +datum=WGS84")
data1.utm=spTransform(data1, CRS("+proj=utm +zone=29 +zone=30 +zone=31 +ellps=WGS84 "))
######################Kriging interpolation #####################
#Performs an automatic interpolation
kriging_result<-autoKrige(Z~1,data1.utm,mapa.utm,data_variogram = data1.utm)
#Plot the kriging
result1<-automapPlot(kriging_result$krige_output,"var1.pred",sp.layout = list("sp.points", data1.utm));result1
result2<-plot(kriging_result);result2
The error you get is related to the fact you are using unprojected data as input for automap. Automap can only deal with projected data. Googling for map projections should give you some background information. To project your data to a suitable projection, you can use spTransform from the sp package.
The fact that it works without newdata is because in that object the projection is not set, so automap cannot warn you. However, the results of automap with latlon input data is not reliable.

Assigning spatial coordinates to an array in R

I have downloaded a text file of data from the following link: http://radon.unibas.ch/files/us_rn_50km.zip
After unzipping I use the following lines of code to plot up the data:
# load libraries
library(fields)
# function to rotate a matrix (and transpose)
rotate <- function(x) t(apply(x, 2, rev))
# read data
data <- as.matrix(read.table("~/Downloads/us_rn_50km.txt", skip=6))
data[data<=0] <- NA
# rotate data
data <- rotate(data)
# plot data
mean.rn <- mean(data, na.rm=T)
image.plot(data, main=paste("Mean Rn emissions =", sprintf("%.3f", mean.rn)) )
This all looks OK, but I want to be able to plot the data on a lat-long grid. I think I need to convert this array into an sp class object but I don't know how. I know the following (from the web site): "The projection used to project the latitude and longitude coordinates is that used for the Decade of North American Geology (DNAG) maps. The projection type is Spherical Transverse Mercator with a base latitude of zero degrees and a reference longitude of 100 degrees W. The scale factor used is 0.926 with no false easting or northing. The longitude-latitude datum is NAD27 and the units of the xy-coordinates are in meters. The ellipsoid used is Clarke 1866. The resolution of the map is 50x50km". But don't know what to do with this data. I tried:
proj4string(data)=CRS("+init=epsg:4267")
data.sp <- SpatialPoints(data, CRS("+proj=longlat+ellps=clrk66+datum=NAD27") )
But had various problems (with NA's) and fundamentally I think that the data isn't in the right format.. I think that the SpatialPoints function wants a data on location (in 2-D) and a third array of values associated with those locations (x,y,z data - I guess my problem is working out the x and the y's from my data!)
Any help greatly appreciated!
Thanks,
Alex
The file in question is an ASCII raster grid. Coordinates are implicit in this format; a header describes the position of the (usually) lower left corner, as well as the grid dimensions and resolution. After this header section, values separated by white space describe how the variable varies across the grid, with values given in row-major order. Open it in a text editor if you're interested.
You can import such files to R with the fantastic raster package, as follows:
download.file('http://radon.unibas.ch/files/us_rn_50km.zip',
destfile={f <- tempfile()})
unzip(f, exdir=tempdir())
r <- raster(file.path(tempdir(), 'us_rn_50km.txt'))
You can plot it immediately, without assigning the projection:
If you didn't want to transform it to another CRS, you wouldn't necessarily need to assign the current coordinate system. But since you do want to transform it to WGS84 (geographic), you need to first assign the CRS:
proj4string(r) <- '+proj=tmerc +lon_0=-100 +lat_0=0 +k_0=0.926 +datum=NAD27 +ellps=clrk66 +a=6378137 +b=6378137 +units=m +no_defs'
Unfortunately I'm not entirely sure whether this proj4string correctly reflects the info given at the website that provided the data (it would be great if they actually provided the definition in a standard format).
After assigning the CRS, you can project the raster with projectRaster:
r.wgs84 <- projectRaster(r, crs='+init=epsg:4326')
And if you want, write it out to a raster format of your choice, e.g.:
writeRaster(r.wgs84, filename='whatever.tif')

Resources