Is it possible to overlay SpatialLinesDataFrame and SpatialPolygonDataFrame - r

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')

Related

Overlay shapefile over Raster in Multiple plots

I am trying overlay the shapefile of south asia on top of multiple raster plots using the code as below: 'a' is a multilayered raster file. Here is the link to the data (917KB size) Test_Data
ras <- list.files("/filepath/", pattern = "\\.tif$", full=TRUE)
s <- stack(ras)
south_asia <- readOGR('/filepath/south_asia.shp') #to import shapefile
cropped <- crop(x = s, y = extent(south_asia)) #crop raster
plot(cropped)
plot(south_asia, add=TRUE)
This code gives me one shapefile and multiple raster plots. How do i overlay the shapefile on top of the rasters?
Any help will be appreciated.
P.S: They are in same CRS
Thanks
First, please try to give a reproducible example instead of a link to download files externally!
If you manually construct the plot (e.g. using par with base plotting) you can get your desired behaviour:
library(raster)
## testdata
# shapefile
shp <- getData(country='IND', level=1)
# raster
r <- getData('alt', country='IND', mask=TRUE)
# create 4 layer rasterstack
rs <- stack(r,r,r,r)
## finally plot
# 2 rows, 2 cols
par(mfrow=c(2,2))
# loop layers
for (ii in 1:nlayers(rs)){
plot(subset(rs,ii), main=names(rs)[ii])
plot(shp, add=T)
}
Edit:
Use plot(subset(rs,ii), main=names(rs)[ii]) in the loop to plot the respective layer.
The result:
I would suggest using the argument addfun in the plot option for raster stack/brick
For example:
# Function to add shapefile "shp_file" on each raster plot
add_shp=function(){plot(shp_file, bg="transparent", add=TRUE)}
#Plot selected raster of a raster stack, rs
plot(rs[[c(1:5)]],col=tim.colors(5),addfun=add_shp)
This will add shapefile shp_file to each of the 5 plots from the rasterstack rs.

R raster: the cropped raster had different color (brigtness) from original one?

I would like to crop a multiband raster (4 bands) by spatial polygons (in SpatialPolygonsDataFrame). When I displayed the original and cropped rasters in QGIS, I found that the cropped raster had different colours from the original one. Here is my code:
library(raster)
mosaic_shp <- shapefile("mo_clipper.shp")
mosaic <- brick('orthomosaic.tif')
mosaic_sub <- crop(mosaic, extent(mosaic_shp))
writeRaster(mosaic_sub, 'mosaic_sub.tif', format = "GTiff", overwrite = TRUE)
Partial cropped raster and the corresponding part in original raster in QGIS:
I have no idea how to deal with this issue, any help will be appreciated.
After comparing the two rasters carefully in QGIS, I have found the answer. The issue is related to dataType argument in the writeRaster function. So we just need to modify the code like:
library(raster)
mosaic_shp <- shapefile("mo_clipper.shp")
mosaic <- brick('orthomosaic.tif')
mosaic_sub <- crop(mosaic, extent(mosaic_shp))
data_type <- unique(dataType(mosaic)) # get data type from original raster;
writeRaster(mosaic_sub, 'mosaic_sub.tif', format = "GTiff", overwrite = TRUE,
datatype = data_type) # set datatype;

Dealing with unordered XY points to create a polygon shapefile in R

I've inherited a geodatabase of polygons of lakes for which I am trying to create sampling grids on each lake. My current strategy is to export spatial data to CSV, use R to run a loop to create the grids on each lake, and then write to a new shapefile. However, here is my problem, when exporting to a CSV the WKT strings get messed up and put onto different lines. Okay, no problem, I moved on to exporting just the geometry to CSV so that I get X-Y values. When I simply plot the points they look perfect (using plot(y~x)), but the points are not in order. So, when I transform the data to a SpatialPolygon in the sp package in R using the following sequence:
XY-points -> Polygon -> Polygons -> SpatialPolygon
and then plot the SpatialPolygon I get this:
I know this is an artifact of incorrectly ordered points, because when I order the points by X and then by Y and run the same procedure here is what I get:
This is what the correct plotting is supposed to look like (X-Y data plotted with open circles):
Here is a short reproducible example of what I am trying to deal with:
library(sp)
# correct polygon
data <- data.frame(x=c(1:10, 10:1), y=c(5:1, 1:10, 10:6))
# plot(y~x, data=data)
correct.data.points <- rbind(data, data[1,]) # to close the ring for a polygon
correct.data.coords <- as.matrix(cbind(correct.data.points))
correct.data.poly <- Polygon(correct.data.coords, hole=F)
correct.data.poly <- Polygons(list(correct.data.poly), ID=0)
correct.data.poly.sp <- SpatialPolygons(list(correct.data.poly))
plot(correct.data.poly.sp)
# incorrect polygon
scr.data <- data[c(sample(1:20)),]
# plot(y~x, data=scr.data)
scr.data.points <- rbind(scr.data, scr.data[1,]) # to close the ring for a polygon
scr.data.coords <- as.matrix(cbind(scr.data.points))
scr.data.poly <- Polygon(scr.data.coords, hole=F)
scr.data.poly <- Polygons(list(scr.data.poly), ID=0)
scr.data.poly.sp <- SpatialPolygons(list(scr.data.poly))
plot(scr.data.poly.sp)
Any thoughts? Thanks for any help or insight anyone can provide. Also, for reference I am using QGIS 2.6.0 and the MMQGIS Python plugin to do the geometry exporting.

How to properly project and plot raster in R

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)

Merge polygons and plot using spplot()

I would like to merge some regions in gadm data and then plot the map. So far I have the following:
#install.packages("sp",dependencies=TRUE)
#install.packages("RColorBrewer",dependencies=TRUE)
#install.packages("maptools",dependencies=TRUE)
library(sp)
library(maptools)
#library(RColorBrewer)
# get spatial data
con <- url("http://gadm.org/data/rda/CZE_adm2.RData")
print(load(con))
close(con)
IDs <- gadm$ID_2
IDs[IDs %in% c(11500:11521)] <- "11500"
gadm_new <- unionSpatialPolygons(gadm, IDs)
# plot map
spplot(gadm_new, "NAME_2", col.regions=col, main="Test",colorkey = FALSE, lwd=.4, col="white")
However this results in error:
Error in function (classes, fdef, mtable) :
unable to find an inherited method for function "spplot", for signature "SpatialPolygons"
Now I have no idea what can possibly fix this error.
I'm not sure about what you're trying to do here.
The error is due to the fact that spplot is used to draw spatial objects with attributes, ie with associated data. Your gadm object is of class SpatialPolygonsDataFrame, so it defines polygons and associated data that can be accessed via the slot gadm#data. When you use UnionSpatialPolygons, you only get a SpatialPolygons class object, which can be plotted with plot, but not with spplot :
IDs <- gadm$ID_2
IDs[IDs %in% c(11500:11521)] <- "11500"
gadm_new <- unionSpatialPolygons(gadm, IDs)
plot(gadm_new)
If you want to use spplot, you have to merge your associated data manually, the same way you merged your polygons, and then build back a SpatialPolygonsDataFrame. One way to do it is the following :
gadm_new <- gadm
## Change IDs
gadm_new$ID_2[gadm_new$ID_2 %in% c(11500:11521)] <- "11500"
## Merge Polygons
gadm_new.sp <- unionSpatialPolygons(gadm_new, gadm_new$ID_2)
## Merge data
gadm_new.data <- unique(gadm_new#data[,c("ID_2", "ENGTYPE_2")])
## Rownames of the associated data frame must be the same as polygons IDs
rownames(gadm_new.data) <- gadm_new.data$ID_2
## Build the new SpatialPolygonsDataFrame
gadm_new <- SpatialPolygonsDataFrame(gadm_new.sp, gadm_new.data)
Then you can use spplot to plot a map with an associated attribute :
spplot(gadm_new, "ENGTYPE_2", main="Test", lwd=.4, col="white")
Note that here I only used the ENGTYPE_2 variable of your data, not the NAME_2 variable, as I don't see the point to represent a variable where each value seems unique for each polygon.

Resources