SHOW:
|
|
- or go back to the newest paste.
1 | ################################################################################ | |
2 | ### This script takes state/county shapefiles from the Census Bureau, and moves | |
3 | ### Alaska, Hawaii, Puerto Rico, US Virgin Islands, Guam, Samoa, and the Mariana | |
4 | ### Islands to be just under the continental US. This format is very useful for | |
5 | ### mapping data. | |
6 | ### | |
7 | ### I originally used the "state_laea" and "county_laea" maps from the | |
8 | ### "tidycensus" package, but kept hitting various issues: | |
9 | ### | |
10 | ### 1) The Tidycensus maps are low-resolution, so counties don't look good if | |
11 | ### you zoom in on a particular state | |
12 | ### | |
13 | ### 2) The "Tidycensus" maps are old and require various FIPS mods every time I | |
14 | ### use them, such as changing fips 46113 -> 46102 to handle Oglala Co SD, | |
15 | ### changing fips 02270 -> 02158 to handle Kusilvak Census Area, AK | |
16 | ### | |
17 | ### 3) The Tidycensus map lacked the smaller US territories. | |
18 | ### | |
19 | ### I took inspiration for this script from the URL below: | |
20 | ### | |
21 | ### https://rud.is/b/2014/11/16/moving-the-earth-well-alaska-hawaii-with-r/ | |
22 | ### | |
23 | ### If you find any bugs or issues with the script or with the maps it generates | |
24 | ### please let me know - /u/MetricT | |
25 | ### | |
26 | ### KNOWN BUGS: | |
27 | ### | |
28 | ### * Sourcing the script will cause errors at these lines near the bottom: | |
29 | ### | |
30 | ### > state_map %>% st_as_sf() %>% write_sf(mod_state_map) | |
31 | ### There were 50 or more warnings (use warnings() to see the first 50) | |
32 | ### > county_map %>% st_as_sf() %>% write_sf(mod_county_map) | |
33 | ### There were 50 or more warnings (use warnings() to see the first 50) | |
34 | ### | |
35 | ### Just run them manually at that point and it should work fine. | |
36 | ################################################################################ | |
37 | ||
38 | library(tidyverse) | |
39 | library(maptools) | |
40 | library(mapproj) | |
41 | library(rgeos) | |
42 | library(rgdal) | |
43 | library(RColorBrewer) | |
44 | library(ggplot2) | |
45 | library(sf) | |
46 | ||
47 | ### Path/filename to save modified shapefiles at when we're done | |
48 | mod_state_map <- "../Shapefiles/us_state/us_state.shp" | |
49 | mod_county_map <- "../Shapefiles/us_county/us_county.shp" | |
50 | ||
51 | ### We want our map to use the Albers projection | |
52 | map_crs <- "+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs" | |
53 | #map_crs <- "epsg:5070" | |
54 | ||
55 | state_map <- | |
56 | read_sf("../Shapefiles/cb_2018_us_state_500k/cb_2018_us_state_500k.shp") %>% | |
57 | st_transform(map_crs) %>% | |
58 | as(Class = "Spatial") | |
59 | ||
60 | county_map <- | |
61 | read_sf("../Shapefiles/cb_2018_us_county_500k/cb_2018_us_county_500k.shp") %>% | |
62 | st_transform(map_crs) %>% | |
63 | as(Class = "Spatial") | |
64 | ||
65 | state_map@data$id <- rownames(state_map@data) | |
66 | county_map@data$id <- rownames(county_map@data) | |
67 | ||
68 | ### We want to strip out states/territories that aren't in the continental US | |
69 | ### and move them around to make a more convenient map | |
70 | non_conus_fips <- c("02", "11", "15", "60", "66", "69", "72", "78") | |
71 | ||
72 | ################################################################################ | |
73 | ### Adjust the state-level map | |
74 | ################################################################################ | |
75 | ||
76 | ### Alaska | |
77 | alaska_state <- state_map[state_map$STATEFP=="02",] | |
78 | alaska_state <- elide(alaska_state, rotate=-50) | |
79 | alaska_state <- elide(alaska_state, scale=max(apply(bbox(alaska_state), 1, diff)) / 1.8) | |
80 | alaska_state <- elide(alaska_state, shift=c(-2400000, -2800000)) | |
81 | proj4string(alaska_state) <- proj4string(state_map) | |
82 | ||
83 | ### Hawaii | |
84 | hawaii_state <- state_map[state_map$STATEFP=="15",] | |
85 | hawaii_state <- elide(hawaii_state, rotate=-35) | |
86 | hawaii_state <- elide(hawaii_state, shift=c(5800000, -1900000)) | |
87 | proj4string(hawaii_state) <- proj4string(state_map) | |
88 | ||
89 | ### Puerto Rico | |
90 | puertorico_state <- state_map[state_map$STATEFP=="72",] | |
91 | puertorico_state <- elide(puertorico_state, rotate=+13) | |
92 | puertorico_state <- elide(puertorico_state, scale=max(apply(bbox(puertorico_state), 1, diff)) / 0.5) | |
93 | puertorico_state <- elide(puertorico_state, shift=c(+600000, -2600000)) | |
94 | proj4string(puertorico_state) <- proj4string(state_map) | |
95 | ||
96 | ### US Virgin Islands | |
97 | usvi_state <- state_map[state_map$STATEFP=="78",] | |
98 | usvi_state <- elide(usvi_state, rotate=+13) | |
99 | usvi_state <- elide(usvi_state, scale=max(apply(bbox(usvi_state), 1, diff)) / 0.25) | |
100 | usvi_state <- elide(usvi_state, shift=c(+1500000, -2600000)) | |
101 | proj4string(usvi_state) <- proj4string(state_map) | |
102 | ||
103 | ### Guam | |
104 | guam_state <- state_map[state_map$STATEFP=="66",] | |
105 | guam_state <- elide(guam_state, rotate=-65) | |
106 | guam_state <- elide(guam_state, scale=max(apply(bbox(guam_state), 1, diff)) / 0.15) | |
107 | guam_state <- elide(guam_state, shift=c(+1200000, -3200000)) | |
108 | proj4string(guam_state) <- proj4string(state_map) | |
109 | ||
110 | ### Northern Mariana Islands | |
111 | noma_state <- state_map[state_map$STATEFP=="69",] | |
112 | noma_state <- elide(noma_state, rotate=-55) | |
113 | noma_state <- elide(noma_state, scale=max(apply(bbox(noma_state), 1, diff)) / 0.85) | |
114 | noma_state <- elide(noma_state, shift=c(+300000, -3400000)) | |
115 | proj4string(noma_state) <- proj4string(state_map) | |
116 | ||
117 | ### American Samoa | |
118 | amsam_state <- state_map[state_map$STATEFP=="60",] | |
119 | amsam_state <- elide(amsam_state, rotate=-55) | |
120 | amsam_state <- elide(amsam_state, scale=max(apply(bbox(amsam_state), 1, diff)) / 0.25) | |
121 | amsam_state <- elide(amsam_state, shift=c(-2300000, -3400000)) | |
122 | proj4string(amsam_state) <- proj4string(state_map) | |
123 | ||
124 | ### Add the moved states/territories back to the CONUS map | |
125 | state_map <- state_map[!state_map$STATEFP %in% non_conus_fips,] | |
126 | state_map <- rbind(state_map, | |
127 | alaska_state, | |
128 | hawaii_state, | |
129 | puertorico_state, | |
130 | usvi_state, | |
131 | noma_state, | |
132 | guam_state, | |
133 | amsam_state | |
134 | ) | |
135 | ||
136 | ################################################################################ | |
137 | ### Adjust the county-level map | |
138 | ################################################################################ | |
139 | ||
140 | ### Alaska | |
141 | alaska_county <- county_map[county_map$STATEFP=="02",] | |
142 | alaska_county <- elide(alaska_county, rotate=-50) | |
143 | alaska_county <- elide(alaska_county, scale=max(apply(bbox(alaska_county), 1, diff)) / 1.8) | |
144 | alaska_county <- elide(alaska_county, shift=c(-2400000, -2800000)) | |
145 | proj4string(alaska_county) <- proj4string(county_map) | |
146 | ||
147 | ### Hawaii | |
148 | hawaii_county <- county_map[county_map$STATEFP=="15",] | |
149 | hawaii_county <- elide(hawaii_county, rotate=-35) | |
150 | hawaii_county <- elide(hawaii_county, shift=c(5800000, -1900000)) | |
151 | proj4string(hawaii_county) <- proj4string(county_map) | |
152 | ||
153 | ### Puerto Rico | |
154 | puertorico_county <- county_map[county_map$STATEFP=="72",] | |
155 | puertorico_county <- elide(puertorico_county, rotate=+13) | |
156 | puertorico_county <- elide(puertorico_county, scale=max(apply(bbox(puertorico_county), 1, diff)) / 0.5) | |
157 | puertorico_county <- elide(puertorico_county, shift=c(+600000, -2600000)) | |
158 | proj4string(puertorico_county) <- proj4string(county_map) | |
159 | ||
160 | ### US Virgin Islands | |
161 | usvi_county <- county_map[county_map$STATEFP=="78",] | |
162 | usvi_county <- elide(usvi_county, rotate=+13) | |
163 | usvi_county <- elide(usvi_county, scale=max(apply(bbox(usvi_county), 1, diff)) / 0.25) | |
164 | usvi_county <- elide(usvi_county, shift=c(+1500000, -2600000)) | |
165 | proj4string(usvi_county) <- proj4string(county_map) | |
166 | ||
167 | ### Guam | |
168 | guam_county <- county_map[county_map$STATEFP=="66",] | |
169 | guam_county <- elide(guam_county, rotate=-65) | |
170 | guam_county <- elide(guam_county, scale=max(apply(bbox(guam_county), 1, diff)) / 0.15) | |
171 | guam_county <- elide(guam_county, shift=c(+1200000, -3200000)) | |
172 | proj4string(guam_county) <- proj4string(county_map) | |
173 | ||
174 | ### Northern Mariana Islands | |
175 | noma_county <- county_map[county_map$STATEFP=="69",] | |
176 | noma_county <- elide(noma_county, rotate=-55) | |
177 | noma_county <- elide(noma_county, scale=max(apply(bbox(noma_county), 1, diff)) / 0.85) | |
178 | noma_county <- elide(noma_county, shift=c(+300000, -3400000)) | |
179 | proj4string(noma_county) <- proj4string(county_map) | |
180 | ||
181 | ### American Samoa | |
182 | amsam_county <- county_map[county_map$STATEFP=="60",] | |
183 | amsam_county <- elide(amsam_county, rotate=-55) | |
184 | amsam_county <- elide(amsam_county, scale=max(apply(bbox(amsam_county), 1, diff)) / 0.25) | |
185 | amsam_county <- elide(amsam_county, shift=c(-2300000, -3400000)) | |
186 | proj4string(amsam_county) <- proj4string(county_map) | |
187 | ||
188 | ### Add the moved states/territories back to the CONUS map | |
189 | county_map <- county_map[!county_map$STATEFP %in% non_conus_fips,] | |
190 | county_map <- rbind(county_map, | |
191 | alaska_county, | |
192 | hawaii_county, | |
193 | puertorico_county, | |
194 | usvi_county, | |
195 | noma_county, | |
196 | guam_county, | |
197 | amsam_county | |
198 | ) | |
199 | ||
200 | ################################################################################ | |
201 | ### Save maps, reload, and graph to make sure it worked ok | |
202 | ############################################################################### | |
203 | ||
204 | ### Save modified maps to new shapefile | |
205 | state_map %>% st_as_sf() %>% write_sf(mod_state_map) | |
206 | county_map %>% st_as_sf() %>% write_sf(mod_county_map) | |
207 | ||
208 | ### Load our newly created maps | |
209 | state_map <- read_sf(mod_state_map) | |
210 | county_map <- read_sf(mod_county_map) | |
211 | ||
212 | ### Overlay the state/county maps so we can verify that the map looks correct | |
213 | ggplot() + | |
214 | theme_void() + | |
215 | geom_sf(data = county_map, size = 0.1) + | |
216 | geom_sf(data = state_map, size = 0.6, fill = NA) |