¿Dibuja líneas paralelas dentro de polígonos (Well Paths) usando ArcGIS Desktop?

11

Me gustaría tomar una clase de entidad poligonal con múltiples polígonos irregulares, y hacer que Arc dibuje líneas paralelas dentro de cada polígono. Idealmente, sería bueno para Arc calcular el ángulo del lado más largo del polígono y dibujar líneas paralelas a ese lado, pero para simplificarlo, creo que si pudiera ingresar un ángulo para todas las líneas paralelas, eso Sería más fácil.

Entonces, mi criterio básico es el ángulo de línea, el ancho entre líneas, la longitud mínima / máxima y el ancho del búfer desde los lados de los polígonos.

Imagen adjunta si eso ayuda.

ingrese la descripción de la imagen aquí

Tx_Dan
fuente
¿Es un requisito que las líneas terminen a cierta distancia del borde del polígono?
cndnflyr
Sí, necesito tener un búfer alejado de los bordes. Si puedo declarar ese valor, sería genial. Gracias.
Tx_Dan

Respuestas:

9

Como @cndnflyr menciona, esto puede ser programado en Python.

UI de la herramienta de script:

ingrese la descripción de la imagen aquí

Salida de muestra: ingrese la descripción de la imagen aquí

# 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
líber
fuente
Wow este hermoso, floema! Echaremos un vistazo. Muchas gracias!
Tx_Dan
Este es un gran uso de los métodos en el objeto SHAPE. Es elegante Lo único que falta es establecer el ángulo de las líneas. Tal como está, dibujará las líneas a lo largo del lado más largo del polígono.
cndnflyr
4

Esto podría hacerse con Python, pero llevaría algún tiempo escribirlo.

Creo que la forma más rápida de implementarlo sin Python es tener un archivo SHP de plantilla de estas líneas paralelas. Tenga algunos si necesita diferentes anchos, y simplemente use el apropiado para ese Polígono. Haga que las líneas de la plantilla cubran suficiente área para cubrir el Polígono más grande que encontrará.

  1. Mientras edita, mueva las líneas sobre el polígono.
  2. Use la herramienta Rotar, mueva el punto de anclaje donde coinciden una línea Paralela y el borde del Polígono, y gire las líneas para que encaje en el borde del Polígono en el que lo alineó.
  3. Convierta el polígono en una polilínea
  4. Proteja la polilínea independientemente de la distancia que desee que estén las líneas paralelas desde el borde del polígono.
  5. Use la herramienta Borrar para borrar las Polilíneas que están cubiertas por el Borde del polígono protegido
  6. Seleccione por ubicación todas las líneas que no están dentro del polígono y elimínelas. O creo que la herramienta Clip también funcionaría.
  7. Seleccione por atributo todas las líneas que tengan menos de cierta longitud (demasiado cortas para mantener, aunque es posible que deba agregar un campo y calcule primero la geometría), y más de cierta longitud (demasiado largas para mantener si eso es lo que desea ), borra los.
  8. Enjuague y repita...

Los pasos 3 a 7 se pueden modelar, sin tener que escribir ningún código.

Se podría usar casi el mismo proceso para codificar el proceso, pero en lugar de tener líneas de plantilla, puede hacer que el código dibuje las líneas en el ángulo correcto, distanciadas, etc. No he hecho esto por un tiempo, pero creo que un La biblioteca Python como bien proporcionada ayudaría. Solo asegúrese de que cubra un área más grande que el Polígono, y use las herramientas para convertir automáticamente a polilínea, amortiguar, borrar, seleccionar las líneas que no están dentro del polígono y eliminarlas.

cndnflyr
fuente
Gracias por la respuesta detallada. Lo intentaré y veré cómo funciona. ¡Gracias!
Tx_Dan