Creating a GIS layer for "Distance from..." in R |
|
| Back to home page |
Updated 14 Nov 2017
: functions
We recently ran a workshop on Geographical Information Systems (GIS) using Quantum GIS for ecologists and wildlife researchers. For many species, distance from water, a road, forest edge, or a settlement may be an important habitat variable. For example, we may be using automatic cameras to investigate occupancy of sites by leopards. Probability of occupancy may depend on distance from the nearest road. Given vector layers with roads and camera locations, we want to do two things:
We had trouble doing this in QGIS, but succeeded with R. [I've since managed to do it in QGIS: see here .] On this page we'll see
We'll use a toy data set which you can download here . Extract all the files to a folder named "data" inside your working folder on your hard drive ( not on the desktop). You can open the project in QGIS by double-clicking on the file "toy_example.qgs". The example has a raster file for land use and vector layers for roads, streams and camera locations.
I assume you have the R statistical software package installed on your computer and you are somewhat familiar with R. Open R and go to File > Change dir..., then browse to the folder containing the data folder. Load the packages we will need, installing any you don't already have:
library(raster)
(You don't need to load the
Produce a layer with distance-from-nearest-roadRead in the roads shape file and plot it. To indicate what corresponds to a vector layer and what's a raster, I'll put .v or .r on the end of the name. The two arguments of the readOGR function are the folder containing the shape files and the name of the shape file without the .shp extension.
If you have several raster layers, it's important that the pixels match up exactly . So we use an existing layer as a template when creating a new raster layer. We'll use the LandUse.asc file to create our template:
LU.r <- raster("LandUse.asc")
Now we use rasterize to create a roads raster matching the template. This takes 15 secs on my old laptop:
roads.r <- rasterize(roads.v, r, field=1)
The yellow raster-roads should fall almost exactly on the vector-roads. Now we have our road data in a raster file, we can use distance to create the layer we want. This can be slow if you have a raster with lots of pixels - our example has 171,600 and took 22 secs on my laptop:
roaddist.r <- distance(roads.r)
The road lines should fall neatly into the area with zero distance from road. Now we can save to a geo-tiff file (or an ESRI ascii file) for loading into QGIS:
writeRaster(roaddist.r, "DistFromRoad.tiff", "GTiff")
Get distance-from-nearest-road for each of our camerasRead in the cameras shape file and plot cameras and roads together to check:
Now extract the distance-from-road information from roaddist.r for the camera locations:
distFromRoad <- extract(roaddist.r,
cams.v)
You can add this information to the attribute table for the cameras and save it in a new shape file:
cams2.v <- cams.v
Now load the new cameras2.shp layer back into QGIS and check the attribute table. It has a column for roadDist. It also has columns for the coordinates of the centre of the pixel containing the camera. Getting distance-from-waterDistance from permanent water is often important, but it's trickier - at least in our example - as water includes streams on the streams layer and water bodies (lakes, reservoirs, etc) on the land use layer. We'll start with a raster including just the water body from the land use raster, where it is coded as 5. Pixels in water.r which have a value other than 5 are replaced with NA:
water.r <- LU.r
Now load the streams layer and plot the water body and streams together to check:
|
|
Updated 14 Nov 2017 by Mike Meredith
|
|