arcpy.geometry __geo_interface__ e AsShape (): perdita di precisione e buchi


10

Sto serializzando le mie geometrie arcpy come geojson in modo da poterle "idratare" come geometrie in seguito e sto avendo 2 problemi nel ciclo .:

PROBLEMA 1: Precisione

    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 controllo la rappresentazione della stringa, le coordinate sono leggermente cambiate:

    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: Buchi Se il poligono ha buchi, geo_interface genera un errore:

    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'

Qualche idea su come risolvere questi problemi?


Sì, ho appena incontrato il numero 2 da solo. E non sembra essere molto amore per questo argomento.
valvolaLondra

Questo è ancora rotto in arcpia in ArcGIS 10.1 - Sarebbe bello se ESRI potesse commentare l'argomento.
James Mills,

Mi sono imbattuto nel primo e nel secondo problema. Con me, il coordinato non sembra cambiare (quando li stampi) ma geom1.equals (geom2) mi fallisce solo poche volte. Non sono sicuro del perché accada anche quello. Il secondo problema è stato risolto usando il suggerimento di @valveLondon. Se hai scoperto come correggere i .equals, ti preghiamo di condividere.
Michalis Avraam,

@MichalisAvraam Abbiamo avuto anche lo stesso problema e siamo entrati in ESRI per una soluzione - si scopre che è un bug noto (quando si crea un geom senza una proiezione che tronca la precisione) - dare un'occhiata anche a questa domanda .
om_henners,

@om_henners l'ho assunto. Ma la funzione arcpy.AsShape () non consente di specificare un riferimento spaziale. Ho impostato tutte le variabili di ambiente sperando che avrebbe fatto qualcosa (coord di output, ecc ...). La soluzione quindi è decodificare manualmente GeoJSON perché ESRI non si preoccupa dell'accuratezza?
Michalis Avraam,

Risposte:


5

OK - beh, ho pensato di averlo risolto.

sostituisci la linea ~ 80 di questo file C: \ Python26 \ ArcGIS10.0 \ Lib \ arcpy \ arcobjects \ geometries.py da questo:

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

a questo (o qualcosa che è più conciso ed elegante e fa la stessa cosa):

  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

Fondamentalmente si sono dimenticati di considerare le ciambelle nella forma che sono contrassegnate da valori di punti nulli. Questo sputa buon geoJson (parti separate) ma il metodo arcpy.AsShape elimina GeoJSON.

questo codice:

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__

genera questo:

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

Mi arrendo. ;)

Aggiornamento Il problema dei buchi è stato risolto alla 10.1 con questo pezzo di pitone:

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

non dovrebbe restituire un dizionario invece di una stringa che rappresenta un dizionario? :)
blah238,

Sì, hai ragione, dovrebbe. L'ho cambiato per sputare un obj del dizionario GeoJSON valido. ma dopo aver verificato il metodo AsShape mi sono reso conto dell'inutilità dei miei sforzi.
valvolaLondra,

Mi chiedo se ciò abbia a che fare con il problema descritto in questo thread: forums.arcgis.com/threads/9763-Errors-in-arcpy-s-Polygon-class - avrebbe dovuto essere risolto in 10 SP2 e sicuramente 10.1.
blah238,

2
ESRI aggiornato C:\Program Files\ArcGIS\Server\arcpy\arcpy\arcobjects\geometries.pyalla 10.1, ma se sei alla 10.0 puoi risolverlo da solo.
valvolaLondra,

3
Sì, l'ho corretto in 10.1, l'aggiornamento sopra è la nuova fonte nel .pyfile. Ho pensato che lo trasformasse in un service pack per 10, ma credo di no.
Jason Scheirer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.