arcpy.geometry __geo_interface__ et fonction AsShape (): perte de précision et trous

10

Je sérialise mes géométries arcpy en tant que geojson afin de pouvoir les `` hydrater '' plus tard en tant que géométries et j'ai 2 problèmes dans le cycle .:

PROBLÈME 1: Précision

    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 je vérifie la représentation des chaînes, les coordonnées ont légèrement changé:

    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)]]}

PROBLÈME 2: trous Si le polygone a des trous, geo_interface génère une erreur:

    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'

Avez-vous des idées sur la façon de résoudre ces problèmes?

Víctor Velarde
la source
Oui, je suis tombé sur le numéro 2 moi-même. Et il ne semble pas y avoir beaucoup d'amour pour ce sujet.
valveLondon
C'est encore cassé dans arcpy dans ArcGIS 10.1 - Ce serait bien si ESRI pouvait commenter le sujet.
James Mills
J'ai rencontré les premier et deuxième problèmes. Avec moi, les coordonnées ne semblent pas changer (lorsque vous les imprimez) mais geom1.equals (geom2) ne me manque que quelques fois. Je ne sais pas pourquoi cela se produit également. Le 2ème problème a été corrigé en utilisant la suggestion de @valveLondon. Si vous avez découvert comment corriger les .equals, veuillez les partager.
Michalis Avraam
@MichalisAvraam Nous avons également rencontré le même problème et nous sommes allés sur ESRI pour trouver une solution - il s'avère que c'est un bogue connu (lorsque vous créez un geom sans projection, il tronque la précision) - jetez également un œil à cette question .
om_henners
@om_henners J'ai supposé cela. Mais la fonction arcpy.AsShape () ne vous permet pas de spécifier une référence spatiale. J'ai défini toutes les variables d'environnement en espérant que cela ferait quelque chose (cordons de sortie, etc ...). La solution est alors de décoder manuellement le GeoJSON car ESRI ne se soucie pas de la précision?
Michalis Avraam

Réponses:

5

OK - eh bien je pensais l'avoir résolu.

remplacez la ligne ~ 80 de ce fichier C: \ Python26 \ ArcGIS10.0 \ Lib \ arcpy \ arcobjects \ geometries.py à partir de ceci:

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

à cela (ou quelque chose qui est plus concis et élégant et fait la même chose):

  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

Fondamentalement, ils ont oublié de considérer les beignets dans la forme qui sont marqués par des valeurs de point nul. Cela crache un bon geoJson (parties séparées) mais la méthode arcpy.AsShape supprime GeoJSON.

ce code:

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__

sort ceci:

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

J'abandonne. ;)

Mise à jour Le problème des trous a été résolu à 10.1 avec ce morceau de python:

return {'type': 'Polygon', 'coordinates': [[((pt.X, pt.Y) if pt else None)
                                                    for pt in part]
                                                        for part in self]}
valveLondres
la source
cela ne devrait-il pas renvoyer un dictionnaire au lieu d'une chaîne représentant un dictionnaire? :)
blah238
Oui, tu as raison, ça devrait. Je l'ai changé pour cracher un obj de dictionnaire GeoJSON valide. mais après avoir vérifié la méthode AsShape, j'ai réalisé la futilité de mes efforts.
valveLondon
Je me demande si cela a quelque chose à voir avec le problème décrit dans ce fil: forums.arcgis.com/threads/9763-Errors-in-arcpy-s-Polygon-class - aurait dû être corrigé dans 10 SP2 et définitivement 10.1.
blah238
2
ESRI a été mis C:\Program Files\ArcGIS\Server\arcpy\arcpy\arcobjects\geometries.pyà jour à 10.1, mais si vous êtes à 10.0, vous pouvez le corriger vous-même.
valveLondon
3
Oui, je l'ai corrigé dans 10.1, la mise à jour ci-dessus est la nouvelle source du .pyfichier. Je pensais que cela en faisait un service pack pour 10 mais je suppose que non.
Jason Scheirer