Spatial data: OSM_Notes
1 Set-up
Note updated on 2022-08-27 from index.rmarkdown with knitr version 1.39.
These notes make use of the following R packages and general set-up.
Code
if (!require("pacman")) {
install.packages("pacman")
}
pacman::p_load(tidyverse
,tidylog
,Cairo
,here
,dplyr
,crsuggest # Suggest CRS information for spatial data
,ggplot2
,ggnewscale # For multiple fill and colour scales in ggplot2
,ggsn # North Symbols and Scale Bars for Maps
,osmdata # For downloading and using data from OSM
,sf # DONT'T FORGET uses the s2geometry library
,tmap # For creating thematic maps
,leaflet # JavaScript libraries for interactive maps
,leafem # Extensions for leaflet
,simplevis # Leaflet and ggplot2 functions wrapper
,knitr
,rvest # For Web scrapping
,DT # R interface to the JavaScript library DataTables
,ragg # Graphic devices based on the AGG library
,downlit # For syntax highlighting and automatic linking
,git2r # Provides access to 'Git' repositories
,xfun # For alternative Session Info
)
#pacman::p_update() # Update out-of-date packages
options(scipen = 100, digits = 2) # Prefer non-scientific notation
knitr::opts_chunk$set( dev = "ragg_png"
,fig.path = "Figs/"
,dpi = 600
,fig.width = 10
,fig.hight = 12
# Automatically formatting code using styler
,tidy = "styler"
)
2 Obtaining data
Using osmdata
package you can download data from OSM. Consider that this package provides access to vector data while the OpenStreetMap
package to raster tiles. For more information about OpenStreetMap
see here.
Code
Lima <-
getbb("Lima Metropolitana") |> # obtaining boundaries
opq(timeout = 20 * 100) |> # overpass query
add_osm_feature( # retrieve administrative boundaries
key = "admin_level",
value = "5" # boundary box at the met level
) |>
osmdata_sf() # import as an sf object
Dowloaded data timestamp: [ sáb. 7 Ago 2022 20:26:09 ].
3 Obtaining boundaries
suggest_crs()
from the crsuggest package returns the top 10 matches for a given input spatial dataset enabeling to browse the returned CRS option and use the EPSG/proj4string codes in your analysis. This package is usefull for customizing arguments (gcs and measurement units) as guessing the CRS of a dataset without projection information.
Consider also that the st_crs
function allows the following:
st_crs(new_vector)$IsGeographic
# Checks if CRS is geographic or not st_crs(new_vector)$units_gdal
# Finds out the CRS units st_crs(new_vector)$srid
#Extracts its ‘SRID’ identifier st_crs(new_vector)$proj4string
# Extracts the proj-string representation
Code
possible_crs <- suggest_crs(Lima_multipolygons)
kable(head(possible_crs, "simple"))
crs_code | crs_name | crs_type | crs_gcs | crs_units | crs_proj4 |
---|---|---|---|---|---|
5387 | Peru96 / UTM zone 18S | projected | 5373 | m | +proj=utm +zone=18 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs |
24892 | PSAD56 / Peru central zone | projected | 4248 | m | +proj=tmerc +lat_0=-9.5 +lon_0=-76 +k=0.99932994 +x_0=720000 +y_0=1039979.159 +ellps=intl +towgs84=-279,175,-379,0,0,0,0 +units=m +no_defs |
24878 | PSAD56 / UTM zone 18S | projected | 4248 | m | +proj=utm +zone=18 +south +ellps=intl +units=m +no_defs |
29188 | SAD69 / UTM zone 18S | projected | 4618 | m | +proj=utm +zone=18 +south +ellps=aust_SA +towgs84=-57,1,-41,0,0,0,0 +units=m +no_defs |
31993 | SIRGAS 1995 / UTM zone 18S | projected | 4170 | m | +proj=utm +zone=18 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs |
31978 | SIRGAS 2000 / UTM zone 18S | projected | 4674 | m | +proj=utm +zone=18 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs |
32718 | WGS 84 / UTM zone 18S | projected | 4326 | m | +proj=utm +zone=18 +south +datum=WGS84 +units=m +no_defs |
32518 | WGS 72BE / UTM zone 18S | projected | 4324 | m | +proj=utm +zone=18 +south +ellps=WGS72 +towgs84=0,0,1.9,0,0,0.814,-0.38 +units=m +no_defs |
32318 | WGS 72 / UTM zone 18S | projected | 4322 | m | +proj=utm +zone=18 +south +ellps=WGS72 +towgs84=0,0,4.5,0,0,0.554,0.2263 +units=m +no_defs |
6932 | WGS 84 / NSIDC EASE-Grid 2.0 South | projected | 4326 | m | +proj=laea +lat_0=-90 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs |
Now we can covert the GIS coordinates to CRS using st_transform
Code
# convert the GIS coordinates to CRS
Lima_multipolygons <- st_transform(Lima_multipolygons, "EPSG:24892")
Lima_multipolygons
sf [1, 1]
active geometry column: geometry (MULTIPOLYGON)
crs: 24892 (PSAD56 / Peru central zone)
crs unit: metre
geometry sfc MPOLY 181.49kB
See OPQ for explanation of timeout and memsize (or maxsize in overpass terms). See ESPG codes on spatialreference.org. See nominatim for admin_level keys. Search for feature in the following table.
Code
page <- read_html("https://wiki.openstreetmap.org/wiki/Map_features")
features_list <- html_nodes(page, css = ".toctext") |>
html_text2() |>
as.data.frame() |>
rename(feature = starts_with("html"))
datatable(features_list,
options = list(
searchHighlight = TRUE,
dom = "ltipr" # Deactivate search box
),
filter = "top" # Deactivate search box
, selection = "multiple" # Deactivate search box
, escape = FALSE # Deactivate search box
, width = "300px"
)
In order to select Features there is a list available with 114 features, as shown in @OSM_features. We can also use the available_features( )
function that returns a list of available OSM features that have different tags.
Lets map the boundaries of the selected city.
4 Adding data: Streets, buildings, and population density
Code
roads <-
getbb("Lima Metropolitana") %>%
opq(timeout = 20 * 110) %>%
add_osm_feature( # requesting features related to highway
key = "highway",
value = c(
"trunk",
"primary",
"secondary"
# ,"tertiary"
)
) %>%
osmdata_sf()
Code
roads_sf <- roads |>
(\(x) osm_lines(x, x$osm_lines$osm_id))() |>
# which means using other type of geometry
dplyr::select(geometry) |>
st_transform("EPSG:24892") |>
st_intersection(Lima_multipolygons) |> # only highways in the city
dplyr::filter(st_is(geometry, c("LINESTRING"))) # assure only line geometry
Code
buildings_sf <-
getbb("Lima Metropolitana") |>
opq(timeout = 20 * 100) |>
add_osm_feature(
key = "building",
value = c(
# Accommodation
"apartments", "house", "residential"
# Commercial
, "commercial", "office", "retail", "supermarket"
# Religious
, "cathedral", "church"
# Civic/amenity
, "civic", "college", "government", " hospital", "public", "transportation", "university"
# Other buildings
, "bridge"
)
) |>
osmdata_sf()
buildings_sf <- buildings_sf |>
(\(x) osm_polygons(x, x$osm_polygons$osm_id))() |>
dplyr::select(geometry) |>
st_transform("EPSG:24892") |>
st_intersection(Lima_multipolygons)
For obtaining population data we use data from the National Institute of Statistics and Informatics (INEI, 2018).
Code
shp <- read_sf(here("data", "EstratoLimaMetropolitanashp.shp"))
shp <- st_transform(shp, "EPSG:24892") # Extra care is needed with the ESRI shapefile format, because WKT1 does not store axis order unambiguously.
st_layers(dsn = here("data", "EstratoLimaMetropolitanashp.shp"), do_count = TRUE)$name # Displays list of layers
[1] "EstratoLimaMetropolitanashp"
Population data is in geodetic CRS, we need to transform this data to Projected CRS. More details about the difference between these systems here.
Code
population_sf <- shp |>
st_intersection(Lima_multipolygons)
4.1 Tilting sf objects
Following Stefan Jünger we will tilt each sf object by:
- Displace each point in a fixed direction, by an amount proportional to its signed distance from the line that is parallel to that direction and goes through the origin (plane angle), while preserving the size of the area (shearing),
- rotate each plane / layer, and
- offset x and y axis.
We will apply this by using the following formula:
\[ \underbrace{\begin{bmatrix} x & y \end{bmatrix}}_\text{Coordinates} \times \underbrace{\begin{bmatrix} 1 & 0 \\ 1.2 & 1 \end{bmatrix}}_{(1)} \times \underbrace{\begin{bmatrix} \cos(\pi/20) & \sin(\pi/20)\\-\sin(\pi/20) & \cos(\pi/20) \end{bmatrix}}_{(2)} + \underbrace{\begin{bmatrix} x\_add & y\_add \end{bmatrix}}_{(3)} \]
Function to tilt sf objects code by Stefan Jünger. Consider that \(\pi/20 = 9^\circ\) and that \(\cos(\pi/20) \approx 0.987\) width and \(\sin(\pi/20) \approx 0.156\) height in an unit circle.
Code
rotate_sf <- function(data, x_add = 0, y_add = 0) {
shear_matrix <- function() {
matrix(c(2, 1.2, 0, 1), 2, 2)
}
rotate_matrix <- function(x) {
matrix(c(cos(x), sin(x), -sin(x), cos(x)), 2, 2)
}
data %>%
dplyr::mutate(
geometry =
.$geometry * shear_matrix() * rotate_matrix(pi / 20) + c(x_add, y_add)
)
}
5 Visualize data with ggplot2, tmap and leaflet
Code
# Parameters, plot 1st with coordinates and retrieve x and initial y values
x <- 2320000
# Set label text and colour
text_0 <- paste0("Main roads")
text_1 <- paste0("Buildings footprint")
text_2 <- paste0("Population at block-level")
text_3 <- paste0("Socio-economic strata \n by income pc of households")
label_col <- "#286ce6"
# Plot tilted layers
ggplot() +
#-----------First layer includes borders and roads---------------#
geom_sf(
data = Lima_multipolygons |> rotate_sf(),
fill = NA
) +
geom_sf(data = roads_sf |> rotate_sf()) +
annotate("text",
label = text_0,
x = x, y = 420000, hjust = 0, color = label_col
) +
labs(caption = "Visualization by @Andrei-WongE") +
#-----------Second layer includes borders and buildings----------#
geom_sf(
data = Lima_multipolygons |> rotate_sf(y_add = 100000),
fill = NA
) +
geom_sf(data = rotate_sf(buildings_sf, y_add = 100000)) +
annotate("text",
label = text_1,
x = x, y = 520000, hjust = 0, color = label_col
) +
#-----------Third layer includes population---------------------#
geom_sf(
data = Lima_multipolygons |> rotate_sf(y_add = 200000),
fill = NA
) +
geom_sf(
data = subset(population_sf, POB > 0) |> rotate_sf(y_add = 200000),
aes(
fill = POB,
alpha = .7
),
color = NA
) +
scale_fill_viridis_c(option = "E", guide = "none") + # E = cividis
annotate("text",
label = text_2,
x = x, y = 620000, hjust = 0, color = label_col
) +
# theme(legend.position = "none"
# , plot.caption = element_text(hjust = 0.5)) + #Centre align caption
# ggsn::blank()
#-----------Fourth layer includes socio-economic strata--------#
new_scale_fill() +
new_scale_color() +
geom_sf(
data = Lima_multipolygons |> rotate_sf(y_add = 300000),
fill = NA
) +
geom_sf(
data = subset(population_sf, POB > 0) |> rotate_sf(y_add = 300000),
aes(
fill = ESTR_INGPE,
alpha = .7
),
color = NA
) +
scale_fill_viridis_c(option = "A", guide = "none") + # A = magma
annotate("text",
label = text_3,
x = x, y = 720000, hjust = 0, color = label_col
) +
coord_sf(clip = "off") + # Keeps the annotation from disappearing
theme(
legend.position = "none",
plot.caption = element_text(hjust = 0.5)
) + # Centre align caption
ggsn::blank()
I will use simplevis
, a leaflet and ggplot2 wrapper, to integrate both functions and apply it on a sf object.
Using leaflet.minicharts to add and update small charts on an interactive maps created with the leaflet package
. First I create a basemap
For other zoom/pan options see here.
I add to the base map a pie chart for each district that represents the share of XXXXXX. We need to change the width of the pie chart so their area is proportional to the total XXXXX of the corresponding district.
As Spacedman mentions: While tiles must be in the same projection as used in the leafletCRS function, you must always use WGS 84 longitude/latitude data for markers, circles, polygons, and lines. Leaflet will automatically project the coordinates when displaying.
You should only use leafletCRS if your tiles are in a different coordinate system. The standard OSM ones – and most others – are in EPSG:3857 and so that’s the default.
Code
# Upload data
addr.geo_added <- read_csv(here("data", "addr_geo.csv"),
col_names = TRUE
)
icons <- awesomeIcons(
icon = "ios-close",
iconColor = "black",
library = "ion",
# markerColor = getColor(addr.geo)
)
# Create map
basemap <- leaflet(addr.geo_added) |>
addTiles() |>
addProviderTiles(providers$Stamen.Toner) |>
addAwesomeMarkers(
lng = ~lon, lat = ~lat,
popup = ~id,
icon = icons
)
basemap
Bars
6 Appendix
All code for this report
Code
knitted_when <- format(Sys.Date())
knitted_where <- knitr::current_input()
knitted_with <- packageVersion("knitr")
knitted_doc_url <- downlit::autolink_url("knitr::knit()")
if (!require("pacman")) {
install.packages("pacman")
}
pacman::p_load(
tidyverse,
tidylog,
Cairo,
here,
dplyr,
crsuggest # Suggest CRS information for spatial data
, ggplot2,
ggnewscale # For multiple fill and colour scales in ggplot2
, ggsn # North Symbols and Scale Bars for Maps
, osmdata # For downloading and using data from OSM
, sf # DONT'T FORGET uses the s2geometry library
, tmap # For creating thematic maps
, leaflet # JavaScript libraries for interactive maps
, leafem # Extensions for leaflet
, simplevis # Leaflet and ggplot2 functions wrapper
, knitr,
rvest # For Web scrapping
, DT # R interface to the JavaScript library DataTables
, ragg # Graphic devices based on the AGG library
, downlit # For syntax highlighting and automatic linking
, git2r # Provides access to 'Git' repositories
, xfun # For alternative Session Info
)
# pacman::p_update() # Update out-of-date packages
options(scipen = 100, digits = 2) # Prefer non-scientific notation
knitr::opts_chunk$set(
dev = "ragg_png",
fig.path = "Figs/",
dpi = 600,
fig.width = 10,
fig.hight = 12
# Automatically formatting code using styler
, tidy = "styler"
)
Lima <-
getbb("Lima Metropolitana") |> # obtaining boundaries
opq(timeout = 20 * 100) |> # overpass query
add_osm_feature( # retrieve administrative boundaries
key = "admin_level",
value = "5" # boundary box at the met level
) |>
osmdata_sf() # import as an sf object
Lima_multipolygons <- Lima |>
(\(x) osm_multipolygons(x, x$osm_polygons$osm_id))() |> # extracting polygons
dplyr::filter(name == "Lima Metropolitana") |> # only at specific city level
dplyr::select(geometry)
possible_crs <- suggest_crs(Lima_multipolygons)
kable(head(possible_crs, "simple"))
# convert the GIS coordinates to CRS
Lima_multipolygons <- st_transform(Lima_multipolygons, "EPSG:24892")
Lima_multipolygons
page <- read_html("https://wiki.openstreetmap.org/wiki/Map_features")
features_list <- html_nodes(page, css = ".toctext") |>
html_text2() |>
as.data.frame() |>
rename(feature = starts_with("html"))
datatable(features_list,
options = list(
searchHighlight = TRUE,
dom = "ltipr" # Deactivate search box
),
filter = "top" # Deactivate search box
, selection = "multiple" # Deactivate search box
, escape = FALSE # Deactivate search box
, width = "300px"
)
ggplot(Lima_multipolygons, fill = NA) +
geom_sf() +
ggsn::blank()
roads <-
getbb("Lima Metropolitana") %>%
opq(timeout = 20 * 110) %>%
add_osm_feature( # requesting features related to highway
key = "highway",
value = c(
"trunk",
"primary",
"secondary"
# ,"tertiary"
)
) %>%
osmdata_sf()
roads_sf <- roads |>
(\(x) osm_lines(x, x$osm_lines$osm_id))() |>
# which means using other type of geometry
dplyr::select(geometry) |>
st_transform("EPSG:24892") |>
st_intersection(Lima_multipolygons) |> # only highways in the city
dplyr::filter(st_is(geometry, c("LINESTRING"))) # assure only line geometry
ggplot() +
#---The layer added later will come on top of the preceding layers---#
geom_sf(data = Lima_multipolygons) +
geom_sf(data = roads_sf) +
ggsn::blank()
buildings_sf <-
getbb("Lima Metropolitana") |>
opq(timeout = 20 * 100) |>
add_osm_feature(
key = "building",
value = c(
# Accommodation
"apartments", "house", "residential"
# Commercial
, "commercial", "office", "retail", "supermarket"
# Religious
, "cathedral", "church"
# Civic/amenity
, "civic", "college", "government", " hospital", "public", "transportation", "university"
# Other buildings
, "bridge"
)
) |>
osmdata_sf()
buildings_sf <- buildings_sf |>
(\(x) osm_polygons(x, x$osm_polygons$osm_id))() |>
dplyr::select(geometry) |>
st_transform("EPSG:24892") |>
st_intersection(Lima_multipolygons)
ggplot() +
#---The layer added later will come on top of the preceding layers---#
geom_sf(data = Lima_multipolygons) +
geom_sf(data = buildings_sf) +
ggsn::blank()
shp <- read_sf(here("data", "EstratoLimaMetropolitanashp.shp"))
shp <- st_transform(shp, "EPSG:24892") # Extra care is needed with the ESRI shapefile format, because WKT1 does not store axis order unambiguously.
st_layers(dsn = here("data", "EstratoLimaMetropolitanashp.shp"), do_count = TRUE)$name # Displays list of layers
population_sf <- shp |>
st_intersection(Lima_multipolygons)
ggplot() +
#---The layer added later will come on top of the preceding layers---#
geom_sf(data = Lima_multipolygons) +
geom_sf(data = subset(population_sf, POB > 0), aes(fill = POB)) +
ggsn::blank()
rotate_sf <- function(data, x_add = 0, y_add = 0) {
shear_matrix <- function() {
matrix(c(2, 1.2, 0, 1), 2, 2)
}
rotate_matrix <- function(x) {
matrix(c(cos(x), sin(x), -sin(x), cos(x)), 2, 2)
}
data %>%
dplyr::mutate(
geometry =
.$geometry * shear_matrix() * rotate_matrix(pi / 20) + c(x_add, y_add)
)
}
# Parameters, plot 1st with coordinates and retrieve x and initial y values
x <- 2320000
# Set label text and colour
text_0 <- paste0("Main roads")
text_1 <- paste0("Buildings footprint")
text_2 <- paste0("Population at block-level")
text_3 <- paste0("Socio-economic strata \n by income pc of households")
label_col <- "#286ce6"
# Plot tilted layers
ggplot() +
#-----------First layer includes borders and roads---------------#
geom_sf(
data = Lima_multipolygons |> rotate_sf(),
fill = NA
) +
geom_sf(data = roads_sf |> rotate_sf()) +
annotate("text",
label = text_0,
x = x, y = 420000, hjust = 0, color = label_col
) +
labs(caption = "Visualization by @Andrei-WongE") +
#-----------Second layer includes borders and buildings----------#
geom_sf(
data = Lima_multipolygons |> rotate_sf(y_add = 100000),
fill = NA
) +
geom_sf(data = rotate_sf(buildings_sf, y_add = 100000)) +
annotate("text",
label = text_1,
x = x, y = 520000, hjust = 0, color = label_col
) +
#-----------Third layer includes population---------------------#
geom_sf(
data = Lima_multipolygons |> rotate_sf(y_add = 200000),
fill = NA
) +
geom_sf(
data = subset(population_sf, POB > 0) |> rotate_sf(y_add = 200000),
aes(
fill = POB,
alpha = .7
),
color = NA
) +
scale_fill_viridis_c(option = "E", guide = "none") + # E = cividis
annotate("text",
label = text_2,
x = x, y = 620000, hjust = 0, color = label_col
) +
# theme(legend.position = "none"
# , plot.caption = element_text(hjust = 0.5)) + #Centre align caption
# ggsn::blank()
#-----------Fourth layer includes socio-economic strata--------#
new_scale_fill() +
new_scale_color() +
geom_sf(
data = Lima_multipolygons |> rotate_sf(y_add = 300000),
fill = NA
) +
geom_sf(
data = subset(population_sf, POB > 0) |> rotate_sf(y_add = 300000),
aes(
fill = ESTR_INGPE,
alpha = .7
),
color = NA
) +
scale_fill_viridis_c(option = "A", guide = "none") + # A = magma
annotate("text",
label = text_3,
x = x, y = 720000, hjust = 0, color = label_col
) +
coord_sf(clip = "off") + # Keeps the annotation from disappearing
theme(
legend.position = "none",
plot.caption = element_text(hjust = 0.5)
) + # Centre align caption
ggsn::blank()
# Upload data
addr.geo_added <- read_csv(here("data", "addr_geo.csv"),
col_names = TRUE
)
icons <- awesomeIcons(
icon = "ios-close",
iconColor = "black",
library = "ion",
# markerColor = getColor(addr.geo)
)
# Create map
basemap <- leaflet(addr.geo_added) |>
addTiles() |>
addProviderTiles(providers$Stamen.Toner) |>
addAwesomeMarkers(
lng = ~lon, lat = ~lat,
popup = ~id,
icon = icons
)
basemap
## Datetime
Sys.time()
## Repository
git2r::repository()
## session info
xfun::session_info()
Reproducibility receipt
[1] "2022-08-27 16:28:04 -05"
Local: origin D:/Documents/R/R_projects/OSM_Lima
Remote: origin @ origin (https://github.com/Andrei-WongE/Spatial_notes.git)
Head: [64b33e3] 2022-08-27: Added leaflet and tmap sections
R version 4.2.1 (2022-06-23 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19044)
Locale:
LC_COLLATE=Spanish_Peru.utf8 LC_CTYPE=Spanish_Peru.utf8
LC_MONETARY=Spanish_Peru.utf8 LC_NUMERIC=C
LC_TIME=Spanish_Peru.utf8
Package version:
abind_1.4-5 askpass_1.1 assertthat_0.2.1
backports_1.4.1 base64enc_0.1-3 bit_4.0.4
bit64_4.0.5 bitops_1.0-7 blob_1.2.3
brew_1.0.7 brio_1.1.3 broom_0.8.0
bslib_0.3.1 cachem_1.0.6 Cairo_1.5-15
callr_3.7.0 cellranger_1.1.0 class_7.3-20
classInt_0.4-7 cli_3.3.0 clipr_0.8.0
clisymbols_1.2.0 codetools_0.2-18 colorspace_2.0-3
commonmark_1.8.0 compiler_4.2.1 cpp11_0.4.2
crayon_1.5.1 crosstalk_1.2.0 crsmeta_0.3.0
crsuggest_0.3.1 curl_4.3.2 data.table_1.14.2
DBI_1.1.3 dbplyr_2.2.0 desc_1.4.1
dichromat_2.0-0.1 digest_0.6.29 downlit_0.4.0
dplyr_1.0.9 DT_0.23 dtplyr_1.2.1
e1071_1.7-11 ellipsis_0.3.2 evaluate_0.15
fansi_1.0.3 farver_2.1.0 fastmap_1.1.0
fontawesome_0.3.0 forcats_0.5.1 foreign_0.8-82
fs_1.5.2 gargle_1.2.0 generics_0.1.2
geojsonsf_2.0.3 geometries_0.2.0 ggmap_3.0.0
ggnewscale_0.4.7 ggplot2_3.3.6 ggsn_0.5.0
git2r_0.30.1 glue_1.6.2 googledrive_2.0.0
googlesheets4_1.0.0 graphics_4.2.1 grDevices_4.2.1
grid_4.2.1 gridExtra_2.3 gtable_0.3.0
haven_2.5.0 here_1.0.1 highr_0.9
hms_1.1.1 htmltools_0.5.2 htmlwidgets_1.5.4
httpuv_1.6.5 httr_1.4.3 httr2_0.2.1
ids_1.0.1 isoband_0.2.5 jpeg_0.1-9
jquerylib_0.1.4 jsonify_1.2.1 jsonlite_1.8.0
KernSmooth_2.23-20 keypress_1.2.0 knitr_1.39
labeling_0.4.2 later_1.3.0 lattice_0.20-45
lazyeval_0.2.2 leafem_0.2.0 leaflet_2.1.1
leaflet.providers_1.9.0 leafpop_0.1.0 leafsync_0.1.0
lifecycle_1.0.1 lobstr_1.1.2 lubridate_1.8.0
lwgeom_0.2-8 magrittr_2.0.3 maptools_1.1-4
mapview_2.11.0 markdown_1.1 MASS_7.3.57
Matrix_1.4.1 memoise_2.0.1 methods_4.2.1
mgcv_1.8.40 mime_0.12 modelr_0.1.8
munsell_0.5.0 nlme_3.1.158 openssl_2.0.2
osmdata_0.1.10 pacman_0.5.1 paint_0.1.5
parallel_4.2.1 pillar_1.7.0 pkgconfig_2.0.3
plotly_4.10.0 plyr_1.8.7 png_0.1-7
prettyunits_1.1.1 processx_3.6.1 progress_1.2.2
PROJ_0.4.0 proj4_1.0.11 promises_1.2.0.1
proxy_0.4-27 pryr_0.1.5 ps_1.7.1
purrr_0.3.4 R.cache_0.16.0 R.methodsS3_1.8.2
R.oo_1.25.0 R.utils_2.12.0 R6_2.5.1
ragg_1.2.2 rapidjsonr_1.2.0 rappdirs_0.3.3
raster_3.5-15 RColorBrewer_1.1-3 Rcpp_1.0.9
readr_2.1.2 readxl_1.4.0 rematch_1.0.1
rematch2_2.1.2 remotes_2.4.2 renv_0.15.5
reprex_2.0.1 reproj_0.4.2 RgoogleMaps_1.4.5.3
rjson_0.2.21 rlang_1.0.4 rmarkdown_2.14
rprojroot_2.0.3 rstudioapi_0.13 rvest_1.0.2
s2_1.0.7 santoku_0.8.0 sass_0.4.1
satellite_1.0.4 scales_1.2.0 selectr_0.4-2
servr_0.24 sf_1.0-7 sfheaders_0.4.0
shiny_1.7.2 simplevis_6.4.0 snakecase_0.11.0
sourcetools_0.1.7 sp_1.5-0 splines_4.2.1
stars_0.5-5 stats_4.2.1 stats4_4.2.1
stringi_1.7.6 stringr_1.4.0 styler_1.7.0
svglite_2.1.0 sys_3.4 systemfonts_1.0.4
terra_1.5-34 textshaping_0.3.6 tibble_3.1.8
tidylog_1.0.2 tidyr_1.2.0 tidyselect_1.1.2
tidyverse_1.3.1 tinytex_0.40 tmap_3.3-3
tmaptools_3.1-1 tools_4.2.1 tzdb_0.3.0
units_0.8-0 utf8_1.2.2 utils_4.2.1
uuid_1.1.0 vctrs_0.4.1 viridis_0.6.2
viridisLite_0.4.0 vroom_1.5.7 webshot_0.5.3
widgetframe_0.3.1 withr_2.5.0 wk_0.6.0
xfun_0.31 XML_3.99-0.10 xml2_1.3.3
xtable_1.8.4 yaml_2.3.5
DRAFT
Citation
@misc{wong](https://github.com/andrei-wonge)2022,
author = {{[}Andrei Wong{]}(https://github.com/Andrei-WongE)},
editor = {},
title = {Spatial Data: {OSM\_Notes}},
date = {2022-06-01},
url = {https://andrei-wonge.github.io/Spatial_notes/},
langid = {en}
}