arcpy.geometry __geo_interface__ i funkcja AsShape (): utrata precyzji i dziur

10

Serializuję swoje arkadowe geometrie jako geojson, aby móc je później „uwodnić” jako geometrie i mam 2 problemy w cyklu:

PROBLEM 1: Precyzja

    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

Jeśli sprawdzę reprezentację ciągu, współrzędne nieznacznie się zmieniły:

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

PROBLEM 2: Otwory Jeśli wielokąt ma otwory, interfejs geo generuje błąd:

    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'

Wszelkie pomysły na rozwiązanie tych problemów?

Víctor Velarde
źródło
Tak, właśnie natknąłem się na numer 2. I wydaje się, że nie jest to miłość do tego tematu.
valveLondon
W ArcGIS 10.1 nadal jest to zepsute w Arcpy - Byłoby miło, gdyby ESRI mógł komentować ten temat.
James Mills,
Natknąłem się na pierwszy i drugi problem. U mnie skoordynowane nie zmieniają się (kiedy je drukujesz), ale geom1.equals (geom2) zawodzi mnie tylko kilka razy. Nie jestem pewien, dlaczego tak się dzieje. Drugi problem został rozwiązany za pomocą sugestii @valveLondon. Jeśli dowiedziałeś się, jak naprawić .equals, udostępnij.
Michalis Avraam,
@MichalisAvraam Mieliśmy ten sam problem i dostaliśmy się do ESRI w celu znalezienia rozwiązania - okazuje się, że jest to znany błąd (kiedy tworzysz geom bez projekcji, zmniejsza precyzję) - spójrz również na to pytanie .
om_henners
@om_henners Przyjąłem, że. Ale funkcja arcpy.AsShape () nie pozwala określić odniesienia przestrzennego. Ustawiłem wszystkie zmienne środowiskowe, mając nadzieję, że coś to zrobi (współrzędne wyjściowe itp.). Rozwiązaniem jest zatem ręczne odkodowanie GeoJSON, ponieważ ESRI nie dba o dokładność?
Michalis Avraam,

Odpowiedzi:

5

OK - cóż, myślałem, że to rozwiązałem.

zastąp wiersz ~ 80 tego pliku C: \ Python26 \ ArcGIS10.0 \ Lib \ arcpy \ arcobjects \ geometries.py z tego:

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

do tego (lub czegoś, co jest bardziej zwięzłe i eleganckie i robi to samo):

  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

Zasadniczo zapomnieli wziąć pod uwagę pączki w kształcie oznaczonym zerowymi wartościami. Wydziela to dobre geoJson (osobne części), ale metoda arcpy.AsShape niszczy GeoJSON.

ten kod:

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__

wyprowadza to:

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

Poddaję się. ;)

Aktualizacja Problem z dziurami został rozwiązany w wersji 10.1 z tą częścią Pythona:

return {'type': 'Polygon', 'coordinates': [[((pt.X, pt.Y) if pt else None)
                                                    for pt in part]
                                                        for part in self]}
klapa Londyn
źródło
czy nie powinno to zwracać słownika zamiast ciągu reprezentującego słownik? :)
blah238
Tak, masz rację, powinien. Zmieniłem go, żeby wypluł prawidłowy słownik GeoJSON obj. ale po sprawdzeniu metody AsShape zdałem sobie sprawę z daremności moich wysiłków.
valveLondon
Zastanawiam się, czy to ma coś wspólnego z problemem opisanym w tym wątku: forums.arcgis.com/threads/9763-Errors-in-arcpy-s-Polygon-class - powinien zostać naprawiony w 10 SP2 i na pewno 10.1.
blah238
2
ESRI zaktualizowano C:\Program Files\ArcGIS\Server\arcpy\arcpy\arcobjects\geometries.pyo 10.1, ale jeśli masz 10.0, możesz to naprawić samodzielnie.
valveLondon
3
Tak, naprawiłem to w 10.1, powyższa aktualizacja to nowe źródło w .pypliku. Myślałem, że to zrobiło z pakietu serwisowego dla 10, ale chyba nie.
Jason Scheirer