Leggere una tabella da un geodatabase di file ESRI (.gdb) utilizzando R


21

Sto cercando di leggere una tabella direttamente da un geodatabase di file ESRI in R. Un file di dati di esempio può essere scaricato qui . Il database contiene una classe di caratteristiche punto (Zone9_2014_01_Broadcast) e due tabelle collegate (Zone9_2014_01_Vessel e Zone9_2014_01_Voyage). Puoi leggere lo shapefile in R usando readOGRdal rgeospacchetto:

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

Le due tabelle collegate mostrano anche quando si utilizza ogrListLayerso ogrInfo. Tuttavia, ogrInfodà un avvertimento:

Messaggio di avviso: in ogrInfo ("Zone9_2014_01.gdb", layer = "Zone9_2014_01_Vessel"): ogrInfo: tutte le funzioni NULL

E se si tenta di utilizzare readOGRsui tavoli si ottiene un errore:

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

Errore in readOGR (dsn = "Zone9_2014_01.gdb", layer = "Zone9_2014_01_Vessel"): nessuna funzione trovata Inoltre: Messaggio di avviso: In ogrInfo (dsn = dsn, layer = layer, codifica = codifica, use_iconv = use_iconv,: ogrInfo: tutte le funzioni NULL

Pertanto, sembra che solo readOGR possa leggere solo le caratteristiche geografiche. Esiste un modo per importare le tabelle direttamente in R o è l'unica soluzione per esportarle da ArcGIS come file * .dbf (o * .txt) come in questa risposta?

Inoltre, se qualcuno può fornire chiamate da R a uno script Python che automatizza l'esportazione di file * csv (preferibilmente) o * .dbf, sarebbe una soluzione accettabile. La soluzione deve solo essere scalabile e automatizzata.


2
Hai visto la nuova integrazione di R e ArcGIS? r-arcgis.github.io forse qualcosa di utile per il tuo lavoro.
Alex Tereshenkov,

Grazie per il suggerimento ... Avevo visto menzionarlo ad un certo punto, ma non l'ho mai esaminato più a fondo. Forse ora sarebbe un buon momento per farlo!
Cotton.Rockwood

@AlexTereshenkov, se vuoi scrivere una breve risposta per questa soluzione, la accetterò poiché è quello che stavo cercando.
Cotton.Rockwood,

1
Sembra che il bridge R-ArcGIS menzionato da @AlexTereshenkov abbia la funzionalità di leggere le tabelle direttamente in R. L'integrazione richiede ArcGIS Desktop> 10.3.1 (o ArcGIS Pro) e R> 3.2. La R a 64 bit può essere utilizzata solo con il geoprocessing in background a 64 bit (e consente l'utilizzo solo da ArcGIS, non da R) o ArcGIS Pro. Una volta installati i binding, è possibile utilizzare il pacchetto arcgisbbindingin R. La funzione arc.open()aprirà la tabella come arc.dataset-class object. Per aprire direttamente come a data.table, utilizzare la funzione arc.select.
Cotton.Rockwood,

buono a sapersi. Ho aggiunto una risposta solo per chiudere il thread, ma hai capito tutto da solo, quindi accetta ma non dare il massimo: D
Alex Tereshenkov

Risposte:


18

Sono un po 'in ritardo alla festa, ma questo può ora essere letti da sf, con

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

Restituisce un avviso (non sono presenti geometrie di feature) ma anche un data.frame con la tabella. Vedi la discussione iniziata qui: https://stat.ethz.ch/pipermail/r-sig-geo/2018-February/026344.html


eccellente! Grazie Edzer ... felice di vedere questo e l'evoluzione di sf !!
Cotton.Rockwood,

strano, non sono stato in grado di eseguirlo su 3 macchine: ho ricevuto un errore, non un avviso?
Matifou,

1
dovrai installare la versione dev da github, dalla fonte, o attendere la versione 0.6-1 il mese prossimo
Edzer Pebesma,

Meglio tardi che mai alla festa! Sono venuto a questa festa ~ 2 anni fa e ho implementato una delle soluzioni precedenti. Ho appena cercato una sfsoluzione e Google mi ha riportato felicemente a questa stessa festa con una soluzione super utile (quindi ho aggiunto felicemente il mio voto a questa domanda).
D. Woods,

9

Uso GDAL 2.0.2 che viene "spedito" con supporto FDGB e senza terze parti un driver FGDB per indagare su quel materiale. L'ambiente di test è Debian Jessie a 64 bit.

In breve, sembra che il "layer" Zone9_2014_01_Vesselcontenga dati di attributo puri e il layer Zone9_2014_01_Broadcastcontenga dati di posizione. È possibile utilizzare una soluzione alternativa all'interno di R tramite una chiamata di sistema e la conversazione del GDB con un contenitore shapefile (ultimo script alla fine della risposta).

Ecco i passaggi dell'indagine:

$ 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

Come vedi il campo Geometryè impostato su None. Puoi convertire i dati in un file di forma usando ogr2ogre ottenere anche solo un file di attributi dbase:

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

Zone9_2014_01_Vessel.dbf

Geometrie (posizioni) possono essere trovate nel livello 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

Nave e viaggio che non contengono dati di posizione secondo il protocollo dei messaggi AIS .

Qui la soluzione completa in R che utilizza una chiamata di sistema per GDB per modellare la conversazione e il pacchetto foreignper leggere i dbf:

# 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

grazie @huckfinn! Questa è una bella soluzione. Ho parecchi file (molti dei quali sono molto più grandi dell'esempio), quindi ci darò una possibilità e vedrò come la conversione in un file di forma influisce sui tempi di elaborazione. Spero anche che ci sia una soluzione diretta in R, ma se nessuno risponde con uno, selezionerò il tuo come risposta.
Cotton.Rockwood

3

Non sono sicuro se puoi farlo con readOGR ma prova

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

Se il problema ogr2ogrpersiste, provare direttamente, che può esportare non geometrie nella tabella. (Forse prova il pacchetto R gdalUtilsper eseguirlo, una volta che hai finito il processo.)


1
Sfortunatamente, readOGRnon ha la capacità di leggere le tabelle gdb.
Aaron

1
Probabilmente lo fa, ora.
mdsumner,

Ancora non come da rgdal 1.2-8, gdal 2.0.1
gregmacfarlane,

Si chiama OpenFileGDB in ogrDrivers () $ name, forse stai cercando di leggere un raster? Questo è ancora in fase di implementazione, in entrambi i casi se vuoi scoprire che potresti pubblicare una domanda con i dettagli sul tuo sistema e cosa hai provato.
mdsumner,

3

Esiste un'integrazione recentemente rilasciata tra R e ArcGIS di Esri, chiamata R ArcGIS Tools . Fornisce l'integrazione tra R e ArcGIS consentendo di accedere in modo intercambiabile agli strumenti R e alle risorse ArcGIS. Dovresti essere in grado di accedere alle classi / tabelle delle caratteristiche del geodatabase con questa integrazione.

Strumenti R campione sono disponibili qui e gli strumenti di esempio che illustrano l'utilizzo R in geoprocessing script sono qui .


1

Questa funzione personalizzata segue sostanzialmente il percorso indicato da @huckfinn ma utilizza la gdalUtilslibreria suggerita da @mdsumner.

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)
}

Eseguilo in questo modo:

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

Se non hai già gdalinstallato, dovrai installarlo per fornire l'accesso a gdalUtils. Puoi trovare i binari e le istruzioni per l'installazione di 'gdal' qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.