I have downspout points that are currently emptying at the foundation. We need to redirect those into the roadway to be collected by the storm sewer. However we need to check that there is enough vertical elevation change between the base of the house and the curb to slope the pipe appropriately (e.g. if the downspout is 50ft away and the elevation at the foundation is 700ft and at the curb 699ft and I need 18" of cover then this will not work). So I need to construct a line from every single downspout point that connects to the edge of pavement line and get the elevation at each end. This line also needs to meet the edge of pavement line at a 90-degree angle. I have over 4000 downspouts so I'm looking for a way to automate the generation of the line segment between the two in such a way that when I calculate the start and end elevation using my DEM I will know my grade change.
[GIS] Drawing perpendicular line between point and line layer using ArcMap
arcgis-desktoppolyline-creation
Related Solutions
Here's some pseudo code with notes for the arcobjects interfaces you could use. I've made this community wiki since I don't have time to go into details.
Foreach lateral
// use IFeatureClass.Search with queryfilter
mainline = findmainlinebyid(lateral.mainid)
// use IMSegmentation2.GetPointsatM
point1 = mseg.Getpoint(lateral.measure)
// use ICurve.QueryNormal
polyline1 = constructperpendicular(point1,mainline,length)
// use IFeatureclass.Search with spatialfilter
listofparcels = getintersectedparcels(polyline1)
// loop through each parcel calling IProximityOperator.ReturnDistance
closestparcel = getclosestparcel(point1,listofparcels)
// use ITopologicalOperator.Intersect
multipoint = getcrossingpoint(closestparcel,polyline1)
// use IproximityOperator.Return distance to get closest point
point2 = getclosestpoint(multipoint,point1)
// use ipointcollection to create a polyline
polyline2 = makepolyline(point1,point2)
// use ICurve.QueryPoint with distance of 2
polyline3 = ExtendPolyline(polyline2, 2)
// use IFeatureClass.CreateFeature(), store
WriteFeature(polyline3,lateral.mainid)
next lateral
I found a way! I used a couple of different sources and manipulated the script to fit my needs (mostly from gotanuki on StackExchange). A variation of this is already on the site, but the of data that I was using is different. In case someone else runs into this issue, this is the solution I used:
# Define orientation (start, mid, end) and draw Matchlines function
# This function is defined before it is called
def orientMatchlines(feat,ix,iy):
# If the line is horizontal or vertical, the slope and
# negative reciprocal calculations will fail, so do this instead
if starty==endy or startx==endx:
if starty == endy:
y1 = iy + matchDist
y2 = iy - matchDist
x1 = ix
x2 = ix
if startx == endx:
y1 = iy
y2 = iy
x1 = ix + matchDist
x2 = ix - matchDist
else:
# Get slope of line
m = float((starty - endy)/(startx - endx))
# Get negative reciprocal
negativereciprocal = -1*((startx - endx)/(starty - endy))
# For all values of slope, calculate perpendicular line
# with length = matchDist
if m > 0:
if m >= 1:
y1 = negativereciprocal*(matchDist)+ iy
y2 = negativereciprocal*(-matchDist) + iy
x1 = ix + matchDist
x2 = ix - matchDist
if m < 1:
y1 = iy + matchDist
y2 = iy - matchDist
x1 = (matchDist/negativereciprocal) + ix
x2 = (-matchDist/negativereciprocal)+ ix
if m < 0:
if m >= -1:
y1 = iy + matchDist
y2 = iy - matchDist
x1 = (matchDist/negativereciprocal) + ix
x2 = (-matchDist/negativereciprocal)+ ix
if m < -1:
y1 = negativereciprocal*(matchDist)+ iy
y2 = negativereciprocal*(-matchDist) + iy
x1 = ix + matchDist
x2 = ix - matchDist
point1.X = x1
point1.Y = y1
point2.X = x2
point2.Y = y2
lineArray.add(point1)
lineArray.add(point2)
del x1
del x2
del y1
del y2
# Create search cursor in inLine
rows = arcpy.SearchCursor(inLine)
# Get number of records in inLine
numRecords = int(arcpy.GetCount_management(inLine).getOutput(0))
# Create new point files and array to collect values
point1 = arcpy.Point()
point2 = arcpy.Point()
lineArray = arcpy.Array()
# Define counter
counter = 0
# Loop over rows in outLine
for row in rows:
# Create the geometry object
feat = row.Shape
# Get coordinate values as lists
firstpoint = feat.firstPoint
lastpoint = feat.lastPoint
midpoint = feat.centroid
# Get X and Y values for each point
startx = firstpoint.X
starty = firstpoint.Y
endx = lastpoint.X
endy = lastpoint.Y
midx = midpoint.X
midy = midpoint.Y
m = ((starty - endy)/(startx - endx+.0001))
# For all points besides the last one
if counter < numRecords - 1:
orientMatchlines(feat,startx,starty)
# For the last point
else:
orientMatchlines(feat,endx,endy)
#Create insert cursor
cur = arcpy.InsertCursor(matchlines)
#Insert new row from array
feat = cur.newRow()
#feat.slope = m
feat.shape = lineArray
cur.insertRow(feat)
lineArray.removeAll()
del cur
# Increase counter by 1 and start again
counter = counter + 1
del row
del rows
Best Answer
INPUT:
PROCESS:
OUTPUT: