Eu estou tentando comparar duas classes de recurso separadas para identificar diferenças entre elas (tipo de uma função diff). Meu fluxo de trabalho básico:
- Extraio as geometrias usando um SearchCursor
- Salve as geometrias das duas classes de recursos como GeoJSON usando um modificado
__geo_interface__
( obtenha -o de valveLondonreturn {'type': 'Polygon', 'coordinates': [[((pt.X, pt.Y) if pt else None) for pt in part] for part in self]}
). Isso é para evitar o objeto de geometria compartilhada que a ESRI usa com cursores e a incapacidade de fazer cópias profundas (algumas discussões aqui no gis.stackexchange falam sobre isso). - Verifique as geometrias das duas classes de recursos com base em um identificador exclusivo. Por exemplo, compare a geometria FC1 OID1 com a geometria FC2 OID1. Para obter a geometria como uma instância de objeto ESRI, chame
arcpy.AsShape()
(modificado para ler polígonos com furos (consulte o ponto 2 acima)) comreturn cls(Array([map(lambda p: Point(*p) if p is not None else Point(), part) for part in coordinates]))
. A comparação é simplesmentegeom1.equals(geom2)
como indicado na classe Geometry .
Espero encontrar ~ 140 mudanças nas geometrias, mas meu script insiste que existem 430. Tentei verificar essas representações do GeoJSON e elas são idênticas, mas a classe Geometry equals () se recusa a dizer isso.
Um exemplo está abaixo:
>>> geom1geoJSON
{'type': 'Polygon', 'coordinates': [[(-122.8423481559999, 47.060497293000083), (-122.84239755599992, 47.059262423000064), (-122.84416913599989, 47.059309693000046), (-122.84416913599989, 47.060497293000083), (-122.8423481559999, 47.060497293000083)]]}
>>> geom2geoJSON
{'type': 'Polygon', 'coordinates': [[(-122.8423481559999, 47.060497293000083), (-122.84239755599992, 47.059262423000064), (-122.84416913599989, 47.059309693000046), (-122.84416913599989, 47.060497293000083), (-122.8423481559999, 47.060497293000083)]]}
>>> geom1 = arcpy.AsShape(geom1geoJSON)
>>> geom2 = arcpy.AsShape(geom2geoJSON)
>>> geom1.equals(geom2)
False
>>> geom2.equals(geom1)
False
O comportamento esperado aqui deve ser verdadeiro (não falso).
Alguém tem alguma sugestão antes de eu mudar tudo para geometrias ogr? (Eu hesito em ogr.CreateGeometryFromGeoJSON () espera uma string e o arcpy's __geo_interface__
retorna um dicionário e sinto que estou adicionando complexidade extra).
Os seguintes recursos foram úteis, mesmo que eles não respondam à pergunta:
- pergunta arcpy.Geometry aqui em gis.stackexchange.com, que foi vinculada acima no meu texto.
- Erros na classe Polygon do arcpy nos fóruns do arcgis.com (aparentemente existem muitos erros de precisão no ArcGIS 10.0 que teoricamente foram corrigidos na 10.1, mas não posso verificar se, no 10.0 SP5, você ainda recebe o erro).
numpy.allclose()
rtol
parâmetro como 0. Por padrão, é 1e-05 e pode levar a uma grande tolerância se os valores das matrizes forem grandes, consulte: stackoverflow.com/a/57063678/1914034A precisão de coordenadas será uma consideração importante aqui. Números de ponto flutuante não podem ser armazenados exatamente.
Se você usar a ferramenta Comparação de recursos , ela obtém o resultado esperado usando a tolerância XY padrão?
fonte
ao lado da resposta @ blah328, você tem a opção de comparar duas tabelas para relatar diferenças e semelhanças com valores tabulares e definições de campo com Tabela Comparada .
Exemplo:
fonte
Se a
.equals()
função não estiver funcionando conforme o esperado e / ou as coordenadas forem ligeiramente alteradas no ArcGIS, você poderá massagear as coordenadas XY e comparar o equivalente em cadeia da geometria. Observe,truncateCoordinates()
corta todos os valores além da quarta casa decimal.fonte
Você pode usar a ferramenta Selecionar camada por local (gerenciamento de dados) com o parâmetro overlap_type "ARE_IDENTICAL_TO", alternar a seleção , verificar a contagem de linhas e percorrer as linhas para coletar os objectids ou qualquer outra informação pertinente.
fonte