7

I want to create offset/parallel lines for my centre lines (over 12000 polylines) in different distance for each class number(i have numbers in column) and with the same line direction as centre line.

My idea was to create mid point for each line and then move the line at the same angle but i don't know how to do it in Python.

Also i know the way creating line buffer, splitting buffer etc. but then lines are not in the same direction and ArcGIS Pro basic not support polygon to lines tools etc.

The problem is that I am using basic licence in ArcGIS Pro which not support advanced tools.

Is there any way to do it using Python script?


import arcpy

#setup inputs
inFC = arcpy.GetParameterAsText(0) 
outFC = arcpy.GetParameterAsText(2)


#setup output path
fcPath = outFC.rpartition("\\")[0]
fcName = outFC.rpartition("\\")[2]

if arcpy.Exists(outFC):
    arcpy.Delete_management(outFC)
arcpy.CreateFeatureclass_management(fcPath,fcName,"POLYLINE","#","DISABLED","DISABLED",inFC)
arcpy.AddField_management(outFC,"inFID","LONG","#","#","#","#","NULLABLE","NON_REQUIRED","#")


def shift_features(inFC):
    """
    Shifts features by an x and/or y value. The shift values are in
    the units of the inFC coordinate system.

    Parameters:
    inFC: string
        An existing feature class or feature layer.  If using a
        feature layer with a selection, only the selected features
        will be modified.

    x_shift: float
        The distance the x coordinates will be shifted.

    y_shift: float
        The distance the y coordinates will be shifted.
    """

    with arcpy.da.UpdateCursor(inFC, ['SHAPE@XY', 'Shift_X_right', 'Shift_Y_right']) as cursor:
        for row in cursor:
            cursor.updateRow([[row[0][0] + (row[1] or 0),
                               row[0][1] + (row[2] or 0)]])

    return

outFC = shift_features(inFC)

I try to shift my lines using attribute stored inside my table. When i put normal x_shift value like 2 meters shift function work correctly. But when i try to call my table it creates error. I don't know if shift function support shifting by attribute table values. Can you help me?

UPDATE If that will help i got script that do the same us feature vertix to points.

# Feature Class to Points
# 
# Paul Smith (2012) paul@neoncs.com.au

# Imports 
import arcpy import numpy

#Inputs from user parameters 
InFc  = arcpy.GetParameterAsText(0) 
OutFc = arcpy.GetParameterAsText(1) 

# Spatial reference of input feature class 
SR = arcpy.Describe(InFc).spatialReference

# Create NumPy array from input feature class 
array = arcpy.da.FeatureClassToNumPyArray(InFc,["SHAPE@XY"], spatial_reference=SR, explode_to_points=True)

# Check array and Exit if no features found if array.size == 0:
arcpy.AddError(InFc + " has no features.")

# Create a new points feature class else:
arcpy.da.NumPyArrayToFeatureClass(array, OutFc, ['SHAPE@XY'], SR)
  • 1
    Example of shifting features using updatecursor: arcpy.wordpress.com/2012/11/15/shifting-features – BERA Jan 16 '17 at 12:26
  • @BERA please expand your comment as an answer. Copy-pasting the code while citing the source would be fine, ideally you could replace the update cursor with an insert cursor. – radouxju Jan 16 '17 at 12:54
  • @Adam Pańkowski could you add a screenshot of some of the lines and attribute table – BERA Jan 16 '17 at 13:01
  • Sure here you go :) s28.postimg.org/fai73h7vh/Lines_err.jpg – Losbaltica Jan 16 '17 at 14:18
  • The distance which i would like to move lines is also inside column. Is different for each class but all information are already inside. – Losbaltica Jan 16 '17 at 14:25
10
+100

Unfortunately Basic license does not support Feature Vertices to Points and you cannot use technique applied here. This is why run the script on the copy of the original:

import arcpy, math
infc=r'..\SCRARCH\clone.shp'

def CopyParallel(plyP,sLength):
    part=plyP.getPart(0)
    lArray=arcpy.Array();rArray=arcpy.Array()
    for ptX in part:
        dL=plyP.measureOnLine(ptX)
        ptX0=plyP.positionAlongLine (dL-0.01).firstPoint
        ptX1=plyP.positionAlongLine (dL+0.01).firstPoint
        dX=float(ptX1.X)-float(ptX0.X)
        dY=float(ptX1.Y)-float(ptX0.Y)
        lenV=math.hypot(dX,dY)
        sX=-dY*sLength/lenV;sY=dX*sLength/lenV
        leftP=arcpy.Point(ptX.X+sX,ptX.Y+sY)
        lArray.add(leftP)
        rightP=arcpy.Point(ptX.X-sX, ptX.Y-sY)
        rArray.add(rightP)
    array = arcpy.Array([lArray, rArray])
    section=arcpy.Polyline(array)
    return section


with arcpy.da.UpdateCursor(infc,("Shape@","Width")) as cursor:
    for shp,w in cursor:
        twoLines=CopyParallel(shp,w)
        cursor.updateRow((twoLines,w))

This will replace shapes by two parallels. You'll need to convert them to single parts.

Notes:

  • Works on single part 2D polylines only
  • tested on shapefile
  • no check of topology errors (self-intersections) performed

enter image description here

  • Thanks for this FelixIP. I am new to working with shapefiles as well I am rusty on using python in the Arcgis environment. Can you explain the code, please? Also, do I need to make a clone first!? How is distance defined? – icypy Mar 19 at 3:13
  • Yes, create a copy. Change 2nd line to path to your shapefile. Table of shapefile need field Width, populated by values >O. Logic is basic geometry. Draw straight line and follow the code to understand it better. – FelixIP Mar 19 at 4:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.