Экономный способ добавить стрелку севера и масштабную линейку в ggmap

Я пытаюсь использовать ggmap для создания карты охраняемых территорий, над которыми я работаю, со спутниковым изображением из Google Earth внизу. Я могу сделать очень удовлетворительное изображение, за исключением того, что на нем отсутствует стрелка севера и масштабная линейка:

введите описание изображения здесь

Я знаю, что есть очень длинные способы добавления этих элементов (например, здесь ), но наверняка должен быть более экономный способ сделать это!

Я пробовал использовать map.scale и north.arrow, но оба они дают мне:

Error in polygon(xb + arrow.x * s, yb + arrow.y * s, ...) : 
  plot.new has not been called yet

Я могу заставить и map.scale, и north.arrow работать в базе R, используя plot, но тогда я не могу правильно построить свой спутниковый снимок. Я также могу получить то, что хочу, используя arrows и text в базе R, но опять же, в ggmap это не сработает.

Код, который я использую, приведен ниже. У вас не будет многоугольника (поэтому я не буду включать его в код), но вы сможете загрузить изображение Google Earth и воспроизвести ошибку.

library(rgdal)
library(ggmap)
library(GISTools)

# Load satellite picture

map.centre <- c(lon = 35, lat = -2.5)
map <- get_map(location=map.centre, source="google", maptype="satellite", zoom = 8)

# Plot map

ggmap(map, extent= "device")

map.scale(xc= 34, yc= -3, len= 10, units= "Kilometers",
 ndivs= 4, tcol= "black", scol= "black", sfcol="black")

north.arrow(xb= 35.5, yb= -1, len=100, lab="N")

После небольшого чтения кажется, что функции map.scale и north.arrow не распознают окно, которое функция ggmap создает как открытое графическое окно. Я провел небольшое исследование и попытался исправить это, но ничего не помогло. Может ли кто-нибудь предложить способ исправить ошибку, которую я получаю, или получить масштабную линейку и стрелку севера в ggmap без использования сотен строк кода?


person James    schedule 21.08.2016    source источник
comment
пакет ggsn у вас не работал? (cran.rstudio.com/web/packages/ggsn) Кроме того, если вы действительно заботится о краткости, "сжатый" - это на 3 символа меньше и $ BIGWORD.   -  person hrbrmstr    schedule 21.08.2016
comment
Это тот, который мне подходит: github.com/3wen/legendMap Мне нравится внешний вид ggsn , но слишком много возни, чтобы заставить его работать с ggmap, по сравнению с legendMap   -  person Ben    schedule 03.05.2017


Ответы (2)


Похоже, что map.scale и north.arrow предназначены для работы с базовой графикой, но ggplot использует grid графику. Я не так хорошо знаком с графическим отображением пространственных данных, но в качестве быстрого взлома стрелки севера приведенный ниже код включает два разных варианта:

ggmap(map, extent= "device") +
  geom_segment(arrow=arrow(length=unit(3,"mm")), aes(x=33.5,xend=33.5,y=-2.9,yend=-2.6), 
               colour="yellow") +
  annotate(x=33.5, y=-3, label="N", colour="yellow", geom="text", size=4) +
  geom_segment(arrow=arrow(length=unit(4,"mm"), type="closed", angle=40), 
               aes(x=33.7,xend=33.7,y=-2.7,yend=-2.6), colour=hcl(240,50,80)) +
  geom_label(aes(x=33.7, y=-2.75, label="N"),
             size=3, label.padding=unit(1,"mm"), label.r=unit(0.4,"lines"))  

введите описание изображения здесь

person eipi10    schedule 21.08.2016

Я обычно использую свою функцию для рисования масштабных полос на ggmaps. Это дает вам прекрасный контроль, чтобы выложить его именно так, как вы хотите. Например,

scalebar = function(x,y,w,n,d, units="km"){
  # x,y = lower left coordinate of bar
  # w = width of bar
  # n = number of divisions on bar
  # d = distance along each division

  bar = data.frame( 
    xmin = seq(0.0, n*d, by=d) + x,
    xmax = seq(0.0, n*d, by=d) + x + d,
    ymin = y,
    ymax = y+w,
    z = rep(c(1,0),n)[1:(n+1)],
    fill.col = rep(c("black","white"),n)[1:(n+1)])

  labs = data.frame(
    xlab = c(seq(0.0, (n+1)*d, by=d) + x, x), 
    ylab = c(rep(y-w*1.5, n+2), y-3*w),
    text = c(as.character(seq(0.0, (n+1)*d, by=d)), units)
    )
  list(bar, labs)
}

sb = scalebar(33.5, -3.8, 0.05, 5, 0.3, "degrees" )

# Plot map

ggmap(map, extent= "device") +
  geom_rect(data=sb[[1]], aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, fill=z), inherit.aes=F,
            show.legend = F,  color = "black", fill = sb[[1]]$fill.col) +
  geom_text(data=sb[[2]], aes(x=xlab, y=ylab, label=text), inherit.aes=F, show.legend = F) 

введите описание изображения здесь

person dww    schedule 22.08.2016
comment
Хороший. Я использовал его с проекцией измерителя. Изменена следующая часть text = c(as.character(seq(0.0, ((n+1)*d)/1000, by=d/1000)), units), чтобы на шкале масштаба отображались номера км. - person Andre Silva; 03.11.2017