arcpy.geometry __geo_interface__ y AsShape () función: pérdida de precisión y agujeros

10

Estoy serializando mis geometrías arcpy como geojson para poder 'hidratarlas' como geometrías más tarde y tengo 2 problemas en el ciclo .:

PROBLEMA 1: Precisión

    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

Si verifico la representación de la cadena, las coordenadas han cambiado ligeramente:

    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: agujeros Si el polígono tiene agujeros, geo_interface genera un error:

    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'

¿Alguna idea sobre cómo resolver estos problemas?

Víctor Velarde
fuente
Sí, me encontré con el número 2. Y no parece ser mucho amor por este tema.
valveLondon
Esto todavía está roto en arcpy en ArcGIS 10.1 - Sería bueno si ESRI pudiera comentar sobre el tema.
James Mills
Encontré el primer y el segundo problema. Conmigo, las coordenadas no parecen cambiar (cuando las imprime) pero geom1.equals (geom2) me falla solo unas pocas veces. No estoy seguro de por qué sucede eso también. El segundo problema se solucionó utilizando la sugerencia de @valveLondon. Si descubrió cómo solucionar los .equals, por favor comparta.
Michalis Avraam
@MichalisAvraam También tuvimos el mismo problema y nos metimos en ESRI para encontrar una solución: resulta que es un error conocido (cuando creas una geom sin proyección, trunca la precisión), mira esta pregunta también.
om_henners
@om_henners Asumí eso. Pero la función arcpy.AsShape () no le permite especificar una referencia espacial. He configurado todas las variables de entorno con la esperanza de que haga algo (salida de coordenadas, etc.). ¿Entonces la solución es decodificar manualmente el GeoJSON porque a ESRI no le importa la precisión?
Michalis Avraam

Respuestas:

5

OK, bueno, pensé que lo había resuelto.

reemplace la línea ~ 80 de este archivo C: \ Python26 \ ArcGIS10.0 \ Lib \ arcpy \ arcobjects \ geometries.py de esto:

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

a esto (o algo que es más conciso y elegante y hace lo mismo):

  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

Básicamente se olvidaron de considerar donas en la forma que están marcadas por valores de punto nulo. Esto arroja un buen geoJson (partes separadas) pero el método arcpy.AsShape destruye GeoJSON.

este codigo:

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__

produce esto:

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

Me rindo. ;)

Actualización El problema de agujeros se resolvió en 10.1 con este fragmento de python:

return {'type': 'Polygon', 'coordinates': [[((pt.X, pt.Y) if pt else None)
                                                    for pt in part]
                                                        for part in self]}
válvula de Londres
fuente
¿no debería eso devolver un diccionario en lugar de una cadena que representa un diccionario? :)
blah238
Sí, tienes razón, debería. Lo cambié para escupir un obj de diccionario GeoJSON válido. pero después de verificar el método AsShape me di cuenta de la inutilidad de mis esfuerzos.
valveLondon
Me pregunto si eso tiene algo que ver con el problema descrito en este hilo: forums.arcgis.com/threads/9763-Errors-in-arcpy-s-Polygon-class - debería haberse solucionado en 10 SP2 y definitivamente 10.1.
blah238
2
ESRI se actualizó C:\Program Files\ArcGIS\Server\arcpy\arcpy\arcobjects\geometries.pyen 10.1 pero si está en 10.0 puede solucionarlo usted mismo.
valveLondon
3
Sí, lo arreglé en 10.1, la actualización anterior es la nueva fuente en el .pyarchivo. Pensé que se convirtió en un paquete de servicio para 10, pero supongo que no.
Jason Scheirer