人们如何在ArcPy中使用Python数据结构和类?


16

这个问题可能暴露了我对编程的无知,但我对人们如何在ArcPy中使用不同的python数据结构感到好奇。

此页面列出了Python中的数据结构。我了解如何在GIS中实现列表(要素类列表,要素类型列表,数据框列表等)。我了解如何也可以使用集合(删除重复项)。人们如何在ArcPy中实现元组,字典和其他数据结构?另外,还有其他未列出的列表和集合示例吗?

此外,毫无疑问,人们正在ArcPy中创建自定义类。在什么情况下需要这些条件?你能提供例子吗?是否有人创建从内置arcpy类继承的自定义类?

我不需要所有这些问题的答案,我只是很好奇人们在GIS中如何使用Python,以及哪些工作流程需要这些自定义。


4
有趣的问题,但这没有确定的答案。应该是社区维基。
2012年

Answers:


14

许多接受多个输入的arcpy函数都接受Python列表对象。

例如,该Dissolve_management函数接受要溶解的字段名称列表:

arcpy.Dissolve_management("taxlots", "C:/output/output.gdb/taxlots_dissolved",
    ["LANDUSE", "TAXCODE"], "", "SINGLE_PART", "DISSOLVE_LINES")

当您不需要修改元素的顺序或数量时,可以使用元组代替列表,因为元组是不可变的。对于异构但相关的数据片段(例如时间戳记的元素或点的坐标),它们是有用的数据结构。您经常会看到元组列表,其中元组用作具有固定数量属性的不同记录,而该列表可以轻松更改大小,重新排序(排序)等。有关更多用法,请参见此StackOverflow问题列表与元组的比较。

字典可以用作快速查找表,以将相对较小但经常使用的一组键值对缓存到内存中。我在ArcGIS论坛上看到了一个有趣的示例:http : //forums.arcgis.com/threads/55099-Update-cursor-with-joined-tables-work-around-w-dictionaries

他们使用字典而不是联接的方法将计算时间从3.5小时缩短到15分钟。

一个简单的示例是,如果您有一百万个地址记录,并且该属性的状态名称带有缩写的州名(CA),但是出于显示目的,您希望拼写正确的名称(加利福尼亚州),则可以在以下情况下将该词典用作查找表:填充完整的州名称字段。

我没有发现需要用Python编写一个类供自己在arcpy中使用,但这并不是说没有这种用例。当您具有一组对某些输入(数据)进行操作的紧密相关的函数(行为),并且希望能够以面向对象的方式使用这些数据和行为时,类可能会很有用。可能是特定于业务逻辑的,与arcpy无关。


7

Blah238很好地涵盖了这个主题,因此我将在自己的工作中添加几个示例。我开发了许多机场数据,并且需要定期执行的一项操作是按顺序从跑道的被调查跑道中心线点读取数据。您可能认为这些要点已经在GIS数据库中按顺序排列了,但是很少。中心线点沿中心线每10英尺出现一次,在两侧两侧为相隔10英尺的另外两排测量点。您会看到图片:过多的点...通常在数据库方面都混合在一起。对于我在脚本中所做的事情,通常通常最简单的方法是按属性(或根据需要在空间上)选择中心线点,读取每个点的坐标,然后将结果转储到Python列表中。然后,我可以排序,弹出,反转等。

同样,我广泛使用Python词典(可能远远超过某些人的认可)。我必须为机场的每个跑道末端创建3D单位矢量集,并且需要在脚本中不断访问这些3D单位矢量,并在许多脚本中执行此操作。我还将许多其他定期访问的数据集保存在字典中。像列表一样,它们又快速又灵活。强烈推荐。

就像Blah238这样的类而言,我还没有发现需要创建任何类。在某些情况下,我的脚本中首选使用类,但是我确实无法识别这些位置。具有更多编程经验的人可能会很快找到它们。


5

我也喜欢字典-一直使用'em'。此方法获取一些空间参考属性并将其全部存储在dict中:

def get_coord_sys(self, in_dataset):
    """Get and return info on dataset coord sys/projection"""
    spatial_ref = arcpy.Describe(in_dataset).spatialReference
    # Get spatial ref props and put in dictionary
    spat_ref_dict = {}
    spat_ref_dict["name"] = spatial_ref.name
    spat_ref_dict["type"] = spatial_ref.type
    spat_ref_dict["gcs_code"] = spatial_ref.GCSCode
    spat_ref_dict["gcs_name"] = spatial_ref.GCSName
    spat_ref_dict["pcs_code"] = spatial_ref.PCSCode
    spat_ref_dict["pcs_name"] = spatial_ref.PCSName
    return spat_ref_dict

此方法片段从两个要素类中提取点几何,然后稍后再使用这些几何进行trig:

def build_fields_of_view(self):
        """For all KOPs in a study area, build left, right, center FoV triangles"""
        try:    
            fcs = {os.path.join(self.gdb, "WindFarmArray"):[], os.path.join(self.gdb, "KOPs"):[]}
            # Build a dict of WTG and KOP array geometries, looks like:
            #  {'KOPs': [[1, -10049.2697098718, 10856.699451165374], 
            #            [2, 6690.4377855260946, 15602.12386816188]], 
            #   'WindFarmArray': [[1, 5834.9321158060666, 7909.3822339441513], 
            #                     [2, 6111.1759513214511, 7316.9684107396561]]}
            for k, v in fcs.iteritems():
                rows = arcpy.SearchCursor(k, "", self.sr)
                for row in rows:
                    geom = row.shape
                    point = geom.getPart()
                    id = row.getValue("OBJECTID")
                    v.append([id, point.X, point.Y])   

            kops = fcs[os.path.join(self.gdb, "KOPs")] # KOP array
            wtgs = fcs[os.path.join(self.gdb, "WindFarmArray")] # WTG array

我目前正在从事的工作涉及从矢量要素类和栅格中提取坐标和属性,以便将数据推送到甚至不知道GIS数据是什么的另一软件中。因此,为此我经常使用列表和字典。


感谢您的回答。在这些情况下,为什么词典比其他数据结构更好?
Fezter

我只是希望能够通过键来调用我的值。
乍得·库珀

2
dict可能更可取的另一个原因是,因为它们没有顺序,所以它们的读取速度比列表快得多。因此,如果列表很长,则如果有很多条目,则可能会花费更多时间。
ndimhypervol

@gotanuki是的,如果您需要使用大列表,请改用元组,因为它们也比列表快。
乍得·库珀

2

阅读而制定了一份答案,不得不做出一些修改..

我不是Python专家,但我认为使用类的想法是,您可以实例化一个对象,该对象具有准备就绪的与数据结构相关的大量方法,并且可以集中化您的方法。类vs模块也有一些可变范围的好处,上面的链接到了这一点。

我有一个名为featureLayer的类(可能不是pythonic命名的...仍在学习中)。我可以

sys.path.append(r"\\Path\To\Scripts")
import gpFuncs as gpF
fc = arcpy.GetParameterAsText(0)
featureLayer = gpF.featureLayer(fc)
points = featureLayer.featureVerticesToPoints(featureid, "", first_and_last)

为此的定义是一个类方法,它仅迭代特征,零件和顶点。然后,我可以将我的点对象转换为featureLayer实例,并执行类具有的其他功能。

我认为,如果构建正确的类应该没有功能。例如,很快我将开始重构,以便拥有一个featureLayer类,该类具有所有要素图层都具有的方法和属性。然后从其继承以构建一个featureLayerStrict类实例,该实例将继承所有featureLayers属性/方法,但将使用诸如多边形之类的特定几何类型进行实例化。


4
查看Python样式指南(又名PEP 8)以了解命名约定。
blah238 2013年

0

我主要在VB .net工作,但越来越多地使用python和arcpy。在VB中,我喜欢并尝试使用Enums,因为它使阅读代码更加清晰。较早的python版本没有实现Enums,因此黑客可以创建一个暴露某些属性的Class,有关Stack Overflow的例子很多。现在看来,最新版本的python实现了这些功能,将在此处进行讨论。

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.