icon rotation in leaflet package
Asked Answered
S

2

6

I'm learning to program in R with the leaflet package. I want to give an angle to the icons, and am trying it with this code:

m <- leaflet()
m <- addTiles(m,urlTemplate = "http://xdworld.vworld.kr:8080/2d/Base/201310/{z}/{x}/{y}.png")
m = m %>% setView(127.074167,34.456806, zoom = 9)
arrowIcon <- makeIcon(
  iconUrl = "arrow.png" 
  ,iconWidth = 100, iconHeight = 100 
  ,iconAnchorX = 25, iconAnchorY =25
)
arrowIcon <- makeIcon(
  iconUrl = "ARROW_B2.png" 
  ,iconWidth = 100, iconHeight = 100 
  ,iconAnchorX = 25, iconAnchorY = 25
)
offset = 0.00 # zoom 10-> 0.03, 9->0.06, 8 -> 0.12, 7 -> 0.24
m_lat = 34.45 + offset
m_lon = 127.07 - offset
m <- addMarkers(m,  lng=m_lon, lat= m_lat
            , options = c( markerOptions(), iconAngle= 0)
            ,icon= arrowIcon)
m <- addCircles(m, lng=127.07, lat=34.45 , weight = 10,radius = 100)
m

However, it does not work.

Shu answered 1/12, 2015 at 12:6 Comment(2)
hi Seo there is no need to add unnecessary bold font there. And also there is no need to put a line full of "=" at bottom of the code block.Pharyngitis
Thank you NSNoob. I'm so insufficient because I'm first here. :)Shu
B
6

This is the only way I could get it to work. You want to use the RotatedMarker plugin, available here. To use this plugin with R, I followed instructions here.

Two things to be aware of that I can't seem to figure out:

  1. I can't seem to find the icon when it's stored locally - it needs to be accessible via URL. If you can fix that, please let me know.

  2. You need to download the javascript file and save it locally. In the example below I've put it in the same directory as my R script. Theoretically you should be able to load it via a URL but that doesn't work. If you can fix that, please let me know.

So here's the working code:

library(htmltools)
library(htmlwidgets)
library(leaflet)

# this is taken from: https://gist.github.com/jcheng5/c084a59717f18e947a17955007dc5f92
rotatedMarker <- htmlDependency(
  "Leaflet.rotatedMarker",
  "0.1.2",
  src = normalizePath("."),
  script = "leaflet.rotatedMarker.js"
)

# this is taken from: https://gist.github.com/jcheng5/c084a59717f18e947a17955007dc5f92
registerPlugin <- function(map, plugin) {
  map$dependencies <- c(map$dependencies, list(plugin))
  map
}

leaflet() %>%
  addTiles(urlTemplate = "http://xdworld.vworld.kr:8080/2d/Base/201310/{z}/{x}/{y}.png") %>%
  setView(127.074167,34.456806, zoom = 9) %>%
  registerPlugin(rotatedMarker) %>%
  onRender("function(el, x) {
    var planeIcon = L.icon({iconUrl: 'https://raw.githubusercontent.com/bbecquet/Leaflet.PolylineDecorator/master/example/icon_plane.png', iconAnchor: [16, 16]});
    var pathPattern = L.marker([34.45, 127.07], {icon: planeIcon, rotationAngle: 90}).addTo(this);
  }") %>%
  addCircles(lng = 127.07, lat = 34.45, weight = 10, radius = 100)

Which produces: Leaflet in R with rotated icons!

Notice that I've rotated the plane icon 90 degrees.

Bewick answered 30/3, 2017 at 15:59 Comment(4)
is it possible to extend this solution for more icons each with a different rotation?Cornett
a bit less hacky way than the onRender workaround would be to use planeIcon = makeIcon(...) first, and then set icon = planeIcon in the addMarkers). The rotation can be then added using options = markerOptions(rotationAngle = c(90))`. The rest is identical.Cowhide
@Cornett if you do it the way I described above, a loop with %>% should be possible, but no vectorized way of doing it. The thing is, marker's are static, and rotation is their property. So, the same marker with different angels is actually two different markers. Although, I think the original package leaflet.rotatedMarker.js could be extended. Which is probably your best bet, if you really need to use various rotations mass-scale.Cowhide
@Bewick I am trying to do something similar but rotation for me is an angle value stored as a variable in a dataframe. How can I use that? #50453250Burgos
T
1

For your first point, I've found that you can load your image if it's stored in a directory named www.

|
|- app.R
|- www
    |- icon_plane.pg

Then you'll be able to load it with this piece of code

onRender("function(el, x) {
          var planeIcon = L.icon({iconUrl: 'icon_plane.png', iconAnchor:[16, 16]});
          var pathPattern = L.marker([34.45, 127.07], {icon: planeIcon, rotationAngle: 90}).addTo(this);
          }")

Becareful of loading correctly your js file. I spent a lot of time looking why my image wasn't showing and finally it was only because my script wasn't in the correct place.

Toplevel answered 17/11, 2017 at 13:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.