Determinando se shapefile e raster se sobrepõem no Python usando OGR / GDAL? [fechadas]

9

Estou construindo um script em python usando OGR / GDAL.

Eu tenho um conjunto de shapefiles e um conjunto de arquivos raster GeoTiff.

Eu gostaria que meu script ignorasse os shapefiles se eles não cruzarem com a área raster.

O shapefile não é um retângulo, portanto, não posso simplesmente comparar os valores xmin / xmax, ymin / ymax retornados por layer.GetExtent (). Eu preciso do polígono real que representa sua forma geral e, em seguida, de alguma maneira de determinar se esse polígono cruza com o quadrado raster.

Eu estava pensando que, de alguma forma, poderia mesclar todos os polígonos no arquivo shapefile em um recurso e, em seguida, ler a geometria desse recurso e comparar essas informações na extensão da varredura. No entanto, não tenho certeza de como executar isso.

  1. Como extrair informações de polígono de borda do shapefile?
  2. Como determinar se esse polígono cruza uma determinada área quadrada?
JFerg
fonte
Eu não estou familiarizado com o osgeo, mas o equivalente do arco-íris poderia (poderia) envolver: ler a extensão raster, criar extensão de cobertura de polígono na memória, percorrer os shapefiles, recortar cada um na extensão do retângulo, testar se há algum resultado.
Phloem

Respostas:

17

O script a seguir determina a caixa delimitadora de uma varredura e cria com base na geometria da caixa delimitadora.

import ogr, gdal

raster = gdal.Open('sample.tif')
vector = ogr.Open('sample.shp')

# Get raster geometry
transform = raster.GetGeoTransform()
pixelWidth = transform[1]
pixelHeight = transform[5]
cols = raster.RasterXSize
rows = raster.RasterYSize

xLeft = transform[0]
yTop = transform[3]
xRight = xLeft+cols*pixelWidth
yBottom = yTop-rows*pixelHeight

ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(xLeft, yTop)
ring.AddPoint(xLeft, yBottom)
ring.AddPoint(xRight, yTop)
ring.AddPoint(xRight, yBottom)
ring.AddPoint(xLeft, yTop)
rasterGeometry = ogr.Geometry(ogr.wkbPolygon)
rasterGeometry.AddGeometry(ring)

A seguir, é determinada a geometria do polígono do vetor. Isso responde à sua primeira pergunta.

# Get vector geometry
layer = vector.GetLayer()
feature = layer.GetFeature(0)
vectorGeometry = feature.GetGeometryRef()

Por fim, a geometria do vetor e da varredura são testadas para interseção (retornos Trueou False). Isso responde à sua segunda pergunta.

print rasterGeometry.Intersect(vectorGeometry)
ustroetz
fonte
2
Obrigado, era exatamente isso que eu estava procurando. Esta resposta mostra claramente como criar, extrair e executar funções entre objetos de geometria, que é exatamente o que eu estava procurando.
JFerg
Esta solução testa se o polígono FID = 0 cruza com a varredura. Como você obtém a geometria do total do shapefile quando nenhum polígono representa isso?
JFerg
11
EDIT: O aumento no tempo de computação é irrelevante, então eu verifico se cada polígono no shapefile cruza agora.
JFerg
4

Acho a solução @ustroetz muito útil, mas precisava ser corrigida em dois lugares. Em primeiro lugar, pixelHeight = transform [5] já é um valor negativo, portanto, a equação deve ser

yBottom = yTop+rows*pixelHeight

Em segundo lugar, a ordem dos pontos no anel deve ser no sentido anti-horário. Eu estava tendo problemas com isso. A ordem correta é:

ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(xLeft, yTop)
ring.AddPoint(xLeft, yBottom)
ring.AddPoint(xRight, yBottom)
ring.AddPoint(xRight, yTop)
ring.AddPoint(xLeft, yTop)
Pandza
fonte