Как повернуть символы (представляющие данные пространственной точки) на основе функции с Tmap и SF? - PullRequest
0 голосов
/ 11 января 2019

Я хочу представить 2 корабля на карте в интерактивном режиме (метод листовки), а также некоторые их метаданные. Естественно, что метаданные судна обычно содержат курс судна, и наиболее легко усваиваемый способ представить это - соответственно повернуть символ данных точки.

После некоторых первых испытаний мне удалось воссоздать его, выполнив вращение значка в пакете листовок , используя простую листовку и плагин, который позволял мне писать в гладком синтаксисе, например rotationAngle=~T_heading. Результат этого пути выглядит следующим образом. enter image description here

Однако я ищу способ использования пакетов sf и tmap в качестве синтаксиса (интерактивное представление tmap также основано на листовках), поскольку они представляют собой гораздо более совершенные и сложные структуры для управления и визуализации геопространственной информации.

Давайте снова воссоздаем образцы данных двух судов и нанесем их на график.

aship<-c(23.622333,37.937489,'Santa Maria',8,300)
bship<-c(23.621303,37.937430,'Vancouver CC',10,35)
shipdata<-data.frame(rbind(aship,bship))
colnames(shipdata)<-c('long','lat','VesselName','sog','T_heading')
shipdata$long<-as.numeric(as.character(shipdata$long))
shipdata$lat<-as.numeric(as.character(shipdata$lat))
shipdata$sog<-as.numeric(as.character(shipdata$sog))
shipdata$T_heading<-as.numeric(as.character(shipdata$T_heading))
#Simple features transformation 
ship_sf<-shipdata%>%
st_as_sf(coords=c('long','lat'))%>%
st_set_crs(4326)
# Use tmap and plot the vessels using a vessel_icon of my own
map_s1<-tm_basemap(leaflet::providers$OpenStreetMap)+
tm_shape(ship_sf)+
tm_markers(shape = vessel_icon)+
tm_view(set.view=c(lon=23.622333,lat=37.937489,zoom=17))

enter image description here

До сих пор я не нашел способа вращать маркеры способом tmap. Есть ли какое-то простое решение, которое я пропускаю?

высоко ценится

1 Ответ

0 голосов
/ 21 января 2019

Это решение на основе leaflet. Не может быть супер удовлетворительным, но мне кажется менее хакерским, чем другие решения ( это или это ). Как вы сказали, tmap использует leaflet, поэтому простым решением является использование addAwesomeMarkers и небольшая настройка значков. Создайте свою карту с помощью tmap, как вы сделали, и создайте из нее виджет листовки с tmap_leaflet(). Обратите внимание, что это аналогичный случай: R Листовка с указанием направления корабля .

Ваши данные и объект tmap:

library(tmap)
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
library(leaflet)

tmap_mode("view")
#> tmap mode set to interactive viewing

# Your data
shipdata <- data.frame(long = c(23.622333, 23.62130),
                       lat = c(37.93749, 37.93743),
                       VesselName = c("Santa Maria", "Vancouver CC"),
                       sog = c(8, 10),
                       T_heading = c(300, 35))
ship_sf <- st_as_sf(x = shipdata, 
                    coords = c('long', 'lat'), 
                    crs = "+proj=longlat +datum=WGS84")

# Make use of tmap functionality to produce the map as you posted
map_s1 <-
  tm_basemap(leaflet::providers$OpenStreetMap) +
  tm_shape(ship_sf) +
  tm_symbols(size = 0) + # need to add a layer after tm_shape(), so add "empty" points
  tm_view(set.view = c(lon = 23.622333, lat = 37.937489, zoom = 17))

Теперь подделайте несколько значков; см. также https://ionicons.com Хорошо работает только значок со стрелкой вверх при заданных углах поворота; другие стрелки уже имеют свое собственное вращение, которое может все испортить. Затем перенаправьте объект tmap в tmap_leaflet(), чтобы создать виджет листовки. Наконец, добавьте пользовательские значки:

shipIcon <- makeAwesomeIcon(icon = "arrow-up",
                            iconRotate = shipdata$T_heading,
                            squareMarker = TRUE,
                            markerColor = "black")

map_s1 %>% 
  tmap_leaflet() %>% 
  addAwesomeMarkers(lng = shipdata$lon, 
                    lat = shipdata$lat, 
                    icon = shipIcon, 
                    popup = shipdata$VesselName)

Дополнительные мысли

Другая идея заключается в использовании функции iconList() (упомянутой здесь , например), определяющей серию повернутых изображений / значков, соответствующих нескольким классам вращения. Другой подход в этом направлении представлен здесь .

Создано в 2019-01-21 с помощью представительного пакета (v0.2.1)

...