Saya sedang bekerja dengan file .kml besar (hingga 10 Gb) dan perlu cara yang efisien untuk membacanya menjadi R. Sampai sekarang saya telah mengonversinya menjadi shapefile melalui QGIS dan kemudian kembali ke R dengan readShapePoly dan readOGR (yang terakhir , omong-omong, ~ 1000 lebih cepat dari yang sebelumnya). Saya idealnya ingin memotong tahap perantara QGIS karena rumit dan lambat.
Bagaimana cara membaca file .kml secara langsung?
Saya melihat ini bisa juga dilakukan dengan readOGR . Sayangnya, saya tidak bisa melihat bagaimana menerapkan contoh yang dikerjakan (setelah persiapan panjang file .kml:) xx <- readOGR(paste(td, "cities.kml", sep="/"), "cities")
. Tampaknya "kota" di sini adalah nama objek spasial.
Roger Bivand mengakui bahwa "Bagaimana seseorang menemukan nama ini tidak jelas, karena driver KML di OGR membutuhkannya untuk mengakses file. Salah satu kemungkinan adalah:
system(paste("ogrinfo", paste(td, "cities.kml", sep="/")), intern=TRUE)
"
Tapi ini juga tidak berhasil untukku. Berikut ini file uji .kml untuk dicoba. Dengan itu di direktori kerja saya, readOGR("x.kml", "id")
menghasilkan pesan kesalahan ini:
Error in ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv) :
Cannot open layer .
Dan system(paste("ogrinfo", "x.kml"), intern=TRUE)
menghasilkan:
[1] "Had to open data source read-only." "INFO: Open of `x.kml'"
[3] " using driver `KML' successful." "1: x (3D Polygon)"
, yang saya tidak mengerti.
Apakah getKMLcoordinates
{maptools} menjadi alternatif yang valid?
Saya juga sudah mencoba ini:
tkml <- getKMLcoordinates(kmlfile="x.kml", ignoreAltitude=T)
head(tkml[[1]])
tkml <- SpatialPolygons(tkml,
proj4string=CRS("+init=epsg:3857"))
Koordinat dihasilkan dengan benar, tetapi upaya saya untuk mengubahnya kembali menjadi objek poligon gagal dengan pesan berikut:
Error in SpatialPolygons(tkml, proj4string = CRS("+init=epsg:3857")) :
cannot get a slot ("area") from an object of type "double"
Jawaban:
Untuk membaca KML dengan driver OGR, Anda berikan nama file dan nama layer.
Komentar Roger adalah bahwa nama layer disembunyikan dalam file KML, dan kecuali Anda tahu bagaimana KML dibuat, Anda tidak dapat menyimpulkan nama layer dari nama file KML.
Melihat contoh KML Anda, saya dapat melihat:
Yang memberitahu saya nama layer adalah
x
, tidakid
, dan sebagainya:berfungsi dengan baik.
Sekarang, Anda bisa mencoba dan mendapatkan nama dengan parsing KML sebagai XML menggunakan parser R XML, atau Anda dapat mungkin mencoba membacanya di R sebagai file teks sampai Anda menemukan tag nama.
Pendekatan lain adalah menjalankan program ogrinfo baris perintah yang memuntahkan nama layer dari file KML:
di sini menunjukkan ada lapisan poligon yang disebut
x
.sumber
system
di R dibutuhkanpath.expand
pada~
untukogrinfo
bekerja, meskipun bekerja dengan baik di jalan tidak dikembangkan pada baris perintah (MacOS,Sys.which('ogrinfo')
danwhich ogrinfo
kembali jalur yang sama)Jika Anda ingin melakukan cara alternatif menggunakan maptool, ini harusnya berfungsi:
Kuncinya di sini adalah Anda harus melalui beberapa langkah untuk membuat kelas poligon spasial.
sumber
Tidak tahu apakah ini masih menjadi masalah bagi orang lain, tapi saya berlari berputar-putar untuk sementara waktu dengan ini. Apa yang akhirnya berhasil untuk saya ada di bawah ini. Ia menggunakan
XML
paket untuk mendapatkanxmlValue
dari simpul yang tepat. Saya harus mengaturlayer
parameterreadOGR
ke nama salah satu folder dalam file kml. Ketika saya mengaturlayer
parameter ke file kml, saya akan mendapatkan kesalahan yang sama seperti yang dijelaskan oleh RobinLovelace di atas.Yang ditunjukkan di bawah ini adalah banyak baris kode yang hanya menunjukkan cara melihat berbagai tingkat simpul dari dokumen kml. Saya pikir ini akan sedikit berbeda tergantung pada sumber kml. Tetapi Anda harus dapat menggunakan logika yang sama untuk menentukan nilai parameter yang benar.
Juga, saya membuat sebuah daftar file kml sehingga bisa dengan mudah dibuat menjadi fungsi yang dapat dimasukkan ke dalam
lapply
-do.call
pasangan. Ini kemudian bisa menarik data dari daftar panjang file kml. Atau, banyak subfolder dalam file kml tunggal karena tampaknyareadOGR
tidak dapat menangani beberapa subfolder dalam file kml.sumber
Tidak tahu apakah saya harus mengubah jawaban saya sebelumnya. Mungkin, tetapi itu mencakup beberapa hal yang tidak ada dalam jawaban ini, jadi saya memutuskan untuk meninggalkannya.
Bagaimanapun, kode di bawah ini berfungsi dengan baik untuk saya. Itu mencari semua xmlNodes dalam file kml yang disebut "Folder" dan kemudian menetapkan
layer
parameterreadOGR
untuk ituxmlValue
. Diuji pada direktori kerja dengan sekitar 6 file kml terpisah. Output adalah daftar objek SpatialDataFrames yang diimpor. Setiap SpatialDataFrame dapat dengan mudah diatur dari daftar.Masih tidak membahas file kml dengan beberapa folder Folder. Tetapi fitur itu dapat dengan mudah ditambahkan dengan
apply
fungsi bersarang lainnya .sumber