I'm trying to use the raster package to get a partial view of Portugal, using a bounding box
library(raster)
pt <- getData('GADM', country='Portugal', level=1)
I'm not used to work with this kind of data, so I'm actually lost.
All I know is that I need to crop this information using this bounding box:
bbx[1,1] = -9.290005
bbx[2,1] = 38.612098
bbx[1,2] = -8.969858
bbx[2,2] = 38.836554
Can anyone help? I really need to get the information from raster package using the getData function.
Cheers
library(raster)
pt <- getData('GADM', country='Portugal', level=1)
If you just want to plot a small area, you can do
plot(pt, xlim=c(-9.290005, -8.969858), ylim=c(38.612098, 38.836554))
Or you can create a SpatExtent and use crop to cut out the area of interest
e <- extent(-9.290005, -8.969858, 38.612098, 38.836554)
a <- crop(pt, e)
plot(a)
Related
I'm trying to crop a large multipolygon shapefile by a single, smaller polygon. It works using st_intersection, however this takes a very long time, so I'm instead trying to convert the multipolygon to a raster, and crop that raster by the smaller polygon.
## packages - sorry if I've missed any!
library(raster)
library(rgdal)
library(fasterize)
library(sf)
## load files
shp1 <- st_read("pathtoshp", crs = 27700) # a large multipolygon shapefile to crop
### image below created using ggplot- ignore the black boundaries!
shp2 <- st_read("pathtoshp", crs = 27700) # a single, smaller polygon shapefile, to crop shp1 by
plot(shp2)
## convert to raster (faster than st_intersection)
projection1 <- CRS('+init=EPSG:27700')
rst_template <- raster(ncols = 1000, nrows = 1000,
crs = projection1,
ext = extent(shp1))
rst_shp1 <- fasterize(shp1, rst_template)
plot(rst_shp1)
rst_shp2 <- crop(rst_shp1, shp2)
plot(rst_shp2)
When I plot shp2, the upper boundary is flat, rather than fitting the true boundary of the shp2 polygon.
Any help would be greatly appreciated!
Maybe try raster::mask() instead of crop(). crop() uses the second argument as an extent with which to crop a raster; i.e. it's taking the bounding box (extent) of your second argument and cropping that entire rectangle from your raster.
Something important to understand about raster objects is that they are all rectangular. The white space you see surrounding your shape are just NA values.
raster::mask() will take your original raster, and a spatial object (raster, sf, etc.) and replace all values in your raster which don't overlap with your spatial object to NA (by default, you can supply other replacement values). Though I will say, mask() will likely also take awhile to run, so you may be better off just sticking with sf objects.
I would suggest moving to the "terra" package (faster and easier to use than "raster").
Here is an example.
library(terra)
r <- rast(system.file("ex/elev.tif", package="terra"))
v <- vect(system.file("ex/lux.shp", package="terra"))[4]
x <- crop(r, v)
plot(x); lines(v)
As edixon1 points out, a raster is always rectangular. If you want to set cells outside of the polygon to NA, you can do
x <- crop(r, v, mask=TRUE)
plot(x); lines(v)
In this example it makes no sense, but you could first rasterize
x <- crop(r, v)
y <- rasterize(v, x)
m <- mask(x, y)
plot(m); lines(v)
I am not sure if this answers your question. But if it does not, then please edit your question to make it reproducible, for example using the example data above.
How to add an polygon to a SpatialPolygonsDataFrame?
Example: The script underneath will create a SpatialPolygonsDataFrame. I would like to add a polygon which consists of a large square around the existing polygons.
library(rgdal)
dsn <- system.file("vectors", package = "rgdal")[1]
Scotland <- readOGR(dsn=dsn , layer="scot_BNG")
plot(Scotland)
Preferred end result:
It is important that the rectangle becomes part of the SpatialPolygonsDataFrame. Since I have to do some calculation of the dataframe. So manually adding a visual layer of a square is insufficient.
Thanks!
The following code creates a rectangle that encloses the original spatial polygons and adds this as a spatial polygon to the original shape.
library(rgdal)
library(rgeos)
dsn <- system.file("vectors", package = "rgdal")[1]
Scotland <- readOGR(dsn=dsn , layer="scot_BNG")
# change the width parameter to make the rectangle the desired size
# this results in an extent object that surrounds the original shape
eScotland <- extent(gBuffer(Scotland, width = 50000))
# turn the extent into a Spatial Polygon
pScotland <- as(eScotland, 'SpatialPolygons')
crs(pScotland) <- crs(Scotland)
newScotland <- bind(pScotland, Scotland)
plot(newScotland)
I have a raster in an equal area Behrmann projection and I would like to project it to the Mollweide projection and plot.
When I do this with the following code, however, the plotting doesn't seem right, as the map extends to the sides, and there are outlines of various landmasses where I wouldn't expect them.Also, the map extends beyond the plot window.
Can anyone please help me get this to plot nicely?
Thanks!
The data file used can be downloaded from this link.
Here is the code I have so far:
require(rgdal)
require(maptools)
require(raster)
data(wrld_simpl)
mollCRS <- CRS('+proj=moll')
behrmannCRS <- CRS('+proj=cea +lat_ts=30')
sst <- raster("~/Dropbox/Public/sst.tif", crs=behrmannCRS)
sst_moll <- projectRaster(sst, crs=mollCRS)
wrld <- spTransform(wrld_simpl, mollCRS)
plot(sst_moll)
plot(wrld, add=TRUE)
Alright, since the example at this page seems to work, I tried to mimic it as much as possible. I think problems arise because the far left and far right side of the raster image overlap. Cropping and an intermediate reprojection to Lat-Lon as in the example seem to solve your problem.
Perhaps this workaround can be a basis for a more elegant solution that directly addresses the problem, as it is not benificial to reproject a raster twice.
# packages
library(rgdal)
library(maptools)
library(raster)
# define projections
mollCRS <- CRS('+proj=moll')
behrmannCRS <- CRS('+proj=cea +lat_ts=30')
# read data
data(wrld_simpl)
sst <- raster("~/Downloads/sst.tif", crs=behrmannCRS)
# crop sst to extent of world to avoid overlap on the seam
world_ext = projectExtent(wrld_simpl, crs = behrmannCRS)
sst_crop = crop(x = sst, y=world_ext, snap='in')
# convert sst to longlat (similar to test file)
# somehow this gets rid of the unwanted pixels outside the ellipse
sst_longlat = projectRaster(sst_crop, crs = ('+proj=longlat'))
# then convert to mollweide
sst_moll <- projectRaster(sst_longlat, crs=mollCRS, over=T)
wrld <- spTransform(wrld_simpl, mollCRS)
# plot results
plot(sst_moll)
plot(wrld, add=TRUE)
I would like to add an enlarged portion of my map to the original map and have as the final product, one map that shows both the original map, and also the enlarged/zoomed portion. Using the meuse dataset as an example:
library(sp)
library(lattice)
data(meuse)
coordinates(meuse)=~x+y
gridded(meuse)<-TRUE
rasters.m<-list()
for (i in 1:12){
rasDF <- raster(meuse, layer=i)
rasters.m[[i]]<-rasDF
}
stack.sp<-stack(rasters.m)
plot(stack.sp) # gives a gridded view of the stacked rasters. But now I would like to zoom in..
zoom.ent<-zoom(stack.sp,1) # The zoomed in portion appears as a new window, with the boundaries of the zoomed area highlighted in red on the original map.
I am not sure if there is a command in the raster or rasterVIS packages that would allow one to add the zoomed in part of the raster onto the original map. I have tried the par function but that doesn't work. Any suggestions would be welcomed.
This is more or less the same question you asked here. For Raster* objects you have to use the shift function. The result can be combined with the +.trellis function of the latticeExtra package:
library(raster)
library(rasterVis)
f <- system.file("external/test.grd", package="raster")
r <- raster(f)
rZoom <- crop(r, extent(180000, 181000, 330000, 331500))
displaced <- shift(rZoom, x = -1200, y = 2000)
levelplot(r) + levelplot(displaced)
I am wondering if this is possible to do this R .
I have one data as SpatialLinesDataFrame and another as spatialPolygonDataFrame. Is it possible to overlay these two data ?
When I try to overlay these I get the following error:
jd <- overlay(res,hello)
Error in function (classes, fdef, mtable) : unable to find an inherited method for function
‘overlay’ for signature ‘"SpatialLinesDataFrame", "SpatialPolygonsDataFrame"’
In the above code res is the SpatialLinesDataFrame and hello is SpatialPolygonDataFrame.
I have an shapefile and then I have data points with x,yand z
coordinates. I want to show the contour lines on the shapefile.
The procedure I used is using akima package to do the interpolation. The
code I used to interpolate is
fld <- interp(x,y,z)
Then I changed this to spatial object by using following code:
res <-ContourLines2SLDF(contourLines(fld))
The above command would store the contourlines as spatial data.
Then I read the shapefile and I plot both shapefile and res as follows:
p1 <-
spplot(hello,sp.layout=list(list("sp.lines",res)),col="blue",lwd=0,fill="grey",colorkey=F)
p1
"hello" is my shapefile and "res" is the object I created as shown above.
The problem is contour stored in "res" extends beyond the shapefile. So I
want to clip that contour with the shapefile and only display the contour
within the shapefile area.
So I am looking for a way to clip the contour layer with the polygon layer.
I have attached the image I got with my code.
In the image you can see the lines out of the shapefile. I also want to know
how can I display the contour levels on the map.
Thank you so much.
Jdbaba
I also want to know what does overlay does exactly. Does it intersect the area of both the data ?
Thank you.
It sounds like you're trying to clip your lines to the polygon extent. Use gIntersection from the rgeos package. Here's a reproducible example:
library(rgeos)
xx <- SpatialPoints(coords=matrix(data=c(0,0), nrow=1))
xx <- gBuffer(spgeom=xx, width=1)
yy <- SpatialLines(list(Lines(Line(matrix(c(-1,1,-1,1), nrow=2)), ID=1)))
zz <- gIntersection(yy, xx)
You can overlay the plot like so:
plot(xx)
plot(zz, add = TRUE, col = "blue")
Noah's answer has worked quite well for me. However, the output of his answer is a SpatialLines object, which cannot be saved as a shape file.
My two cents here is about how you can convert your SpatialLines object into a SpatialLinesDataFrame and save it as a shape file.
res.df <- fortify(res) # create data frame of res, your original SpatialLinesDataFrame
data <- data.frame(id = unique(res.df$id)) # get ids of road segments
rownames(data) <- data$id
# transform SpatialLines object into SpatialLinesDataFrame
zzSpatialLineDF <- SpatialLinesDataFrame(zz, data) # convert zz object keeping road ids
# 5 Save Shape File to your working directory
writeOGR(zzSpatialLineDF, dsn = '.', layer ='zzSpatialLineDF', driver = 'ESRI Shapefile')