tl;dr
I made Wot3LdnEmojis: a London-only clone of What3Emojis using London-related emojis and very little R code.
Hover over a grid cell to get the emoji-triplet reference. Zoom and pan, change to dark mode, toggle the grid.
U wot m8
By now youβve heard about various βalternativeβ location systems that split the world into a grid and assign each with a value thatβs more human-interpretable than latitude and longitude. For example, Google Plus Codes and What3Words.
The latter has been in the news a lot.1 In the meantime, their product has spawned a raft of spoofs, like the NSFW Four Kings Map, What3Emojis and What2Numbers, lol.2
I like What3Emojis because itβs tongue-in-cheek3, yes, but they also understand the 21st Century mantra that:
No system is perfect, except for emoji.
The What3Emojis code is openly available, but of course I wondered how easy it would be to make something like this in R.
Iβve limited it to London because us Londoners arenβt aware of anything outside of the M25. Read on for the how-to of this obnoxiously-named, cockney-baiting Wot3LdnEmojis system.
Adam βnβ Eve it
First we need to attach the {sf} package for geospatial operations; {leaflet} for interactive mapping; and {tidyverse} for data wrangling. Weβll also set a seed here for reproducible results.4
suppressPackageStartupMessages({
library(sf)
library(leaflet)
library(tidyverse)
})set.seed(9002488)
We can grab the official Greater London boundary from a GeoJSON of geographic units in the UK5, which is served by the Open Geography Portal from the Office for National Statistics.
Or we would, if the site wasnβt down when I went to run this. Instead, we can use the handy JSONs hosted by Martin Chorley on GitHub. Hero.
<- paste0(
nuts_path "https://raw.githubusercontent.com/martinjc/UK-GeoJSON/",
"master/json/eurostat/ew/nuts1.json"
)
<- st_read(nuts_path, quiet = TRUE) %>%
ldn_sf filter(NUTS112NM == "London")
ldn_sf
Simple feature collection with 1 feature and 2 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -0.5102962 ymin: 51.28676 xmax: 0.3339957 ymax: 51.69187
Geodetic CRS: WGS 84
NUTS112CD NUTS112NM geometry
1 UKI London MULTIPOLYGON (((-0.3210316 ...
So, itβs an sf-class object that behaves like a dataframe, but has some extra geospatial information stored in it.
Weβve got the boundary, how do we do a grid?
What3Emojis say they used βgazillions of 4mΓ4m trianglesβ in their grid, but I donβt have the computing power for that and I canβt count that high.
Instead, I bring you low-fidelity, massive hexagons. But hexagons are the patron shape of R users, so I think thatβs okay.
{sf} has st_make_grid()
makes gridding easy. We can pass arguments for size and shape, then st_intersection()
limits the grid to the area inside the London boundary only.
<- ldn_sf %>%
grid_sf st_make_grid(cellsize = 0.01, square = FALSE, flat_topped = TRUE) %>%
st_intersection(ldn_sf)
length(grid_sf)
[1] 2554
Iβve checked the length of the object so we know how many grid cells we need to label uniquely. The fewest number of emoji weβll need is therefore 14, since 14^3 is 2744.
Of course, I have chosen emojis that at least vaguely represent London. Below Iβve added names and commented with my interpretation. Let me know if you have better ideas.
<- c(
ldn_emo metro = "π", # the tube
guard = "π", # Queen's Guard
queen = "πΈ", # HMQE2
castle = "π°", # Tower of London
ferris_wheel = "π‘", # London Eye
bell = "π", # Big Ben (not a clock!)
whale = "π", # Natural History Museum
cityscape = "ποΈ", # Canary Wharf
cucumber = "π₯", # The Gherkin
performing_arts = "π", # Theatre District
stadium = "ποΈ", # Wembley Stadium
dragon = "π", # City of London emblem
bird = "π¦", # pigeon
deciduous_tree = "π³" # London plane tree
)
Depending on your operating system, thereβs a chance you might note be able to see some of these emoji. Oh no! Ah well.
You may also have noticed that itβs utterly ridiculous to use London-related emojis to label locations in London. βWhere are you?β βLondon Eye, London Eye, London Eyeβ. βYouβre at the London Eye?β βNo.β Oh no! Ah well.
Anyway, we can get all three-way combinations of these with expand.grid()
, then shuffle them randomly.
<- expand.grid(
ldn_emo_combo emo_a = ldn_emo, emo_b = ldn_emo, emo_c = ldn_emo
%>%
) sample_n(length(grid_sf)) %>%
transmute(emo_triplet = paste(emo_a, emo_b, emo_c))
$emo_triplet[1:3] ldn_emo_combo
[1] "π ποΈ π³" "π π° π‘" "ποΈ π π₯"
Then itβs a case of adding the emoji information into the grid_sf
object, which can be done via st_df()
.
<- grid_sf %>%
grid_sf_emo st_sf(ldn_emo_combo) %>%
rename(., geometry = .)
head(grid_sf_emo)
Simple feature collection with 6 features and 1 field
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: -0.1289476 ymin: 51.28676 xmax: 0.07882465 ymax: 51.29676
Geodetic CRS: WGS 84
emo_triplet geometry
1 π ποΈ π³ POLYGON ((-0.123496 51.2868...
2 π π° π‘ POLYGON ((-0.114679 51.2917...
3 ποΈ π π₯ POLYGON ((0.06512026 51.290...
4 π¦ π‘ π POLYGON ((0.07882465 51.291...
5 ποΈ π³ π POLYGON ((-0.1149681 51.291...
6 ποΈ ποΈ ποΈ POLYGON ((-0.1003241 51.296...
You can see the triplets have been added as an extra column so thereβs one triplet per grid cell.
Time to create the interactive map with {leaflet}, which is built up in layers.
Iβve added a light and a dark underlying map that you can toggle between6 Iβve also made the hexagons transparent with thin borders to itβs easier to see the map, but you can toggle the grid on and off to help pinpoint a location.
leaflet() %>%
addProviderTiles("CartoDB.Voyager", group = "Light") %>%
addProviderTiles("CartoDB.DarkMatter", group = "Dark") %>%
addPolygons(
data = grid_sf_emo, group = "Grid",
color = "grey", weight = 1, opacity = 0.5,
fill = TRUE, fillOpacity = 0,
label = paste(grid_sf_emo$emo_triplet),
labelOptions = labelOptions(
direction = "top", style = list("font-size" = "35px")
),highlightOptions = highlightOptions(color = "blue", weight = 3,)
%>%
) addLayersControl(
baseGroups = c("Light", "Dark"),
overlayGroups = "Grid",
position = "topright",
options = layersControlOptions(collapsed = FALSE)
)
I found:
- Buckingham Palace at ππ¦π₯ (Big Ben, pigeon, gherkin)
- Leicester Square at π³π³ποΈ (plane tree, plane tree, Canary Wharf)
- The Shard at π¦ππ (pigeon, whale, guard)
- Wimbledon at ππ³π (guard, plane tree, Wembley)
- The Millennium Dome at πΈππ (Queen, tube, dragon)
Literally minutes of fun. Of course, you shouldnβt use this map for anything whatsoever, possibly not even for your own amusement. I, on the other hand, can do whatever I like.
Environment
Session info
Last rendered: 2023-07-21 19:29:22 BST
R version 4.3.1 (2023-06-16)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.2.1
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.11.0
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: Europe/London
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] leaflet_2.1.2 lubridate_1.9.2 forcats_1.0.0 stringr_1.5.0
[5] dplyr_1.1.2 purrr_1.0.1 readr_2.1.4 tidyr_1.3.0
[9] tibble_3.2.1 ggplot2_3.4.2 tidyverse_2.0.0 sf_1.0-14
loaded via a namespace (and not attached):
[1] s2_1.1.4 utf8_1.2.3 generics_0.1.3
[4] class_7.3-22 KernSmooth_2.23-21 stringi_1.7.12
[7] hms_1.1.3 digest_0.6.33 magrittr_2.0.3
[10] timechange_0.2.0 evaluate_0.21 grid_4.3.1
[13] fastmap_1.1.1 jsonlite_1.8.7 e1071_1.7-13
[16] DBI_1.1.3 fansi_1.0.4 crosstalk_1.2.0
[19] scales_1.2.1 cli_3.6.1 rlang_1.1.1
[22] units_0.8-2 ellipsis_0.3.2 munsell_0.5.0
[25] withr_2.5.0 yaml_2.3.7 tools_4.3.1
[28] tzdb_0.4.0 colorspace_2.1-0 vctrs_0.6.3
[31] R6_2.5.1 proxy_0.4-27 lifecycle_1.0.3
[34] classInt_0.4-9 leaflet.providers_1.9.0 htmlwidgets_1.6.2
[37] pkgconfig_2.0.3 pillar_1.9.0 gtable_0.3.3
[40] glue_1.6.2 Rcpp_1.0.11 xfun_0.39
[43] tidyselect_1.2.0 rstudioapi_0.15.0 knitr_1.43.1
[46] htmltools_0.5.5 rmarkdown_2.23 wk_0.7.3
[49] compiler_4.3.1
Footnotes
This post is not about that company or its practices. See instead, for example, the excellent YouTube videos by Andrew Steele and Mia Mulder, or Terence Edenβs blog post. Even the BBC covered it.β©οΈ
I was genuinely tricked by this websiteβs joke, fair play.β©οΈ
This blog is obviously a fan of emojis, see the one about creating SVG versions of the original emoji set or the one about a package for generating βemojiscapesβ.β©οΈ
The seed value has a meaning related to London; guess what it is.β©οΈ
The file contains NUTS level 1, which is a European standard for administrative geographies. Now the UK has left the EU, it has technically switched to something called βInternational Territorial Unitsβ (ITU), which I think are the same boundaries as NUTS for the time being.β©οΈ
Darkmode required to prevent damage to poor Millennial eyes when doomscrolling at 0300.β©οΈ