Re-projecting a SpatialPointsDataFrame does not change the extent - r

I'm trying to overlay data related to bat locations (SpatialPointsDataFrame) on to the state of Colorado (SpatialPolygonsDataFrame). The CRS of the two objects are different:
crs(colorado)
#CRS arguments:
# +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
crs(BatRange_data)
#CRS arguments:
# +proj=utm +zone=13 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0
When I reproject the bat data, the CRS does indeed change, but the extent is unaffected.
Before:
BatRange_data
#class : SpatialPointsDataFrame
#features : 2456
#extent : 139996.3, 748812, 4094998, 4535103 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=utm +zone=13 +datum=NAD83 +units=m +no_defs +ellps=GRS80 +towgs84=0,0,0
#variables : 17
After:
geo_proj = "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
crs(BatRange_data) = geo_proj
BatRange_trnsfrmd = spTransform(BatRange_data,geo_proj)
BatRange_trnsfrmd
#class : SpatialPointsDataFrame
#features : 2456
#extent : 139996.3, 748812, 4094998, 4535103 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
#variables : 17
I can't plot the points on the polygon, as the extent of my polygon object is dissimilar to that of my points object:
colorado
#class : SpatialPolygonsDataFrame
#features : 1
#extent : -109.0608, -102.042, 36.99223, 41.00561 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
#variables : 13
Why is the extent of the SpatialPointsDataFrame not changing when re-projected and transformed?
Reproducible example(I tested this myself, and sent it to a friend; it IS reproducible with what is provided):
#Libraries
x = c('raster','sp','rgdal')
# If you don't know if you've installed the packages for some of these
# libraries, run this:
# install.packages(x)
lapply(x, library, character.only=TRUE)
rm(x)
# Read in and format data -------------------------------------------------
BatRange_data = new("SpatialPoints", coords = structure(c(179935.719907205, 179935.938979813, 179935.938979813, 176598.335967664, 176598.335967664, 4499963.43180688, 4499963.30060606, 4499963.30060606, 4489332.4211975, 4489332.4211975), .Dim = c(5L, 2L), .Dimnames = list(NULL, c("coords.x1", "coords.x2"))), bbox = structure(c(176598.335967664, 4489332.4211975, 179935.938979813, 4499963.43180688), .Dim = c(2L, 2L), .Dimnames = list(c("coords.x1", "coords.x2"), c("min", "max"))) , proj4string = new("CRS" , projargs = NA_character_))
#Use state bounds from gadm website:
us = getData("GADM", country="USA", level=1)
#Extract states (need to uppercase everything)
co = "Colorado"
colorado = us[match(toupper(co),toupper(us$NAME_1)),]
#Re-project bat data to 'longlat'
geo_proj =
"+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
crs(BatRange_data) = geo_proj
BatRange_trnsfrmd =
spTransform(BatRange_data,geo_proj)
plot(BatRange_trnsfrmd)
plot(colorado,add=TRUE)

In your code:
geo_proj = "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
crs(BatRange_data) = geo_proj
BatRange_trnsfrmd = spTransform(BatRange_data,geo_proj)
BatRange_trnsfrmd
you are overwriting the original projection of BatRange_data to lat/long before trying to reproject it. spTransform therefore is doing nothing, since it's trying to reproject from epsg:4326 to epsg:4326. This is why your extent is not changing.
You should therefore probably just remove this line:
crs(BatRange_data) = geo_proj
and all should work.
HTH.

Related

Replacing "rdgal" with a Data Frame in R?

I found this R code (Search button for Leaflet R map?) and was able to make a interactive map in R:
library(inlmisc)
city <- rgdal::readOGR(system.file("extdata/city.geojson",
package = "inlmisc")[1])
opt <- leaflet::markerClusterOptions(showCoverageOnHover = FALSE)
map <- CreateWebMap("Topo")
map <- leaflet::addMarkers(map, label = ~name, popup = ~name,
clusterOptions = opt,
clusterId = "cluster",
group = "marker", data = city)
map <- AddHomeButton(map)
map <- AddClusterButton(map, clusterId = "cluster")
map <- AddSearchButton(map, group = "marker", zoom = 15,
textPlaceholder = "Search city names...")
map
I was curious and wanted to see the format and entries of the "city" file. I was expecting this file to be a "tabular" file (i.e. containing rows and columns, like a data frame), but when I opened the file, it did not appear in this format at all - this file is apparently a "SpatialPointsDataFrame":
> head(city)
class : SpatialPointsDataFrame
features : 6
extent : -123.09, -73.8, 31.58, 44.62 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
variables : 2
names : name, capital
min values : Abilene TX, 0
max values : Albany OR, 2
I then found this post here (How to convert a spatial dataframe back to normal dataframe?) and saw that you can convert a SpatialPointsDataFrame into a regular data frame like this:
DF <- as.data.frame(city)
> head(DF)
name capital coords.x1 coords.x2
1 Abilene TX 0 -99.74 32.45
2 Akron OH 0 -81.52 41.08
3 Alameda CA 0 -122.26 37.77
4 Albany GA 0 -84.18 31.58
5 Albany NY 2 -73.80 42.67
6 Albany OR 0 -123.09 44.62
But is there a way to convert a regular data frame into a "SpatialDataFrame"? I tried the following code and then tried to plot the results:
#https://stackoverflow.com/questions/29736577/how-to-convert-data-frame-to-spatial-coordinates
library(sf)
city <- st_as_sf(x = DF,
coords = c("coords.x1", "coords.x2"),
crs = "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0")
map <- CreateWebMap("Topo")
map <- leaflet::addMarkers(map, label = ~name, popup = ~name,
clusterOptions = opt,
clusterId = "cluster",
group = "marker", data = city)
map <- AddHomeButton(map)
map <- AddClusterButton(map, clusterId = "cluster")
map <- AddSearchButton(map, group = "marker", zoom = 15,
textPlaceholder = "Search city names...")
map
The code ran, but I get this warning message:
Warning message:
sf layer has inconsistent datum (+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs).
Need '+proj=longlat +datum=WGS84
Am I doing this correctly?
Thank you!
Leaflet uses a slightly different format of crs than sf with st_as_sf, which you can read more about on GitHub. You have a few options, where first we could use a shortened crs, like here:
library(sf)
city <- st_as_sf(x = DF,
coords = c("coords.x1", "coords.x2"),
crs = "+proj=longlat +datum=WGS84 +no_defs")
Or you can use sp::CRS along with your crs definition, so that it is properly read by leaflet:
city <- st_as_sf(x = DF,
coords = c("coords.x1", "coords.x2"),
crs = sp::CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))
Or another option would be to use the SRID 4326 as the crs (which will set the Geodetic CRS):
city <- st_as_sf(x = DF,
coords = c("coords.x1", "coords.x2"),
crs = 4326)
map <- CreateWebMap("Topo")
map <- leaflet::addMarkers(map, label = ~name, popup = ~name,
clusterOptions = opt,
clusterId = "cluster",
group = "marker", data = city)
map <- AddHomeButton(map)
map <- AddClusterButton(map, clusterId = "cluster")
map <- AddSearchButton(map, group = "marker", zoom = 15,
textPlaceholder = "Search city names...")
map
You will notice that in the answer you are using that they are using mapview, which does work with the format that you give (i.e., crs = "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"). So, it would work with your code, but it won't be in the leaflet style:
city <- st_as_sf(x = DF,
coords = c("coords.x1", "coords.x2"),
crs = "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0")
mapview::mapview(city)

How to add european countries borders to a Raster in R?

I have this raster file:
fdiff_north:
class : RasterLayer
dimensions : 5500, 12000, 6.6e+07 (nrow, ncol, ncell)
resolution : 100, 100 (x, y)
extent : 4e+06, 5200000, 2250000, 2800000 (xmin, xmax, ymin, ymax)
crs : +proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs
source : memory
names : layer
values : -1, 1 (min, max)
to get a plot:
cl <- colorRampPalette(c("red","white","blue"))(100)
plot(fdiff_north, col=cl)
I need boundaries to make the plot more usable.
I also tried to change the crs of my raster:
rfdiff_north:
class : RasterLayer
dimensions : 12571, 6151, 77324221 (nrow, ncol, ncell)
resolution : 9e-04, 0.00128 (x, y)
extent : 42.7836, 48.3195, 5.672145, 21.76303 (xmin, xmax, ymin, ymax)
crs : +proj=longlat +datum=WGS84 +no_defs
source : r_tmp_2022-02-07_151752_9872_54603.grd
names : layer
values : -1.466443, 1.366832 (min, max)
I want to add european countries boundaries to my raster, but I can't get it. I've tried with many different functions but I achieved no results. Can you help me to do that ?
The boundaries of European countries you can get from spMaps or any other source (OpenStreetMap data for example)
# devtools::install_github("rte-antares-rpackage/spMaps", ref = "master")
library(spMaps)
eu <- getEuropeCountries(mergeCountry = FALSE)
Trying to create similar (in size and CRS) raster:
library(terra)
#> terra 1.5.17
x <- rast(nrows=5500, ncols = 12000, nlyrs = 1,
xmin = 4e+06, xmax = 5200000, ymin = 2250000, ymax = 2800000,
crs = "+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs",
resolution = 100)
x <- setValues(x,runif(ncell(x)))
x
#> class : SpatRaster
#> dimensions : 5500, 12000, 1 (nrow, ncol, nlyr)
#> resolution : 100, 100 (x, y)
#> extent : 4e+06, 5200000, 2250000, 2800000 (xmin, xmax, ymin, ymax)
#> coord. ref. : +proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs
#> source : memory
#> name : lyr.1
#> min value : 4.889444e-09
#> max value : 1
Now it's time to convert SpatialPolygons to SimpleFeature and transform the coordinates to yours CRS:
library(sf)
eu <- st_as_sf(eu)
plot(x)
plot(st_transform(eu$geometry,
crs = "+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs"),
add = TRUE)
Created on 2022-02-09 by the reprex package (v2.0.1)
You can crop boundaries to your raster bbox with st_crop()
Regards,
Grzegorz

downloading satellite map for a specific region - R

I have run sum analysis on points summarized within a SpatialPointsDataFrame:
> trjct_pts
class : SpatialPointsDataFrame
features : 104559
extent : 696621.4, 696688.7, 167659.2, 167739.8 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs
variables : 1
names : Intensity_kJ
min values : 161.951
max values : 1192.526
Which I have used to create 2 rasters:
library(raster)
rockfall_count <- raster (xmn = 696583.6, xmx = 696799.6, ymn = 167579.6, ymx = 167789.6, res = 2,
crs = "+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs")
rockfall_intensity <- raster (xmn = 696583.6, xmx = 696799.6, ymn = 167579.6, ymx = 167789.6, res = 2,
crs = "+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs")
# count unique ID per raster
rockfall_count <- rasterize(trjct_points_coords, rockfall_count, fun = "count", by = ID)
rockfall_count
plot(rockfall_count,col=brewer.pal(9,"YlOrRd"))
# average kinetic energy per raster cell
rockfall_intensity <- rasterize(trjct[, c('x', 'y')], rockfall_intensity, trjct$Etot, fun = mean)
plot(rockfall_intensity, col=brewer.pal(9,"YlOrRd"))
For nice illustration, I would like to download the corresponding satellite image. I have tried the following:
library(rgdal)
longlatcoor<-spTransform(trjct_pts,CRS("+proj=longlat"))
coordinates(longlatcoor)
longlatcoor
library(ggmap)
library(ggplot2)
# Set a range
lat <- c(-13.4003, -13.39943)
lon <- c(35.419, 35.41961)
# Get a map
map <- get_map(location = c(lon = mean(lon), lat = mean(lat)), zoom = 14,
maptype = "satellite", source = "google")
ggmap(map)
#limit lon and lat.
tschamut <- ggmap(map)+
scale_x_continuous(limits = c(-13.4003, -13.39943), expand = c(0, 0)) +
scale_y_continuous(limits = c(35.419, 35.41961), expand = c(0, 0))
tschamut
However, R crashes everytime i try to run this code, so i suspect something is seriously wrong with it. I derived the number used in the code from the bounding box:
> longlatcoor
class : SpatialPointsDataFrame
features : 104559
extent : -13.4003, -13.39943, 35.419, 35.41961 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84
variables : 1
names : Intensity_kJ
min values : 161.951
max values : 1192.526
How can I import the aerial photograph into R ?

How to plot spatial points (vector) on a raster file (landsat img) in R

I want to plot spatial points (sp) on a landsat compository, plotting landsat works and plotting the sp as well, but it does not work together. I am quite sure that I somehow don't get the overwriting of the projection/coordinate system, but don't know what I am doing wrong. Googleing didn't help, so I ask you.
Here is the code:
coords_glaciers <- data.frame(x = prec_year$latitude, y = prec_year$longitude)
head(coords_glaciers)
x y
1 30.69800 95.10474
2 30.69628 95.09544
3 30.69173 95.04394
4 30.68793 95.08615
5 30.68799 95.20155
6 30.68472 95.21425
pts_glaciers <- SpatialPoints(coords = coords_glaciers)
pts_glaciers
class : SpatialPoints
features : 865
extent : 29.50121, 30.82512, 94.24684, 96.19304 (xmin, xmax, ymin, ymax)
coord. ref. : NA
proj <- projection(landsat)
proj
[1] "+proj=utm +zone=46 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"
pts_glaciers <- SpatialPoints(coords = coords_glaciers, proj4string = CRS(proj))
pts_glaciers
class : SpatialPoints
features : 865
extent : 29.50121, 30.82512, 94.24684, 96.19304 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=46 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
plotRGB(landsat, r=5, g=4,b=3)
plot(pts_glaciers, add =TRUE)
I think the solution is:
coords_glaciers <- data.frame(x = prec_year$longitude, y = prec_year$latitude)
coordinates(coords_glaciers) <- c("x","y")
proj4string(coords_glaciers) <- CRS("+proj=longlat +datum=WGS84")
pts_glaciers <- spTransform(coords_glaciers, CRS("+proj=utm +zone=46 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"))

Projecting a SpatialLines object from lat/lon to utm

I created a great-circle trajectory of lat/lon using the geosphere package:
flightTraj = greatCircle( c( originAptLon, originAptLat ), c( destinAptLon, destinAptLat ), n = nPts, sp = TRUE )
Its properties are:
class : SpatialLines
features : 1
extent : -180, 180, -52.74719, 52.74719 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84
I want to project to a UTM zone 14 cartography with WGS84 ellipsoid. I tried:
projectedTrajectories <- CRS("+proj=utm +zone=14 +datum=WGS84 +units=km +no_defs") %>%
spTransform( flightTraj, . )
But, the console displayed:
non finite transformation detected:
V1 lat
Error in .spTransform_Line(input[[i]], to_args = to_args, from_args = from_args, :
failure in Lines 1 Line 1 points
In addition: Warning message:
In .spTransform_Line(input[[i]], to_args = to_args, from_args = from_args, :
6 projected point(s) not finite
Any help, please.
"All's well that ends well..."
distOrigDest = distGeo( c( originAptLon, originAptLat ), c( destinAptLon, destinAptLat ), a = earthRadius, f = earthFlattening ) / km2m
nPts = 20 * floor( distOrigDest / cellCentroidDist )
flightTraj = gcIntermediate( c( originAptLon, originAptLat ), c( destinAptLon, destinAptLat ), n = nPts, sp = TRUE )
flightTraj = spTransform( flightTraj, "+proj=utm +zone=14 +datum=WGS84 +units=km" )
plot( flightTraj, col= "blue", add = TRUE, lwd = 2 )

Resources