arcpy.geometry __geo_interface__ e função AsShape (): perda de precisão e furos

10

Estou serializando minhas geometrias do arco-íris como geojson, para poder 'hidratá-las novamente como geometrias mais tarde e estou tendo 2 problemas no ciclo .:

PROBLEMA 1: Precisão

    R0 = arcpy.SearchCursor(self.shpTest, "FID=0").next().getValue("Shape")          
    geojson = R0.__geo_interface__                        
    R1 = arcpy.AsShape(geojson)
    self.assertTrue(R0.equals(R1)) <<< THIS FAILS

Se eu verificar a representação da string, as coordenadas mudaram ligeiramente:

    geojson2 = R1.__geo_interface__
    print geojson
    print geojson2  

    {'type': 'Polygon', 'coordinates': [[(442343.5516410945, 4814166.6184399202), (442772.17749834526, 4811610.7383281607), (441565.67508534156, 4811499.6131059099), (440772.50052100699, 4814184.7808806188), (442343.5516410945, 4814166.6184399202)]]}
    {'type': 'Polygon', 'coordinates': [[(442343.55169677734, 4814166.6185302734), (442772.17749023438, 4811610.73828125), (441565.67510986328, 4811499.6130981445), (440772.50048828125, 4814184.7808837891), (442343.55169677734, 4814166.6185302734)]]}

PROBLEMA 2: Furos Se o polígono possui furos, geo_interface gera um erro:

    R0_WithHoles = arcpy.SearchCursor(self.shpTest, "FID=0").next().getValue("Shape")          
    geojson = R0.__geo_interface__  <<< generates this ERROR:

    File "C:\Program Files\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\geometries.py", line 68, in __geo_interface__
        return {'type': 'Polygon', 'coordinates': [[(pt.X, pt.Y) for pt in part] for part in self]}
    AttributeError: 'NoneType' object has no attribute 'X'

Alguma idéia de como resolver esses problemas?

Víctor Velarde
fonte
Sim, apenas me deparei com o número 2. E não parece haver muito amor por esse tópico.
usar o seguinte código
Isso ainda está quebrado no arcpy no ArcGIS 10.1 - Seria bom se a ESRI pudesse comentar sobre o assunto.
James Mills
Me deparei com o primeiro e o segundo problemas. Comigo, as coordenadas parecem não mudar (quando você as imprime), mas geom1.equals (geom2) falha comigo apenas algumas vezes. Não sei por que isso acontece também. O segundo problema foi corrigido usando a sugestão de @valveLondon. Se você descobriu como corrigir os .equals, compartilhe.
Michalis Avraam
@MichalisAvraam Também tivemos o mesmo problema e entramos na ESRI em busca de uma solução - acontece que é um bug conhecido (quando você cria um geom sem uma projeção que trunca a precisão) - dê uma olhada nessa pergunta também.
Om_henners
@om_henners Eu assumi isso. Mas a função arcpy.AsShape () não permite especificar uma referência espacial. Eu configurei todas as variáveis ​​de ambiente esperando que fizesse algo (cordas de saída, etc ...). A solução é decodificar manualmente o GeoJSON porque a ESRI não se importa com a precisão?
Michalis Avraam

Respostas:

5

OK - bem, eu pensei que tinha resolvido.

substitua a linha ~ 80 deste arquivo C: \ Python26 \ ArcGIS10.0 \ Lib \ arcpy \ arcobjects \ geometries.py a partir disso:

return {'type': 'Polygon', 'coordinates': [[(pt.X, pt.Y) for pt in part] for part in self]}

para isso (ou algo que seja mais conciso e elegante e faça a mesma coisa):

  obj = {"type": "Polygon"}
    coordinates = []
    for part in self:
        _part = []
        for pt in part:
            if pt is not None:
                print pt
                _part.append([pt.X,pt.Y])
            else:
                print "none"
                coordinates.append(_part)
                _part=[]
        coordinates.append(_part)
    obj["coordinates"]=coordinates
    return obj

Basicamente, eles esqueceram de considerar rosquinhas na forma que são marcadas por valores de pontos nulos. Isso gera um bom geoJson (partes separadas), mas o método arcpy.AsShape destrói o GeoJSON.

este código:

import arcpy
gj = {
  'type': 'Polygon', 'coordinates': [
   [[-122.803764, 45.509158], [-122.796246, 45.500050], [-122.808193, 45.500109],
      [-122.803764, 45.509158]],
   [[-122.804206, 45.504509], [-122.802882, 45.502522], [-122.801866, 45.504479], 
      [-122.804206, 45.504509]]
   ]
 }

 p = arcpy.AsShape(gj)
 print p.__geo_interface__

gera isso:

    {'type': 'Polygon', 'coordinates': [[[-122.8037109375, 45.50927734375],  
    [-122.79620361328125, 45.5001220703125], [-122.80810546875, 45.5001220703125],
    [-122.8037109375, 45.50927734375]]]}

Desisto. ;)

Atualização O problema dos buracos foi resolvido na versão 10.1 com este pedaço de python:

return {'type': 'Polygon', 'coordinates': [[((pt.X, pt.Y) if pt else None)
                                                    for pt in part]
                                                        for part in self]}
valveLondon
fonte
isso não deveria retornar um dicionário em vez de uma string que representa um dicionário? :)
blah238
Sim, você está certo, deveria. Eu mudei para cuspir um objeto válido do dicionário GeoJSON. mas depois de checar o método AsShape, percebi a futilidade dos meus esforços.
valveLondon
Gostaria de saber se isso tem algo a ver com o problema descrito neste tópico: forums.arcgis.com/threads/9763-Errors-in-arcpy-s-Polygon-class - deveria ter sido corrigido no 10 SP2 e definitivamente 10.1.
blah238
2
ESRI atualizado C:\Program Files\ArcGIS\Server\arcpy\arcpy\arcobjects\geometries.pyem 10.1, mas se você estiver em 10.0, poderá corrigi-lo.
valveLondon
3
Sim, eu o corrigi na versão 10.1, a atualização acima é a nova fonte no .pyarquivo. Eu pensei que ele fez um service pack para 10, mas acho que não.
Jason Scheirer