Я работаю с огромными файлами .kml (до 10 Гб) и мне нужен эффективный способ чтения их в R. До сих пор я конвертировал их в шейп-файлы через QGIS, а затем обратно в R с помощью readShapePoly и readOGR (последний кстати, на ~ 1000 быстрее, чем прежний). В идеале я бы хотел исключить промежуточную стадию QGIS, так как она громоздкая и медленная.
Как читать файлы .kml напрямую?
Я вижу, что это также можно сделать с помощью readOGR . К сожалению, я не вижу, как реализовать сработавший пример (после длительной подготовки файла .kml:) xx <- readOGR(paste(td, "cities.kml", sep="/"), "cities")
. Кажется, что «города» здесь - это название пространственных объектов.
Роджер Биванд признает, что «как можно найти это имя, не очевидно, поскольку драйвер KML в OGR нуждается в нем для доступа к файлу. Одна из возможностей:
system(paste("ogrinfo", paste(td, "cities.kml", sep="/")), intern=TRUE)
"
Но это не работает для меня тоже. Вот тестовый файл .kml, чтобы попробовать его. С этим в моем рабочем каталоге, readOGR("x.kml", "id")
генерирует это сообщение об ошибке:
Error in ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv) :
Cannot open layer .
И system(paste("ogrinfo", "x.kml"), intern=TRUE)
генерирует:
[1] "Had to open data source read-only." "INFO: Open of `x.kml'"
[3] " using driver `KML' successful." "1: x (3D Polygon)"
что я просто не понимаю.
Будет ли getKMLcoordinates
{maptools} верной альтернативой?
Я также попробовал это:
tkml <- getKMLcoordinates(kmlfile="x.kml", ignoreAltitude=T)
head(tkml[[1]])
tkml <- SpatialPolygons(tkml,
proj4string=CRS("+init=epsg:3857"))
Координаты сгенерированы правильно, но моя попытка преобразовать их обратно в объект многоугольника не удалась со следующим сообщением:
Error in SpatialPolygons(tkml, proj4string = CRS("+init=epsg:3857")) :
cannot get a slot ("area") from an object of type "double"
Ответы:
Чтобы прочитать KML с помощью драйвера OGR, вы должны указать ему имя файла и имя слоя.
Комментарий Роджера заключается в том, что имя слоя скрыто в файле KML, и если вы не знаете, как был создан KML, вы не сможете вывести имя слоя из имени файла KML.
Глядя на ваш пример KML, я вижу:
Что говорит мне имя слоя
x
, а неid
, и так:работает хорошо.
Теперь, вы можете попытаться получить имя путем анализа KML , как XML , используя R XML парсер, или вы можете , возможно , попробуйте прочитать его в R в виде текстового файла до тех пор , пока не найдете имя тега.
Другой подход заключается в запуске программы ogrinfo из командной строки, которая выплевывает имена слоев файла KML:
здесь показано, что слой многоугольника называется
x
.источник
system
в R нужноpath.expand
на~
дляogrinfo
к работе, даже если он работал отлично на нераскрытом пути в командной строке (MacOS,Sys.which('ogrinfo')
иwhich ogrinfo
вернулись те же пути)Если вы хотите сделать альтернативный способ с помощью maptool, это должно работать:
Ключевым моментом здесь является то, что вам нужно пройти пару шагов, чтобы создать класс пространственного многоугольника.
источник
Не знаю, если это все еще проблема для кого-то еще, но я некоторое время бегал кругами с этим. То, что в итоге сработало для меня, ниже. Он использует
XML
пакет, чтобы добраться доxmlValue
нужного узла. Я должен был установитьlayer
параметрreadOGR
для имени одной из папок в файле kml. Когда я устанавливаюlayer
параметр в файл kml, я получаю ту же ошибку, что и RobinLovelace, описанный выше.Ниже показано много строк кода, которые показывают, как увидеть различные уровни узлов документа kml. Я думаю, что это будет немного отличаться в зависимости от источника кмл. Но вы должны иметь возможность использовать ту же логику, чтобы определить правильное значение параметра.
Кроме того , я создал список файлов KML так что это может быть легко превращен в функцию , которая может быть поставлена в
lapply
-do.call
парах. Затем можно получить данные из длинного списка файлов kml. Или много подпапок в одном файле kml, так как кажется, чтоreadOGR
они не могут работать с несколькими подпапками в файле kml.источник
Не знаю, должен ли я изменить свой предыдущий ответ. Возможно, но это касается некоторых вещей, не вошедших в этот ответ, поэтому я решил оставить это.
Во всяком случае, код ниже работает хорошо для меня. Он ищет все xmlNodes в файле kml, которые называются «Папка», а затем устанавливает
layer
параметрreadOGR
для этогоxmlValue
. Проверено на рабочем каталоге с 6 отдельными файлами kml. Выходные данные представляют собой список импортированных объектов SpatialDataFrames. Каждый SpatialDataFrame может быть легко подмножеством из списка.Все еще не обращается к файлам kml с несколькими узлами папки. Но эту функцию можно легко добавить с помощью другой вложенной
apply
функции.источник