Намалювання паралельних ліній всередині багатокутників (ну доріжки) за допомогою ArcGIS Desktop?


11

Я хотів би взяти клас особливості багатокутника з декількома неправильними багатокутниками, а дуга намалювати паралельні лінії всередині кожного багатокутника. В ідеалі, Arc було б добре визначити кут найдовшої сторони багатокутника і провести паралельні лінії до цієї сторони, але щоб це було просто, я думаю, якби я міг просто ввести один кут для всіх паралельних прямих, було б простіше.

Отже, кут лінії, ширина між лініями, довжина хв / макс та ширина буфера від сторін багатокутників - це мої основні критерії.

Зображення додається, якщо це допомагає.

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


Чи є вимогою, щоб лінії закінчували певну відстань від краю полігона?
cndnflyr

так, мені потрібно мати буфер подалі від країв. Якщо я можу визнати це значення, це було б чудово. Дякую.
Tx_Dan

Відповіді:


9

Як згадує @cndnflyr, це може бути написано в Python.

Інтерфейс інтерфейсу сценарію:

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

Вибірка зразка: введіть тут опис зображення

# 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. Виберіть за місцем розташування всі лінії, які не знаходяться всередині полігону, та видаліть їх. Або я думаю, що інструмент "Кліп" теж працював.
  7. Виділіть за атрибутом всі рядки, менші за певну довжину (занадто короткі, щоб зберегти, хоча, можливо, спочатку потрібно буде додати поле та обчислити геометрію), і більше певної довжини (занадто довго, щоб зберегти, якщо це те, що ви хочете ), видаліть їх.
  8. Промийте і повторіть ...

Етапи від 3 до 7 можна моделювати без необхідності писати будь-який код.

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


Дякую за детальну відповідь. Я спробую це спробувати і подивитися, як це працює. Дякую!
Tx_Dan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.