我想创建一个显示城市公共(public)交通线路的交互式 map 。我正在尝试使用 R 中的 Leaflet 来做到这一点(但我愿意接受替代方案,建议?)

数据:传输系统的数据是 GTFS 格式,组织在文本文件(.txt)中,我将其作为数据框读入 R。*

问题:我找不到如何指示每条 Poly 线的 id(变量 shape_id),因此该图实际上会遵循每条公交线的路线。相反,它以随机顺序连接点。

这是我尝试过的,到目前为止没有成功:

# Download GTFS data of the Victoria Regional Transit System 
  tf <- tempfile()  
  td <- tempdir() 
  ftp.path <- "http://www.gtfs-data-exchange.com/agency/bc-transit-victoria-regional-transit-system/latest.zip" 
  download.file(ftp.path, tf)  
 
# Read text file to a data frame 
  zipfile <- unzip( tf , exdir = td ) 
  shape <- read.csv(zipfile[9]) 
 
# Create base map 
  basemap <- leaflet() %>% addTiles() 
 
 
# Add transit layer 
  basemap  %>% addPolylines(lng=shape$shape_pt_lon, lat=shape$shape_pt_lat,  
                            fill = FALSE, 
                            layerId =shape$shape_id)  

我很高兴收到您对此的评论。

*我知道可以将此数据导入 GIS 软件(例如 QGIS)以创建 shapefile,然后使用 readOGR 将 shapefile 读入 R。 Robin Lovelace has shown how to do this .但是,我正在寻找一个纯 R 解决方案。 ;)

附言。 Kyle Walker has written a great intro to interactive maps in R using Leaflet .不幸的是,他没有在他的教程中介绍折线。

请您参考如下方法:

您的问题不是方法之一,而是数据:请注意,您下载了 8 MB,并且您尝试通过 Shiny 加载到 Leaflet 的行文件是 5 MB。作为一般原则,您应该始终先尝试使用小型数据集的新方法,然后再扩大规模。这就是我在下面诊断问题并解决问题的方法。

第 1 阶段:探索和子集数据

pkgs <- c("leaflet", "shiny" # packages we'll use 
  , "maps" # to test antiquated 'maps' data type 
  , "maptools" # to convert 'maps' data type to Spatial* data 
  ) 
lapply(pkgs, "library", character.only = TRUE) 
 
 
class(shape) 
## [1] "data.frame" 
 
head(shape) 
 
##   shape_id shape_pt_lon shape_pt_lat shape_pt_sequence 
## 1 1-39-220    -123.4194     48.49065                 0 
## 2 1-39-220    -123.4195     48.49083                 1 
## 3 1-39-220    -123.4195     48.49088                 2 
## 4 1-39-220    -123.4196     48.49123                 3 
## 5 1-39-220    -123.4197     48.49160                 4 
## 6 1-39-220    -123.4196     48.49209                 5 
 
object.size(shape) / 1000000 # 5 MB!!! 
 
## 5.538232 bytes 
 
summary(shape$shape_id) 
shape$shape_id <- as.character(shape$shape_id) 
ids <- unique(shape$shape_id) 
shape_orig <- shape 
shape <- shape[shape$shape_id == ids[1],] # subset the data 

第 2 阶段:转换为 Spatial* 对象

这像 data.frame map 中的物体?
state.map <- map("state", plot = FALSE, fill = TRUE) 
str(state.map) 
 
## List of 4 
##  $ x    : num [1:15599] -87.5 -87.5 -87.5 -87.5 -87.6 ... 
##  $ y    : num [1:15599] 30.4 30.4 30.4 30.3 30.3 ... 
##  $ range: num [1:4] -124.7 -67 25.1 49.4 
##  $ names: chr [1:63] "alabama" "arizona" "arkansas" "california" ... 
##  - attr(*, "class")= chr "map" 

是的,类似,所以我们可以使用 map2Spatial*转换它:
shape_map <- list(x = shape$shape_pt_lon, y = shape$shape_pt_lat) 
shape_lines <- map2SpatialLines(shape_map, IDs = ids[1]) 
plot(shape_lines) # success - this plots a single line! 



第 3 阶段:将所有线路连接在一起

一个 for循环会很好地做到这一点。请注意,我们只使用前 10 行。使用 2:length(ids)对于所有行:
for(i in 2:10){ 
  shape <- shape_orig[shape_orig$shape_id == ids[i],] 
  shape_map <- list(x = shape$shape_pt_lon, y = shape$shape_pt_lat) 
  shape_temp <- map2SpatialLines(shape_map, IDs = ids[i]) 
  shape_lines <- spRbind(shape_lines, shape_temp) 
} 

第 4 阶段:情节

使用 SpatialLines object 使代码更短 - 在这种情况下,这将绘制前 10 行:
leaflet() %>%  
  addTiles() %>% 
  addPolylines(data = shape_lines) 



结论

在将其转换为具有正确 ID 的 Spatial* 数据类型进行绘图之前,您需要使用数据并对其进行操作。 maptools::map2Spatial* , unique()和一个聪明的 for循环可以解决问题。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!