Рисование параллельных линий внутри полигонов (Well Paths) с использованием ArcGIS Desktop?

11

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

Таким образом, мои основные критерии - это угол линии, ширина между линиями, минимальная / максимальная длина и ширина буфера со стороны многоугольников.

Изображение прикреплено, если это поможет.

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

Tx_Dan
источник
Требуется ли, чтобы линии заканчивались на определенном расстоянии от края многоугольника?
cndnflyr
да, мне нужно иметь буфер подальше от краев. Если бы я мог объявить это значение, это было бы здорово. Спасибо.
Tx_Dan

Ответы:

9

Как упоминает @cndnflyr, это может быть написано в Python.

Интерфейс Script Tool:

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

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

# import libraries
import arcpy

# set input/output parameters
polyFC = arcpy.GetParameterAsText(0)        # input polygons
outParallel = arcpy.GetParameterAsText(1)   # output parallel lines
lineSpacing = arcpy.GetParameterAsText(2)   # line spacing
buffDist = arcpy.GetParameterAsText(3)      # inner buffer distance

# parse numbers from parameters
lineSpaceNum = float(lineSpacing.split(' ')[0])
buffNum = float(buffDist.split(' ')[0])

# establish spatial reference
desc = arcpy.Describe(polyFC)
SR = desc.spatialReference

# set overwrite environment
arcpy.env.overwriteOutput = True
arcpy.env.outputCoordinateSystem = SR

parallels = []
# loop through each input shape
for row in arcpy.da.SearchCursor(polyFC, ["SHAPE@"], spatial_reference=SR):

    # create inner buffer
    polyBuff = row[0].buffer(buffNum * -1)

    # create hull rectangle to establish a rotated area of interest
    coordSplit = row[0].hullRectangle.split(' ')

    # collect corner coordinates
    coordList = arcpy.Array([arcpy.Point(coordSplit[0],coordSplit[1]),arcpy.Point(coordSplit[2],coordSplit[3]),arcpy.Point(coordSplit[4],coordSplit[5]),arcpy.Point(coordSplit[6],coordSplit[7]),arcpy.Point(coordSplit[0],coordSplit[1])])

    # create lines from hull rectangle
    currentLines = []
    for pointNum in range(0,4):
        arcpy.Array([coordList.getObject(pointNum),coordList.getObject(pointNum+1)])
        hullRecLine = arcpy.Polyline(arcpy.Array([coordList.getObject(pointNum),coordList.getObject(pointNum+1)]))
        currentLines.append(hullRecLine)

    # compare first and second line to determine if first line is short or long
    firstLong = 0
    if currentLines[0].length > currentLines[1].length:
        firstLong = 1

    # calculate number of points needed along short axis
    numPoints = int(math.floor(currentLines[firstLong].length/lineSpaceNum))

    # create and join points to create parallel lines
    for point in range(1,numPoints+1):
        shortPoint1 = currentLines[firstLong].positionAlongLine(lineSpaceNum*point)
        shortPoint2 = currentLines[firstLong + 2].positionAlongLine(currentLines[firstLong + 2].length - (lineSpaceNum*point))
        parallel = arcpy.Polyline(arcpy.Array([shortPoint1.centroid,shortPoint2.centroid]), SR)

        # intersect parallel lines with buffer
        parallelBuff = parallel.intersect(polyBuff,2)
        parallels.append(parallelBuff)

# write geometries to disk
arcpy.CopyFeatures_management(parallels, outParallel)

# add to map
mxd = arcpy.mapping.MapDocument("CURRENT")
dataFrame = arcpy.mapping.ListDataFrames(mxd, "*")[0]
addLayer = arcpy.mapping.Layer(outParallel)
arcpy.mapping.AddLayer(dataFrame, addLayer)

del row
флоэма
источник
Ух эта красивая, флоэма! Посмотрю. Огромное спасибо!
Tx_Dan
Это отличное использование методов в объекте SHAPE. Это элегантно Единственное, чего не хватает, - это установки угла линий. Как он есть, он проведет линии вдоль самой длинной стороны многоугольника.
cndnflyr
4

Это можно сделать с помощью Python, но для его написания потребуется некоторое время.

Я думаю, что самый быстрый способ реализовать это без Python - это иметь шаблонный файл SHP этих параллельных линий. Имейте несколько, если вам нужна переменная ширина, и просто используйте соответствующую для этого полигона. Сделайте так, чтобы линии шаблона занимали достаточно места, чтобы покрыть самый большой полигон, с которым вы столкнетесь.

  1. При редактировании перемещайте линии над многоугольником.
  2. Используйте инструмент «Поворот», переместите опорную точку туда, где параллельная линия и край многоугольника совпадают, и поверните линии так, чтобы они привязывались к краю многоугольника, на котором вы выстроились.
  3. Преобразовать многоугольник в полилинию
  4. Поместите ломаную линию на любое расстояние, которое вы хотите, чтобы параллельные линии были от края многоугольника.
  5. Используйте инструмент «Стереть», чтобы стереть полилинии, которые покрыты буферным ребром полигона.
  6. Выберите по расположению все линии, которые не находятся внутри многоугольника, и удалите их. Или я думаю, что инструмент Clip тоже подойдет.
  7. Выберите по атрибуту все строки, которые меньше определенной длины (слишком короткая, чтобы ее сохранить, хотя вам может понадобиться сначала добавить поле и вычислите геометрию), и больше определенной длины (слишком длинная, чтобы ее сохранить, если вы этого хотите ), удалите их.
  8. Промыть и повторить...

Шаги с 3 по 7 могут быть смоделированы, без необходимости написания кода.

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

cndnflyr
источник
Спасибо за подробный ответ. Я попробую и посмотрю, как это работает. Благодаря!
Tx_Dan