Apologies as i'm a little new to GIS features within R, so any help and explanation would be very helpful!
I have downloaded this shape file (Simple Feature Polygon) from source like so:
fire <-tempfile()
download.file("http://frap.fire.ca.gov/webdata/data/statewide/fhszs.sn.zip",destfile = fire)
unzip(fire,exdir = ".")
fire_map<-read_shape("fhszs06_3.shp")
Map has small polygons based on Hazard code (i.e.: 1,2,3)
I also have an internal dataframe that is about 15 variables with 3584 rows, I also have lat/lon for all points (commercial properties in california) that I'm trying to convert to either spatial points DF or simple feature in order to figure out which properties lie within a hazard code.
Example of property file:
ln_bal<- c(500000,200000,6000000,12000,130000)
ln_city <-c('Ventura','Torrance','Buena Park','Concord','Lake View Terrace')
lon <- c(-119.213504,-118.311072,-117.985452,-122.057139,-116.893845)
lat <-c(34.278122,33.844817,33.846594,37.979995,32.844287)
cmbs3 <- data.frame(ln_bal,ln_city,lon,lat)
I think my problem is getting the correct CRS and then matching with the shape file.
The CA Fire map has the following:
epsg (SRID): NA
proj4string: +proj=aea +lat_1=34 +lat_2=40.5 +lat_0=0 +lon_0=-120 +x_0=0 +y_0=-4000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
I've Tried sf_intersect by creating a SF points DF:
fire_map <-st_read("fhszs06_3.shp")%>%
st_transform(4326) #need to set CRS the same as your dataframe below
#transforms coordinates to ellips code and creates matching values with fire_map:
proj4string(cmbs3)<-CRS("+proj=longlat +datum=WGS84")
cmbs3 <- spTransform(cmbs3, CRS("+proj=utm +zone=51 ellps=WGS84"))
#fire_map is a simple feature data frame need to convert our data to this, and then match
cmbs3<-st_as_sf(cmbs3,precision=0)
cmbs3<-st_set_crs(cmbs3,4326)
inters <- st_intersection(cmbs3,fire_map)
Expected (potential) Results:
ln_bal ln_city lon lat HAZ_CODE HAZ_CLASS
12000 Concord -122.057139 37.97 1 Moderate
Related
I have a dataset form the public repo https://github.com/highsource/verbundkarte
Reading the dataset with st_read and plotting it with ggplot yields a beautiful map with correct lng and lat data.
df <- st_read("~/Verkehrsverbunde.shp")
map <- ggplot(df) + geom_sf(aes(fill=SHORTNAME))
I therefore assume, that the lng/lat values are included in the variable df$geometry. However, if I use leaflet, no matter what I try I end up with an error. For instance
df%>% leaflet() %>%
addProviderTiles("CartoDB") %>%
addPolygons(label = htmlEscape(verbunddaten$SHORTNAME)) %>%
setView(lng = 10.3, lat = 51.9, zoom = 5.1)
ends up with
Warning messages:
1: sf layer is not long-lat data
2: sf layer has inconsistent datum (+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=3500000 +y_0=0 +datum=potsdam +units=m +no_defs ).
Need '+proj=longlat +datum=WGS84'
I found this beautiful conversation of which I understood basically nothing. Reading the data with readOGR as suggested here doesn't solve my problem.
How do I force leaflet to assume the same longlat and EPSG as ggplot?
The data in your Verkehrsverbunde.shp shapefile is in a custom traverse mercator projection, where coordinates are expressed in meters. By contrast, r-leaflet expects data to be expressed in degrees of latitude-longitude, which would look like an equirectangular projection if/when plotted.
I'll guess that, contrary to your belief, ggplot is not using latitude and longitude in degrees, but rather northing and easting values in meters. The representation of the data might look similar for small areas.
In GIS terms, your data is using the EPSG:31467 CRS (Coordinate Reference System), as can be inferred by proj=tmerc and datum=postdam; r-leaflet expects data in the EPSG:4326 CRS.
The approach here would be to reproject your data, so that coordinates are in latitude-longitude as expected. There are plenty of ways to do this; running ogr2ogr -t_srs epsg:4326 Verkehrsverbunde-latlng.shp Verkehrsverbunde-latlng.shp on a command line, using R, or using QGIS, amongst other methods.
Im trying to do a point pattern analysis. To do this I have to convert a SpatialPolygonsDataFrame so it contains projected coordinates instead of curved coordinates. However I keep getting the same error:
Error in as.owin.SpatialPolygons(Netherlands_flat) :
Only projected coordinates may be converted to spatstat class objects
this is the data I used for a border:
download.file("http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_1_states_provinces.zip",destfile="ne_10m_admin_1_states_provinces.zip")
unzip("ne_10m_admin_1_states_provinces.zip",exdir="NaturalEarth")
border <- shapefile("NaturalEarth/ne_10m_admin_1_states_provinces.shp")
#extract the border of the Netherlands
Netherlands <- border[paste(border$iso_a2)=="NL",]
Im able to plot the plot the Netherlands with the events.
#Plot
plot(babesia$Longitude, babesia$Latitude, pch="+",cex=0.5, xlim=c(3.360782, 7.227095), ylim = c(50.723492, 53.554584))
plot(Netherlands, add = T)
Netherlands with events
But upon using the Spatstat package I keep running into this error.
I tried this code to transform the coordinates
coord_netherlands <- coordinates(Netherlands)
proj4string(Netherlands)
summary(Netherlands)
Netherlands_flat <- spTransform(coord_netherlands, CRS("+proj=longlat +datum=WGS84 +no_defs"))
Netherlands <- as.owin(Netherlands_flat)
Error in as.owin.SpatialPolygons(Netherlands_flat) :
Only projected coordinates may be converted to spatstat class objects
Does anyone know how to solve this? Thank you very much in advance!
You are almost there. You just need to project to another coordinate system when you call spTransform. You currently ask for geographic coordinates on a spheriod model of the earth (long,lat). Instead you should ask for a flat (x,y) coordinate system. This could be utm coordinates in the appropriate zone for the Netherlands or there might well be a better alternative. Your events also need to be transformed from (long,lat) to the same coordinate system. Maybe you can look at the shapefile vignette of the spatstat package for an example. Or look under the spatstat tag on this site. I'm on my phone do I can't give detailed help.
Good luck.
If your events are in a data.frame called xy you can project to UTM zone 31N like this:
xy <- data.frame(lon = 1:2, lat = 1:2)
coordinates(xy) <- ~lon+lat
proj4string(xy) <- CRS("+proj=longlat +datum=WGS84")
xy
# SpatialPoints:
# lon lat
# [1,] 1 1
# [2,] 2 2
# Coordinate Reference System (CRS) arguments: +proj=longlat +datum=WGS84
# +ellps=WGS84 +towgs84=0,0,0
events.utm <- spTransform(xy, CRS("+proj=utm +zone=31N +datum=WGS84"))
events.utm
# SpatialPoints:
# lon lat
# [1,] 277438.3 110598.0
# [2,] 388786.7 221094.9
# Coordinate Reference System (CRS) arguments: +proj=utm +zone=31N
# +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
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)
Apparently NOAA and the NWS use a non-traditional projection for some of their rainfall data and don't offer a lot of help in terms of projecting it to a traditional format for other users. I've had a bit of success in getting the raster to overlay for part of the United States but it still isn't quite right.
I'm hoping someone can help me decipher what I am missing and correct the projection of this data.
You can find more information of this data here: https://polyploid.net/blog/?p=216
https://water.weather.gov/precip/download.php
library(tidyverse)
library(raster)
library(rgdal)
library(sp)
setwd("C:/Users/MPE_Data/")
file_list <- list.files("201809")
grib0<-raster::brick("201809//ST4_2018091307_24h.nc", varname="APCP_SFC")[[1]]
grib0#crs
crs(grib0) <- "+proj=longlat +a=6371200 +b=6371200 +no_defs"
crs(grib0) <- "+proj=stere +lat_0=90 +lat_ts=60 +lon_0=-105 +x_0=0 +y_0=0 +a=6371200 +b=6371200 +units=m +no_defs"
us_shp <- rgdal::readOGR("C:/Users/cb_2017_us_state_500k/US_clipped.shp")
shp <- rgdal::readOGR("C:/Users/nc_sc_counties_wgs1984.shp")
wgs<-"+proj=longlat +datum=WGS84 +ellps=WGS84 +no_defs"
wgsraster <- projectRaster(grib0, crs=wgs)
plot(wgsraster)
shp <- spTransform(shp, CRS(wgs))
us_shp <- spTransform(us_shp, CRS(wgs))
plot(shp,add=TRUE)
plot(us_shp,add=TRUE)
I couldn't find your exact map but here is an example using recent precipitation data. You don't need to assign a CRS as the netCDF file already has a CRS associated with it, you can simply projectRaster. Also the NOAA website has the option to download to geoTIFF which I would recommend if you are more comfortable with that.
require(raster)
require(ncdf4)
require(maptools)
data(wrld_simpl)
us_shp=wrld_simpl[which(wrld_simpl$NAME=="United States"),]
rs=raster::brick("./nws_precip_1day_20200509_netcdf/nws_precip_1day_20200509_conus.nc",varname="observation")[[1]]
rs#crs ##note already has a crs associated with it
+proj=stere +lat_0=90 +lat_ts=60 +lon_0=-105 +x_0=0 +y_0=0 +a=6371200
+b=6371200 +units=m +no_defs
##assign the pixels with -10000 to NA.
NAvalue(rs) = -10000
##reproject to longlat WGS84
rs=projectRaster(rs,crs=crs(us_shp))
plot(rs,col=rainbow(100))
lines(us_shp)
##note the data extends outside the bounds of country
##use mask to remove data that is not over the land area
rs=mask(rs,us_shp)
plot(rs,col=rainbow(100)
lines(us_shp)
Note that the maximum value of rs changed from 7.8 to 7.0 due to the bilinear interpolation method used in projectRaster. You need to consider whether you require bilinear or nearest neighbour interpolation and if you need to be specific about the output raster resolution and extent I would suggest supplying a model raster for the to argument.
Edited to incorporate #Robert Hijmans' suggestion.
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)