what3words in R: threewords V0.1.0 and my own language extension

Recently I scrolled through the list of recently published R packages when something caught my eye: threewords: Represent Precise Coordinates in Three Words which sounded interesting.

What is what3words?

The about page of their website explains it very well. what3words is an alternative to represent coordinates using exactly three words (instead of GPS coordinates for example). For each 3x3m square on the planet earth they defined 3 words that identify it. These words are defined in a way that if you make a typo, the wrong location is so far away from the desired location that you will notice it (e.g. on a different continent).

The advantages they see themselves are:

  • Words are easier to remember than numbers. That’s probably true when you need to remember “table”, “chair”, “potato” instead of -36.8092 174.7276.
  • They have used short and easy words. I have not tested that thoroughly but the steps they mention (automated and human processing, removing homophones like “sale” and “sail”) seem reasonable.
  • Error-detection that I mentioned above
  • Lat/Lon to what3words and what3words to Lat/Lon conversion
  • Availability in 9 languages (some still beta).
  • Fixed and universal. The words for each position are fixed and will never change again.
  • Offline availability

One advantage I see is that you can choose between a few addresses because usually a few 3×3 squares should cover your house 😉

What can you do with the R package threewords (V0.1.0)

Currently the R package does not much but convert three words to coordinates (if they exist) or coordinates to three words. So far it only provides english words.

First you need an API key that you can request at their website.

my_key<-'YOURKEY'

Install and load the library:

install.packages("threewords")
library(threewords)

The first thing you can do is convert GPS coordinates into the what3words representation:

from_position(key=my_key, positions = c(48.12345, 14.12345))

The output looks like this:

$words
[1] "freshen" "combed" "relating"

$position
[1] 48.12345 14.12345

$language
[1] "en"

Then you can check whether the other method, from_words, returns the original coordinates:

from_words(key=my_key, words=c("freshen", "combed", "relating"))

Yes it does!

$type
[1] "3 words"

$words
[1] "freshen" "combed" "relating"

$position
[1] 48.12345 14.12345

$language
[1] "en"

The order of the words is important, but when you swap them by accident, you will definitely notice.

from_words(key=my_key, words=c("combed", "freshen", "relating"))

The position is totally far away from the original position, so we might notice that we mixed something up.

$type
[1] "3 words"

$words
[1] "combed" "freshen" "relating"

$position
[1] 63.67501 125.27388

$language
[1] "en"

You can also try some random words:

from_words(key=my_key, words=c("table", "chair", "potato"))

$type
[1] "3 words"

$words
[1] "table" "chair" "potato"

$position
[1] -36.8092 174.7276

$language
[1] "en"

Invalid queries are not handled very well yet:

from_words(key=my_key, words=c("table", "chair", "potatoes"))

Error in threeword_query(url, ...) : String not recognised

Extend the R package to other languages than English (en)

Unfortunately the package does not support other languages than english yet (I don't criticise it, it's version 0.1.0) but it can easily be extended.

I simply downloaded the source code for the package and modified 4 of the methods. For each method I added the parameter "lang" and modified the urls accordingly.

Position to words

single_position <- function(position, key, lang, ...){
  url <- paste0("https://api.what3words.com/position?key=", key,
                "&position=", paste(position, collapse = ","), "&lang=", lang)
  return(clean(threeword_query(url, ...)))
}
from_position <- function(key, positions, lang="en", ...){
  if(is.list(positions)){
    return(lapply(positions, single_position, key, lang, ...))
  }
  return(single_position(positions, key, lang, ...))
}

I used lang="en" so that it would still work like the package function when I don't provide a language parameter.

Words to position

single_words <- function(words, key, lang, ...){
  url <- paste0("https://api.what3words.com/w3w?key=", key,
                "&string=", paste(words, collapse = "."), "&lang=", lang)
 return(clean(threeword_query(url, ...)))
}
from_words <- function(key, words, lang="en", ...){
  if(is.list(words)){
    return(lapply(words, single_words, key, lang, ...))
  }
  return(single_words(words, key, lang, ...))
}

These changes are of course only possible because what3words provides a GET parameter "lang" that takes values like "en" (for English) and "de" (for German).

Test cases

Since I used the same GPS coordinates you can see that the words are not simply a translation but completely different words.

from_position(key=my_key, positions = c(48.12345, 14.12345), lang="de")

$words
[1] "schreiben" "halb" "eisenbahn"

$position
[1] 48.12345 14.12345

$language
[1] "de"

You can even use it as a translator between english and german coordinates:

from_words(key=my_key, words=c("table", "chair", "potato"), lang="de")

$type
[1] "3 words"

$words
[1] "mich" "landesbank" "westlich"

$position
[1] -36.8092 174.7276

$language
[1] "de"

And, as expected, it works with german words:

from_words(key=my_key, words=c("mich", "landesbank", "westlich"), lang="de")

$type
[1] "3 words"

$words
[1] "mich" "landesbank" "westlich"

$position
[1] -36.8092 174.7276

$language
[1] "de"

Feature image taken from the what3words Presskit.

Leave a Reply

Your email address will not be published. Required fields are marked *