A maneira mais rápida de converter big raster em polilinha usando R ou Python?

14

Eu tenho um grande arquivo raster (129600 por 64800 pixels) com corpos de água globais (valores de 1 bit 0 e 1) e tento extrair as linhas costeiras do oceano e da água interior.

Eu tentei com o ArcGIS e o QGIS converter de raster para polilinha, mas leva séculos.

Alguém conhece uma maneira melhor / mais rápida (Python ou R) ou uma ferramenta melhor para esta tarefa?

Atualizar

  • R: rasterToContour pode ser rápido e preciso, mas se você tiver um conjunto de dados muito grande como o meu (8.398.080.000 pixels), precisará de uma quantidade muito grande de RAM (mais de 16 GB) ou forçar R a fazer mais processamento no disco rígido e também levará idades.
  • Python / GDAL: gdal_poligonize cria polígonos em vez de polilinhas

Atualização 2

  • R rasterToContour: rasterToContour não fornece os resultados desejados. Comparado ao ArcGIS (raster para polígono seguido de recurso para linha), ele não extrai o contorno exato do pixel, conforme mostrado nos exemplos abaixo.

resultado rasterToContour resultado rasterToContour

Resultado ArcGIS Resultado ArcGIS

ATUALIZAÇÃO 3

Python / GDAL: Eu executei gdal_polygonize a partir da linha de comando no ArcGIS em um conjunto de dados de teste e os resultados foram extremamente claros:

  • gdal: 49 segundos
  • ArcGIS: 1,84 segundos
Wevers genéricos
fonte
Feito isso, consulte a Atualização 3.
Generic Wevers
Você pode fornecer esse conjunto de dados de teste para ver se as alternativas propostas são mais rápidas e / ou produzem os resultados necessários?
Kersten
Para uma varredura tão grande, seria muito melhor usar C / C ++ com a biblioteca gdal.
Rodrigo Rodrigo

Respostas:

7

Estou trabalhando com R e usado rasterToPolygonsno rasterpacote no passado, mas agora prefiro gdal_polygonizeRJohn Baumgartner. Baseia-se gdal_polygonize.pye é muito mais rápido. John Baumgartner publicou o código e deu um exemplo para uso em seu blog .

Se você está familiarizado com python, você pode usá-lo gdal_polygonize.pydiretamente, é claro.

Íris
fonte
1
Eu vou tentar. A última vez que usei gdal_polygonize.py, o ArcGIS foi ainda mais rápido.
Wevers genéricos
Eu não esperava que o ArcGis pudesse ser mais rápido que o Gdal. @Generic Militzer
Iris
Ah, espere, isso criará polígonos, mas eu preciso de polilinhas.
Wevers genéricos
Se você colocar seus dados em um Geodatabase de Arquivos, é bastante rápido. Mas ainda não é rápido o suficiente. É por isso que estou procurando alternativas.
Wevers genéricos
2
Não é necessariamente um problema o fato de obter polígonos, você sempre pode convertê-los em polilinhas (embora, com tantos, é claro que isso também pode demorar um pouco).
Martin
6

Para a posteridade, tenho tido sucesso com o stars::pacote Rpor fazer esse tipo de operação rapidamente.

library(raster)
library(stars)
library(sf)
library(magrittr)

f <- system.file("external/test.grd", package="raster")
r <- raster(f)
r[r[] < 750] <- 0
r[r[] >= 750] <- 1

x <- st_as_stars(r) %>% 
  st_as_sf() %>% # this is the raster to polygons part
  st_cast("MULTILINESTRING") # cast the polygons to polylines

plot(x)

insira a descrição da imagem aqui

plot(r)
plot(x, add = TRUE)

insira a descrição da imagem aqui

mikoontz
fonte
5

Tente rasterToContourdo pacote raster .

f <- system.file("external/test.grd", package="raster")
r <- raster(f)
r[r[] < 750] <- 0
r[r[] >= 750] <- 1

x <- rasterToContour(r)
class(x)
> [1] "SpatialLinesDataFrame"
> attr(,"package")
> [1] "sp"

plot(r)
plot(x, add=TRUE)

insira a descrição da imagem aqui

Você pode gravar facilmente os arquivos em uma pasta local, por exemplo, como 'ESRI Shapefile' (.shp), usando o código abaixo. Ter um olhar para ogrDriversa partir rgdal para descobrir quais drivers de seu sistema é compatível com.

library(rgdal)
writeOGR(x, dsn = getwd(), layer = "coastlines", driver = "ESRI Shapefile")
fdetsch
fonte
Vou tentar manter os dedos cruzados para não matar minha memória RAM. Embora eu tenha 16 GB, o que, espero, é suficiente, o R às vezes não é tão eficiente com grandes arquivos rasterizados. Mas vamos ver.
Wevers genéricos
A conversão funcionou de alguma forma, mas não pude verificar em detalhes. Como geralmente gosto mais do processamento de dados rasterizados, você pode me dizer como posso transferir o SpatialLineDataFrame para um shapefile ou algo comparável. Eu pesquisei no Google e ainda estou lutando, pois não sei o nome da camada (OGRwrite).
Wevers genéricos
Haha, eu definitivamente entendo o seu ponto. Veja a atualização acima.
Fdetsch
2
Outra dica: tente definir 'maxpixels' rasterToContourpara um valor mais alto, por exemplo, 1e + 9. Você vai acabar com mais detalhes. A configuração padrão cria linhas de contorno bastante generalizadas.
Fdetsch
1
Se você não deseja que resampleseus dados tenham uma resolução espacial mais grossa, a única solução que posso imaginar seria dividir seus dados em vários blocos (por exemplo, 16 sub-rasters), depois executar rasterToContourcada bloco separadamente de maneira iterativa e , finalmente, mergeos shapefiles resultantes em um enorme shapefile. Caso você esteja interessado, o pacote Rsenal do nosso grupo de trabalho oferece uma função chamada splitRasterpara criar vários sub-rasters a partir de uma enorme varredura.
Fdetsch 16/10/2015
2

Embora eu seja um grande fã do GDAL, a ferramenta polygonize também foi lenta demais para meus aplicativos.

Uma alternativa rápida é a gdal_trace_outlinepartir dos scripts Dans GDAL, que também tem mais opções de tolerância, rosquinhas, etc.

Assim gdal_polygonizetambém produz polígonos com os quais você precisaria converter depois ogr2ogr -nlt MULTILINESTRING.

A desvantagem disso é que você precisa compilá-lo, a menos que esteja em um sistema Linux ou Mac OsX.

Kersten
fonte
Infelizmente, falhou com a mensagem de erro: "Falha na segmentação (núcleo despejado)". Suponho que meu arquivo seja muito grande ou mais preciso; ele produzirá muitos polígonos pequenos.
Genérico Wevers