arcpy.geometry __geo_interface__和AsShape()函数:精度和孔的损失


10

我正在将arcpy几何序列化为geojson,以便以后可以将它们“水化”为几何形状,并且在周期中遇到两个问题:

问题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'

关于如何解决这些问题的任何想法?


是的,我自己遇到了第二名。似乎并不太喜欢这个话题。
valve伦敦2011年

这在ArcGIS 10.1中的arcpy中仍然没有解决-如果ESRI可以对此主题发表评论,那就太好了。
James Mills

我遇到了第一个和第二个问题。对于我来说,协调的似乎没有变化(当您打印它们时),但是geom1.equals(geom2)仅使我失败了几次。我不确定为什么也会发生这种情况。使用@valveLondon的建议解决了第二个问题。如果您找到了如何修复.equals的方法,请共享。
Michalis Avraam '11年

@MichalisAvraam我们也遇到了同样的问题,并获得了ESRI的解决方案-事实证明这是一个已知的错误(当您创建没有投影的geom时,它会截断精度)- 也请看一下这个问题
om_henners 2012年

@om_henners我以为是。但是arcpy.AsShape()函数不允许您指定空间参考。我已经设置了所有环境变量,希望它能完成某些工作(输出坐标等)。然后解决方案是手动解码GeoJSON,因为ESRI不在乎准确性?
Michalis Avraam 2012年

Answers:


5

OK-好吧,我以为我已经解决了。

从以下位置替换此文件C:\ Python26 \ ArcGIS10.0 \ Lib \ arcpy \ arcobjects \ geometries.py的〜80行:

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

那不应该返回字典而不是代表字典的字符串吗?:)
blah238

是的,您是正确的,应该。我将其更改为吐出有效的GeoJSON字典obj。但是在检查了AsShape方法后,我意识到自己的努力是徒劳的。
valve伦敦2012年

我想知道这是否与该线程中描述的问题有关:forums.arcgis.com/threads/9763-Errors-in-arcpy-s-Polygon-class-应该已经在10 SP2中并且肯定在10.1中修复了。
blah238'3

2
ESRI的更新C:\Program Files\ArcGIS\Server\arcpy\arcpy\arcobjects\geometries.py为10.1,但如果您的值为10.0,则可以自己进行修复。
valve伦敦2012年

3
是的,我在10.1中修复了它,上面的更新是.py文件中的新源。我以为它可以放入10个服务包中,但我想不是。
杰森·谢勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.