简体   繁体   中英

R: Plotting Multiple Decoded Polylines Using Leaflet

I have a vector with thousands of polylines that i have retrieved using the Google Directions API. I'm trying to plot all the polylines using the leaflet package. I was wondering if there is a more concise way of plotting all the polylines without using thousands of addPolylines() functions?

Here is a sample of four polylines:

polylines <- c(
"ksktDdp|dQJmB|@uEp@eDr@_D`@yB`@uBRm@LUtAkCZu@Pk@Nu@Hs@DwABoB@u@Gg@WDkCh@_@TaLfDiD~@yUfF{GvAqAX]NkBb@_A\\q@RiAZgAZe@Pu@^g@^o@n@o@z@_AdBqB`EwBrDiDfFIZ_@f@kHzJWZoBzCaCbEi@bAsHfNmGbLqA~B{HjNqEhIiFnJaB~CGf@Sh@iArC]pAQlACh@AjAFbARrAV~@f@fA^h@l@n@`@\\fClBRPFPr@f@hHhFdFtDzCzBzIrGNNNNb@^nD`DtEdEZ`@xAvBZl@r@fB^nA\\dB`@`FDfCF|AXhIJpERlHXzJh@|KL~DDpD?fIBrGbAzYxAbc@VlSVxMRdOJlTF~KH~CX|IDjKAxGDxDHbXR|FZpEpAvO~@rJh@vGRtFL|G^`SZvQ@hEQ`HM`Cg@xFm@tEe@bDi@dF[xEQlFCjED~P@zCKl@?|AFtBPtDZdEANAt@MbAa@fAU^k@j@IF_AZ_ADo@BGBy@A]AM?{BOeEc@g@QmCg@kDs@EEcGaAmFs@aD_@o@CeHs@yB[P|JLjFLxDHpEPxGNrGLbEFl@PhAvBbJnA`Ff@tB_A?mDBsC@?gAi@BEAEECwA@KFGHCP@", 
"ksktDdp|dQJmB|@uEdBeI`@yB`@uBRm@LUtAkCl@aBNu@Hs@HgE@u@Gg@WDkCh@_@TkQfFyUfF{GvAqAX]NkBb@qBp@iAZmBl@u@^g@^o@n@o@z@qDfHwBrDiDfFIZ_@f@kHzJgCvDaCbEi@bAsHfNmGbL_Rt\\kInOmBjE}A~EeB~Fy@nC}@rCcAtC{BjFkA|B}D~HaIpO{EhJYb@oA~AcA`AoBlAcBl@uB`@uCRq@@cSBaBAe@C}@MoAYmHaC{DoAaAe@uAaAoAwAcAkBs@eBe@aBoAkDkCeHk@gAa@m@uAyAcAs@eAm@s@WkDmAgC{@}I{CiCs@}AQqBDwBd@mEtB}At@oE`C_FhCwBz@sA\\aBXyCRaJFkFHkIJcEJoDb@u@ToCfAsC~AcEfCyErCcClAeA\\{@RoALyAHC?wDB{FEq@CuGIsZBY?cCBuEF{AHuFf@kLrAq@HgMxAyGt@sGbAqBd@uD~@[PoErAoF`B}HdC{Bn@_LdD_ARyH~CWJGBwEhBgMtEuFxAuF|@eNhBcCf@uBl@}Bx@gB~@{A`AqHvFcHbFwHzF}EdDyI`FcUlMkIvEiO~I}L`Iym@``@aQvKiFbCkMlFiOfGuc@rQ_FzBaDfBaGdDkD~AkD~@cDl@}FrAeCd@{Cj@mDZgBDmTPmWFkIFeB@eI@c`@T{HFcA@qyAt@{MF}JBoDAwHO}e@uAuWk@kFAgCB{@@{A@gA?a@WEAsG?sCNcCZgP|BcA`@cAn@}@v@_BlBm@bAg@fAc@zAg@bCQhCAtGBfMCnA^tFR|Aj@|CTfAHLJHvA|IfIdf@b@jDTzDHtEI|F}@tRGlCArDVtr@J|K\\zMDjLJr[@|CBpGO|PJlf@^`hA?fDJlWX|{@@pCH~OPhi@@zMOlHMlJ?lMMjBW`A[v@o@bA_LfPmFbI_@t@kLzPwCbEqK~NKd@aGpIwNdT}DdG_EfGeE`HUf@s@lAo@nAu@`@gDxEi@x@}A`CsBpCqDhFgChD}DrEqCnCWPM@}ChDaDzDW\\aJzL{CtEW@MAQIo@_@}Ag@WIWK]O[Q}@}@g@q@g@_A]oAUoA]cEOcA_@cBcAsB[c@o@s@wAkBiAkBkBiEGWUHoCzAKNc@LqAZ_Ad@a@ZOPs@eAa@`@o@[[M_AUk@GUAN_AHIr@Y", 
"ksktDdp|dQJmB|@uEp@eDr@_D`@yB`@uBRm@LUtAkCZu@Pk@Nu@Hs@DwABoB@u@Gg@WDkCh@_@TaLfDiD~@yUfF{GvAqAX]NkBb@_A\\q@RiAZgAZe@Pu@^g@^o@n@o@z@_AdBqB`EwBrDiDfFIZ_@f@kHzJWZoBzCaCbEi@bAsHfNmGbLqA~B{HjNqEhIiFnJaB~CGf@Sh@iArC]pAQlACh@AjAFbARrAV~@f@fA^h@l@n@`@\\fClBRPFPr@f@hHhFdFtDzCzBzIrGNNNNb@^nD`DtEdEZ`@xAvBZl@r@fB^nA\\dB`@`FDfCF|AXhIJpERlHXzJh@|KL~DDpD?fIBrGbAzYxAbc@VlSVxMRdOJlTF~KH~CX|IDjKAxGDxDHbXR|FZpEpAvO~@rJh@vGRtFL|G^`SZvQ@hEQ`HM`Cg@xFm@tEe@bDi@dF[xEQlFCjED~P@zCP|FVxD\\bCv@nELd@Pp@f@hBf@hBnHxVdAdEPvAl@zBZ~Al@dE^hERtFRzLNnPDdQNdu@FtCNzBXfBx@zCn@bBZt@dAhBZd@@VFTlA~Bt@~BR~@PhALtAJpDj@bOLrCD\\JhDl@tNBr@HxA^pKbAxY`AbWn@hRvA|_@VbHfC|r@jCdw@D~Aj@nTH~CDRZhIRtFb@rLFbBp@fRj@fOR|FRbGd@bMr@lSNnF\\vId@~H\\jH`@dLD|@zBbm@j@rPlA~[TtH@~AEVErE@hAX`HNbEbC?BjGD|Bl@vOp@vRfAjZVjFr@`RHb@d@tIzA?lMI?XBzFBjF?N`AAf@CnASp@KvAErFC~AA^?@_@v@?", 
"ksktDdp|dQJmB|@uEp@eDr@_D`@yB`@uBRm@LUtAkCZu@Pk@Nu@Hs@DwABoB@u@Gg@WDkCh@_@TaLfDiD~@yUfF{GvAqAX]NkBb@_A\\q@RiAZgAZe@Pu@^g@^o@n@o@z@_AdBqB`EwBrDiDfFIZ_@f@kHzJWZoBzCaCbEi@bAsHfNmGbLqA~B{HjNqEhIEHmBhDKFMLu@hAeBtCoAbCgC~Eo@lAa@h@e@b@UNq@Ve@Ho@D}@Gw@UcAi@eAw@yD{CsIsHiEqDO]u@i@gNeKaIaGoMsJ_HgF]Uk@SaB}@cBq@_Cg@sEg@c@GmJoAuCgA_BcAcBiAmAwAoAgBk@cAi@mAg@{Aq@}C_C_Jy@{Cq@uBu@gB{AqB_A{@w@i@mCeAsBYoBQiCMsLGoAAeEGuACoDQ}FOuLScNG}D@uD@iKAiOOyEIoP?wA@s@@wULoSLwAD_@?}@AcBKeBQoASqA[cA[gBs@uAu@gCaBqEeDyFkEkBmAcBy@{@]kBe@eB[qCU_GG_G@sNAeIFuE@[D{G?yI@}@?aEDuKFsHDiC?}BIuBOeAGcBUeH{@iHcAiV}CuCWyCSoEIoBB}B@sA@aB?eIB{C?uGBeHBoJHcODeWHmEAkSU_PUeCG_EQuFq@_@E_@GOCgGkB{Ak@{Am@yHyDuGmDsAm@{YoN{MwGgLsFqAm@i@YmDcBsE}BoLuFqUaLgFkCmHmDaBu@_@QcAg@wGaDkYeNgP_IgD{AwI}CqA[u@QgGsAsf@oHaDg@iMcB}IsA{Be@mBm@wB_AmBgAwCgBu@a@eMaIiDuB{D}BsGcEqEkCmCkAiCcAcEsAkHaC_GmBcDaAqIcCiBk@GY?AA?_N}F_GeCiBo@_@YmB{A{AeBsAcCc@gA]sAQu@KeAGe@MgAEeLOuDe@mE?GEaDYcJk@oKIuB]wJI{D?yBNoGd@iHh@}GTaD^mDX}Bd@yCbAyEdC{Kn@wCnGsYpBkJ`AcE|BeKlAiGp@_Fb@mEV{EJmCDuCAkGEcMEyOEsGCwIBqFJkDb@gIx@yNV}FD_FEePSsh@?kAOcc@I}NIe[FeDBs@H_AXmCXqB`@iBt@iC`AiC~@oBlAoBpBoCrDiFb@k@|@oA^Qj@m@hAsAzCmDxAaBlCaCpA}@zB_AbC{@VEX@jBe@|AWjAMy@_MMuDBiFDw@?YJmATyBRqAZ}BR{BL_D@gDEuBMcC_@sEWiDG_D?Ce@?cDAcCUTeCME[GkAY{Ak@UOEQ@WJa@R}@Fo@?i@Cg@Mi@GQOBODO@e@Au@OGC"
)

I normally decode them using the gepaf package:

> gepaf::decodePolyline(polylines[1]) %>% head()

       lat       lon
1 29.71974 -95.34227
2 29.71968 -95.34172
3 29.71937 -95.34065
4 29.71912 -95.33982
5 29.71886 -95.33902
6 29.71869 -95.33841

When plotting a single polyline, i use the following:

gepaf::decodePolyline(polylines[1]) -> SOF_sample

leaflet(SOF_sample) %>% 
    addProviderTiles("CartoDB.DarkMatter") %>% 
    addPolylines(lng = SOF_sample$lon, lat = SOF_sample$lat)

Here is a screenshot of the result: SOF_sample

What i am trying to figure out is how can i plot all the polylines without adding multiple addPolylines() functions like so:

leaflet(SOF_sample) %>% 
    addProviderTiles("CartoDB.DarkMatter") %>% 

    #first polyline
    addPolylines(lng = SOF_sample$lon, lat = SOF_sample$lat) %>% 

    #second polyline
    addPolylines(lng = gepaf::decodePolyline(polylines[2])$lon, 
             lat = gepaf::decodePolyline(polylines[2])$lat) %>% 

    #third polyline
    addPolylines(lng = gepaf::decodePolyline(polylines[3])$lon, 
             lat = gepaf::decodePolyline(polylines[3])$lat) %>% 

    #fourth polyline
    addPolylines(lng = gepaf::decodePolyline(polylines[4])$lon, 
             lat = gepaf::decodePolyline(polylines[4])$lat) 

Adding thousands of addPolylines() will give me the result i want . I was wondering if there is a more efficient/cleaner way of doing it because i have a feeling what i scripted above can't possibly be the best way to go about it.

Thanks!

One way is to convert your polylines into a SpatialLines object, and plot that. If you're not familiar with spatial objects I suggest looking into them as they are very useful for plotting.

library(leaflet)
library(sp)
library(data.table)
library(googleway)      ## disclosure: this is my package 
                        ## (and you can also access the google directions API 
                        ## through the google_directions() function)

lst <- lapply(polylines, function(x) googleway::decode_pl(x))

## I like working with data.tables
dt <- rbindlist(lst, idcol = "id")

lst_lines <- lapply(unique(dt$id), function(x){
    ## the order of the 'lon' and 'lat' fields is important
    Lines(Line(dt[id == x, .(lon, lat)]), ID = x)
})

## spatial lines object
spl_lst <- SpatialLines(lst_lines)

## can now plot the spatial lines
leaflet(spl_lst) %>%
    addProviderTiles("CartoDB.DarkMatterNoLabels") %>%
    addPolylines(opacity = 0.4, weight = 3, color = "#ffff00")

在此处输入图片说明


Update 14-12-2017

As of version 2 of googleway the encoded polylines can be plotted directly using my googleway package

library(googleway)

## You need a Google API key to use their maps
mapKey <- 'your_api_key'

## the lines need to be in a data.frame
df <- data.frame(polylines = polylines)

google_map(key = mapKey) %>%
    add_polylines(data = df, polyline = "polylines")

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM