Shapefile with multiple shapes but only one polygon - r

I am using the "King County with Natural Shoreline for Puget Sound and Lake Washington" shapefile from http://www5.kingcounty.gov/gisdataportal/. The outline for Lake Washington appears when I plot the shapefile but is not saved as an additional polygon relative to the outline of King County. I wish to color Lake Washington a different color to the rest of the county but am not sure how to do this because the shapefile only has 1 feature. I am trying to manipulate the shapefile in R.

You can extract the "hole" that is Lake Washington and then add that to the plot. This uses base graphics but it's just as easy with ggplot.
library(rgdal)
# your shapefile
kc <- readOGR("kingsh/kingsh.shp", "kingsh")
# extract the singular hole that is Lake Washington and
# make it into something plottable
lw <- SpatialPolygons(list(Polygons(list(kc#polygons[[1]]#Polygons[[2]]), ID="lw")))
plot(kc, col="steelblue")
plot(lw, col="maroon", add=TRUE)
You can find the hole by manually scanning the objects or something like:
unlist(lapply(kc#polygons, function(p) {
polys <- slot(p, "Polygons")
lapply(polys, function(q) {
slot(q, "hole")
})
}))
I had to guess at how you're reading it in since you didn't provide any code.

Related

How to extract New Mexico state from USA boundaries package in R

I am trying to make a Tmap with two points but I am having some issues.
`library(tmap)
library(maps)
library(sf)
library(USAboundaries)
#Open soil pit location data
data<-read.csv("SoilPit_Locations___.csv")
#Converting locations to an sf object
points<-st_as_sf(data,coords=c("Longitude","Latitude"),crs=4326)
#Set up map mode as view for an interactive map
tmap_mode("plot")
#Set up style as natural to view topography
tmap_style("natural")
#Map us borders and add points for locations as dots
#tm_shape(us) + tm_borders("black", lwd = .5) +
m=tm_shape(points)+tm_dots()
m
tmap_save(m, "my_mapp.png")`
The issue I am having is that when I try run my code the two points are on the corners of the map, I would like to plot them on the New Mexico state map so they can look nicer.
I have tried extracting the NM state boundary from the world map but I have been unsuccessful.
If you do:
library(USAboundariesData)
then you get states_contemporary_lores (amongst other things) which are the USA state boundaries, so you can subset NM like this:
nm = states_contemporary_lores[
states_contemporary_lores$state_abbr=="NM",
]
and then nm is an sf object which is just New Mexico. You can map this in tmap using tm_shape(nm) + tm_borders() and then adding whatever other layers you have.

Is it possible to create a map of the UK counties with the packages spData/tmap

I have recently used the package spData for plotting the London boroughs but I haven't found anything for plotting the counties in the UK.
Is it possible the the package spData contains only a few countries in it?
Thank you for your help,
Andrea
Could this be what you are looking for? A shp of the counties?
spData isn't a complete set of world spatial data.
You can find a complete set (with good county shapes) in the Natural Earth 10m (high resolution) cultural vectors. Here's how I was able to make a quick map of UK counties, coloured by the length of the county name:
library("tmap")
library("tmaptools")
library("rnaturalearth")
library("rnaturalearthhires")
library("sf")
data("states10")
uk_counties <- states10[which(states10$iso_a2 =="GB"),]
uk_counties = st_as_sf(uk_counties)
qtm(uk_counties, fill="name_len")
Once you have this dataframe called uk_counties, you can join it to your data & quickly make some nice maps.
choropleth of uk counties by length of county name

Extract BC census shapefile

I have downloaded the Canada census level polygon shapefiles strong text (https://www12.statcan.gc.ca/census-recensement/2011/geo/bound-limit/bound-limit-2011-eng.cfm) and imported into R using readOGR function from rgdal package.
However, I am struggling to extract the shapefiles specifically from British Columbia. I have used some of the previous explanations to extract my US state zip codes with success (Choropleth Maps in R - TIGER Shapefile issue).
I need assistance in extracting the BC shapefiles.
I don't know which Geographic area or water feature you have selected from that website. I have downloaded the Digital Boundary File of Provinces/territories. I have read and subsetted British Columbia shapefile using following command
library(rgdal)
df <- readOGR(dsn = "C:\\Users\\User\\Desktop\\gpr_000a11a_e", layer = "gpr_000a11a_e")
#To see the data head
head(df#data)
#To see a particular column of the shapefile
df#data$PRENAME
#Subsetting British Columbia from the shapefile
BC = subset(df, PRENAME=="British Columbia")
#Plotting it
plot(BC)

Mapping specific States and Provinces in R

I'm trying to use R to generate a figure with sample localities for my FieldBio project. So far, I've been able to map the US states I want, to map Canada (national border), to overlay these two maps; what I'd like to do, though, is to map the following states/provinces specifically, excluding the others:
California
Nevada
Utah
Colorado
Wyoming
Montana
Idaho
Washington
Oregon
British Columbia
Alberta
Here is the code I've been using so far:
>map('state', region = c('california', 'nevada', 'utah', 'colorado', 'wyoming', 'montana', 'idaho', 'oregon', 'washington'), xlim=c(-130,-90), ylim=c(30,60), fill=TRUE, col="gray95")
>map("worldHires","Canada", xlim=c(-130,-90), ylim=c(30,60), col="gray95", fill=TRUE, add=TRUE)
This produces a map with the desired states, but canada as a country (cut off at the delimitors I set).
Is there a way to do only the provinces I want? I think I know how to plot the points (I have them as a .csv with lat and long data) on top of this afterward.
I realize that (R: creating a map of selected Canadian provinces and U.S. states) is pretty similar, but I'm getting a little lost in the code for that particular example, and I don't need to highlight anything specific.
Thanks
Like this?
library(raster)
states <- c('California', 'Nevada', 'Utah', 'Colorado', 'Wyoming', 'Montana', 'Idaho', 'Oregon', 'Washington')
provinces <- c("British Columbia", "Alberta")
us <- getData("GADM",country="USA",level=1)
canada <- getData("GADM",country="CAN",level=1)
us.states <- us[us$NAME_1 %in% states,]
ca.provinces <- canada[canada$NAME_1 %in% provinces,]
us.bbox <- bbox(us.states)
ca.bbox <- bbox(ca.provinces)
xlim <- c(min(us.bbox[1,1],ca.bbox[1,1]),max(us.bbox[1,2],ca.bbox[1,2]))
ylim <- c(min(us.bbox[2,1],ca.bbox[2,1]),max(us.bbox[2,2],ca.bbox[2,2]))
plot(us.states, xlim=xlim, ylim=ylim)
plot(ca.provinces, xlim=xlim, ylim=ylim, add=T)
So this uses the getData(...) function in package raster to grab the SpatialPolygonDataFrames for US states and Canadian provinces from the GADM site. Then it extracts only the states you want (notice that the relevant attribute table field is NAME_1 and the the states/provinces need to be capitalized properly). Then we calculate the x and y-limits from the bounding boxes of the two (subsetted) maps. Finally we render the maps. Note the use of add=T in the second call to plot(...).
And here's a ggplot solution.
library(ggplot2)
ggplot(us.states,aes(x=long,y=lat,group=group))+
geom_path()+
geom_path(data=ca.provinces)+
coord_map()
The advantage here is that ggplot manages the layers for you, so you don't have to explicitly calculate xlim and ylim. Also, IMO there is much more flexibility in adding additional layers. The disadvantage is that, with high resolution maps such as these (esp the west coast of Canada), it is much slower.

R: creating a map of selected Canadian provinces and U.S. states

I am attempting to create a map of selected Canadian provinces/territories and selected U.S. states. So far the nicest maps appear to be those generated with GADM data: http://www.gadm.org/
However, I have not been able to plot the U.S. and Canada on the same map or plot only selected provinces/territories and states. For example, I am interested in Alaska, Yukon, NWT, British Columbia, Alberta, and Montana among others.
Also, the U.S. map appears to be split along the international dateline.
Can someone please help me to:
plot the aforementioned provinces/territories and states on a single map
avoid having the U.S. split along the International dateline
overlay a latitude-longitude grid
select a specific projection, maybe the polyconic.
Maybe spplot does not allow users to specify projections. I did not see an option to select a projection on the spplot help page. I know how to select projections with the map function in the maps package but those maps did not appear to look as nice and I could not plot the desired subset of provinces/territories and states with that function either.
I do not know how to begin adding a latitude-longitude grid. However, Section 3.2 of the file 'sp.pdf' seems to address the topic.
Below is the code I have come up with so far. I have loaded every map-related package I have stumbled upon and commented out GADM data except for provincial/territorial or state boundaries.
Unfortunately, so far I have only managed to plot maps of Canada or the U.S.
library(maps)
library(mapproj)
library(mapdata)
library(rgeos)
library(maptools)
library(sp)
library(raster)
library(rgdal)
# can0<-getData('GADM', country="CAN", level=0) # Canada
can1<-getData('GADM', country="CAN", level=1) # provinces
# can2<-getData('GADM', country="CAN", level=2) # counties
plot(can1)
spplot(can1, "NAME_1") # colors the provinces and provides
# a color-coded legend for them
can1$NAME_1 # returns names of provinces/territories
# us0 <- getData('GADM', country="USA", level=0)
us1 <- getData('GADM', country="USA", level=1)
# us2 <- getData('GADM', country="USA", level=2)
plot(us1) # state boundaries split at
# the dateline
us1$NAME_1 # returns names of the states + DC
spplot(us1, "ID_1")
spplot(us1, "NAME_1") # color codes states and
# provides their names
#
# Here attempting unsuccessfully to combine U.S. and Canada on one map.
# Attempts at selecting given states or provinces have been unsuccessful.
#
plot(us1,can1)
us.can1 <- rbind(us1,can1)
Thanks for any help. So far I have made no progress with Steps 2 - 4 above. Perhaps I am asking for too much. Perhaps I should simply switch to ArcGIS and try that software.
I have read this StackOverflow post:
Can R be used for GIS?
EDIT
I have now borrowed an electronic copy of 'Applied Spatial Data Analysis with R' Bevand et al. (2008) and downloaded (or located) associated R code and data from the book's website:
http://www.asdar-book.org/
I also found some nice-looking GIS-related R code here:
https://sites.google.com/site/rodriguezsanchezf/news/usingrasagis
If and when I learn how to accomplish the desired objectives I will post solutions here. Although I may eventually move to ArcGIS if I cannot accomplish the objectives in R.
To plot multiple SpatialPolygons objects on the same device, one approach is to specify the geographic extent you wish to plot first, and then using plot(..., add=TRUE). This will add to the map only those points that are of interest.
Plotting using a projection, (e.g. a polyconic projection) requires first using the spTransform() function in the rgdal package to make sure all the layers are in the same projection.
## Specify a geographic extent for the map
## by defining the top-left and bottom-right geographic coordinates
mapExtent <- rbind(c(-156, 80), c(-68, 19))
## Specify the required projection using a proj4 string
## Use http://www.spatialreference.org/ to find the required string
## Polyconic for North America
newProj <- CRS("+proj=poly +lat_0=0 +lon_0=-100 +x_0=0
+y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs")
## Project the map extent (first need to specify that it is longlat)
mapExtentPr <- spTransform(SpatialPoints(mapExtent,
proj4string=CRS("+proj=longlat")),
newProj)
## Project other layers
can1Pr <- spTransform(can1, newProj)
us1Pr <- spTransform(us1, newProj)
## Plot each projected layer, beginning with the projected extent
plot(mapExtentPr, pch=NA)
plot(can1Pr, border="white", col="lightgrey", add=TRUE)
plot(us1Pr, border="white", col="lightgrey", add=TRUE)
Adding other features to the map, such as highlighting jurisdictions of interest, can easily be done using the same approach:
## Highlight provinces and states of interest
theseJurisdictions <- c("British Columbia",
"Yukon",
"Northwest Territories",
"Alberta",
"Montana",
"Alaska")
plot(can1Pr[can1Pr$NAME_1 %in% theseJurisdictions, ], border="white",
col="pink", add=TRUE)
plot(us1Pr[us1Pr$NAME_1 %in% theseJurisdictions, ], border="white",
col="pink", add=TRUE)
Here is the result:
Add grid-lines when a projection is used is sufficiently complex that it requires another post, I think. Looks as if #Mark Miller as added it below!
Below I have modified PaulG's outstanding answer to display a latitude-longitude grid. The grid is coarser than I would like, but might be adequate. I use the United Kingdom with the code below. I do not know how to include the result in this post.
library(rgdal)
library(raster)
# define extent of map area
mapExtent <- rbind(c(0, 62), c(5, 45))
# BNG is British National Grid
newProj <- CRS("+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.999601271625
+x_0=400000 +y_0=-100000 +ellps=airy +units=m +no_defs")
mapExtentPr <- spTransform(SpatialPoints(mapExtent,
proj4string=CRS("+proj=longlat")),
newProj)
# provide a valid 3 letter ISO country code
# obtain a list with: getData("ISO3")
uk0 <- getData('GADM', country="GBR", level=0) # UK
uk1 <- getData('GADM', country="GBR", level=1) # UK countries
uk2 <- getData('GADM', country="GBR", level=2) # UK counties
# United Kingdom projection
uk1Pr <- spTransform(uk1, newProj)
# latitude-longitude grid projection
grd.LL <- gridlines(uk1, ndiscr=100)
lat.longPR <- spTransform(grd.LL, newProj)
# latitude-longitude text projection
grdtxt_LL <- gridat(uk1)
grdtxtPR <- spTransform(grdtxt_LL, newProj)
# plot the map, lat-long grid and grid labels
plot(mapExtentPr, pch=NA)
plot(uk1Pr, border="white", col="lightgrey", add=TRUE)
plot(lat.longPR, col="black", add=TRUE)
text(coordinates(grdtxtPR),
labels=parse(text=as.character(grdtxtPR$labels)))
Result looks like:

Resources