我有多个.gpx
文件,我想使用 R 将多个文件合并为具有多个轨道的单个文件。例如,可以在此处下载两个文件:
https ://github.com/twesleyb/StackOverflow/blob/master/Afternoon_Ride.gpx
https://github.com/twesleyb/StackOverflow/blob/master/Evening_Run.gpx
注意:我尝试用 下载这些download.file()
,但是.gpx
文件的格式搞砸了,所以不要这样做。手动下载它们。或者,您可以复制我在下面粘贴的一些数据作为最小示例。
gpx_files <- c("Evening_Run.gpx","Afternoon_Ride.gpx")
我可以使用包加载文件plotKML
。
library(plotKML)
# Create empty list for storing .gpx files.
list_gpx <- list()
# Loop to read files, store in a list with name:
for (i in seq_along(gpx_files)){
list_gpx[[i]] <- readGPX(gpx_files[1])
names(list_gpx)[[i]] <- gpx_files[i]
}
gpx 数据存储在数据帧轨道中。我可以从列表中提取每个,然后将它们合并到一个数据框中。
# Loop through list_gpx, get track df, clean up columns, and save in list.
# Empty list for tracks.
track_list <- list()
# Loop
for (i in 1:length(list_gpx)){
track_list[[i]] <- do.call(cbind,list_gpx[[i]]$tracks[[1]])[,c(1:4)]
if (grepl("Run",colnames(track_list[[i]]))==TRUE){
track_list[[i]]$activity <- rep("Run",nrow(track_list[[i]]))
}else{
track_list[[i]]$activity <- rep("Bike",nrow(track_list[[i]]))
}
names(track_list[[i]]) <- c("lon","lat","ele","time","activity")
}
# Merge dataframes in track_list.
data <- do.call(rbind,track_list)
我有一个自定义函数(改编自此处),用于将此数据写入新文件。结果是一个.gpx
文件,其中包含来自两个文件的曲目信息。
# A function for writting GPX files.
writeGPX <- function(lat,lon,ele,time,file="file.gpx"){
o <- c('<gpx version="1.1" creator="R">','<trk>','<trkseg>')
o <- c(o, paste('<trkpt lat="',lat,'" lon="',lon,'"><time>',
paste("<ele>",ele,"</ele>",sep=""),
paste(gsub(' ','T', as.character(time)), 'Z', sep=''),'</time></trkpt>', sep=''))
o <- c(o, '</trkseg>', '</trk>', '</gpx>')
cat(o, file=file, sep='\n')
}
# Write gpx data to a new file.
lat <- data$lat
lon <- data$lon
ele <- data$ele
time <- data$time
writeGPX(lat,lon,ele,time,file=paste(Sys.Date(),"merged.gpx",sep="_"))
问题是,这会导致.gpx
文件只有一条轨道。因为这两个原始文件在不同的地方开始和结束,所以当你将它加载到谷歌地球时,这会导致一个轨道的结尾和另一个轨道的开头之间有一个很大的跳跃,我想避免这种情况。如何修改我的writeGPX
函数或使用其他现有函数来编写.gpx
具有多个轨道的单个文件?
附录:
一个简单的.gpx
轨道可能如下所示:
<trk>
<trkseg>
<trkpt lat="40.779" lon="-74.428" />
<trkpt lat="40.777" lon="-74.418" />
</trkseg>
</trk>
</gpx>
所以,我的问题的一个天真的解决方案可能是这样的:
<gpx version="1.1" creator="R">
<trk>
<trkseg>
<trkpt lat="40.779" lon="-74.428" />
<trkpt lat="40.777" lon="-74.418" />
</trkseg>
<trkseg>
<trkpt lat="50.779" lon="-64.428" />
<trkpt lat="50.777" lon="-64.418" />
</trkseg>
</trk>
</gpx>
但是,这不起作用(如果您将其保存为 .gpx 并尝试将其加载到谷歌地球中,则没有任何反应——谷歌地球中未检测到它)。
谢谢!
数据
## The last 10 lines of evening_run and first ten lines of afternoon_ride:
data <- structure(list(lon = c(-79.045899, -79.045919, -79.045937, -79.045951,
-79.045967, -79.046174, -79.04619, -79.046203, -79.046302, -79.046311,
-79.046704, -79.046694, -79.046687, -79.046702, -79.046727, -79.046735,
-79.046739, -79.046752, -79.046879, -79.046885), lat = c(35.898049,
35.89805, 35.898054, 35.898059, 35.898066, 35.8981, 35.898108,
35.898115, 35.898169, 35.898177, 35.898017, 35.898038, 35.898021,
35.89801, 35.898004, 35.897989, 35.897964, 35.897954, 35.897897,
35.897905), ele = c("99.6", "99.6", "99.8", "99.8", "99.8", "101.2",
"101.2", "101.2", "101.6", "102.0", "105.8", "134.2", "134.2",
"134.2", "107.2", "107.0", "107.2", "107.4", "107.6", "107.6"
), time = c("2019-02-06T01:34:35Z", "2019-02-06T01:34:36Z", "2019-02-06T01:34:37Z",
"2019-02-06T01:34:38Z", "2019-02-06T01:34:39Z", "2019-02-06T01:34:52Z",
"2019-02-06T01:34:53Z", "2019-02-06T01:34:54Z", "2019-02-06T01:35:02Z",
"2019-02-06T01:35:07Z", "2019-02-06T00:15:59Z", "2019-02-06T00:16:00Z",
"2019-02-06T00:16:01Z", "2019-02-06T00:16:03Z", "2019-02-06T00:16:04Z",
"2019-02-06T00:16:05Z", "2019-02-06T00:16:09Z", "2019-02-06T00:16:10Z",
"2019-02-06T00:16:15Z", "2019-02-06T00:16:17Z"), activity = c("Run",
"Run", "Run", "Run", "Run", "Run", "Run", "Run", "Run", "Run",
"Run", "Run", "Run", "Run", "Run", "Run", "Run", "Run", "Run",
"Run")), row.names = c(1020L, 1021L, 1022L, 1023L, 1024L, 1025L,
1026L, 1027L, 1028L, 1029L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L,
10L), class = "data.frame")