Desenhando linhas paralelas dentro de polígonos (Well Paths) usando o ArcGIS Desktop?

11

Gostaria de fazer uma classe de recurso de polígono com vários polígonos irregulares e fazer com que o Arc desenhe linhas paralelas dentro de cada polígono. Idealmente, seria bom para Arc descobrir o ângulo do lado mais longo do polígono e desenhar linhas paralelas para esse lado, mas, para simplificar, acho que se eu pudesse inserir um ângulo para todas as linhas paralelas, seria mais fácil.

Portanto, ângulo de linha, largura entre linhas, comprimento mínimo / máximo e largura do buffer dos lados dos polígonos são os meus critérios básicos.

Imagem anexada, se isso ajudar.

insira a descrição da imagem aqui

Tx_Dan
fonte
É um requisito para as linhas terminarem uma certa distância da aresta do polígono?
cndnflyr 17/09/14
Sim, preciso ter um buffer longe das bordas. Se eu puder declarar esse valor, isso seria ótimo. Obrigado.
Tx_Dan 17/09/14

Respostas:

9

Como o @cndnflyr menciona, isso pode ser script em Python.

Interface do usuário da ferramenta de script:

insira a descrição da imagem aqui

Saída de amostra: insira a descrição da imagem aqui

# 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
floema
fonte
Uau, esse lindo floema! Vai dar uma olhada. Muito obrigado!
Tx_Dan 20/09/14
Este é um ótimo uso dos métodos no objeto SHAPE. É elegante. A única coisa que falta é definir o ângulo das linhas. Como é, ele irá desenhar as linhas ao longo do lado mais longo do polígono.
Cndnflyr 29/09/14
4

Isso poderia ser feito com o Python, mas levaria algum tempo para escrevê-lo.

Acho que a maneira mais rápida de implementá-lo sem o Python é ter um arquivo SHP modelo dessas linhas paralelas. Tenha alguns, se você precisar de larguras variadas, e use apenas o apropriado para esse polígono. Faça com que as linhas do modelo cubram a área suficiente para cobrir o maior polígono que você encontrará.

  1. Durante a edição, mova as linhas sobre o polígono.
  2. Use a ferramenta Girar, mova o ponto de ancoragem para onde a linha Paralela e a aresta do polígono coincidem e gire as linhas para que encaixem na aresta do polígono em que você a alinha.
  3. Converter o polígono em uma polilinha
  4. Coloque a Polilinha no buffer, a qualquer distância que você deseja que as linhas paralelas estejam da borda do polígono.
  5. Use a ferramenta Apagar para apagar as polilinhas cobertas pela borda do polígono em buffer
  6. Selecione por local todas as linhas que não estão dentro do polígono e exclua-as. Ou acho que a ferramenta Clip também funcionaria.
  7. Selecione por atributo todas as linhas com menos de um determinado comprimento (muito curto para manter, embora seja necessário adicionar um campo e calcular a geometria primeiro) e mais que um certo comprimento (muito longo para manter, se é isso que você deseja ), exclua-os.
  8. Enxague e repita...

As etapas 3 a 7 podem ser modeladas, sem a necessidade de escrever nenhum código.

O mesmo processo pode ser usado para codificar o processo, mas em vez de ter linhas de modelo, você pode fazer com que o código desenhe as linhas no ângulo certo, na distância, etc. Eu não faço isso há algum tempo, mas acho que um Biblioteca Python como bem torneada ajudaria. Apenas verifique se ele cobre uma área maior que o polígono e use as ferramentas para converter automaticamente em polilinha, amortecer, apagar, selecionar as linhas que não estão dentro do polígono e excluí-las.

cndnflyr
fonte
Obrigado pela resposta detalhada. Vou tentar e ver como funciona. Obrigado!
Tx_Dan