Unit of calculated area for polygons using raster package area function - r

I am trying to calculate the area (square km or miles) of the intersection of counties and watersheds in R using the raster package and the area function.
My code looks like this so far:
counties <- readOGR('C:\\Shapefiles\\tl_2017_us_county\\tl_2017_us_county.shp')
counties <- spTransform(counties, CRS("+init=epsg:3455"))
huc2_10 <- readOGR('C:\\Shapefiles\\WBD_10_HU2_Shape\\Shape\\WBDHU6.shp')
huc2_10 <- spTransform(huc2_10, CRS("+init=epsg:3455"))
I then intersect the two shapefiles:
pi <- raster::intersect(huc2_10, counties)
The units of this projection are normally in meters (I believe), as it is a NAD83 projection for southern South Dakota, so the area function should calculate area in square meters. I am attempting to calculate the area (in square miles) of each polygon that is formed as a result of this intersection using the area function.
pi$area <- area(pi)/2.589988e6
However, the proj4string looks like this:
+init=epsg:3455 +proj=lcc +lat_1=44.4 +lat_2=42.83333333333334 +lat_0=42.33333333333334 +lon_0=-100.3333333333333 +x_0=600000 +y_0=0 +datum=NAD83 +units=us-ft +no_defs +ellps=GRS80 +towgs84=0,0,0
According to this, the units are "us-ft". So, does the area function output areas for each polygon in square feet because of this? This seems to make sense, but I would like to confirm this, changing my code to:
pi$area <- area(pi)/5280**2
Thank you.

The manual confirms what you expect:
?raster::area
If x is a SpatialPolygons* object: area if each spatial object in squared meters if the CRS is longitude/latitude, or in squared map units (typically meter)
If your map units are feet, the area will be in square feet.

Related

Abnormal projection shift

I have produced and compiled random points (blue) and data points (red) that are spread across Europe - but when I try to represent them on a baseline map, I have a shift that appears between the points and the map. This can be clearly seen in the lower right part near Crete, where the red points should be on the island.
The baseline map is a Raster Layer and the points are kept within a data frame which contains the coordinate (longitude & latitude).
The CRS arguments for the baseline are as follows:
> crs(baseline_EU[[1]])
CRS arguments:
+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs
but I do not know the CRS arguments for the points:
> crs(P.points)
[1] NA
I do not know how to solve this issue, so I would really appreciate your help.
Many thanks.
EDIT: here is an extract of the raw data. It contains latitude and longitude informations, plus a column that tells that it is a presence point.
Also, maybe this can helps, but following Robert Hijmans' advice I have checked the CRS arguments of the data points on QGIS:
EPSG:4326 - WGS 84 - Geographic
EDIT 2:
large picture, same CRS for points & baseline map:
small picture, same CRS for points & baseline map:

How read disk image file (.img) in R [duplicate]

I am working with U.S. National Landcover Dataset (NLCD) to classify habitat type at more than 150 sites across the northeast U.S. The dataset is very large (15GB) so I cannot upload it here, but it comes in .img format at 30m resolution.
I have GPS coordinates for the center point of all the sites. I would like to be able to extract the proportion of landcover classes in a 1 square kilometer around the point. My questions are:
1) How do I upload .img files into r?
2) How do I extract the information from around the GPS coordinates as proportions of the different habitat classes?
Has anyone worked with this dataset in r before? If so I could really use the help.
Cheers,
Israel
Use the raster package which can process the files from disk, only reading in chunks at a time.
the raster package has an extract function with a buffer argument. set your buffer to the appropriate value (1000 if your map units are metres and you want a km radius)
Thanks to mnel. I have gotten the basic idea to work (code below). Now if anyone could give me a pointer on how to calculate the proportion of each category for every coordinate. The extract function gives me matrices of values for each set of coordinates. Is there a way to summarize this data?
#load in map and locality data
NLCD<-raster ('NLCD2006/NLCD2006.img')
sites<-read.csv('sites.csv', header=T)
#crop site data to just latitude and longitude
sites<-sites[,4:5]
#convert lat/lon to appropirate projection
str (sites)
coordinates(sites) <- c("Longitude", "Latitude")
proj4string(sites) <- CRS("+proj=longlat +ellps=WGS84 +datum=WGS84")
sites_transformed<-spTransform(sites, CRS("+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"))
#plot the map
plot (NLCD)
#add the converted x y points
points (sites_transformed, pch=16, col="red", cex=.75)
#extract values to poionts
Landcover<-extract (NLCD, sites_transformed, buffer=1000)

OSM, rgeos, osmar, area calculation, does not add up

I am trying to get the size of a polygon from OSM, using osmar to download the data. However, sanity check tells me the are is not right.
Below is an example of what I mean.
(1) Geographical area around Hyde Park in London. Extracting all ways and relations tagged as 'park'.
devtools::install_github('osmdatar/osmdata')
library(osmdata)
library(osmar)
library(sp)
library(sf)
library(rgeos)
osmO <- get_osm(center_bbox(-0.167919, 51.5072682, 2000, 2000))
ids_relations <- osmO$relations$tags[osmO$relations$tags$v=="park","id"]
ids_ways <- osmO$ways$tags[osmO$ways$tags$v=="park","id"]
ids_sub <- find_down(osmO, way(c(ids_relations, ids_ways)))
sp_sub_park <- as_sp(subset(osmO, ids = ids_sub), "polygons")
Now, I want to know the area of each of these 'parks' [Fig1] (the big one in the middle being Hyde Park).
spplot(sp_sub_park, c("version"), colorkey = FALSE, col.regions=c('green'))
There are two ways:
1) Use the slot 'area' in the polygon itself.
a1 <- sapply(sp_sub_park#polygons, function(x) x#area)
2) Calculate the area with the specified projection.
bg_poly_t <- spTransform(sp_sub_park, CRS("+proj=longlat +datum=WGS84"))
a2 <- rgeos::gArea(bg_poly_t, byid=TRUE)
These two give me the same result [Fig2] (note the two biggest areas are Hyde Park, split in two by a road)
plot(a1*1000000, a2*1000000)
However, the size is not what I would expect. The area is returned in square-km (plotted square-meters). According to that the two parts of Hyde Park add up to about 300 square-meters, the size of a big flat but not a park (Hyde Park ~1.420.000 square-meters).
Any ideas?
Since your "map" is in lat/lon coordinates, to compute the areas you have to either convert it to a "metric" projection (as suggested by #Phil), or use spherical geometry (e.g., as implemented in package geosphere).
Luckily, function st_area of the sf package computes areas of polygons using geosphere in case the object is in geographical coordinates. Therefore, you can do simply:
sf_sub_park <- st_as_sf(sp_sub_park)
areas <- st_area(sf_sub_park)
sum(areas)
, giving:
2551269 m^2
, which is pretty close to #Phil results.
HTH
I've transformed the data into British National Grid which uses metres as its unit of length (WGS84 maybe uses degrees, IDK?). The area is then 2.5million sq m, which seems more plausible?
sp_sub_park <- spTransform(sp_sub_park, CRS("+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 "))
gArea(sp_sub_park)
# [1] 2550387
This is higher than your estimated ~1.4million sq m, but is Hyde Park both large areas of your map (i.e. is Kensington Gardens separate?).

Using R to change raster projection

I'm trying to change raster projection using R and the raster package. The input raster projection is Lambert Azimuthal; the parameters are here:
Coordinate System:
Lambert_Azimuthal_Equal_Area
False_Easting: 4321000,000000
False_Northing: 3210000,000000
Central_Meridian: 10,000000
Latitude_Of_Origin: 52,000000
GCS_ETRS_1989
Datum: D_ETRS_1989
Prime Meridian: 0
PROJCS
["ETRS_1989_LAEA",
GEOGCS ["GCS_ETRS_1989",
DATUM ["D_ETRS_1989",
SPHEROID ["GRS_1980",6378137.0,298.257222101]],
PRIMEM["Greenwich",0.0],
UNIT["Degree",0.0174532925199433]],
PROJECTION["Lambert_Azimuthal_Equal_Area"],
PARAMETER["False_Easting",4321000.0],
PARAMETER["False_Northing",3210000.0],
PARAMETER["Central_Meridian",10.0],
PARAMETER["Latitude_Of_Origin",52.0],
UNIT["Meter",1.0]]
I need to convert them to simple rasters in ESRI ASCII format, using longitude and latitude coordinates, with a Mercator-style projection, with a cell size of 0.1 degrees (I hope I explain myself well enough, because I don't have enough GIS skills, sorry). What I need are rasters in format .ASC where each value of the raster corresponds to a single cell of size N x N, where N is in degrees (e.g. 0.1 degrees), and the raster coordinates are in longitude/latitude.
I tried to use raster library in R, and follow examples found for the projectRaster function. But after many attempts using many several parameters, I wasn't be able to make it correctly. I think I'm not using the correct parameters for projection, datum, or something like this.
Here's what I tried. I load the raster in R, then I set its projection using:
>crs(r)<-"+proj=laea +lat_1=52 +lon_0=-10 +ellps=GRS80"
Then I define the output projection and I try the conversion and save:
>newproj <- "+proj=lonlat +lat_1=52 +lon_0=-10 +ellps=WGS84"
>pr2 <- projectRaster(r, crs=newproj, res=0.1)
>writeRaster(pr2, "newraster.asc", overwrite=TRUE)
No error messages, but resulting raster is not correctly projected (country borders don’t match, countries are slightly distorted).
Thanks for any help!
Given the description of the projection you provide, this seems wrong:
crs(r) <- "+proj=laea +lat_1=52 +lon_0=-10 +ellps=GRS80"
As you do not include the false northing and easting parameters; and lat_1 should probably be lat_0. This may be better:
crs(r) <- "+proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m"
This also looks odd:
newproj <- "+proj=lonlat +lat_1=52 +lon_0=-10 +ellps=WGS84"
How about
newproj <- "+proj=longlat +datum=WGS84"

Large .img file processing in R (GIS)

I am working with U.S. National Landcover Dataset (NLCD) to classify habitat type at more than 150 sites across the northeast U.S. The dataset is very large (15GB) so I cannot upload it here, but it comes in .img format at 30m resolution.
I have GPS coordinates for the center point of all the sites. I would like to be able to extract the proportion of landcover classes in a 1 square kilometer around the point. My questions are:
1) How do I upload .img files into r?
2) How do I extract the information from around the GPS coordinates as proportions of the different habitat classes?
Has anyone worked with this dataset in r before? If so I could really use the help.
Cheers,
Israel
Use the raster package which can process the files from disk, only reading in chunks at a time.
the raster package has an extract function with a buffer argument. set your buffer to the appropriate value (1000 if your map units are metres and you want a km radius)
Thanks to mnel. I have gotten the basic idea to work (code below). Now if anyone could give me a pointer on how to calculate the proportion of each category for every coordinate. The extract function gives me matrices of values for each set of coordinates. Is there a way to summarize this data?
#load in map and locality data
NLCD<-raster ('NLCD2006/NLCD2006.img')
sites<-read.csv('sites.csv', header=T)
#crop site data to just latitude and longitude
sites<-sites[,4:5]
#convert lat/lon to appropirate projection
str (sites)
coordinates(sites) <- c("Longitude", "Latitude")
proj4string(sites) <- CRS("+proj=longlat +ellps=WGS84 +datum=WGS84")
sites_transformed<-spTransform(sites, CRS("+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"))
#plot the map
plot (NLCD)
#add the converted x y points
points (sites_transformed, pch=16, col="red", cex=.75)
#extract values to poionts
Landcover<-extract (NLCD, sites_transformed, buffer=1000)

Resources