Функция arcpy.geometry __geo_interface__ и AsShape (): потеря точности и дыр

10

Я сериализую свои дугообразные геометрии как geojson, чтобы потом я мог «гидрировать» их обратно в виде геометрий, и у меня есть 2 проблемы в цикле:

ПРОБЛЕМА 1: Точность

    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

Если я проверю строковое представление, координаты немного изменились:

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

ПРОБЛЕМА 2: Отверстия Если у многоугольника есть отверстия, geo_interface генерирует ошибку:

    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'

Есть идеи, как решить эти проблемы?

Виктор Веларде
источник
Да, просто наткнулся на номер 2 сам. И, похоже, не очень люблю эту тему.
valveLondon
В ArcGIS 10.1 это все еще не работает в arcpy. Было бы неплохо, если бы ESRI мог прокомментировать эту тему.
Джеймс Миллс
Я столкнулся с первой и второй проблемами. Со мной скоординированные, похоже, не меняются (когда вы их печатаете), но geom1.equals (geom2) подводит меня только несколько раз. Я не уверен, почему это происходит также. Вторая проблема была решена с помощью предложения @valveLondon. Если вы узнали, как исправить .equals, пожалуйста, поделитесь.
Михалис Авраам
@MichalisAvraam У нас была та же проблема, и мы нашли решение ESRI - оказалось, что это известная ошибка (когда вы создаете геом без проекции, это урезает точность) - взгляните и на этот вопрос .
om_henners
@om_henners Я предполагал это. Но функция arcpy.AsShape () не позволяет указывать пространственную привязку. Я установил все переменные окружения, надеясь, что это что-то сделает (выходные координаты и т. Д.) Тогда решение заключается в том, чтобы вручную декодировать GeoJSON, потому что ESRI не заботится о точности?
Михалис Авраам

Ответы:

5

Хорошо - я думал, что решил это.

замените строку ~ 80 этого файла C: \ Python26 \ ArcGIS10.0 \ Lib \ arcpy \ arcobjects \ geometryries.py из этого:

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

на это (или что-то более краткое и элегантное и делает то же самое):

  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

В основном они забыли рассмотреть пончики в форме, которые отмечены нулевыми значениями. Это выдает хороший geoJson (отдельные части), но метод arcpy.AsShape уничтожает GeoJSON.

этот код:

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__

выводит это:

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

Я сдаюсь. ;)

Обновление Проблема с дырами была решена в 10.1 с помощью этого фрагмента python:

return {'type': 'Polygon', 'coordinates': [[((pt.X, pt.Y) if pt else None)
                                                    for pt in part]
                                                        for part in self]}
valveLondon
источник
разве это не должно возвращать словарь вместо строки, представляющей словарь? :)
blah238
Да, ты прав, так и должно быть. Я изменил его, чтобы выложить действительный словарь GeoJSON obj. но после проверки по методу AsShape я понял тщетность моих усилий.
valveLondon
Интересно, имеет ли это какое-либо отношение к проблеме, описанной в этой теме: forums.arcgis.com/threads/9763-Errors-in-arcpy-s-Polygon-class - должно быть исправлено в 10 SP2 и определенно в 10.1.
blah238
2
ESRI обновлен C:\Program Files\ArcGIS\Server\arcpy\arcpy\arcobjects\geometries.pyдо 10.1, но если вы на 10.0, вы можете исправить это самостоятельно.
valveLondon
3
Да, я исправил это в 10.1, обновление выше - новый источник в .pyфайле. Я думал, что это превратилось в пакет обновления для 10, но я думаю, что нет.
Джейсон Шайрер,