Как люди используют структуры данных и классы Python в ArcPy?

16

Этот вопрос может разоблачить мое незнание в программировании, но мне любопытно, как люди используют разные структуры данных Python в ArcPy.

На этой странице перечислены структуры данных в Python. Я понимаю, как списки могут быть реализованы в ГИС (список классов объектов, список типов объектов, список фреймов данных и т. Д.). Я понимаю, как можно использовать наборы (для удаления дубликатов). Как люди реализуют кортежи, словари и другие структуры данных в ArcPy? Кроме того, есть ли другие примеры списков и наборов, которые я не перечислил?

Кроме того, без сомнения, люди создают собственные классы в ArcPy. При каких обстоятельствах и ситуациях вам это требуется? Можете ли вы привести примеры? Кто-нибудь создает пользовательские классы, которые наследуются от встроенных классов arcpy?

Мне не нужны ответы на все эти вопросы, мне просто интересно, как люди используют Python в ГИС и какие рабочие процессы требуют этих настроек.

Fezter
источник
4
Интересный вопрос, но на него нет однозначного ответа. Должно быть сообщество вики.
РК

Ответы:

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.

оборота blah238
источник
7

Blah238 хорошо освещает эту тему, поэтому я просто добавлю пару примеров из моей собственной работы. Я собираю много данных об аэропортах, и одна из вещей, которые я должен делать регулярно, - это читать по порядку вдоль осевых точек взлетно-посадочной полосы. Можно подумать, что эти пункты уже будут в порядке (в базе данных ГИС), но они редко бывают. Точки осевой линии встречаются каждые 10 футов вдоль осевой линии и по бокам с двух сторон окружены двумя другими рядами точек обзора, разнесенными на 10 футов друг от друга. Вы получаете картину: множество точек ... и, как правило, все они смешиваются в базе данных. Из того, что я делаю в своих сценариях, обычно проще всего выбрать точки центральной линии по атрибутам (или пространственно, если необходимо), прочитать координаты для каждого и вывести результаты в список Python. Я могу затем сортировать, всплывать, перевернуть и т. Д

Кроме того, я широко использую словари Python (вероятно, гораздо больше, чем некоторые одобряют). Я должен создать наборы трехмерных векторов единиц для каждого конца ВПП в аэропорту, и я постоянно получаю к ним доступ в сценарии и делаю это во многих своих сценариях. Я также храню много других наборов регулярно используемых данных в словарях. Как и списки, они быстрые и гибкие. Настоятельно рекомендуется.

Что касается классов, как Blah238, я не нашел необходимости создавать какие-либо. Вероятно, есть несколько случаев, когда класс был бы предпочтительным в моих сценариях, но я действительно не смог определить эти места. Кто-то с большим опытом программирования, вероятно, найдет их быстро.

celticflute
источник
5

Я тоже люблю словари - используй их все время. Этот метод получает некоторые свойства пространственной привязки и сохраняет их все в формате 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

Этот фрагмент метода извлекает геометрические точки из двух классов пространственных объектов, а затем я использую геометрические элементы для выполнения некоторых триггеров:

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

МНОГО того, над чем я сейчас работаю, включает в себя извлечение координат и атрибутов из векторных классов пространственных объектов и растров, чтобы данные могли быть помещены в другое программное обеспечение, которое даже не знает, что такое ГИС-данные. Поэтому я очень часто использую списки и словари.

Chad Cooper
источник
Спасибо за ответ. Почему словарь является лучшим выбором, чем другая структура данных в этих случаях?
Фезтер
Мне просто нравится иметь возможность вызывать мои значения по моим ключам.
Чед Купер
2
Другая причина, по которой дикты могут быть предпочтительнее, заключается в том, что они читаются намного быстрее списков, потому что они не упорядочены. следовательно, очень длинные списки могут занять немного больше времени для обработки, если в них много записей.
ndimhypervol
@gotanuki Правда, и если вам нужно использовать большой список, используйте вместо него кортеж, так как они также быстрее, чем списки.
Чед Купер
2

Прочитайте это , составляя ответ, и пришлось внести некоторые изменения.

Я не эксперт по Python, но я думаю, что идея использования классов заключается в том, что вы можете создать экземпляр объекта, у которого есть готовая группа методов, которые относятся к структуре данных, а также централизуют ваши методы. В классах и модулях также есть некоторые преимущества с переменными областями видимости.

У меня есть класс с именем featureLayer (вероятно, не с именем pythonic-ly ... все еще учусь). я могу сделать

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)

Определение для этого - метод класса, который просто перебирает элементы, части и вершины. Затем я могу превратить мой объект points в экземпляр featureLayer и делать другие вещи, которые есть в моем классе.

Я думаю, что если классы построены правильно, они должны приводить в действие функциональность. Например, скоро я начну рефакторинг, чтобы у меня был класс featureLayer, который имеет методы и атрибуты, которые есть во всех слоях объектов. Затем наследуйте его, чтобы создать экземпляр класса featureLayerStrict, который унаследует все атрибуты / методы featureLayers, но создаст экземпляр с конкретным типом геометрии, таким как polygon.

Джастин
источник
4
Посмотрите руководство по стилю Python (также известное как PEP 8) для соглашений об именах.
blah238
0

Я работаю в основном в VB .net, но все больше и больше использую python и arcpy. В VB я люблю и пытаюсь использовать Enums, так как это делает чтение кода более понятным. Более ранние версии python не реализовывали Enums, так что взломать было создать класс, предоставляющий некоторые свойства, множество примеров обсуждается на переполнении стека. . Похоже, что последняя версия python реализует их, что обсуждается здесь .

оборота Хорнбидд
источник