কেএমএল ফাইলটি আর-তে পড়ছেন?


42

আমি বিশাল .kML ফাইলগুলি (10 গিগাবাইট পর্যন্ত) নিয়ে কাজ করছি এবং তাদের আরে পড়ার জন্য একটি দক্ষ পদ্ধতির প্রয়োজন now যাইহোক, পূর্বের চেয়ে 1000 ডলার দ্রুত)। আমি আদর্শভাবে কিউজিআইএস মধ্যস্থতাকারী পর্যায়টি কাটাতে পছন্দ করি কারণ এটি জটিল এবং ধীর।

কিভাবে সরাসরি .kML ফাইলগুলি পড়বেন?

আমি দেখছি এটিও রিডওজিআর দিয়ে করা যায় । দুর্ভাগ্যক্রমে, আমি কীভাবে কাজের উদাহরণটি প্রয়োগ করতে পারি তা দেখতে পাচ্ছি না (.kML ফাইলের দীর্ঘ প্রস্তুতির পরে xx <- readOGR(paste(td, "cities.kml", sep="/"), "cities"):)। মনে হয় এখানে "শহরগুলি" স্থানিক বস্তুর নাম।

রজার বিভান্ড স্বীকার করেছেন যে "এই নামটি কীভাবে আবিষ্কার হয় তা স্পষ্ট নয়, যেহেতু ওজিআরের কেএমএল ড্রাইভারের ফাইলটি অ্যাক্সেস করার জন্য এটির প্রয়োজন needs একটি সম্ভাবনা হ'ল:

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"

1
আপনি rgdal এর ফাংশন ogrListLayers ব্যবহার করে কিলোমিটারে স্তর পেতে পারেন।
মারিও বেরসার

উত্তর:


37

ওজিআর ড্রাইভারের সাথে একটি কেএমএল পড়তে, আপনি এটির ফাইলের নাম এবং স্তরটির নাম দিন।

রজারের মন্তব্য হ'ল স্তরটির নামটি কেএমএল ফাইলে লুকিয়ে রয়েছে এবং কেএমএল কীভাবে তৈরি হয়েছিল তা আপনি যদি না জানেন তবে আপনি কেএমএল ফাইলের নাম থেকে স্তরটির নাম নির্ধারণ করতে পারবেন না।

আপনার উদাহরণ কেএমএল দেখে, আমি দেখতে পাচ্ছি:

<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document><Folder><name>x</name>
<Schema name="x" id="x">

যা আমাকে লেয়ারের নামটি বলছে x, তা নয় idএবং তাই:

> foo = readOGR("/tmp/x.kml", "x")
OGR data source with driver: KML 
Source: "/tmp/x.kml", layer: "x"
with 1 features and 2 fields
Feature type: wkbPolygon with 2 dimensions

সুন্দরভাবে কাজ করে

এখন, আপনি চেষ্টা করে দেখতে পারেন এবং আর এক্সএমএল পার্সার ব্যবহার এক্সএমএল যেমন KML এ পার্স নাম পাওয়া, অথবা আপনি পারেন হয়তো একটি টেক্সট ফাইল হিসাবে আর এটা পড়া পর্যন্ত আপনি নাম ট্যাগ দেখুন।

অন্য পদ্ধতিটি হ'ল কমান্ড-লাইন ওগ্রিনফো প্রোগ্রাম চালানো যা কোনও কেএমএল ফাইলের স্তর নামগুলি ছড়িয়ে দেয়:

$ ogrinfo /tmp/x.kml 
Had to open data source read-only.
INFO: Open of `/tmp/x.kml'
      using driver `KML' successful.
1: x (Polygon)

এখানে দেখানো হচ্ছে একটি বহুভুজ স্তর বলা আছে x


আপনার উত্তরের জন্য ধন্যবাদ ব্যবধানে - সমস্যাটি সরাসরি সমাধান করুন। এটি এর মতো স্পষ্ট ব্যাখ্যা যা আমাকে স্ট্যাক এক্সচেঞ্জকে ভালবাসে! একটি 'বোনাস পয়েন্ট' প্রশ্ন: আমি কি একই কমান্ডটি উপাত্তের সাবসেটে পড়ার জন্য ব্যবহার করতে পারি (উদাহরণস্বরূপ প্রথম 1 মিলিয়ন বহুভুজ)? অন্যথায় বাহ্যিক প্রোগ্রাম সহ বিশাল কিলোমিটার বিভক্ত হবে।
রবিনলাভলেস

2
এক্সএমএল হওয়া কেএমএল সত্যই এলোমেলো অ্যাক্সেসের জন্য ডিজাইন করা হয়নি। আসল সমাধানটি হল আপনার স্থানিক ডেটা একটি স্থানিক ডাটাবেসে রাখা এবং গতির জন্য কিছু স্থানিক সূচি থাকে। পোস্টজিআইএস দেখুন।
স্পেসডম্যান

ঠিক আছে ভাল পরিকল্পনা - আমি ক্লায়েন্টকে বলেছি যে পোস্টজিআইএস হ'ল এত বড় ডেটার জন্য এগিয়ে যাওয়ার উপায় এবং আমি নিশ্চিত যে তিনি যে ধরনের কাজ করতে চান তার জন্য এটি সঠিক বিকল্প। এটি সঠিকভাবে শেখার জন্য আমার অজুহাত!
রবিনলাভলেস

রয়েছে SQLite করার স্থানিক এক্সটেনশন , ভিত্তি করে ডাটাবেসের একটি ফাইল, যা একটি সেবা ইনস্টল করতে হয় এবং PostGIS কম কনফিগারেশন প্রয়োজন would't।
ফ্রাঙ্ক

অদ্ভুতভাবে কাজ করার জন্য আরে systemদরকার ছিল , যদিও এটি কমান্ড লাইনের (ম্যাকোস; এবং একই পথে ফিরে এসেছে) path.expand~ogrinfoSys.which('ogrinfo')which ogrinfo
অপ্রস্তুত

5

আপনি যদি ম্যাপটোলটি ব্যবহার করে বিকল্প পদ্ধতি করতে চান তবে এটি কাজ করা উচিত:

tkml <- getKMLcoordinates(kmlfile="yourkml.kml", ignoreAltitude=T)
#make polygon
p1 = Polygon(tkml)
#make Polygon class
p2 = Polygons(list(p1), ID = "drivetime")
#make spatial polygons class
p3= SpatialPolygons(list(p2),proj4string=CRS("+init=epsg:4326"))

এখানে মূল কীটি আপনাকে স্থানিক বহুভুজ শ্রেণি তৈরি করতে কয়েকটি পদক্ষেপ অতিক্রম করতে হবে।


হাই @ সাইন, আমি আপনার পদ্ধতির চেষ্টা করেছি কিন্তু মনে হচ্ছে এটি কাজ করে না? আমার একটি ত্রুটি রয়েছে: বহুভুজের ত্রুটি (tkml): কর্ডগুলি অবশ্যই একটি দ্বি-কলামের ম্যাট্রিক্স> হেড (tkML) হতে হবে [[1]] [1] -87.88141 30.49800 অ্যাডন আমার কাছে এটির একটি তালিকা আছে .. আপনি কি মনে করেন এটির ঠিক রূপান্তর আছে? ম্যাট্রিক্সের স্থানাঙ্কের তালিকা? তাহনস!
maycca

1

এটি এখনও অন্য কারও জন্য সমস্যা কিনা তা আপনি জানেন না, তবে আমি এটির সাথে কিছুক্ষণ চলাচল করছিলাম was অবশেষে আমার জন্য যা কাজ করেছে তা নীচে। এটি ডান নোডের XMLপেতে প্যাকেজটি ব্যবহার করে xmlValue। আমাকে কিমিএল ফাইলের মধ্যে একটি ফোল্ডারের নামের layerপ্যারামিটার সেট readOGRকরতে হয়েছিল। আমি যখন layerকিমিএল ফাইলের প্যারামিটারটি সেট করি তখন আমি রবিনলভ্যাসেস উপরে বর্ণিত একই ত্রুটিটি পেয়ে যাব।

নীচে অনেকগুলি কোড লাইন দেখানো হয়েছে যা কেবলমাত্র কিমিএল ডকুমেন্টের নোডের বিভিন্ন স্তর দেখতে হয় তা দেখায়। আমি মনে করি কিমিএল এর উত্সের উপর নির্ভর করে এটি কিছুটা আলাদা হবে। তবে সঠিক প্যারামিটারের মান নির্ধারণ করতে আপনার একই যুক্তি ব্যবহার করতে সক্ষম হওয়া উচিত।

এছাড়াও, আমি KML ফাইল একটি তালিকা তাই এটি সহজে একটি ফাংশন যে একটি রাখা যেতে পারে মধ্যে তৈরি করা যেতে পারে নির্মিত lapply- do.callজোড়া। এটি তখন কিমিএল ফাইলগুলির দীর্ঘ তালিকা থেকে একটি ডেটা টেনে আনতে পারে। অথবা, একক কিমিএল ফাইলের মধ্যে প্রচুর সাব-ফোল্ডারগুলি মনে হয় যে কোনও এক কিমিএল ফাইলে readOGRএকাধিক সাবফোল্ডারগুলির সাথে ডিল করতে পারে না।

library(rgdal); library(XML)

# SET WORKING DIRECTORY FIRST!!
dir <- getwd()

kmlfilelist <- list.files(dir, pattern =".kml$", full.names=TRUE, recursive=FALSE)

doc0 <- xmlTreeParse(kmlfilelist[2], useInternal = TRUE)
rootNode0 <- xmlRoot(doc0)
rootName0 <- xmlName(rootNode0)
element1Name0 <- names(rootNode0)

nodeNames <- names(rootNode0[1][[1]])

# entire rootNode - kml Document level
rootNode0[[1]]

# 1st element of rootNode - kml file name
rootNode0[[1]][[1]] 

# 2nd element of rootNode - kml Style Map 
rootNode0[[1]][[2]] 

# 3rd element of rootNode - Style
rootNode0[[1]][[3]]

# 4th element of rootNode - Style
rootNode0[[1]][[4]] 

# 5th element of rootNode - kml Folder with data in it.
rootNode0[[1]][[5]] 

# 5th element 1st subelement of rootNode - kml Folder name with data in it. 
#  What to set readOGR() layer parameter to.
rootNode0[[1]][[5]][[1]] 

kmlfoldername <- xmlValue(rootNode0[[1]][[5]][[1]]) # Folder name to set = layer.

readOGR(dsn=kmlfilelist[2], layer =  kmlfoldername)

0

আমার পূর্ববর্তী উত্তরটি পরিবর্তন করা উচিত ছিল কিনা তা জানেন না। সম্ভবত, তবে এতে কিছু উত্তর রয়েছে যা এই উত্তরে নেই, তাই আমি এটি ছেড়ে দেওয়ার সিদ্ধান্ত নিয়েছি।

যাইহোক, নীচের কোডটি আমার পক্ষে ভাল কাজ করে। এটা তোলে KML ফাইল যে "ফোল্ডার" বলা হয় মধ্যে xmlNodes সব জন্য দেখায় এবং তারপর সেট করে layerযে পরামিতি readOGRযে xmlValue। প্রায় 6 টি পৃথক কিমিএল ফাইল সহ ওয়ার্কিং ডিরেক্টরিতে পরীক্ষিত। আউটপুট আমদানিকৃত স্পেসিয়ালডাটা ফ্রেমস অবজেক্টগুলির একটি তালিকা। প্রতিটি স্পেশিয়ালডাটা ফ্রেম তালিকা থেকে সহজেই উপসেট হতে পারে।

তবুও একাধিক ফোল্ডার নোড সহ কিলোমিটার ফাইলগুলি সম্বোধন করে না। তবে সেই বৈশিষ্ট্যটি অন্য একটি নেস্টেড applyফাংশন সহ সহজেই যুক্ত করা যায় ।

library(rgdal); library(XML)

# SET WORKING DIRECTORY FIRST!!
dir <- getwd()

kmlfilelist <- list.files(dir, pattern =".kml$", full.names=TRUE, recursive=FALSE)

ImportKml <- function (kmlfile) {
  doc0 <- xmlTreeParse(kmlfile, useInternal = TRUE)
  rootNode0 <- xmlRoot(doc0)
  rootName0 <- xmlName(rootNode0)
  element1Name0 <- names(rootNode0)

  kmlNodeNames <- unname(names(rootNode0[1][[1]]))
  kmlFolderNodeNum <- which(kmlNodeNames == "Folder")
  kmlFolderNodeName <- xmlValue(rootNode0[[1]][[kmlFolderNodeNum]][[1]])

  kmlIn <- readOGR(dsn=kmlfile, layer = kmlFolderNodeName)
}
ImportedKmls <- lapply(kmlfilelist, ImportKml)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.