Объединение нескольких файлов GPX в один файл GPX с несколькими дорожками - PullRequest
0 голосов
/ 16 февраля 2019

У меня есть несколько .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 с одной дорожкой.Поскольку два исходных файла начинаются и заканчиваются в разных местах, это приводит к большому скачку между концом одной дорожки и началом другой, когда вы загружаете это в Google Earth, и я хотел бы избежать этого.Как я могу изменить свою функцию 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 и попытаетесь загрузить его в Google Планета Земля, то ничего не произойдет - он не обнаружен в Google Планета Земля).

Спасибо!

Данные

## 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")
...