Извлечение количества вершин в каждом многоугольнике?


14

У меня есть ArcGIS Desktop 10.2, и моя задача состоит в том, как извлечь число вершин в каждом многоугольнике для всех функций, подобных этой:

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

У меня есть много участков в моем классе объектов, и я хочу извлечь количество вершин для всех объектов отдельно, затем я хочу отобразить координаты XY для всех вершин.

для получения дополнительной информации я просто хочу преобразовать вершины для каждого многоугольника и отобразить количество каждой вершины, начиная с 1 числа, поэтому, если у меня есть многоугольник, и у него есть 4 вершины, хочу преобразовать многоугольник в вершины, я отображаю количество вершин, подобное этому (1,2,3,4,5), затем отображая xy для каждой вершины, я думаю, что настоящая задача заключается в том, как преобразовать все многоугольники в вершины и сделать каждое число вершин, начиная с 1 числа.


Исходя из ваших правок, хотите ли вы, чтобы у каждого объекта был уникальный идентификатор (1 .... n) для объекта и координаты XY? Вы бы предпочли, чтобы в одном столбце / поле была вся эта информация для маркировки, например [1, 942744.1234, 924654.1234] [2, 952744.1234, 925654.1234] ...?
Аарон

да, если не ошибка, у одного поля есть идентификатор для количества вершин каждого многоугольника, как этот (1,2,3,4), (1,2,3,4,5), (1,2,3,4, 5,6,), (1,2,3,4,5,6,7,8,9) и т. Д., Тогда я думаю, что xy может быть простым, если бы мы назвали инструмент add xy из arctoolbox
GIS Man

Ответы:


5

Код ниже объединяет другие ответы и добавляет немного для нумерации вершин. Результаты

import arcpy
arcpy.env.workspace = "in_memory"
#paths
fc = r"...\polygons"
fc_out = r"...\vertices"
arcpy.MakeFeatureLayer_management(fc, "lyr")
# add fields if needed
for FIELD in ["DRAW_ORDER", "COUNT"]:
    if FIELD not in [field.name for field in arcpy.ListFields(fc)]:
        try:
            arcpy.AddField_management("lyr", FIELD, "SHORT")
        except Exception as e:
            print e
# get the number of points minus overlapping (@dmahr - GSE)
arcpy.CalculateField_management("lyr", "COUNT", "!Shape!.pointCount-!Shape!.partCount", "PYTHON")
# dict to iterate and check count
OIDS = {}
for row in arcpy.da.SearchCursor("lyr", ["OBJECTID", "COUNT"]):
    OIDS[row[0]] = row[1]
del row
# get vertices as points and add XY (@Aaron - GSE)
arcpy.FeatureVerticesToPoints_management("lyr", fc_out)
arcpy.AddXY_management(fc_out)
# start adding a number to the points
for OID in OIDS:
    order_count = 1
    rows = arcpy.da.UpdateCursor(fc_out, ["DRAW_ORDER", "COUNT"], "ORIG_FID = %d"%OID)
    for row in rows:
        # will leave the overlapping as NULL
        if order_count <= OIDS[OID]:
            row[0] = order_count
            rows.updateRow(row)
            order_count += 1
##        # this can set the overlapping to 0 or some unique value (999)
##        else:
##            row[0] = 0
##            rows.updateRow(row)

Точки помечены в порядке рисования. Последняя точка (под первой) не будет иметь метки и может быть удалена путем выбора всех точек с нулевым или уникальным значением «DRAW_ORDER», если они не нужны для реконструкции. Запрос определения может быть использован для удаления перекрывающихся точек с дисплея.

Данные XY присутствуют, но я оставлю это на ваше усмотрение маркировки / отображения. См. Ответ Аарона о добавлении поля XY для маркировки.

Я также играл с FeatureClass для массива numpy, но сначала я закончил.


спасибо @ gm70560, я проследил за твоими переменными кода и сохранил их как .py, но когда я хочу его выполнить, появляется сообщение об ошибке «Указанное имя поля не существует в таблице», так что я могу сделать ?
GIS Man

вот экран печати с моего компьютера, я просто установил путь к целевому классу пространственных объектов
GIS Man

Это не добавило поле (?). Что произошло дальше в результатах? У меня есть чат, чтобы вылить полные результаты. Оставьте комментарий, чтобы я мог проверить комнату.
gm70560

22

Самый простой способ сделать это - добавить новое целочисленное поле в таблицу атрибутов слоя участков. Затем запустите калькулятор поля со следующим выражением:

!Shape!.pointCount-!Shape!.partCount

!Shape!.pointCountВозвращает общее число вершин в этой функции. Однако первая вершина каждой части повторяется в конце, чтобы закрыть объект. Чтобы справиться с этим, вычтите одну вершину для каждой части, используя -!Shape!.partCount.

Обратите внимание, что для работы этого выражения вам придется использовать анализатор Python.

Полевой калькулятор


это действительно довольно круто, но не предоставит XY для каждой из этих вершин. Кажется, что ответом будет использование обоих ответов (то есть @ Aaron's), чтобы получить всю запрошенную информацию.
Роланд

@Roland Вы правы ... Я пропустил часть вопроса о вершинах XY. В этом случае вам придется использовать SearchCursorметод в ответе Аарона или инструмент геообработки, такой как Feature Vertices To Points (хотя для этого инструмента требуется лицензия ArcGIS for Desktop Advanced).
dmahr

большое спасибо @dmahr, я думаю, что пропущен шаг, когда я вычисляю значение, результатом является количество вершин, поэтому, если у меня есть класс пространственных объектов с 5 вершинами, я хочу отобразить его следующим образом 1,2,3 , 4,5 на каждую вершину, не считайте все вершины в одном числе, реальная проблема в том, как отобразить число для каждой вершины, начиная с 1 числа для каждой посылки.
GIS Man

12

Dmahr предоставил хорошее решение для подсчета вершин. Для непрограммного способа обозначить каждую точку с помощью координат XY, попробуйте следующий рабочий процесс:

  1. Вершины функций в точки
  2. Добавьте два новых поля (тип: double) в новую точку FC "X", "Y"
  3. Рассчитать геометрию. Щелкните правой кнопкой мыши поле> Рассчитать геометрию ...> Координата точки X (повторите для поля Y)
  4. Добавьте другое поле "XY" (тип: текст)
  5. Вычислить поле "XY" в полевом калькуляторе, где XY =

    str (! x!) + "," + str (! y!)

  6. Особенности этикетки. Щелкните правой кнопкой мыши слой> Метки> Поле метки: XY

Это дает следующие результаты:

введите описание изображения здесь

Вы также можете выполнить эти действия с помощью программно explode_to_pointsс помощью поиска курсора (как начало).

Разобрать элемент на отдельные точки или вершины. Если для explode_to_points задано значение True, многоточечный объект с пятью точками, например, представлен пятью строками.

(Значение по умолчанию неверно)

arcpy.da.SearchCursor (in_table, field_names, {where_clause}, {spatial_reference}, {explode_to_points}, {sql_clause})

Похоже, что потребуется постобработка или использование ответа @ dmahr для получения суммирования # вершин для каждой функции.
Роланд

4

Если кто-то не хочет вычислять новое поле и просто хочет очень быстро получить количество вершин на слой (для целей обобщения, например, при представлении наборов данных в Интернете), то можно создать собственный инструмент-скрипт внутри панель инструментов или представить код как надстройку Python.

Пользовательский код скрипта:

import arcpy
in_fc = arcpy.GetParameterAsText(0)

features = [feature[0] for feature in arcpy.da.SearchCursor(in_fc,"SHAPE@")]
count_vertices = sum([f.pointCount-f.partCount for f in features])
arcpy.AddMessage("***************************************")
arcpy.AddMessage("Number of vertices in the layer: {0}".format(count_vertices))
arcpy.AddMessage("***************************************")

Код надстройки Python (выберите слой в оглавлении для подсчета вершин):

import arcpy
import pythonaddins

arcpy.env.overwriteOutput = True
mxd = arcpy.mapping.MapDocument("current")
in_fc = pythonaddins.GetSelectedTOCLayerOrDataFrame()

features = [feature[0] for feature in arcpy.da.SearchCursor(in_fc,"SHAPE@")]
count_vertices = sum([f.pointCount-f.partCount for f in features])

pythonaddins.MessageBox(count_vertices, 'Number of vertices in {0}'.format(in_fc.name), 0)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.