I need to convert a shape file into a raster and have absolutely no clue where to even start.
If anyone could help me out I'd really appreciate!
Update: I have found out about the 'readOGR'-function, but everytime I use it I get the following message:
Warning messages:
1: In readOGR(dsn = "C:/Users/Giaco/Dropbox/Random Walk/Waterbodies", :
Dropping null geometries: 308, 309
2: In readOGR(dsn = "C:/Users/Giaco/Dropbox/Random Walk/Waterbodies", :
Z-dimension discarded
Can somebody tell me what that means?
Edit:
altdata <- raster("altitude.tif")
plot(altdata)
Lotic <- readOGR(dsn="C:/Users/Giaco/Dropbox/Random Walk/Waterbodies",layer="Lotic")
Lentic <- readOGR(dsn="C:/Users/Giaco/Dropbox/Random Walk/Waterbodies",layer="Lentic")
How can I plot the raster "altdata", the SpatialPointsDataFrame "Lentic" and the SpatialLinesDataFrame "Lotic" all in one plot ?
Edit:
altdata
class : RasterLayer
dimensions : 1286, 963, 1238418 (nrow, ncol, ncell)
resolution : 15, 15 (x, y)
extent : 90938.29, 105383.3, 190000, 209290 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=tmerc +lat_0=39.66666666666666 +lon_0=1 +k=1 +x_0=200000 +y_0=300000 +ellps=intl +pm=-9.131906111111112 +units=m +no_defs
data source : C:\Users\Giaco\Dropbox\Random Walk\altitude.tif
names : altitude
values : -32768, 32767 (min, max)
> Lentic
class : SpatialPointsDataFrame
features : 182
extent : -108473.2, -95455.86, -107870.9, -91344.22 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=tmerc +lat_0=39.66825833333333 +lon_0=-8.133108333333334 +k=1 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs
variables : 3
names : Presence, Type, Accessible
min values : 0, Fountain, 0
max values : 1, Well, 2
> Lotic
class : SpatialLinesDataFrame
features : 317
extent : -108956.5, -93832.44, -108979.5, -90747.34 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=tmerc +lat_0=39.66825833333333 +lon_0=-8.133108333333334 +k=1 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs
variables : 1
names : Presence
min values : 0
max values : 1
Using base plot, there are two way to overlay vector data on a raster. First plot the raster, then you can either call plot for each feature class using the add=TRUE argument. Alternately, you can use the points and lines functions which will also add to the current plot.
Create some example data
library(raster)
library(sp)
r <- raster(nrows=180, ncols=360, xmn=571823.6, xmx=616763.6, ymn=4423540,
ymx=4453690, resolution=270, crs = CRS("+proj=utm +zone=12 +datum=NAD83
+units=m +no_defs +ellps=GRS80 +towgs84=0,0,0"))
r[] <- runif(ncell(r))
pts <- sampleRandom(r, 10, na.rm = TRUE, sp = TRUE)
Plot the raster then call plot again, with add=TRUE, to add points.
plot(r)
plot(pts, pch=20, cex=2, col="red", add=TRUE)
Or, plot the raster and use points to add the point feature class.
plot(r)
points(pts, pch=20, cex=2, col="red")
Edit: Your extents between the raster and vector feature classes do not overlap.
We can create SpatialPolygons using the extent of your objects and an example raster (with a uniform value of 1).
library(raster)
proj <- sp::CRS("+proj=tmerc +lat_0=39.66666666666666 +lon_0=1 +k=1 +x_0=200000 +y_0=300000
+ellps=intl +pm=-9.131906111111112 +units=m +no_defs")
r.ext <- as(extent(90938.29, 105383.3, 190000, 209290), "SpatialPolygons")
proj4string(r.ext) <- proj
pt.ext <- as(extent(-108473.2, -95455.86, -107870.9, -91344.22), "SpatialPolygons")
proj4string(pt.ext) <- proj
line.ext <- as(extent(-108956.5, -93832.44, -108979.5, -90747.34), "SpatialPolygons")
proj4string(line.ext) <- proj
r <- raster(r.ext, resolution = c(15,15), crs = proj)
r[] <- rep(1, ncell(r))
Here we see that if we plot the raster and then the point and line extent polygons, you cannot see them.
plot(r)
plot(pt.ext, add=TRUE)
plot(line.ext, add=TRUE)
However, if we plot the line and point extent polygons they overlay just fine.
plot(line.ext)
plot(pt.ext,add=TRUE)
If we limit the raster extent to the extent of the line object, you should see the raster sub-region, but do not. And, if you try to crop the raster you will receive an "Error in .local(x, y, ...) : extents do not overlap" error.
plot(line.ext)
plot(r, add=TRUE)
Related
I am trying to work with satelite data from polar regions. They can be download as .nc (netcdf, see below).
They are in polar stereographic projection in a regular grid (https://nsidc.org/data/polar-stereo/ps_grids.html).
I would like to estimate each cell area to calculate the area of ice cover by multiplying the fraction of ice cover in each cell with the area of the cell.
I am able to extract cell area using "area" from {raster} only when the uniform grid is in geographical coordinates (lat-lon). However I could not find any R function to do this when the grid is uniform in stereographic coordinates.
I am very new to spatial data and projections and perhaps I am missing something important.
Below some relevant information and a piece of code with two trials.
RELEVANT DATA AND INFORMATION SOURCES
Polar Watch
https://polarwatch.noaa.gov/erddap/
Sea Ice concentration data
url to downoald data
https://polarwatch.noaa.gov/erddap/griddap/nsidcCDRiceSQnhmday.nc?seaice_conc_monthly_cdr[(2019-12-16T00:00:00Z):1:(2019-12-16T00:00:00Z)][(5837500.0):1:(-5337500.0)][(-3837500.0):1:(3737500.0)]
Can be download in R using
url1<- "https://polarwatch.noaa.gov/erddap/griddap/nsidcCDRiceSQnhmday.nc?seaice_conc_monthly_cdr[(2019-12-16T00:00:00Z):1:(2019-12-16T00:00:00Z)][(5837500.0):1:(-5337500.0)][(-3837500.0):1:(3737500.0)]"
download.file(url1, destfile='nsidcCDRiceSQnhmday_935c_47bd_a147.nc')
Data for the grid
Sea Ice Concentration Lat-Lon Grid, NOAA/NSIDC Climate Data Record V3,
Antarctic, 25km
Dataset ID: nsidcCDRice_sh_grid
url
https://polarwatch.noaa.gov/erddap/griddap/nsidcCDRice_sh_grid.nc?latitude[(4337500.0):1:(-3937500.0)][(-3937500.0):1:(3937500.0)],longitude[(4337500.0):1:(-3937500.0)][(-3937500.0):1:(3937500.0)]
url2<- "https://polarwatch.noaa.gov/erddap/griddap/nsidcCDRice_sh_grid.nc?latitude[(4337500.0):1:(-3937500.0)][(-3937500.0):1:(3937500.0)],longitude[(4337500.0):1:(-3937500.0)][(-3937500.0):1:(3937500.0)]"
download.file(url2, destfile="nsidcCDRice_sh_grid_c513_9d75_76c1.nc")
https://nsidc.org/data/polar-stereo/ps_grids.html
Table 4. Southern Hemisphere Projection Based on WGS 1984
Latitude of True Origin -70
SOME R TRIALS
require(raster)
require(ncdf4)
br<-brick("nsidcCDRiceSQnhmday_935c_47bd_a147.nc")
projection(br)<- CRS("+init=epsg:3976 +proj=stere +lat_0=-90 +lat_ts=-70 +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs") #https://polarwatch.noaa.gov/tools-training/code-gallery/
br
res(br)
area(br)
which gives
Warning message:
In .local(x, ...) :
This function is only useful for Raster* objects with a longitude/latitude coordinates
Using the grid provided in the data sources
IceFgrid<-nc_open("nsidcCDRice_sh_grid_c513_9d75_76c1.nc")
ygridLatLon <- ncvar_get(IceFgrid, varid="ygrid")
xgridLatLon <- ncvar_get(IceFgrid, varid="xgrid")
longitude <- ncvar_get(IceFgrid, varid="longitude")
latitude <- ncvar_get(IceFgrid, varid="latitude")
nc_close(IceFgrid)
dim(longitude) # Matrix with Longitude of each grid point.
length(xgridLatLon)
length(ygridLatLon)
## Try to convert to data frame and the to raster.
dims <- dim(longitude)
icemap.df <- data.frame(Longitude=array(longitude,dims[1]*dims[2]),
Latitude=array(latitude,dims[1]*dims[2]))
icemap.df$Seaice <- array(1,dims[1]*dims[2])# Here I use 1 for ice cover just
rast<-rasterFromXYZ(icemap.df, crs="+proj=stere +lat_0=-90 +lat_ts=-70 +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6378273 +b=6356889.449 +units=m +no_defs")
But gives
Error in rasterFromXYZ(icemap.df, crs = "+proj=stere +lat_0=-90 +lat_ts=-70 +lon_0=0 +k=1 +x_0=0 +y_0=0 +a=6378273 +b=6356889.449 +units=m +no_defs") :
x cell sizes are not regular
Any help will be appreciated.
Thanks in advance
Angel
Here I use terra the replacement for raster
url1 <- "https://polarwatch.noaa.gov/erddap/griddap/nsidcCDRiceSQnhmday.nc?seaice_conc_monthly_cdr[(2019-12-16T00:00:00Z):1:(2019-12-16T00:00:00Z)][(5837500.0):1:(-5337500.0)][(-3837500.0):1:(3737500.0)]"
f <- 'nsidcCDRiceSQnhmday_935c_47bd_a147.nc'
download.file(url1, destfile='nsidcCDRiceSQnhmday_935c_47bd_a147.nc', mode="wb")
library(terra)
#terra version 1.3.4
r <- rast(f)
crs(r) <- "epsg:3976"
r
class : SpatRaster
dimensions : 448, 304, 1 (nrow, ncol, nlyr)
resolution : 25000, 25000 (x, y)
extent : -3850000, 3750000, -5350000, 5850000 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=stere +lat_0=-90 +lat_ts=-70 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs
source : nsidcCDRiceSQnhmday_935c_47bd_a147.nc
varname : seaice_conc_monthly_cdr (NOAA/NSIDC Climate Data Record of Passive Microwave Monthly Northern Hemisphere Sea Ice Concentration)
name : seaice_conc_monthly_cdr
unit : 1
time : 2019-12-16
As you can see, the nominal cell resolution is 25000 x 25000
res(r)
[1] 25000 25000
Because it is constant, raster does not want to compute it for you. But terra will give you either the naïve area (based on the constant the nominal resolution):
na <- cellSize(r, transform=FALSE)
minmax(na)
# area
#[1,] 6.25e+08
#[2,] 6.25e+08
Or the the true area. That is, accounting for distortion:
a <- cellSize(r, mask=F, unit="m", transform=TRUE)
a <- mask(a, r)
a
#class : SpatRaster
#dimensions : 448, 304, 1 (nrow, ncol, nlyr)
#resolution : 25000, 25000 (x, y)
#extent : -3850000, 3750000, -5350000, 5850000 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=stere +lat_0=-90 +lat_ts=-70 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs
#source : memory
#name : area
#min value : 385538624
#max value : 664449196
#time : 2019-12-16
plot(a)
To get the sea-ice area in km2
x <- r * a / 1000000
global(x, "sum", na.rm=TRUE)
# sum
#_conc_monthly_cdr 11312232
The naïve estimate yields
n <- r * prod(res(r)) / 1000000
global(n, "sum", na.rm=TRUE)
# sum
#seaice_conc_monthly_cdr 11134025
That is about 1.5% lower
round(11134025 / 11312232, 3)
#[1] 0.984
This is not that different, because there is no ice at the edges, in the areas of severe distortion. And there is also some compensation in the central area (both smaller and larger areas) than 25*25 km2
I am trying to transform a raster layer to polygons based on its values. My raster looks like this:
> labels_rast
class : RasterLayer
dimensions : 26, 64, 1664 (nrow, ncol, ncell)
resolution : 0.03000146, 0.02999809 (x, y)
extent : 352032, 352033.9, 8551454, 8551455 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs+ellps=WGS84 +towgs84=0,0,0
data source : in memory
names : layer
values : 1, 3 (min, max)
When I apply the rasterToPolygons function (dissolve = TRUE), I get extra polygons (defined by horizontal lines):
How can I avoid the creation of the polygons defined by the horizontal lines?
It works for this very similar case:
library(raster)
r <- raster(nrow=26, ncol=64, xmn=352032, xmx=352033.9, ymn=8551454, ymx=8551455, crs="+proj=utm +zone=18 +south +datum=WGS84 +units=m", vals=3)
r[, 20:40] <- 2
r[1:3, 1:60] <- 1
r[24:26, 5:64] <- 1
x <- rasterToPolygons(r, dissolve=TRUE)
plot(r)
lines(x)
I am guessing that it does not work for you because of floating point imprecision. Would have to see your file to be sure. But, if so, perhaps you can round the extent (or resolution) a little bit.
For example
res(labels_rast) <- 0.03
y <- rasterToPolygons(labels_rast, dissolve=TRUE)
I want to crop a raster stack using a polygon shapefile i made in ArcGIS, however I get error that extent does not overlap.
First I create the raster stack:
test1 < stack("C:/mydir/test1.tif")
define projection
myCRS <- test1#crs
then read shapefile
myExtent <- readShapePoly("C:/mydir/loc1.shp", verbose=TRUE, proj4string=myCRS)
Crop
myCrop <- crop(test1, myExtent)
Error in .local(x, y, ...) : extents do not overlap
I have searched for a solution, but i only find that projection can be the problem, however they are definetly both in the same CRS:
> test1$test1.1
class : RasterLayer
band : 1 (of 4 bands)
dimensions : 10980, 10980, 120560400 (nrow, ncol, ncell)
resolution : 10, 10 (x, y)
extent : 6e+05, 709800, 5690220, 5800020 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=31 +datum=WGS84 +units=m +no_defs +ellps=WGS84
+towgs84=0,0,0
data source : C:\mydir\test1.tif
names : test1.1
values : 0, 65535 (min, max)
> myExtent
class : SpatialPolygonsDataFrame
features : 1
extent : 499386.6, 517068.2, 6840730, 6857271 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=31 +datum=WGS84 +units=m +no_defs +ellps=WGS84
+towgs84=0,0,0
variables : 2
names : Shape_Leng, Shape_Area
min values : 67444.6461177, 283926851.657
max values : 67444.6461177, 283926851.657
The message is pretty self explanatory. Your extent do not overlap... here how to check it:
library(raster)
ext.ras <- extent(6e+05, 709800, 5690220, 5800020)
ext.pol <- extent(499386.6, 517068.2, 6840730, 6857271)
plot(ext.ras, xlim = c( 499386.6,709800), ylim= c(5690220,6857271), col="red")
plot(ext.pol, add=T, col="blue")
I've created extent object from data in your question. You see one extent in the top left corner and the other in the bottom right. Have you tried reading both files in QGIS, you could probably easily see it.
If they really are suppose to overlap, than I would suspect the way you read your shapefile. Instead of
myExtent <- readShapePoly("C:/mydir/loc1.shp", verbose=TRUE, proj4string=myCRS)
use :
library(rgdal)
myExtent <- readOGR("C:/mydir","loc1.shp")
myExtent <- spTRansform(myExtent, CRS(proj4string(test1)))
I have a raster with a forest cover of one area
class : RasterLayer
dimensions : 5436, 2633, 14312988 (nrow, ncol, ncell)
resolution : 100, 100 (x, y)
extent : -109346.5, 153953.5, -290837.1, 252762.9 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=tmerc +lat_0=39.66825833333333 +lon_0=-8.133108333333334 +k=1 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
data source : c://Total_Forest_cove
names : Total_Forest_cove
with values from 0 to 3 I want to create a dataset with random samples from the pixels with values higher than 0.
For that I do
library(dismo)
Forestcover[Forestcover < 1] <- NA
randompoints <- sampleRandom(Forestcover, size = 10, sp=TRUE, na.rm=TRUE)
plot(Forestcover, axes=FALSE, legend=FALSE)
randompoints <- coordinates(randompoints)
when I try to pull out the enviromental variables form worldclim
randpoints_wc <- extract(worldclim, randompoints)
randpoints_wc <- cbind(randompoints, randpoints_wc)
My dataset is always empty
Not sure if there is other method to extract random that can be apply here.
Regards
Your forest cover data set has a Mercator coordinate reference system
coord. ref. : +proj=tmerc
You do not show your WorldClim data, but presumably it has
coord. ref. : +proj=longlat
So, it is no surprise (and a good thing) that you get an empty result set. You can use rgadl::spTransform to make the coordinates match the raster.
For example:
fc <- reclassify(ForestCover, cbind(1, Inf, NA))
randompoints <- sampleRandom(fc, size = 10, sp=TRUE, na.rm=TRUE)
library(rgdal)
rp <- spTransform(randompoints, CRS("+proj=longlat +datum=WGS84"))
rp_wc <- extract(worldclim, rp)
rp_wc <- cbind(coordinates(randompoints), coordinates(rp), rp_wc)
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?