Symbolix presentation at MelbRurn
7 June 2017
Guess the book / song / film / quote
2 * b | !(2 * b)
Guess the book / song / film / quote
# 2 * b | !(2 * b)
if(!broke){
fix(FALSE)
}
get_route() ## now deprecated
decode_pl()
pl <- "jnxeFeaxsZ}u@ngDebEyDa}DjU}|@hkCdDlnBsu@zIy}BrV{dA_}C{VauKynBeZ{yBcn@ssDuSqyAt|@qrAvbEycDtcAeyC_Vg~Fsi@utAcuAqjC_e@mnF_oAeeEgfF{xD|Bg|CoCekCo~B_tA}|@seFyX{bEjKwvFqjBm|B`F}oDyaAewHy`AiiBwlAsnElWapDMexDajBuv@u_AiAckE}{CyqDe}@{yB}jFcyCkrAkuC_xEedHygGapXmrHmmQj]ehFarAa`CgqBqLkhCwmEktDujForCucCi_CknE_pEqxLmtBonJdVcuD}zBodFmXegDnb@ohD_v@mjDcxCysH_jCmjCydBkh@}mA}oGoeDy{Le_@s_GmyAi~Ac}FwbEy~BkgMuhAssCugEquAurBvx@u~Cyi@suSkhOswBm{BenA{_NqOegG{uAi|EkbEyhDc|B_gDihB{zKnOmfFltCo|GhJgvEpE}}Cyx@g|@okCkgBa|EwwG_bDutAcfH{uBcdFrK}m@_sAw@avDxCw}Bsf@aaEgSurDkaAkdFezDwwBy~E_nCwk@qdB_gBepBqlC}zA_fAeeCchEcqC_yEga@k}F_uMsj@cnHslJktLagCg|DuqE_l@_tHcvD_uAoWskCusDorEu~DeaEidDogBclAaqBfI}wCpgBitC_m@qhEg_LsbH{kHosCcvE_eE{cBu^g`GggBo`EaxBkaFyE_iGhH{dCykC}}DcxAmfFo~B}jDmnDci@w{A}wAimImf@}lAgdDggCweBuhB}kBgnDhd@knAskE}aB{dD}jAg~Fc|CivDixBqjByz@keDsCkeKj@wmF}yAy`Jnl@mwPjCcmGreAayC}f@krCa{DouCgy@qvDoZ}yIjIsnFxjFqnLtIkkFlsBm`D~k@qhIy\\meDkaAi}CdG{nDcwE}yN{RqvLrjEw}PbOusHcYegG_\\mqH}v@ikCnW_tDbP{aIa}@q{D{mAe_Ckc@uiEkR_mMyl@auBcrC{bA_pAm{D`OonElm@uvAuAgjHa@eqF{dBgiI_cEgmFemEqvHakAgwBoOkyCaeAkmCqk@k~FkfAwfEooAweBijC_eCksGckDqzF_cEaaD}bBah@oxBcqBwqEkxBc|OiyCq_GiaLsyHebIkhNgpG{uCukI{zIq}BuxBchCiNy{GubDgfDanAueCwuEqyAulAwxC}WuzDiwEyhD_}AmhBqxFjr@emIoi@{iJu@ifLa]mfHnfAq_Da`AkbEy^}lAar@rBc`Fac@s`ChYhQd["
df_line <- decode_pl(pl)
head(df_line)
lat lon
1 -37.81366 144.9629
2 -37.80487 144.9359
3 -37.77364 144.9369
4 -37.74323 144.9333
5 -37.73332 144.9108
6 -37.73415 144.8930
shouldThrow <- switch(house, "glass" = FALSE, TRUE)
# shouldThrow <- switch(house, "glass" = FALSE, TRUE)
tooLate <- function() return(FALSE)
google_directions() ## get_route()
google_distance()
google_elevation()
google_timezone()
google_geocode()
google_reverse_geocode()
google_places()
google_place_details()
res <- google_directions(origin = "Melbourne, Australia",
destination = "Sydney, Australia",
key = apiKey)
str(res)
# List of 3
# $ geocoded_waypoints:'data.frame': 2 obs. of 3 variables:
# ..$ geocoder_status: chr [1:2] "OK" "OK"
# ..$ place_id : chr [1:2] "ChIJ90260rVG1moRkM2MIXVWBAQ" "ChIJP3Sa8ziYEmsRUKgyFmh9AQM"
#
# ...
#
# $ overview_polyline:'data.frame': 1 obs. of 1 variable:
# .. ..$ points: chr "jnxeFeaxsZ}u@ngDebEyDa}DjU}|@hkCdDlnBsu@zIy}BrV{dA_}C{VauKynBeZ{yBcn@ssDuSqyAt|@qrAvbEycDtcAeyC_Vg~Fsi@utAcuAqj"| __truncated__
# ..$ summary : chr "National Highway M31 and M31"
# $ status : chr "OK"
elevation <- google_elevation(df_line, key = apiKey)
library(ggplot2)
df_elevation <- elevation$results
ggplot(data = df_elevation, aes(x = row.names(df), y = elevation, group = 1)) +
geom_line()
geocode <- google_geocode(address = "MCG, Melbourne", key = apiKey)
geocode$results$formatted_address
# [1] "Brunton Ave, Richmond VIC 3002, Australia"
geocode$results$geometry$location
# lat lng
# 1 -37.81997 144.9834
reverse <- google_reverse_geocode(location = c(-37.81997,144.9834), key = apiKey)
reverse$results$formatted_address
# [1] "120 Brunton Ave, East Melbourne VIC 3002, Australia"
# [2] "East Melbourne VIC 3002, Australia"
# [3] "Melbourne VIC, Australia"
# [4] "East Melbourne VIC 3002, Australia"
# [5] "Melbourne, VIC, Australia"
# [6] "CBD & South Melbourne, Melbourne VIC, Australia"
# [7] "Melbourne Metropolitan Area, VIC, Australia"
# [8] "Victoria, Australia"
# [9] "Australia"
place <- google_places(search_string = "Restaurants, Sydney",
key = apiKey)
place$results[1, c('formatted_address', 'name', 'place_id')]
# formatted_address name
# 1 107 Pitt St, Sydney NSW 2000, Australia Jamie's Italian Australia, Sydney
# place_id
# 1 ChIJ283hTECuEmsRHAc-pWx6cUs
details <- google_place_details(place_id = place$results[1, 'place_id'], key = apiKey)
details$result$opening_hours$periods
# close.day close.time open.day open.time
# 1 0 2200 0 1200
# 2 1 2200 1 1130
# 3 2 2200 2 1130
...
lapply(details, names)
# $result
# [1] "address_components" "adr_address" "formatted_address"
# [4] "formatted_phone_number" "geometry" "icon"
# [7] "id" "international_phone_number" "name"
# [10] "opening_hours" "photos" "place_id"
# [13] "rating" "reference" "reviews"
# [16] "scope" "types" "url"
# [19] "utc_offset" "vicinity" "website"
plot(1:5, 1:5, type = "s"); text(5,5,"Heaven")
plot(1:5, 1:5, type = "s"); text(5,5,"Heaven")
load("~/x")
rm(x)
load("~/x")
x
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0.6105372 0.9298755 0.2367368 0.0313123 0.68165312 0.4662871
[2,] 0.5116770 0.9684903 0.1151035 0.2768140 0.20134670 0.6105372
[3,] 0.6328304 0.1683396 0.8505320 0.3834281 0.07474697 0.5116770
library(leaflet)
## using decoded-polyline
leaflet() %>%
addTiles() %>%
addPolylines(data = df_line, lng = ~lon,lat = ~lat)
## But, do I have to decode it?
google_map(key = mapKey)
google_map(key = mapKey, search_box = TRUE, styles = map_styles()$silver)
names(googleway::map_styles())
[1] "standard" "silver" "retro" "dark" "night" "aubergine"
google_map(key = mapKey, zoom = 12, location = c(-37.818, 144.968)) %>%
add_traffic()
google_map(key = mapKey, zoom = 12, location = c(-37.818, 144.968)) %>%
add_bicycling()
paste0("batman ", paste0(names(googleway::map_styles()[4:5]), collapse = " "))
paste0("batman ", paste0(names(googleway::map_styles()[4:5]), collapse = " "))
names(googleway::map_styles()[4:5])
[1] "dark" "night"
paste0("batman ", paste0(names(googleway::map_styles()[4:5]), collapse = " "))
names(googleway::map_styles()[4:5])
[1] "dark" "night"
paste0("batman ", paste0(names(googleway::map_styles()[4:5]), collapse = " "))
[1] "batman dark night"
pl <- "jnxeFeaxsZ}u@ngDebEyDa}DjU}|@hkCdDlnBsu@zIy}BrV{dA_}C{VauKynBeZ{yBcn@ssDuSqyAt|@qrAvbEycDtcAeyC_Vg~Fsi@utAcuAqjC_e@mnF_oAeeEgfF{xD|Bg|CoCekCo~B_tA}|@seFyX{bEjKwvFqjBm|B`F}oDyaAewHy`AiiBwlAsnElWapDMexDajBuv@u_AiAckE}{CyqDe}@{yB}jFcyCkrAkuC_xEedHygGapXmrHmmQj]ehFarAa`CgqBqLkhCwmEktDujForCucCi_CknE_pEqxLmtBonJdVcuD}zBodFmXegDnb@ohD_v@mjDcxCysH_jCmjCydBkh@}mA}oGoeDy{Le_@s_GmyAi~Ac}FwbEy~BkgMuhAssCugEquAurBvx@u~Cyi@suSkhOswBm{BenA{_NqOegG{uAi|EkbEyhDc|B_gDihB{zKnOmfFltCo|GhJgvEpE}}Cyx@g|@okCkgBa|EwwG_bDutAcfH{uBcdFrK}m@_sAw@avDxCw}Bsf@aaEgSurDkaAkdFezDwwBy~E_nCwk@qdB_gBepBqlC}zA_fAeeCchEcqC_yEga@k}F_uMsj@cnHslJktLagCg|DuqE_l@_tHcvD_uAoWskCusDorEu~DeaEidDogBclAaqBfI}wCpgBitC_m@qhEg_LsbH{kHosCcvE_eE{cBu^g`GggBo`EaxBkaFyE_iGhH{dCykC}}DcxAmfFo~B}jDmnDci@w{A}wAimImf@}lAgdDggCweBuhB}kBgnDhd@knAskE}aB{dD}jAg~Fc|CivDixBqjByz@keDsCkeKj@wmF}yAy`Jnl@mwPjCcmGreAayC}f@krCa{DouCgy@qvDoZ}yIjIsnFxjFqnLtIkkFlsBm`D~k@qhIy\\meDkaAi}CdG{nDcwE}yN{RqvLrjEw}PbOusHcYegG_\\mqH}v@ikCnW_tDbP{aIa}@q{D{mAe_Ckc@uiEkR_mMyl@auBcrC{bA_pAm{D`OonElm@uvAuAgjHa@eqF{dBgiI_cEgmFemEqvHakAgwBoOkyCaeAkmCqk@k~FkfAwfEooAweBijC_eCksGckDqzF_cEaaD}bBah@oxBcqBwqEkxBc|OiyCq_GiaLsyHebIkhNgpG{uCukI{zIq}BuxBchCiNy{GubDgfDanAueCwuEqyAulAwxC}WuzDiwEyhD_}AmhBqxFjr@emIoi@{iJu@ifLa]mfHnfAq_Da`AkbEy^}lAar@rBc`Fac@s`ChYhQd["
df_line <- decode_pl(pl)
google_map(key = mapKey) %>%
add_polylines(data = df_line, lat = "lat", lon = "lon")
df_polyline <- data.frame(polyline = pl)
google_map(key = mapKey) %>%
add_polylines(data = df_polyline, polyline = 'polyline')
google_map(key = mapKey, style = style) %>%
add_polylines(data = flights, polyline = "polyline", mouse_over_group = "airport1",
stroke_weight = 0.8, stroke_opacity = 0.3, stroke_colour = "#ccffff")
## ?tram_stops
tram_stops$colour <-ifelse(tram_stops$stop_lat < -37.82, "green", "red")
google_map(data = tram_stops, key = mapKey) %>%
add_markers(lat = "stop_lat", lon = "stop_lon", colour = "colour")
google_map(data = tram_stops, key = mapKey) %>%
add_markers(lat = "stop_lat", lon = "stop_lon", cluster = T, info_window = "stop_name")
tram_stops$radius <- runif(n = nrow(tram_stops), min = 50, max = 250)
google_map(data = tram_stops, key = mapKey) %>%
add_circles(lat = "stop_lat", lon = "stop_lon", radius = "radius", colour =)
google_map(key = mapKey) %>%
add_heatmap(data = dt_heat[route_type == 0],
lat = "stop_lat", lon= "stop_lon", weight = "N",
option_radius = 0.005)
google_map(key = mapKey, styles = map_styles()$night) %>%
add_heatmap(data = dt_heat[route_type == 0],
lat = "stop_lat", lon= "stop_lon", weight = "N",
option_radius = 0.005,
option_gradient = c("red", "orange","yellow","whitesmoke"))
google_map(key = mapKey) %>%
add_polygons(data = df_line, lat = "lat", lon = "lon")
## DEMO
while (FALSE) print("Never")
# while (FALSE) print("Never")
grey(seq(0, 1, length.out=50))
# while (FALSE) print("Never")
# grey(seq(0, 1, length.out=50))
while (FALSE) giveUp(you)
pl_outer <- encode_pl(lat = c(25.774, 18.466,32.321),
lon = c(-80.190, -66.118, -64.757))
pl_inner <- encode_pl(lat = c(28.745, 29.570, 27.339),
lon = c(-70.579, -67.514, -66.668))
df <- data.frame(id = c(1, 2),
polyline = c(pl_outer, pl_inner),
stringsAsFactors = FALSE)
## note; different IDs
df
## id polyline
## 1 1 o~h|CnbmhN~irk@am{tAw`qsAeyhG
## 2 2 ggmnDt}wmLgc`DesuQvvrLofdD
google_map(key = mapKey) %>%
add_polygons(data = df, id = "id", polyline = "polyline")
df <- data.frame(id = c(1, 1),
polyline = c(pl_outer, pl_inner),
stringsAsFactors = FALSE)
## note; same IDs
df
## id polyline
## 1 1 o~h|CnbmhN~irk@am{tAw`qsAeyhG
## 2 1 ggmnDt}wmLgc`DesuQvvrLofdD
google_map(key = mapKey) %>%
add_polygons(data = df, id = "id", polyline = "polyline")
pl_other <- encode_pl(lat = c(22, 23, 22),
lon = c(-50, -49, -51))
df <- rbind(df, data.frame(id = 1, polyline = pl_other))
df
## id polyline
## 1 1 o~h|CnbmhN~irk@am{tAw`qsAeyhG
## 2 1 ggmnDt}wmLgc`DesuQvvrLofdD
## 3 1 _{geC~rdpH_ibE_ibE~hbE~reK
google_map(key = mapKey) %>%
add_polygons(data = df, id = "id", polyline = "polyline", mouse_over_group = "id")
## myId lineId lat lon colour
## 1 1 1 26.774 -80.190 #00FF0F
## 2 1 1 18.466 -66.118 #00FF0F
## 3 1 1 32.321 -64.757 #00FF0F
## 4 1 2 28.745 -70.579 #00FF0F
## 5 1 2 29.570 -67.514 #00FF0F
## 6 1 2 27.339 -66.668 #00FF0F
## 7 2 1 22.000 -50.000 #FF00FF
## 8 2 1 23.000 -49.000 #FF00FF
## 9 2 1 22.000 -51.000 #FF00FF
google_map(key = mapKey) %>%
add_polygons(data = dfc, lat = 'lat', lon = 'lon', id = 'myId', pathId = 'lineId',
fill_colour = 'colour', mouse_over_group = "myId")
## [
## {
## "id": 1,
## "polygon": ["o~h|CnbmhN~irk@am{tAw`qsAeyhG", "ggmnDt}wmLgc`DesuQvvrLofdD", "_{geC~rdpH_ibE_ibE~hbE~reK"]
## }
## ]
## polygon
## 1 ((25.774 -80.19,18.466 -66.118,32.321 -64.757),(28.745 -70.579,29.57 -67.514,27.339 -66.668),(22 -50,23 -49,22 -51))
library(sf)
nc.sf <- st_read(system.file("shape/nc.shp", package="sf"))
head(nc.sf[, 11:15])
## Simple feature collection with 6 features and 4 fields
## geometry type: MULTIPOLYGON
## dimension: XY
## bbox: xmin: -81.74107 ymin: 36.07282 xmax: -75.77316 ymax: 36.58965
## epsg (SRID): 4267
## proj4string: +proj=longlat +datum=NAD27 +no_defs
## NWBIR74 BIR79 SID79 NWBIR79 geometry
## 1 10 1364 0 19 MULTIPOLYGON(((-81.47275543...
## 2 10 542 3 12 MULTIPOLYGON(((-81.23989105...
## 3 208 3616 6 260 MULTIPOLYGON(((-80.45634460...
## 4 123 830 2 145 MULTIPOLYGON(((-76.00897216...
## 5 1066 1606 3 1197 MULTIPOLYGON(((-77.21766662...
## 6 954 1838 5 1237 MULTIPOLYGON(((-76.74506378...
plot(nc.sf[1])
nc.sp <- as(nc.sf, "Spatial")
class(nc.sp)
# [1] "SpatialPolygonsDataFrame"
class(nc.sf)
# [1] "sf" "data.frame"
sapply(mget(c("nc.sf", "nc.sp")), function(x) format(object.size(x), units = "Mb"))
## nc.sf nc.sp
## "0.1 Mb" "0.4 Mb"
library(spatial.data.table)
nc.dt <- spToDT(nc.sf)
class(nc.dt)
# [1] "data.table" "data.frame"
nc.dt[, .(id, lineId, coords.V1, coords.V2)]
# id lineId coords.V1 coords.V2
# 1: 1 1 -81.47276 36.23436
# 2: 1 1 -81.54084 36.27251
# 3: 1 1 -81.56198 36.27359
# 4: 1 1 -81.63306 36.34069
# 5: 1 1 -81.74107 36.39178
sapply(mget(c("nc.sf", "nc.sp", "nc.dt")), function(x) format(object.size(x), units = "Mb"))
# nc.sf nc.sp nc.dt
# "0.1 Mb" "0.4 Mb" "0.3 Mb"
nc.dtpl <- EncodeSF(nc.sf)
nc.dtpl[1:5, .(.id, polyline)]
# .id polyline
# 1: 1 u_d|EtsgpNmmFphLyEbcCibL
# 2: 2 or}|EhdznNyvA~Ce_D
# 3: 3 }re|EbcajNakAf|BqKbyJo{Bxq@cJb
# 4: 4 mtt|E`o|nMkpBhs@~I
# 5: 4 ~b~Ev``oMJcqDfwAe}OnkLpoAgX|fI
sort(sapply(mget(c("nc.sf", "nc.sp", "nc.dt", "nc.dtpl")), function(x) object.size(x)))
# nc.dtpl nc.sf nc.dt nc.sp
# 24440 135168 339968 378192
library(leaflet)
library(microbenchmark)
## shp_sa2 : shape file of SA2 (statistical area 2) of Victoria, Australia
## dt_pl : data.table with encoded polylines of SA2 of Victoria, Australia
microbenchmark(
leaf = {
l <- leaflet() %>%
addTiles() %>%
addPolygons(data = shp_sa2)
},
goo = {
g <- google_map(key = mapKey) %>%
add_polygons(data = dt_pl, polyline = "polyline", id = ".id", pathId = "lineId")
},
times = 5
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# leaf 1260.8853 1384.9013 1462.266 1394.7890 1489.402 1781.3544 5
# goo 210.6741 218.5353 240.975 224.5488 228.355 322.7616 5
geosphere::distHaversine <- function (p1, p2, r = 6378137) {
toRad <- pi/180
p1 <- .pointsToMatrix(p1) * toRad
p2 <- .pointsToMatrix(p2) * toRad
p = cbind(p1[, 1], p1[, 2], p2[, 1], p2[, 2], as.vector(r))
dLat <- p[, 4] - p[, 2]
dLon <- p[, 3] - p[, 1]
a <- sin(dLat/2) * sin(dLat/2) + cos(p[, 2]) * cos(p[, 4]) *
sin(dLon/2) * sin(dLon/2)
dist <- 2 * atan2(sqrt(a), sqrt(1 - a)) * p[, 5]
return(as.vector(dist))
}
dt[, haversine := distHaversine(
matrix(c(LOC1_LONG_CORD, LOC1_LAT_CORD), ncol = 2),
matrix(c(LOC2_LONG_CORD, LOC2_LAT_CORD), ncol = 2)
)]
## usage:
dt1[, dist := dtHaversine(lat_orig, long_orig, lat_dest, long_dest)]
dt1 <- copy(dt)
dt2 <- copy(dt)
microbenchmark(
sdt = { dt1[, dist := dtHaversine(lat1, lon1, lat2, lon2)] },
geo = { dt2[, dist := distHaversine(matrix(c(lon1, lat1), ncol = 2),
matrix(c(lon2, lat2), ncol = 2))] }
)
# Unit: milliseconds
# expr min lq mean median uq
# sdt 10.22558 11.13795 12.07124 11.65805 11.98368
# geo 42.29223 93.21309 96.31312 95.75023 99.91635
Where does this go from here?
## Distance calculations
dtAlongTrackDistance
dtAntipode
dtBearing
dtCosine
dtDestination
dtDist2gc
dtHaversine
dtMidpoint
dtNearestPoints
## spatial operation
PointsInPolygon
while (TRUE) story()
# while (TRUE) story()
wrong <- 0
right <- 1
wrong * 2 == right
[1] FALSE
Vignette: https://github.com/SymbolixAU/googleway/blob/master/vignettes/googleway-vignette.Rmd
Stackoverflow [googleway]: https://stackoverflow.com/questions/tagged/googleway
Symbolix: https://www.symbolix.com.au/
Shiny demos: http://demos.symbolix.com.au/shiny