Получение экстента каждого полигона в шейп-файле с помощью ArcPy?


20

В ArcGIS 10 и Python я хочу получить информацию о экстенте (xmax, ymax, xmin, ymin) каждого из полигонов в шейп-файле.

Я могу получить размер всего шейп-файла, используя

file=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
desc=arcpy.Describe(file)
print desc.extent.Xmax

+394551,52085039532

Но я не могу понять, как получить одинаковую информацию для каждой строки в наборе данных.

rows = arcpy.SearchCursor("100k_trc_tiles_TVM")
for row in rows:
 print row

печатает 31 строку в наборе данных, но

for row in rows:
 desc=arcpy.Describe(row)
 print desc.extent.Xmax

выдает ошибку.

Ошибка времени выполнения: Объект: Опишите входное значение недопустимого типа

Я думал о добавлении значений экстента в таблицу, используя «вычислить геометрию», но это только дает центроид. Тогда я думаю, что мы можем использовать что-то вроде row.GetValue ("xmax").

При этом я знаю, что мы можем создать X / Y, max / min, используя функцию из http://www.ian-ko.com/free/free_arcgis.htm, но было бы лучше, если бы мы могли избежать необходимости добавлять поля, особенно если ArcPy может получить эти значения.

По сути, мне нужно получить экстенты для подачи в инструмент обрезки, чтобы вырезать 30 областей данных (в соответствии с листами карты 1: 100 000) для геообработки, так как инструмент Сплит завершается ошибкой из-за большого размера набора данных (см. Почему Intersect дает ОШИБКА 999999: Ошибка при выполнении функции Неверная топология [Слишком много конечных точек lineseg]? ). Я хочу автоматизировать это, поскольку это повторяется в ряде наборов данных.

=== рабочий скрипт ===

# Emulates Arc Info SPLIT tool by using Clip but
# Requires a FC from which each row is used as the input clip feature.
# Each row must be rectangular.
# Used on 12GB FGDB with 100 million records.


#Licence: Creative Commons
#Created by: George Corea; georgec@atgis.com.au, coreagc@gmail.com
import arcpy, string

#inFrame=arcpy.GetParameterAsText(0) # Input dataframe FC
#inFile=arcpy.GetParameterAsText(1) # Input FC for splitting
#outDir=arcpy.GetParameterAsText(2) # Output FGDB

inFrame=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
inFile=r"c:\junk\106\data\7_Merge.gdb\FullRez_m2b"
outDir=r"D:\SCRATCH\Projects\206\datasplit\test_slaasp.gdb"
#NameField="Name_1"

#arcpy.env.workspace = r"C:/Workspace"
arcpy.env.overwriteOutput = True

rows = arcpy.SearchCursor(inFrame)
shapeName = arcpy.Describe(inFrame).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    Name = row.Name_1
    print "Executing clip on: "+str(Name)
    extent = feat.extent
    #print extent.XMin,extent.YMin,extent.XMax,extent.YMax
# Create an in_memory polygon
    XMAX = extent.XMax
    XMIN = extent.XMin
    YMAX = extent.YMax
    YMIN = extent.YMin
    pnt1 = arcpy.Point(XMIN, YMIN)
    pnt2 = arcpy.Point(XMIN, YMAX)
    pnt3 = arcpy.Point(XMAX, YMAX)
    pnt4 = arcpy.Point(XMAX, YMIN)
    array = arcpy.Array()
    array.add(pnt1)
    array.add(pnt2)
    array.add(pnt3)
    array.add(pnt4)
    array.add(pnt1)
    polygon = arcpy.Polygon(array)
    ShapeFile = outDir+"\\temp_poly"
    arcpy.CopyFeatures_management(polygon, ShapeFile)

    #print Name
### Set local variables
    in_features = inFile
    clip_features = ShapeFile
    out_feature_class = outDir+"\\"+Name
    xy_tolerance = "0.22"

    # Execute Clip

    try:
        arcpy.Clip_analysis(in_features, clip_features, out_feature_class, xy_tolerance)
        print "Completed: "+str(Name)
    except:
        error = arcpy.GetMessages()
        print "Failed on: "+str(Name)+" due to "+str(error)

2
Вам не нужно записывать функцию клипа на диск, просто используйте полигон в памяти, например: polygon = arcpy.Polygon (массив) arcpy.Clip_analysis (in_features, polygon, out_feature_class, xy_tolerance)
user2856

ТКС. Любая идея, как я могу экспортировать строку в новый файл формы, чтобы он использовал, а не только экстент строки? Это так, что он может обрабатывать и непрямоугольные клипы.
GeorgeC

1
Хорошо, если вы просто хотите обрезать эту функцию в том же сценарии, просто используйте объект функции. Опять же, нет необходимости экспортировать в файл формы, например: arcpy.Clip_analysis (in_features, feat, out_feature_class, xy_tolerance)
user2856

Для шейп-файла или для каждого многоугольника в шейп-файле? Похоже, вы говорите здесь о двух разных вещах.
Рейнер

в вашем шейп-файле есть только один объект многоугольника? если нет, используйте цикл for для ваших объектов экстента.
Арагон

Ответы:


26

Получите объект формы в вашем курсоре и получите доступ к его свойству экстента. См. Справка ArcGIS Работа с геометрией в Python :

shapeName = arcpy.Describe(inFeatures).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    extent = feat.extent
    print extent.XMin,extent.YMin,extent.XMax,extent.YMax

1
Спасибо Люк. Это сработало отлично. Я отредактирую свой вопрос, чтобы иметь новый рабочий код, если кто-то захочет использовать инструмент, который - итеративно использует набор инструментов Clip для вырезания прямоугольных областей большого класса объектов. Эмулирует функциональность инструмента разделения информации о дуге без сбоев с наборами данных размером до 10 ГБ FGDB и 100 миллионами записей.
GeorgeC

Одна вещь - мне пришлось жестко закодировать имя столбца, чтобы получить эквивалент Name = row.Name_1, попробовав атрибут name как; NameField = "Name_1"; Name = row.NameField; или Name = row + "." + NameField, где NameField = arcpy.GetParameterAsText (2), а имя хранится в столбце Name_1. Есть идеи? Обратите внимание, я использовал ";" для обозначения новой строки.
GeorgeC

1
понял вышесказанное - row.GetValue (xxx) из gis.stackexchange.com/questions/16586/…
GeorgeC

7

Набор инструментов Bounding Container делает именно то, что вы хотите. Если вам просто нужны фрагменты кода, изучите функции внутри сценариев, один из них имеет дело с экстентом.

РЕДАКТИРОВАТЬ

Следует добавить, что скрипт добавит значения в поля Left, Right, Top и Bottom в созданном выходном файле, которые можно использовать для последующей обработки.


Благодарю. Проверим это. Надеюсь, я смогу использовать код в моих скриптах / моделях python.
GeorgeC

2

Я только что попробовал геометрию минимальной границы (Конверт) (в Data Management) в ArcGIS 10, и она, похоже, делает то же самое для всех полей.


1

Другим способом было бы выполнить SearchCursor () для шейп-файла, тогда вы можете использовать row.shape.extent:

rows = arcpy.SearchCursor(shapefileName)

for row in rows:
   extent = row.shape.extent
   ...
   ...

1

Как описано в разделе Извлечение координат вершин многоугольника в ArcMap? Вы можете получить вершины многоугольника, а затем добавить координаты x и y каждой вершины в качестве полей в таблице атрибутов. Это имеет ограничение не привязывать максимальные / минимальные координаты непосредственно к каждому многоугольнику, но это может быть достигнуто несколькими способами.

Метод, с которым я больше всего знаком, - это чтение полей x и y в списки python с помощью модуля pyshp , который затем можно отсортировать, чтобы найти максимальные и минимальные значения для каждого многоугольника. Затем можно использовать Pyshp, чтобы открыть класс Writer для добавления новых полей в исходные многоугольники и записать эти максимальные и минимальные значения в правильный многоугольник.

Я считаю, что это можно сделать с помощью arcpy, но у меня было много проблем с записью в шейп-файлы в 9.3 с использованием геопроцессора, поэтому я предпочитаю метод pyshp, однако я не уверен, что модуль arcpy решил эти проблемы.


0

Вы пытались использовать заглавную букву "М" в "XMax"? Я думаю, что это должно быть:

print desc.extent.XMax

вместо того

print desc.extent.Xmax

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.