usando shapely: traduzindo entre Polygons e MultiPolygons

12

[EDIT: a solução para isso era simplesmente usar OGR para ler shapefiles. Veja o exemplo da geographika.]

Em um shapefile da ESRI, não há distinção entre polígonos e multipolígonos. Além disso, não há distinção explícita entre orifícios internos e anéis externos (além da "mão" de um determinado polígono).

Então, depois de ler um shapefile, tenho uma lista de sequências de coordenadas que descrevem anéis, mas sem um processamento mais intenso, não consigo distinguir quais desses anéis são anéis externos, orifícios internos ou polígonos adicionais.

Parece que para bem torneadas do polígono e MultiPolygon construtores, deve haver uma distinção clara entre exterior e anéis interiores, assim como eu deveria passar de uma lista claro de toques para um conjunto ordenado de polígonos separados, com interior claramente designada e anéis exteriores ?

Resumindo: se eu tenho uma lista de anéis poligonais, mas não sei quais anéis são orifícios no interior ou polígonos separados, como devo classificá-los em polígonos separados com orifícios internos designados?

Estou procurando uma solução algorítmica simples que eu possa implementar em python, que possa ser usada para processar centenas de polígonos em ~ um minuto ou menos, e estou fazendo isso para realizar um grande número de interseções.

BenjaminGolder
fonte
Esta pergunta está faltando as informações cruciais sobre o que você usa para ler o Shapefile.
inc42
@ inc42 Eu estava usando python para ler o arquivo diretamente.
BenjaminGolder
Ah, então a parte Shapely é enganosa. Seu problema real foi descobrir como determinar o "tipo" de anel no formato Shapefile. :)
inc42

Respostas:

10

Além da resposta da relet sobre como obter polígonos individuais, você pode executar uma interseção em todos os polígonos para criar os orifícios. Se o seu conjunto de dados contém polígonos sobrepostos, você está sem sorte.

Explique novamente o que há de errado com os leitores existentes de shapefile?

Não seria mais fácil exportar IDs de recursos e valores M do shapefile e depois juntá-los de volta aos polígonos depois de usar um leitor de shapefile existente?

Para multipatches, você pode usar a mesma técnica de atribuir IDs de polígono a um "ID de patch" e adicionar esse atributo novamente aos recursos.

Edit: Enquanto você diz que não quer usar o OGR, apenas no caso de mudar de idéia.

import ogr
# Get the driver
driver = ogr.GetDriverByName('ESRI Shapefile')
# Open a shapefile
shapefileName = "D:/temp/myshapefile.shp"
dataset = driver.Open(shapefileName, 0)

layer = dataset.GetLayer()
for index in xrange(layer.GetFeatureCount()):
    feature = layer.GetFeature(index)
    geometry = feature.GetGeometryRef()
    #geometry for polygon as WKT, inner rings, outer rings etc. 
    print geometry

A geometria deve ser impressa da seguinte maneira:

POLYGON ((79285 57742,78741 54273...),(76087 55694,78511 55088,..))

O primeiro suporte contém as cordas do anel externo, e os colchetes subsequentes as cordas dos anéis internos. Se você tiver valores de Z, os pontos deverão estar no formato 79285 57742 10 (onde a última coord é uma altura).

Caso contrário, você poderá usar as funções Shapely Contains e Within para avaliar cada polígono entre si e aplicar um índice espacial previamente - http://pypi.python.org/pypi/Rtree/ para acelerar o processamento.

geographika
fonte
obrigado, não é isso que estou procurando, mas vi mais alguns esclarecimentos sobre a minha pergunta. Para responder às suas perguntas: 1, porque eu as classifico para fazer toneladas de interseções em primeiro lugar. 2, nada, eu só preciso de um que seja leve e que eu possa usar facilmente do python, e eu não aprendi ogr. 3, não, não seria mais fácil neste caso.
BenjaminGolder.
1
Uau! Obrigado geographika! Agora estou 90% convencido de que ogr é a solução aqui. Corri para alguns problemas de instalação com o ogr, mas parece que vale a pena trabalhar. Então ogr organiza os anéis em sua saída wkt? e está tudo bem com shapefiles 3d (eu uso muito 3d)?
BenjaminGolder.
Parece que as respostas para minhas perguntas são sim e sim. E obrigado por me apresentar a rtree. O OGR parece resolver meu problema completamente - desde que eu possa configurar a instalação corretamente neste momento.
BenjaminGolder
Reinstalação do OGR - lembre-se de que você precisará dos binários para Windows e das ligações Python correspondentes.
geographika
9

Primeiro, use ogr para abrir o shapefile:

from osgeo import ogr
source = ogr.Open("mpolys.shp")
layers =  source.GetLayerByName("mpoly")
len(layers)
1

converter geometrias de shapefile em geometrias bem torneadas

from shapely.wkb import loads
element=layers[0] #(because lenght of layer =1, else you need "for element in layers: ...")
geom = loads(element.GetGeometryRef().ExportToWkb())
geom.geom_type
'MultiPolygon'
print geom
MULTIPOLYGON ((..... # the geometry in shapely wkt format

Para os polígonos no multipolígono:

poly=[]
for pol in geom:
    poly.append(pol)
poly[0]
<shapely.geometry.polygon.Polygon object at 0x00B82CB0>
poly[0].geom_type
'Polygon'
print(poly[1])
POLYGON ((.... # the geometry in shapely wkt format

E agora, você pode usar todas as funções de bem torneadas ( bem torneadas )

Constantinius
fonte
1

Não estou muito familiarizado com o modo como os polígonos são realmente armazenados nos arquivos de formas, mas - um anel de polígono não deveria ser um loop fechado se e somente se a coordenada inicial for repetida? Portanto, se você comparar cada coordenada subsequente com a coordenada inicial, encontrará o primeiro ponto em que um polígono está fechado. Se essa é a última coordenada do polígono, é um polígono simples; caso contrário, é um multipolígono e requer o processamento dos outros loops.

Esse pode ser o 'processamento mais intensivo' que você deseja evitar, mas na verdade é apenas uma iteração pelas coordenadas que é gratuita quando você precisa lê-las de qualquer maneira.

relet
fonte
Peço desculpas - minha pergunta foi um pouco enganadora e a editei. Eu tenho os anéis poligonais e sei quando tenho uma lista de mais de um anel poligonal, mas, além da ordem dos pontos no sentido horário ou anti-horário, não sei se são anéis interno ou externo. Se eles são anéis internos, não tenho como ter certeza de qual anel externo eles pertencem, além de medir sua localização.
BenjaminGolder.
Entendo. Também estou feliz em ver que você encontrou o caminho para ogr. ;)
relet 24/01
-2

Conforme indicado por @ inc42 , na página 8 da Descrição técnica do ESRI Shapefile: um white paper da ESRI - julho de 1998 (página 12 de 34 no PDF), há uma discussão sobre o conteúdo dos registros poligonais que pode ser o que você procura:

Um polígono pode conter vários anéis externos. A ordem dos vértices ou orientação de um anel indica qual lado do anel é o interior do polígono.

PolyGeo
fonte
p.10: "Um polígono pode conter vários anéis externos. A ordem dos vértices ou a orientação de um anel indica qual lado do anel é o interior do polígono".
inc42
@ inc42 atualizado de acordo, apesar de achar que o número da página deve ser 8 (ou 12 de 34).
PolyGeo