Листовки Полилинии не go над линией даты Листовка - PullRequest
1 голос
/ 24 февраля 2020

Для проекта Shiny uni я столкнулся с проблемами с полилиниями, пересекающими линию даты в океане Pacifi c. Из одного центра (Ухань) я хотел бы создать 72 линии, показывающие их связь с разными регионами. Я уже создал al oop, чтобы убедиться, что долготы> 0 были изменены на долготу больше 0. У кого-нибудь есть решение, чтобы полилинии правильно пересекли линию даты?

На фотографии, которую вы Я вижу, что мой текущий график неправильно пересекает линию.

library(leaflet)
library(geosphere)
library(sp)

df <- read.table(text = "
Longitude.Central Latitude.Central Longitude Latitude
112.2707         30.97564  117.2264 31.82571
112.2707         30.97564  116.4142 40.18238
112.2707         30.97564    4.4699 50.50390
112.2707         30.97564  -71.0589 42.36010
112.2707         30.97564 -123.1210 49.28270
112.2707         30.97564  104.9910 12.56570",
           header = TRUE)

p1 <- as.matrix(df[,c(1,2)])
p2 <- data.frame(df[,c(3,4)])

p3 <- matrix(nrow = length(p2))
for (j in 1:nrow(p2)) {
  if (p2[j,]$Longitude < 0) {
    p3[j] <- p2[j,]$Longitude + 360
  } else {
    p3[j] <- p2[j,]$Longitude
  }
}

p2 <- as.matrix(cbind(p3, p2$Latitude))
df2 <- gcIntermediate(
  p1, p2, 
  n = 72, 
  addStartEnd = TRUE,
  sp = T)

leaflet( ) %>% 
    setView(df$Longitude.Central[[1]], lat = df$Latitude.Central[[1]], 1) %>%
    addTiles(urlTemplate = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png") %>% 
    addPolylines(data = df2, weight = 1
    )

# Head of the data
> head(df)
# A tibble: 6 x 4
  Longitude.Central Latitude.Central Longitude Latitude
              <dbl>            <dbl>     <dbl>    <dbl>
1          112.2707         30.97564  117.2264 31.82571
2          112.2707         30.97564  116.4142 40.18238
3          112.2707         30.97564    4.4699 50.50390
4          112.2707         30.97564  -71.0589 42.36010
5          112.2707         30.97564 -123.1210 49.28270
6          112.2707         30.97564  104.9910 12.56570

Output Shiny

1 Ответ

0 голосов
/ 25 февраля 2020

Есть несколько вещей, которые вы можете попробовать. Одним из них является использование опции breakAtDateLine = TRUE в gcIntermediate:

df2 <- gcIntermediate(
  p1, p2, 
  n = 72, 
  addStartEnd = TRUE,
  sp = T,
  breakAtDateLine = T)

leaflet( ) %>% 
  setView(lng = df$Longitude.Central[[1]], lat = df$Latitude.Central[[1]], 1) %>%
  addTiles(urlTemplate = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png") %>% 
  addPolylines(data = df2, weight = 1
  )

Как вы можете видеть, она ломает линию, но продолжает ее в левой части экрана, что не идеально.

enter image description here

Еще одна вещь, которую мы могли бы попробовать, - запустить функцию gcIntermediate с помощью breakAtDateLine = FALSE и вручную настроить широту и долготу после . запустить функцию. Это будет проще всего, если мы установим sp=FALSE.

Обратите внимание, что нам нужно только исправить линии, которые идут на восток от нашего местоположения - это единственные, которые пересекают линию даты. Это не будет одинаковым для всех локаций, но логика c должна быть похожей.

p1 <- as.matrix(df[,c(1,2)])
p2 <- data.frame(df[,c(3,4)])

df2 <- gcIntermediate(
  as.matrix(p1),
  as.matrix(p2), 
  n = 72, 
  addStartEnd = TRUE,
  breakAtDateLine = F,
  sp = F)

# correct the longitudes
res <- lapply(df2, function(x) {
  # if direction is east, correct lon, else don't
  if(x[,'lon'][2] - x[,'lon'][1]  > 0){
    cbind(lon =ifelse(x[,'lon']<0, x[,'lon'] + 360, x[,'lon']), lat = x[,'lat'])
  } else {
    x
  }
})

# and convert back to sp (I just took this code from the gcIntermediate function)
for (i in 1:length(res)) {
  if (!is.list(res[[i]])) {
    res[[i]] <- Lines(list(Line(res[[i]])), ID = as.character(i))
  }
  else {
    res[[i]] <- Lines(list(Line(res[[i]][[1]]), Line(res[[i]][[2]])), 
                      ID = as.character(i))
  }
}

res <- SpatialLines(res, CRS("+proj=longlat +ellps=WGS84"))


leaflet() %>% 
  setView(df$Latitude.Central[[1]], lat = df$Longitude.Central[[1]], 1) %>%
  addTiles(urlTemplate = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png") %>% 
  addPolylines(data = res, weight = 1) 

enter image description here

Это все равно немного странно, когда достигает вершины карты, но, надеюсь, это то, с чем вы можете жить

...