Lesen Sie eine Tabelle aus einer ESRI-File-Geodatabase (.gdb) mit R

21

Ich versuche, eine Tabelle direkt aus einer ESRI-File-Geodatabase in R zu lesen. Eine Beispieldatendatei kann hier heruntergeladen werden . Die Datenbank enthält eine Point-Feature-Class (Zone9_2014_01_Broadcast) und zwei verknüpfte Tabellen (Zone9_2014_01_Vessel und Zone9_2014_01_Voyage). Sie können das Shapefile in R mit dem folgenden Befehl readOGRaus dem rgeosPaket lesen :

library(rgeos)
library(downloader)

download("https://coast.noaa.gov/htdata/CMSP/AISDataHandler/2014/01/Zone9_2014_01.zip", dest="Zone9_2014_01.zip", mode="wb")
unzip("Zone9_2014_01.zip", exdir = ".")

#  Not Run (loads large point file)
#  broadcast <- readOGR(dsn = "Zone9_2014_01.gdb", layer = "Zone9_2014_01_Broadcast")

Die beiden verknüpften Tabellen zeigen auch, wann Sie ogrListLayersoder verwenden ogrInfo. Es ogrInfogibt jedoch eine Warnung:

Warnmeldung: In ogrInfo ("Zone9_2014_01.gdb", Layer = "Zone9_2014_01_Vessel"): ogrInfo: Alle Funktionen NULL

Und wenn Sie versuchen, readOGRauf den Tabellen zu verwenden, erhalten Sie eine Fehlermeldung:

vessel <- readOGR(dsn = "Zone9_2014_01.gdb", layer = "Zone9_2014_01_Vessel")

Fehler in readOGR (dsn = "Zone9_2014_01.gdb", layer = "Zone9_2014_01_Vessel"): Keine Features gefunden Zusätzlich: Warnmeldung: In ogrInfo (dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv,: ogrInfo: Alle Funktionen NULL

Somit scheint es, dass nur geografische Merkmale von readOGR gelesen werden können. Gibt es eine Möglichkeit, die Tabellen direkt in R zu importieren, oder ist dies die einzige Lösung, um sie zuerst aus ArcGIS als * .dbf- (oder * .txt-) Dateien zu exportieren, wie in dieser Antwort angegeben?

Wenn außerdem jemand Aufrufe von R an ein Python-Skript senden kann, das den Export von * csv- (vorzugsweise) oder * .dbf-Dateien automatisiert, ist dies eine akzeptable Lösung. Die Lösung muss nur skalierbar und automatisiert sein.

Cotton.Rockwood
quelle
2
Haben Sie die neue Integration von R und ArcGIS gesehen? r-arcgis.github.io Vielleicht etwas Nützliches für Ihre Arbeit.
Alex Tereshenkov
Vielen Dank für den Vorschlag ... Ich hatte ihn irgendwann einmal erwähnt, habe ihn aber nie gründlicher untersucht. Vielleicht wäre jetzt ein guter Zeitpunkt dafür!
Cotton.Rockwood
@AlexTereshenkov, wenn Sie eine kurze Antwort für diese Lösung schreiben möchten, werde ich sie akzeptieren, da es das ist, wonach ich gesucht habe.
Cotton.Rockwood
1
Es sieht so aus, als ob die von @AlexTereshenkov erwähnte R-ArcGIS-Bridge über die Funktionalität verfügt, Tabellen direkt in R zu lesen. Für die Integration sind ArcGIS Desktop> 10.3.1 (oder ArcGIS Pro) und R> 3.2 erforderlich. 64-Bit-R kann nur mit der 64-Bit-Hintergrund-Geoverarbeitung (und nur in ArcGIS, nicht in R) oder ArcGIS Pro verwendet werden. Sobald die Bindungen installiert sind, können Sie das Paket arcgisbbindingin R verwenden. Die Funktion arc.open()öffnet die Tabelle als arc.dataset-class object. data.tableVerwenden Sie die Funktion, um direkt als zu öffnen arc.select.
Cotton.Rockwood
gut zu wissen. Ich habe eine Antwort hinzugefügt, um den Thread zu schließen, aber Sie haben alles selbst herausgefunden, also akzeptieren Sie, aber stimmen Sie nicht zu: D
Alex Tereshenkov

Antworten:

18

Ich bin ein bisschen zu spät zur Party, aber das kann jetzt gelesen werden von sf, mit

vessel <- sf::st_read(dsn = "Zone9_2014_01.gdb", layer = "Zone9_2014_01_Vessel")

Es wird eine Warnung zurückgegeben (keine Feature-Geometrien vorhanden), aber auch ein data.frame mit der Tabelle. Siehe den Thread, der hier begonnen hat: https://stat.ethz.ch/pipermail/r-sig-geo/2018-February/026344.html

Edzer Pebesma
quelle
Ausgezeichnet! Danke Edzer ... ich bin froh, das und die Entwicklung von sf zu sehen !!
Cotton.Rockwood
seltsam, ich konnte dies nicht auf 3 Rechnern ausführen: bekomme ich eine Fehlermeldung, keine Warnung?
Matifou
1
Sie müssen die Dev-Version von Github, aus dem Quellcode, installieren oder bis zur Veröffentlichung von 0.6-1 im nächsten Monat warten
Edzer Pebesma
Besser spät zur Party als nie! Ich bin vor ca. 2 Jahren zu dieser Party gekommen und hatte eine Implementierung einer der vorherigen Lösungen. Ich habe gerade nach einer sfLösung gesucht und Google hat mich glücklich mit einer super hilfreichen Lösung zu derselben Party zurückgebracht (daher habe ich dieser Frage meine positive Bewertung hinzugefügt).
D. Woods
9

Ich verwende GDAL 2.0.2, das mit FDGB-Unterstützung "ausgeliefert" wird, und ohne einen Drittanbieter einen FGDB-Treiber , um dieses Zeug zu untersuchen. Die Testumgebung ist Debian Jessie 64-Bit.

Kurz gesagt, es scheint, dass die "Ebene" Zone9_2014_01_Vesselreine Attributdaten enthält und die Ebene Zone9_2014_01_BroadcastPositionsdaten enthält. Sie können eine Problemumgehung in R über einen Systemaufruf und die Konversation der GDB mit einem Shapefile-Container (letztes Skript am Ende der Antwort) verwenden.

Hier sind die Untersuchungsschritte:

$ mkdir ~/dev.d/gis-se.d/gdb 
$ cd ~/dev.d/gis-se.d/gdb
$ wget https://coast.noaa.gov/htdata/CMSP/AISDataHandler/2014/01/Zone9_2014_01.zip
$ unzip Zone9_2014_01.zip
$ ogrinfo Zone9_2014_01.gdb Zone9_2014_01_Vessel | head -20
Had to open data source read-only.
INFO: Open of `Zone9_2014_01.gdb'
      using driver `OpenFileGDB' successful.

Layer name: Zone9_2014_01_Vessel
Geometry: None <---------------------------- HERE 
Feature Count: 1282
Layer SRS WKT:
(unknown)
FID Column = OID
MMSI: Integer (0.0)
IMO: Integer (0.0)
CallSign: String (255.0)
Name: String (255.0)
VesselType: Integer (0.0)
Length: Integer (0.0)
Width: Integer (0.0)
DimensionComponents: String (255.0)
OGRFeature(Zone9_2014_01_Vessel):1
  MMSI (Integer) = 367603345

Wie Sie sehen, ist das Feld auf Geometryeingestellt None. Sie können die Daten mit in ogr2ogreine Formdatei konvertieren und erhalten auch nur eine Datenbankattributdatei:

$ ogr2ogr -f 'ESRI SHAPEFILE' test Zone9_2014_01.gdb Zone9_2014_01_Vessel
$ ls test

Zone9_2014_01_Vessel.dbf

Geometrien (Positionen) können in der Ebene gefunden werden Zone9_2014_01_Broadcast.

$ ogr2ogr -f 'ESRI SHAPEFILE' test Zone9_2014_01.gdb
$ ls test

Zone9_2014_01_Broadcast.dbf  
Zone9_2014_01_Broadcast.shp  
Zone9_2014_01_Broadcast.prj  
Zone9_2014_01_Broadcast.shx  
Zone9_2014_01_Vessel.dbf
Zone9_2014_01_Voyage.dbf

Schiff und Reise, die keine Positionsdaten gemäß dem AIS-Nachrichtenprotokoll enthalten .

Hier die vollständige Problemumgehung in R unter Verwendung eines Systemaufrufs, damit die GDB die Konversation formt und das Paket foreigndie DBFs liest:

# Load module to get readOGR
require('rgdal');

# Load module to get read.dbf
require('foreign');

# goto the directory with the GDB stuff
setwd('~/dev.d/gis-se.d/gdb')

# Conversation to a shapefile container 
system("ogr2ogr -f 'ESRI SHAPEFILE' test Zone9_2014_01.gdb") 

# read the vessels
vessel <- read.dbf('test/Zone9_2014_01_Vessel.dbf');

# read hte voyage data
voyage <- read.dbf('test/Zone9_2014_01_Voyage.dbf');

# read the geometries in broad cast
broadcast <- readOGR('test/Zone9_2014_01_Broadcast.shp','Zone9_2014_01_Broadcast')

OGR data source with driver: ESRI Shapefile
Source: "test/Zone9_2014_01_Broadcast.shp", layer: "Zone9_2014_01_Broadcast"
with 1639274 features
It has 10 fields

# is vessel OK?    
head(vessel)

MMSI IMO CallSign Name VesselType Length Width   DimensionC
1 367603345  NA     <NA> <NA>         50     20     6     7,13,3,3
2 563000574  NA     <NA> <NA>         70    276    40 188,88,20,20
3 367449580  NA     <NA> <NA>         31     28    10     9,19,5,5
4 367302503  NA     <NA> <NA>         31     20     8     8,12,4,4
5 304003909  NA     <NA> <NA>         71    222    32 174,48,21,11
6 210080027  NA     <NA> <NA>         71    294    32 222,72,22,10

# is voyage OK?
head(voyage)

VoyageID           Destinatio Cargo Draught        ETA  StartTime    EndTime      MMSI
1       12                 KAKE    50      20       <NA> 2014-01-01       <NA> 367603345
2       23             YOKOHAMA    70     125 2014-01-11 2014-01-01 2014-01-30 563000574
3       38         KETCHIKAN AK    31      40 2014-11-12 2014-01-01       <NA> 367449580
4       52 CLARENCE STRAIT LOGS    31      30 2014-09-12 2014-01-01       <NA> 367302503
5       62               JP TYO    71      90 2014-01-13 2014-01-01 2014-01-31 304003909
6       47           VOSTOCHNYY    71     106 2014-01-13 2014-01-01       <NA> 210080027
huckfinn
quelle
danke @huckfinn! Dies ist eine gute Lösung. Ich habe ziemlich viele Dateien (von denen viele viel größer sind als das Beispiel), daher werde ich es ausprobieren und sehen, wie sich die Konvertierung in ein Shapefile auf die Verarbeitungszeiten auswirkt. Ich bin auch hoffnungsvoll, es gibt eine direkte Lösung in R, aber wenn niemand mit einer antwortet, werde ich deine als Antwort auswählen.
Cotton.Rockwood
3

Nicht sicher, ob Sie dies mit readOGR tun können, aber versuchen Sie es

vessel <- readOGR(dsn = "Zone9_2014_01.gdb", layer = "Zone9_2014_01_Vessel", dropNULLGeometries = FALSE)

Wenn dies nicht funktioniert, versuchen Sie es ogr2ogrdirekt. Dadurch können Nicht-Geometrien in eine Tabelle exportiert werden. (Vielleicht versuchen Sie R-Paket gdalUtils, um das auszuführen, sobald Sie Ihren Prozess heruntergefahren haben.)

mdsumner
quelle
1
Leider readOGRhat nicht die Fähigkeit, GDB-Tabellen zu lesen.
Aaron
1
Das tut es jetzt wahrscheinlich.
mdsumner
Immer noch nicht wie bei rgdal 1.2-8, gdal 2.0.1
gregmacfarlane
Es heißt OpenFileGDB in ogrDrivers () $ name, vielleicht versuchen Sie, ein Raster zu lesen? Das wird immer noch implementiert, so oder so, wenn Sie herausfinden möchten, dass Sie eine Frage mit Details zu Ihrem System und den von Ihnen ausgeführten Versuchen stellen können.
Mdsumner
3

Es gibt eine kürzlich veröffentlichte Integration zwischen R und ArcGIS von Esri, R ArcGIS Tools . Es bietet eine Integration zwischen R und ArcGIS und ermöglicht den austauschbaren Zugriff auf R-Tools und ArcGIS-Ressourcen. Mit dieser Integration sollten Sie auf Geodatabase-Feature-Classes / -Tabellen zugreifen können.

Probe R - Tools zur Verfügung hier und Beispiel Tools darstellt , R Nutzung Skripte in Geoverarbeitungs sind hier .

Alex Tereshenkov
quelle
1

Diese benutzerdefinierte Funktion folgt im Wesentlichen dem von @huckfinn angegebenen Pfad, verwendet jedoch die gdalUtilsvon @mdsumner vorgeschlagene Bibliothek.

read_GDB_Layer <- function(dsn, layerName, overwrite = T) {
   conversionDir <- tempdir()

   gdalUtils::ogr2ogr(src_datasource_name = dsn, 
                      dst_datasource_name = conversionDir, 
                      f = "ESRI Shapefile", layer = layerName, 
                      verbose = T, overwrite = overwrite)

   df <- foreign::read.dbf(file.path(conversionDir, paste0(layerName, ".dbf")))

   return(df)
}

Führen Sie es so aus:

vsl <- read_GDB_Layer(dsn = "Zone9_2014_01.gdb", layerName = "Zone9_2014_01_Vessel")
vyg <- read_GDB_Layer(dsn = "Zone9_2014_01.gdb", layerName = "Zone9_2014_01_Voyage")

Wenn Sie es noch nicht gdalinstalliert haben, müssen Sie es installieren, um auf es zugreifen zu können gdalUtils. Sie können Binärdateien und Anweisungen für die ‚gdal‘ Installation finden hier .

D. Woods
quelle