Leia uma tabela de um geodatabase de arquivo ESRI (.gdb) usando R

21

Estou tentando ler uma tabela diretamente de um geodatabase de arquivo ESRI para R. Um arquivo de dados de exemplo pode ser baixado aqui . O banco de dados contém uma classe de recurso de ponto (Zone9_2014_01_Broadcast) e duas tabelas vinculadas (Zone9_2014_01_Vessel e Zone9_2014_01_Voyage). Você pode ler o shapefile no R usando readOGRo rgeospacote:

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

As duas tabelas vinculadas também são exibidas quando você usa ogrListLayersou ogrInfo. No entanto, ogrInfoemite um aviso:

Mensagem de aviso: No ogrInfo ("Zone9_2014_01.gdb", layer = "Zone9_2014_01_Vessel"): ogrInfo: todos os recursos NULL

E se você tentar usar readOGRnas tabelas, receberá um erro:

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

Erro no readOGR (dsn = "Zone9_2014_01.gdb", camada = "Zone9_2014_01_Vessel"): nenhum recurso encontrado Além disso: Mensagem de aviso: No ogrInfo (dsn = dsn, camada = camada, codificação = codificação, use_iconv = use_iconv,: ogrInfo: todos os recursos NULL

Assim, parece que apenas características geográficas podem ser lidas pelo readOGR. Existe alguma maneira de importar as tabelas diretamente para o R ou a única solução para exportá-las primeiro do ArcGIS como arquivos * .dbf (ou * .txt), como nesta resposta?

Além disso, se alguém puder fornecer chamadas de R para um script python que automatize a exportação de arquivos * csv (preferencialmente) ou * .dbf, isso seria uma solução alternativa aceitável. A solução só precisa ser escalável e automatizada.

Cotton.Rockwood
fonte
2
Você viu a nova integração do R e ArcGIS? r-arcgis.github.io talvez algo útil para o seu trabalho.
Alex Tereshenkov # 9/16
Obrigado pela sugestão ... Eu já tinha visto menção a esse ponto, mas nunca o examinei mais detalhadamente. Talvez agora seja um bom momento para fazer isso!
precisa saber é o seguinte
@AlexTereshenkov, se você quiser escrever uma resposta curta para esta solução, eu a aceitarei, pois é o que eu estava procurando.
Cotton.Rockwood
1
Parece que a ponte R-ArcGIS mencionada pelo @AlexTereshenkov possui a funcionalidade de ler tabelas diretamente no R. A integração requer ArcGIS Desktop> 10.3.1 (ou ArcGIS Pro) e R> 3.2. O R de 64 bits só pode ser usado com o geoprocessamento em segundo plano de 64 bits (e só permite o uso do ArcGIS, não do R) ou do ArcGIS Pro. Uma vez instaladas as ligações, você pode usar o pacote arcgisbbindingem R. A função arc.open()abrirá a tabela como um arc.dataset-class object. Para abrir diretamente como data.table, use a função arc.select.
Cotton.Rockwood
bom saber. Eu adicionei uma resposta apenas para fechar o segmento, mas você tem tudo planejado em seu próprio país, por isso, aceitar, mas não upvote: D
Alex Tereshenkov

Respostas:

18

Estou um pouco atrasado para a festa, mas isso agora pode ser lido por sf, com

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

Ele retorna um aviso (sem geometrias de recursos presentes), mas também um data.frame com a tabela. Veja o tópico iniciado aqui: https://stat.ethz.ch/pipermail/r-sig-geo/2018-February/026344.html

Edzer Pebesma
fonte
excelente! Obrigado Edzer ... feliz em ver isso e a evolução do sf !!
Algodão.Rockwood
estranho, não consegui executar isso em três máquinas: recebo um erro, não um aviso?
Matifou 15/02
1
você precisará instalar a versão dev do github, da fonte ou aguardar a versão
0.6-1 no
Melhor tarde para a festa do que nunca! Eu vim para esta festa ~ 2 anos atrás e tive uma implementação de uma das soluções anteriores. Acabei de procurar uma sfsolução e o Google me trouxe de volta a essa mesma festa com uma solução super útil (então, adicionei meu voto positivo a essa pergunta).
D. Woods
9

Eu uso o GDAL 2.0.2 "enviado" com suporte a FDGB e sem terceiros um driver FGDB para investigar essas coisas. O ambiente de teste é o Debian Jessie de 64 bits.

Em suma, parece que a "camada" Zone9_2014_01_Vesselcontém dados puros de atributos e a camada Zone9_2014_01_Broadcastcontém dados de posição. Você pode usar uma solução alternativa no R por meio de uma chamada do sistema e da conversa do GDB em um contêiner de shapefile (último script no final da resposta).

Aqui estão as etapas de investigação:

$ 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

Como você vê o campo Geometry está definido como None. Você pode converter os dados em um arquivo de forma usando ogr2ogre obter também apenas um arquivo de atributo dbase:

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

Zone9_2014_01_Vessel.dbf

Geometrias (posições) podem ser encontradas na camada 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

Navio e Voyage que não contêm dados de posição de acordo com o protocolo de mensagens AIS .

Aqui está a solução completa em R usando uma chamada de sistema para o GDB moldar a conversa e o pacote foreignpara ler os dbf's:

# 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
fonte
obrigado @huckfinn! Esta é uma boa solução alternativa. Eu tenho muitos arquivos (muitos dos quais são muito maiores que o exemplo), então vou tentar e ver como a conversão em um shapefile afeta o tempo de processamento. Também tenho esperança, há uma solução direta em R, mas se ninguém responder com uma, selecionarei a sua como a resposta.
precisa saber é o seguinte
3

Não tenho certeza se você pode fazer isso com o readOGR, mas tente

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

Se isso não funcionar, tente ogr2ogrdiretamente, o que pode exportar não geometrias para a tabela. (Talvez tente o pacote R gdalUtilspara executá-lo, depois que o processo for interrompido.)

mdsumner
fonte
1
Infelizmente, readOGRnão tem a capacidade de ler tabelas gdb.
Aaron
1
Provavelmente agora.
Mdsumner 3/07
Ainda não como de rgdal 1.2-8, gdal 2.0.1
gregmacfarlane
É chamado OpenFileGDB no nome ogrDrivers () $, talvez você esteja tentando ler uma varredura? Isso ainda está sendo implementado, de qualquer forma, se você quiser descobrir, pode postar uma pergunta com detalhes sobre seu sistema e o que você tentou.
Mdsumner 27/09/17
3

Há uma integração lançada recentemente entre o R e o ArcGIS da Esri, chamada R ArcGIS Tools . Ele fornece integração entre o R e o ArcGIS, possibilitando o acesso intercambiável às ferramentas R e aos recursos do ArcGIS. Você deve poder acessar classes / tabelas de recursos do geodatabase com essa integração.

As ferramentas R de amostra estão disponíveis aqui e as ferramentas de amostra que ilustram o uso de R nos scripts de geoprocessamento estão aqui .

Alex Tereshenkov
fonte
1

Essa função personalizada basicamente segue o caminho descrito por @huckfinn, mas usa a gdalUtilsbiblioteca sugerida por @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)
}

Execute-o assim:

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 você ainda não tiver gdalinstalado, será necessário instalá-lo para fornecer acesso gdalUtils. Você pode encontrar binários e instruções para a instalação do 'gdal' aqui .

D. Woods
fonte