googlePolylines package released

For a while I've wanted to get sf objects plotted in googleway, but I was never happy with the speed (or lack of it) I was getting from extracting the relevent geometries to use on the map.

So rather than using the sf objects directly, I explored the option of changing them to natively fit into a Google Map environment. The natural fit, therefore, was to make use of encoded polylines, which

is a lossy compression algorithm that allows you to store a series of coordinates as a single string

I already had this encoding algorithm as a C++ function inside googelway (see encode_pl()), so in the end all I had to do was adapt it to accept various sf geometries, encode the coordinates, and stream the output to a string.

Going our separate ways

I could have kept this new functionality inside googleway, but I thought it would be best suited to its own package. That way other mapping libraries could make use of it if they had support for polylines, without taking a dependency on the whole of googleway.

And thus, the birth of googlePolylines, accepted on CRAN on the 9th Jan 2018.

What does it do

To see it in action, take the North Carolina dataset included in library(sf) and run encode() on it

library(googlePolylines)
library(sf)
nc <- st_read(system.file("shape/nc.shp", package="sf"))

system.time({
    enc <- encode(nc)
})
#  user  system elapsed 
# 0.001   0.000   0.002 

str(enc)

# Classes ‘sfencoded’ and 'data.frame':    100 obs. of  15 variables:
#     $ AREA     : num  0.114 0.061 0.143 0.07 0.153 0.097 0.062 0.091 0.118 0.124 ...
# $ PERIMETER: num  1.44 1.23 1.63 2.97 2.21 ...
# $ CNTY_    : num  1825 1827 1828 1831 1832 ...
# $ CNTY_ID  : num  1825 1827 1828 1831 1832 ...
# $ NAME     : Factor w/ 100 levels "Alamance","Alexander",..: 5 3 86 27 66 46 15 37 93 85 ...
# $ FIPS     : Factor w/ 100 levels "37001","37003",..: 5 3 86 27 66 46 15 37 93 85 ...
# $ FIPSNO   : num  37009 37005 37171 37053 37131 ...
# $ CRESS_ID : int  5 3 86 27 66 46 15 37 93 85 ...
# $ BIR74    : num  1091 487 3188 508 1421 ...
# $ SID74    : num  1 0 5 1 9 7 0 0 4 1 ...
# $ NWBIR74  : num  10 10 208 123 1066 ...
# $ BIR79    : num  1364 542 3616 830 1606 ...
# $ SID79    : num  0 3 6 2 3 5 2 2 2 5 ...
# $ NWBIR79  : num  19 12 260 145 1197 ...
# $ geometry :encoded_column of length 100; first element: List of 1
# ..$ : atomic  u_d|EtsgpNmmFphLyEbcCibLf{Lk~H`bT}rNmjGihHd[kvL_lEzgBkl~@lyE`MnvCimCbmEqfAxnGieH~gEeTd_DmiCxvA_D|oAdwCidAtsKr_Aji| __truncated__
#     .. ..- attr(*, "sfc")= chr  "XY" "MULTIPOLYGON" "sfg"
#     - attr(*, "encoded_column")= chr "geometry"
#     - attr(*, "sfAttributes")=List of 5
#     ..$ type: chr "MULTIPOLYGON"
#     ..$ dim : chr "XY"
#     ..$ bbox:Class 'bbox'  Named num [1:4] -84.3 33.9 -75.5 36.6
#     .. .. ..- attr(*, "names")= chr [1:4] "xmin" "ymin" "xmax" "ymax"
#     ..$ epsg: int 4267
#     ..$ proj: chr "+proj=longlat +datum=NAD27 +no_defs"

Notice a few things

  1. It was quick to do the encoding
  2. The geometry column is now a set of encoded polylines
  3. The goemetry attributes have remained on the polylines
  4. The sf attributes have been retained on the object

However, as the encoding process is lossy, you will likely lose some precision during this process.

For most of my use-cases of plotting data on maps, this loss of precision is acceptable.

What about the maps?

Update: 02/02/18

Version 2.4 of googleway supports sf, and is now on CRAN!