Adding great circle routes as polylines in Leaflet

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Adding great circle routes as polylines in Leaflet

dhirajkhanna
I am trying to add great circle routes between various regions in R. Here’s
the sample data:

structure(list(CommencingRegion = c("RedSea", "EastAfrica", "GulfofMexico",
"FarEast", "RedSea", "GulfofMexico"), LoadRegion = c("RedSea",
"RedSea", "GulfofMexico", "FarEast", "RedSea", "GulfofMexico"
), DischargeRegion = c("NorthWestAfrica", "WestMedditerranean",
"WestCoastLatinAmerica", "AustraliaNewZealand", "WestMedditerranean",
"WestCoastCentralAmerica"), Count = c(1L, 1L, 2L, 1L, 2L, 5L),
    AvgTCE = c(38879.53, 31783.55, 28520.79, 26068.8, 26054.28,
    25883.81), CLon = c(37.8274879335485, 47.0791103099334, -90.9633701509553,
    146.2727573458, 37.8274879335485, -90.9633701509553), CLat =
c(21.4460561443517,
    -12.9570828789565, 25.2035802054683, 47.6530892619773, 21.4460561443517,
    25.2035802054683), LLon = c(37.8274879335485, 37.8274879335485,
    -90.9633701509553, 146.2727573458, 37.8274879335485, -90.9633701509553
    ), LLat = c(21.4460561443517, 21.4460561443517, 25.2035802054683,
    47.6530892619773, 21.4460561443517, 25.2035802054683), DLon =
c(-17.1597117430475,
    7.03639948506481, -73.4238157230412, 151.051220297802, 7.03639948506481,
    255.83509305644), DLat = c(24.2308740597312, 38.8907379374372,
    -25.8934046406896, -25.1880219406131, 38.8907379374372, 21.8130318388702
    )), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
))

I would like to plot great circle routes between CommencingRegion to
LoadingRegion and then from LoadingRegion to DischargeRegion for every row.
Additionally, every row needs to be in a different color and the thickness
needs to be proportional to AvgTCE. The last 6 variables in the data above
are the coordinates in Lat Long for the commencing, loading and discharging
regions respectively. I am quite clueless on how to go about achieving
this. This is what I have tried and failed:

leaflet() %>%
  addTiles() %>%
  for(i in 1:6){
    addPolylines(data=gcIntermediate(c(ByRoute$CLon[i],ByRoute$CLat[i]),c(ByRoute$LLon[i],ByRoute$CLat[i]),n=100,addStartEnd
= T,sp=T))
  }

Regards
Dhiraj Khanna
Mob:09873263331

        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Adding great circle routes as polylines in Leaflet

Ben Tupper
Hi,

Your example is so close to being reproducible, but not quite close enough.  After some noodling around I figured out that you are using geosphere package in addition to leaflet, and that your tibble is assigned to the `ByRoute` variable.  The following gets you closer - you'll want to resolve the warning messages ...

Warning messages:
1: In .pointsToMatrix(p2) :longitude > 180
2: In .pointsToMatrix(p2) :longitude > 180
3: In .pointsToMatrix(p2) : longitude > 180


... which you can fix in your tibble.

When adding layers to a map, you really want to create a map object, store it in a variable, say 'm', and ad each layer in an iteration enclosing the pipes (rather than within the pipes).  I'm sure that there will be some wrapping issues if you copy-and-paste from this email.  (Also, please put a bit more white space in your code.  They are calorie-free and make life so much easier on us old fellows.)

Cheers,
Ben


library(leaflet)
library(geosphere)
ByRoute = structure(list(CommencingRegion = c("RedSea", "EastAfrica", "GulfofMexico",
                                        "FarEast", "RedSea", "GulfofMexico"), LoadRegion = c("RedSea",
                                                                                             "RedSea", "GulfofMexico", "FarEast", "RedSea", "GulfofMexico"
                                        ), DischargeRegion = c("NorthWestAfrica", "WestMedditerranean",
                                                               "WestCoastLatinAmerica", "AustraliaNewZealand", "WestMedditerranean",
                                                               "WestCoastCentralAmerica"), Count = c(1L, 1L, 2L, 1L, 2L, 5L),
                   AvgTCE = c(38879.53, 31783.55, 28520.79, 26068.8, 26054.28,
                              25883.81), CLon = c(37.8274879335485, 47.0791103099334, -90.9633701509553,
                                                  146.2727573458, 37.8274879335485, -90.9633701509553), CLat =
                       c(21.4460561443517,
                         -12.9570828789565, 25.2035802054683, 47.6530892619773, 21.4460561443517,
                         25.2035802054683), LLon = c(37.8274879335485, 37.8274879335485,
                                                     -90.9633701509553, 146.2727573458, 37.8274879335485, -90.9633701509553
                         ), LLat = c(21.4460561443517, 21.4460561443517, 25.2035802054683,
                                     47.6530892619773, 21.4460561443517, 25.2035802054683), DLon =
                       c(-17.1597117430475,
                         7.03639948506481, -73.4238157230412, 151.051220297802, 7.03639948506481,
                         255.83509305644), DLat = c(24.2308740597312, 38.8907379374372,
                                                    -25.8934046406896, -25.1880219406131, 38.8907379374372, 21.8130318388702
                         )), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
                         ))



# create the map object
m <- leaflet() %>%
    addTiles()

# iteratively add each polyline commence-to-load and load-to-destination
for(i in 1:6){
        m <- m %>%
            addPolylines(data=gcIntermediate(c(ByRoute$CLon[i], ByRoute$CLat[i]), c(ByRoute$LLon[i], ByRoute$CLat[i]),
                                            n=100, addStartEnd = TRUE, sp = TRUE)) %>%
            addPolylines(data=gcIntermediate(c(ByRoute$LLon[i], ByRoute$LLat[i]), c(ByRoute$DLon[i], ByRoute$DLat[i]),
                                             n=100, addStartEnd = TRUE, sp = TRUE))
}        

m      





> On Sep 2, 2018, at 10:34 PM, Dhiraj Khanna <[hidden email]> wrote:
>
> I am trying to add great circle routes between various regions in R. Here’s
> the sample data:
>
> structure(list(CommencingRegion = c("RedSea", "EastAfrica", "GulfofMexico",
> "FarEast", "RedSea", "GulfofMexico"), LoadRegion = c("RedSea",
> "RedSea", "GulfofMexico", "FarEast", "RedSea", "GulfofMexico"
> ), DischargeRegion = c("NorthWestAfrica", "WestMedditerranean",
> "WestCoastLatinAmerica", "AustraliaNewZealand", "WestMedditerranean",
> "WestCoastCentralAmerica"), Count = c(1L, 1L, 2L, 1L, 2L, 5L),
>    AvgTCE = c(38879.53, 31783.55, 28520.79, 26068.8, 26054.28,
>    25883.81), CLon = c(37.8274879335485, 47.0791103099334, -90.9633701509553,
>    146.2727573458, 37.8274879335485, -90.9633701509553), CLat =
> c(21.4460561443517,
>    -12.9570828789565, 25.2035802054683, 47.6530892619773, 21.4460561443517,
>    25.2035802054683), LLon = c(37.8274879335485, 37.8274879335485,
>    -90.9633701509553, 146.2727573458, 37.8274879335485, -90.9633701509553
>    ), LLat = c(21.4460561443517, 21.4460561443517, 25.2035802054683,
>    47.6530892619773, 21.4460561443517, 25.2035802054683), DLon =
> c(-17.1597117430475,
>    7.03639948506481, -73.4238157230412, 151.051220297802, 7.03639948506481,
>    255.83509305644), DLat = c(24.2308740597312, 38.8907379374372,
>    -25.8934046406896, -25.1880219406131, 38.8907379374372, 21.8130318388702
>    )), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"
> ))
>
> I would like to plot great circle routes between CommencingRegion to
> LoadingRegion and then from LoadingRegion to DischargeRegion for every row.
> Additionally, every row needs to be in a different color and the thickness
> needs to be proportional to AvgTCE. The last 6 variables in the data above
> are the coordinates in Lat Long for the commencing, loading and discharging
> regions respectively. I am quite clueless on how to go about achieving
> this. This is what I have tried and failed:
>
> leaflet() %>%
>  addTiles() %>%
>  for(i in 1:6){
>    addPolylines(data=gcIntermediate(c(ByRoute$CLon[i],ByRoute$CLat[i]),c(ByRoute$LLon[i],ByRoute$CLat[i]),n=100,addStartEnd
> = T,sp=T))
>  }
>
> Regards
> Dhiraj Khanna
> Mob:09873263331
>
> [[alternative HTML version deleted]]
>
> _______________________________________________
> R-sig-Geo mailing list
> [hidden email]
> https://stat.ethz.ch/mailman/listinfo/r-sig-geo
>

Ben Tupper
Bigelow Laboratory for Ocean Sciences
60 Bigelow Drive, P.O. Box 380
East Boothbay, Maine 04544
http://www.bigelow.org

Ecological Forecasting: https://eco.bigelow.org/

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Adding great circle routes as polylines in Leaflet

Kent Johnson
In reply to this post by dhirajkhanna
>
> From: Dhiraj Khanna <[hidden email]>
> To: [hidden email]
> Subject: [R-sig-Geo] Adding great circle routes as polylines in
>         Leaflet
> Message-ID:
>         <CANHhK31knXB+8ev2LEQWOa3y+ZaUgkJ5noAV=iX7Z14j_foqZw@
> mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> I am trying to add great circle routes between various regions in R.
>
> I would like to plot great circle routes between CommencingRegion to
> LoadingRegion and then from LoadingRegion to DischargeRegion for every row.
> Additionally, every row needs to be in a different color and the thickness
> needs to be proportional to AvgTCE. The last 6 variables in the data above
> are the coordinates in Lat Long for the commencing, loading and discharging
> regions respectively. I am quite clueless on how to go about achieving
> this. This is what I have tried and failed:
>
> leaflet() %>%
>   addTiles() %>%
>   for(i in 1:6){
>     addPolylines(data=gcIntermediate(c(ByRoute$CLon[
> i],ByRoute$CLat[i]),c(ByRoute$LLon[i],ByRoute$CLat[i]),n=100,addStartEnd
> = T,sp=T))
>   }
>
> Here is a (rather clunky) start:
library(leaflet)
library(geosphere)
library(dplyr)

d = byRoute %>%
  rowwise() %>%
  do(leg1=gcIntermediate(c(.$CLon, .$CLat), c(.$LLon, .$LLat), n=50,
addStartEnd=TRUE),
     leg2=gcIntermediate(c(.$LLon, .$LLat), c(.$DLon, .$DLat), n=50,
addStartEnd=TRUE))

colors=palette()
map = leaflet() %>% addTiles()
for (i in seq_len(nrow(d)))
  map = map %>% addPolylines(data=d$leg1[[i]], color=colors[i],
weight=byRoute$AvgTCE[i]/3000-5) %>%
  addPolylines(data=d$leg2[[i]], color=colors[i],
weight=byRoute$AvgTCE[i]/3000-5)
map

You will have to split the great circles using something like
the plot_my_connection function here:
https://www.r-graph-gallery.com/how-to-draw-connecting-routes-on-map-with-r-and-great-circles/

Is this shipping data? Maybe great circles are not the correct route...
Kent


> Regards
> Dhiraj Khanna
> Mob:09873263331

        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Adding great circle routes as polylines in Leaflet

dhirajkhanna
Ben and Kent, thank you so much for your replies. Both work!

@Ben next time will make sure the code is more “calorie-free” :)

@Kent Johnson <[hidden email]> I modified the weight for the lines by
using a scaling factor.

myScale <- function(x){(x-min(x))/(max(x)-min(x))}

ByRoute$AvgTCE <- myScale(ByRoute$AvgTCE)*5 + 1

@Kent Johnson <[hidden email]> yes, this is shipping data and you are
right, great circle routes are not the best visualization. The problem I am
facing is that I have oil trade happening over a period of time from
various ports that I need to visualize. Over the selected period of time,
there are hundreds of voyages being undertaken by ships. Plotting them all
as gc routes looks ugly. My approach has been to classify these ports into
regions, which I drew using mapedit and saved them as SF polygons. I then
calculated their centroids and those are the coordinates in the ByRoute
dataframe. Would appreciate your comments on any other visualization which
you think might be appropriate.

Regards
Dhiraj Khanna
Mob:09873263331

On Mon, Sep 3, 2018 at 10:22 PM Kent Johnson <[hidden email]> wrote:

> From: Dhiraj Khanna <[hidden email]>
>> To: [hidden email]
>> Subject: [R-sig-Geo] Adding great circle routes as polylines in
>>         Leaflet
>> Message-ID:
>>         <CANHhK31knXB+8ev2LEQWOa3y+ZaUgkJ5noAV=
>> [hidden email]>
>> Content-Type: text/plain; charset="utf-8"
>>
>> I am trying to add great circle routes between various regions in R.
>>
>> I would like to plot great circle routes between CommencingRegion to
>> LoadingRegion and then from LoadingRegion to DischargeRegion for every
>> row.
>> Additionally, every row needs to be in a different color and the thickness
>> needs to be proportional to AvgTCE. The last 6 variables in the data above
>> are the coordinates in Lat Long for the commencing, loading and
>> discharging
>> regions respectively. I am quite clueless on how to go about achieving
>> this. This is what I have tried and failed:
>>
>> leaflet() %>%
>>   addTiles() %>%
>>   for(i in 1:6){
>>
>> addPolylines(data=gcIntermediate(c(ByRoute$CLon[i],ByRoute$CLat[i]),c(ByRoute$LLon[i],ByRoute$CLat[i]),n=100,addStartEnd
>> = T,sp=T))
>>   }
>>
>> Here is a (rather clunky) start:
> library(leaflet)
> library(geosphere)
> library(dplyr)
>
> d = byRoute %>%
>   rowwise() %>%
>   do(leg1=gcIntermediate(c(.$CLon, .$CLat), c(.$LLon, .$LLat), n=50,
> addStartEnd=TRUE),
>      leg2=gcIntermediate(c(.$LLon, .$LLat), c(.$DLon, .$DLat), n=50,
> addStartEnd=TRUE))
>
> colors=palette()
> map = leaflet() %>% addTiles()
> for (i in seq_len(nrow(d)))
>   map = map %>% addPolylines(data=d$leg1[[i]], color=colors[i],
> weight=byRoute$AvgTCE[i]/3000-5) %>%
>   addPolylines(data=d$leg2[[i]], color=colors[i],
> weight=byRoute$AvgTCE[i]/3000-5)
> map
>
> You will have to split the great circles using something like
> the plot_my_connection function here:
>
> https://www.r-graph-gallery.com/how-to-draw-connecting-routes-on-map-with-r-and-great-circles/
>
> Is this shipping data? Maybe great circles are not the correct route...
> Kent
>
>
>> Regards
>> Dhiraj Khanna
>> Mob:09873263331
>
>

        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Adding great circle routes as polylines in Leaflet

Kent Johnson
On Tue, Sep 4, 2018 at 12:18 AM, Dhiraj Khanna <[hidden email]>
wrote:

> @Kent Johnson <[hidden email]> yes, this is shipping data and you are right, great circle routes are not the best visualization. The problem I am facing is that I have oil trade happening over a period of time from various ports that I need to visualize. Over the selected period of time, there are hundreds of voyages being undertaken by ships. Plotting them all as gc routes looks ugly. My approach has been to classify these ports into regions, which I drew using mapedit and saved them as SF polygons. I then calculated their centroids and those are the coordinates in the ByRoute dataframe. Would appreciate your comments on any other visualization which you think might be appropriate.
>
> If your primary interest is to visualize the flows (not the geography)
then a circle plot might work well. Here is an example showing migration
flows:
https://gjabel.wordpress.com/2016/05/18/updated-circular-plots-for-directional-bilateral-migration-data/
made with
https://cran.r-project.org/web/packages/circlize/index.html

Kent


> Regards
> Dhiraj Khanna
>

        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo
Reply | Threaded
Open this post in threaded view
|

Re: Adding great circle routes as polylines in Leaflet

dhirajkhanna
Thanks Kent, this looks great!
Hopefully I should be able to convince my client to use this as a
visualization rather than the rather sparse looking current visualization
on a leaflet map.
Regards

Dhiraj Khanna
Mob:09873263331


On Tue, Sep 4, 2018 at 3:55 PM Kent Johnson <[hidden email]> wrote:

>
>
> On Tue, Sep 4, 2018 at 12:18 AM, Dhiraj Khanna <[hidden email]>
> wrote:
>
>> @Kent Johnson <[hidden email]> yes, this is shipping data and you are right, great circle routes are not the best visualization. The problem I am facing is that I have oil trade happening over a period of time from various ports that I need to visualize. Over the selected period of time, there are hundreds of voyages being undertaken by ships. Plotting them all as gc routes looks ugly. My approach has been to classify these ports into regions, which I drew using mapedit and saved them as SF polygons. I then calculated their centroids and those are the coordinates in the ByRoute dataframe. Would appreciate your comments on any other visualization which you think might be appropriate.
>>
>> If your primary interest is to visualize the flows (not the geography)
> then a circle plot might work well. Here is an example showing migration
> flows:
>
> https://gjabel.wordpress.com/2016/05/18/updated-circular-plots-for-directional-bilateral-migration-data/
> made with
> https://cran.r-project.org/web/packages/circlize/index.html
>
> Kent
>
>
>> Regards
>> Dhiraj Khanna
>>
>

        [[alternative HTML version deleted]]

_______________________________________________
R-sig-Geo mailing list
[hidden email]
https://stat.ethz.ch/mailman/listinfo/r-sig-geo