raster detecting and/or projecting crs incorrectly (LCC to WGS84) - raster

I have ncdf files that I read in using the raster function brick. My example / explanation focuses on one layer in the brick
Data available here (too large for tinyupload): https://wetransfer.com/downloads/f21973282c3f9aa4153e9b29ab26227f20190612111133/d1f6b123571e8f7f25cdc633e27c3fa220190612111133/7bd6ec
> rt <- brick("mrros/mrros_EUR-11_CNRM-CERFACS-CNRM-CM5_rcp85_r1i1p1_CNRM-ALADIN63_v2_mon_200601-201012.nc",
+ varname = "mrros")[[1]]
> rt
class : RasterLayer
band : 1 (of 60 bands)
dimensions : 453, 453, 205209 (nrow, ncol, ncell)
resolution : 12.5, 12.5 (x, y)
extent : -6.25, 5656.25, -6.25, 5656.25 (xmin, xmax, ymin, ymax)
crs : +proj=lcc +lat_0=49.5 +lat_1=49.5 +lon_0=10.5 +ellps=WGS84 +lat_2=45
source : C:/Users/coding/Desktop/Files/mrros/mrros_EUR-11_CNRM-CERFACS-CNRM-CM5_rcp85_r1i1p1_CNRM-ALADIN63_v2_mon_200601-201012.nc
names : X2006.01.16
z-value : 2006-01-16
zvar : mrros
>
> plot(rt)
>
The raster brick automatically detects the crs of the data. The only thing that looks like it might be missing is the units of the data (data in 12.5 km intervals)
> crs(rt)
CRS arguments:
+proj=lcc +lat_0=49.5 +lat_1=49.5 +lon_0=10.5 +ellps=WGS84 +lat_2=45
> crs(rt) = paste0(crs(rt), "+units=km")
> crs(rt)
CRS arguments:
+proj=lcc +lat_0=49.5 +lat_1=49.5 +lon_0=10.5 +ellps=WGS84 +lat_2=45+units=km
I want to change the projection into WGS84
> rtPr <- projectRaster(rt, crs = CRS("+init=EPSG:4326"))
> rtPr %>% plot
These units are clearly not WGS84, Europe does not have a longitudinal range of .12 degrees (or a latitudinal range of .5 degrees)!
Is anyone able to advise on why the projectRaster does not return the data on the appropriate grid? I presume it has something to do with the assumption of the input crs, but I have no idea what to change it to as these are the values I would have specified if I had done it manually!

Perhaps this helps a bit
library(raster)
r <- raster(f, var="mrros")
print(r)
This shows
#char Lambert_Conformal[]
# latitude_of_projection_origin: 49.5
# standard_parallel: 49.5
# longitude_of_central_meridian: 10.5
# grid_mapping_name: lambert_conformal_conic
The unit is stored elsewhere, and that is not picked up by raster
#dimensions
# units: km
The raster package creates this proj.4 string
x <- "+proj=lcc +lat_0=49.5 +lat_1=49.5 +lon_0=10.5"
(r)gdal changes it (I do not know why it adds "lat_2")
CRS(x)
CRS arguments:
+proj=lcc +lat_0=49.5 +lat_1=49.5 +lon_0=10.5 +ellps=WGS84 +lat_2=45
The below changes gets it close. But I am just guessing a bit. Perhaps the problem is that there is also a rotation??
crs(r) = "+proj=lcc +lat_1=49.5 +lon_0=-10.5 +ellps=WGS84 +lat_2=49.5 +units=km"
plot( projectRaster(r, crs="+proj=longlat +datum=WGS84") )
It is perhaps best to ask for a standard projection description at the source of the data

Related

convert UTM to lat/long or vice versa

I downloaded elevation data for New Zealand in the form of a tif file, which is accompanied by a "world file" (tfw),
80.000000000000000
0.000000000000000
0.000000000000000
-80.000000000000000
1062571.750000000000000
6282711.000000000000000
My understanding from wikipedia is that the first and third numbers indicate the scale (pixels/km), and the last two locate the origin in UTM coordinates (if I understand correctly).
Now, I would like to align these raster data with a different data set comprising a path traced from GPS coordinates, which give me a lat/long format
X Y
1 174.7771 -41.29805
2 174.7771 -41.29815
3 174.7772 -41.29819
4 174.7772 -41.29824
5 174.7772 -41.29827
6 174.7772 -41.29836
...
I've tried the following to convert from UTM to lat/long, but the results seem completely wrong. What am I missing?
library(rgdal)
utm <- SpatialPoints(cbind(1062571.75, -6282711.0),
proj4string=CRS("+proj=utm"))
spTransform(utm, CRS("+proj=nzmg"))
class : SpatialPoints
features : 1
extent : 1754874408, 1754874408, 5271325323, 5271325323 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=nzmg +ellps=WGS84
Edit: following the suggestion below I got the following data from the tif file,
> library(raster)
> r <- raster("nztm.tif")
> r
class : RasterLayer
dimensions : 19712, 13261, 261400832 (nrow, ncol, ncell)
resolution : 80, 80 (x, y)
extent : 1062532, 2123412, 4705791, 6282751 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000 +y_0=10000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
data source : nztm.tif
names : nztm
values : -32768, 32767 (min, max)
> crs(r)
CRS arguments:
+proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000 +y_0=10000000
+ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
First check if the file comes with a coordinate reference system (perhaps in a .prj file?)
In R, you can do:
library(raster)
r <- raster("elevation.tif")
r
crs(r)
If that is NA, and you cannot find any reference elsewhere, it may be very difficult to figure this out.
It may be that the elevation crs is "UTM" but that is not guaranteed at all. If it is UTM, you need to know which of the 60 UTM zones and then there may be some other parameters. It is actually highly unlikely that someone would choose UTM for New Zealand as the country crosses multiple UTM zones. You could try this:
library(rgdal)
utm <- SpatialPoints(cbind(1062571.75, -6282711.0),
proj4string=CRS("+proj=utm +zone=59 +datume=WGS84 "))
spTransform(utm, CRS("+proj=longlat +datum=WGS84"))
#SpatialPoints:
# coords.x1 coords.x2
#[1,] -179.8818 -56.35255
Not that far from NZ.
"nzmg" or another standard crs for NZ would be more plausible
utm <- SpatialPoints(cbind(1062571.75, -6282711.0),
proj4string=CRS("+proj=nzmg +datum=WGS84"))
spTransform(utm, CRS("+proj=longlat +datum=WGS84"))
# -178.9791 -71.8877
Even further, alas, almost Antarctica

Missing coordinates in raster reprojection from cylindrical equal area to lat/long using Raster function in R

I have a raster that I have reprojected from Cylindrical Equal-Area (Lambert) Central Meridian: -160. Datum: WGS 1984 (+proj=cea +lon_0=Central Meridian +lat_ts=Standard Parallel +x_0=False Easting +y_0=False Northing +ellps=WGS84) to latitude and longitude.
The original raster looks like this:
library(rasterVis)
levelplot(r)
Original raster without missing points
r
#class : RasterLayer
#dimensions : 64, 200, 12800 (nrow, ncol, ncell)
#resolution : 2e+05, 2e+05 (x, y)
#extent : -20037507, 19962493, -6363885, 6436115 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=cea +lon_0=-160 +lat_ts=Standard Parallel +x_0=False Easting +y_0=False Northing +ellps=WGS84
#data source : N:\My documents\Data\Exposure\Reefs at risk\Global_Threats\Acidification\arag_380\w001001.adf
#names : w001001
#values : 1.025163, 4.11939 (min, max)
I have been able to use the projectRaster function from the Raster package by cutting the extent of the y-axis of the raster by 0.95 to the North and South. I was having a few problems reprojecting the raster without cutting the extent (see here: https://gis.stackexchange.com/questions/220589/error-using-projectraster-in-r-error-in-if-maxy-miny-missing-value-whe/220741#220741).
#Cut y-axis values because projectRaster failed using full extent
extent(r) <- c(xmin= -20037507, xmax= 19962493, ymin= 0.95*(-6363885), ymax= 0.95*(6436115))
# Define the new Proj.4 spatial reference
sr <- "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"
# Project Raster
projected_r <- projectRaster(r, crs = sr, method = 'bilinear')
The problem I am having is that there are missing data in the new, reprojected raster.
levelplot(projected_r)
reprojected raster with missing points
The missing coordinates are not located in the 5% North and Souththat I cut from the extent so I am not sure why these data are missing? Any help would be appreciated!

Crop rasterLayer with SpatialPolygonDataFrame leaves out part of the target region R

library(raster)
library(ncdf4)
library(rgdal)
I am trying to crop a raster layer based on polygon: sample data (~45MB) can be found here sample data for illustration:
dat<- raster('data.nc')# make a subset
dat
class : RasterLayer
dimensions : 824, 935, 770440 (nrow, ncol, ncell)
resolution : 10000, 10000 (x, y)
extent : -5000, 9345000, -5000, 8235000 (xmin, xmax, ymin, ymax)
coord. ref. : NA
data source : C:\Users\data.nc
names : Total.Precipitation
zvar : Total.Precipitation
As coord. ref is = NA, I assign a polar stereographic projection based on information from the website of the data provider.
projj=CRS("+proj=stere +lat_0=90 +lat_ts=90 +lon_0=-100 +k=0.994 +x_0=2000000 +y_0=2000000 +datum=WGS84 +units=m +no_defs")
proj4string(dat) <- projj
#rx <- projectRaster(from=dat, crs=wgs84.p4s)
Then transform the bbox shapefile to projj
shgrid <- spTransform(Prairie.Boundaries, projj)# transform to dat spat reference
plot(dat)
plot(shgrid,add=T)# this gives
CROPPING
cr <- crop(dat, extent(shgrid))
plot(cr)
fr <- rasterize(shgrid, cr)
dat1<- mask(x=cr, mask=fr)
levelplot(dat1)
OUTPUT:
The cropped image shows only part of canada but I want all of Canada.
What did I miss within my code? Could it be the projection?
Besides I would prefer the axes labels in latlon coordinates.
Any suggestions?

Converting shapefile to raster

I'm having an issue rasterizing a shapefile to produce points on a 0.5*0.5 grid. The shapefile represents classifications of risk level (Low-0, Medium-100, High-1000, Very High-1500) of global coral reefs to integrated threats.
I pulled the code from another example that works fine, but when I try it for my data I get nothing from the plot function. See below for the link to the shapefile and my code:
Reefs At Risk: Global Integreated Threats
# Read shapefile into R
library(rgdal)
library(raster)
int.threat.2030 <- readOGR(dsn = "Global_Threats/Integrated_Future",
layer = "rf_int_2030_poly")
## Set up a raster "template" for a 0.5 degree grid
ext <- extent(-110, -50, 0, 35)
gridsize <- 0.5
r <- raster(ext, res=gridsize)
## Rasterize the shapefile
rr <- rasterize(int.threat.2030, r)
## Plot raster
plot(rr)
Any ideas where I might be going wrong? Is it an issue with the shapefile itself?
Please and thanks!
You assumed that the polygons were in lon/lat coordinates, but they are not:
library(raster)
library(rgdal)
p <- shapefile('Global_Threats/Integrated_Future/rf_int_2030_poly.shp')
p
#class : SpatialPolygonsDataFrame
#features : 63628
#extent : -18663508, 14601492, -3365385, 3410115 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=cea +lon_0=-160 +lat_ts=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0
#variables : 3
#names : ID, THREAT, THREAT_TXT
#min values : 1, 0, Critical
#max values : 63628, 2000, Very High
You can either change the projection
pgeo <- spTransform(p, CRS('+proj=longlat +datum=WGS84'))
and then do something like:
ext <- floor(extent(pgeo))
rr <- raster(ext, res=0.5)
rr <- rasterize(pgeo, rr, field=1)
Or keep the orginal CRS and do something like:
ext <- extent(p)
r <- raster(ext, res=50000)
r <- rasterize(p, r, field=1)
plot(r)
Note that you are rasterizing very small polygons to large raster cells. A polygon is considered 'inside' if it covers the center of a cell (i.e. assuming a case where polygons cover multiple cells). So for these data you would need to use a much higher resolution (and then perhaps aggregate the results). Alternatively you could rasterize polygon centroids.
But none of the above is relevant really, as you are doing this all backwards. The polygons are clearly derived from a raster (look how blocky they are) and the raster is available in the dataset you point to!
So instead of rasterizing, do:
x <- raster('Global_Threats/Integrated_Future/rf_int_2030')
x
#class : RasterLayer
#dimensions : 25456, 80150, 2040298400 (nrow, ncol, ncell)
#resolution : 500, 500 (x, y)
#extent : -20037508, 20037492, -6363885, 6364115 (xmin, xmax, ymin, ymax)
#coord. ref. : NA
#data source : C:\temp\Global_Threats\Integrated_Future\rf_int_2030
#names : rf_int_2030
#values : 0, 2000 (min, max)
#attributes :
# ID COUNT THREAT_TXT
# 0 80971 Low
# 100 343535 Medium
# 1000 322231 High
# 1500 168518 Very High
# 2000 83598 Critical
Here plotting a part of Palawan:
e <- extent(c(-8990636, -8929268, 1182946, 1256938))
plot(x, ext=e)
plot(p, add=TRUE)
If you need a lower resolution see raster::aggregate. For a different coordinate reference system, see raster::projectRaster.

reproject raster (WGS84 to BNG) with large resolution

i'm doing a simple enough operation, reprojecting a raster from WGS84 to British National Grid, but i am wondering about some of the results post reprojection. The sum of the resulting rasters are quite different; is this due to the resolution and the way the bilinear interpolation in 'projectRaster' works?
I started with a csv that has global data covering the range of -180 to 180 degrees in both latitude and longitude (integer values only), with some z-values. this is subsetted, made into a raster of projection WGS84 and converted to BNG (subset below):
x <- rep(c(-10:3), times = 10)
n <- 14
y <- rep(48:57, each=n)
z <- rnorm(n=140, mean=20, sd=5)
ind <- which(z %in% sample(z, 45))
z[ind]<-NA
df <- data.frame("x"=x,"y"=y,"value"=z)
bng <- '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs'
wgs84 <- '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs'
coordinates(df) = ~x + y
ras = rasterFromXYZ(df, crs=wgs84)
cellStats(ras,sum)
plot(ras)
ras_bng <- projectRaster(ras,crs=bng)
plot(ras_bng)
cellStats(ras_bng,sum)
the sum goes from 1919 to 2625 (in my case), a fair chunk.
Is it purely from the reprojection creating so many extra cells around the 'edges'? if i were to reproject to a raster of much smaller resolution (5km), would this reduce the differing sums considerably?
thanks, S
> ras
class : RasterLayer
dimensions : 10, 14, 140 (nrow, ncol, ncell)
resolution : 1, 1 (x, y)
extent : -10.5, 3.5, 47.5, 57.5 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0
data source : in memory
names : layer
values : 3.243918, 32.21532 (min, max)
> ras_bng
class : RasterLayer
dimensions : 12, 19, 228 (nrow, ncol, ncell)
resolution : 67900, 111000 (x, y)
extent : -375677.8, 914422.2, -343553.2, 988446.8 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs +towgs84=446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894
data source : in memory
names : layer
values : 8.174968, 28.31331 (min, max)
This is because the NA values in 'ras'.
The difference is small when you take out z[ind]<-NA. This is because projectRaster implicitly uses "na.rm=TRUE"; perhaps an argument is needed to change that. This is not as simple as in other cases, as, for example, only one of the cells interpolated from may be NA, in which case it should probably be computed.
In practice it is rare to find this many NA values, typically they are confined to the edges (of land) only.
By the way WGS84 is a datum,it is not a projection. The projection you are using would be 'longitude/latitude' (also known by other names) except that this is also not a projection since the whole point of a projection is to go from such angular coordinates to planar coordinates. So, you are transforming one coordinate reference system ('long/lat, WGS84') to another (BNG).

Resources