I need to extract (calculate) the length of the line crossing polygon. I can find the crossing points but I need 90 degrees angle from alignment projected to the edges of polygon.
Any ideas?
I need to extract (calculate) the length of the line crossing polygon. I can find the crossing points but I need 90 degrees angle from alignment projected to the edges of polygon.
Any ideas?
Would be fairly straightforward in arcpy
.
I saw a similar query here:
ArcMap Near Tool doesn't find nearest feature for some input points on the line
The answer provided uses a script from a Tool / Model published by T. Dilts
Preferred citation: Dilts, T.E. (2015) Station Lines for ArcGIS 10.1. University of Nevada Reno. Available at: http://www.arcgis.com/home/item.html?id=3f05ef15203e4a3ca88fc1d92347512b
A workflow for you would be to convert the polygons to polylines. The tool provided in the link and code below requires points. Assuming the crossings are the blue lines in your example, you can perform an intersect between the newly created polylines and the crossing lines, setting the output type to Point.
Run the tool as provided, setting the distance to something a bit excessive / more than the maximum width of all your polygons.
Perform an intersect between the newly created station lines and the original polygon, setting the output type as line. This new line will now contain the ID of the polygon, and you can create a field called Length and calculate the length of the station line accordingly.
Code for the Python Toolbox is below, otherwise use the Model as supplied in the link:
'''
Name: Create Perpendicular Lines
Purpose:
Author: Tom Dilts
Created: 24 Jan2018
Copyright: None
Licence:
Adapted from the Toolbox Authored by Tom Dilts
Preferred citation: Dilts, T.E. (2015) Station Lines for ArcGIS 10.1. University of Nevada Reno. Available at: http://www.arcgis.com/home/item.html?id=3f05ef15203e4a3ca88fc1d92347512b
'''
# import modules
import arcpy
'''Do not change the name of this class. It will break the toolbox.'''
class Toolbox(object):
def __init__(self):
'''Define toolbox properties (the toolbox anme is the .pyt filename).'''
self.label = "Create Station Lines"
self.alias = ""
# List of tool classes associated with this toolbox
self.tools = [Tool]
class Tool(object):
def __init__(self):
'''Define the tool (tool name is the class name).'''
self.label = "Station Lines"
self.description = "Creates station lines (perpendicular lines) at user-specified points along a polyline. Station lines are a useful first step for hydraulic analysis of rivers"
self.canRunInBackground = False
def getParameterInfo(self):
'''parameter definitions for GUI'''
param0 = arcpy.Parameter(
displayName = "Input Line File",
name = "Input Line",
datatype = "GPFeatureLayer",
parameterType = "Required",
direction = "Input")
param0.filter.list = ['Polyline']
param0.value = ""
param1 = arcpy.Parameter(
displayName = "Input Converted Vertices",
name = "Input Points",
datatype = "GPFeatureLayer",
parameterType = "Required",
direction = "Input")
param1.filter.list = ['Point']
param1.value = ""
param2 = arcpy.Parameter(
displayName = "Input Transect Distance",
name = "Input Transect Distance",
datatype = "GPDouble",
parameterType = "Required",
direction = "Input")
param2.value = '1000'
param3 = arcpy.Parameter(
displayName = "Output File",
name = "Output",
datatype = "DEShapefile",
parameterType = "Required",
direction = "OutPut")
param4 = arcpy.Parameter(
displayName = "Working Directory",
name = "Working Directory",
datatype = "DEFolder",
parameterType = "Required",
direction = "Input")
params = [param0, param1, param2, param3, param4]
return params
def isLicensed(self):
'''Set whether tool is licensed to execute.'''
return True
def updateParameters(self, parameters):
'''Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed.'''
return
def updateMessages(self, parameters):
'''Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation.'''
return
def execute(self, parameters, messages):
'''The source code of the tool.'''
Input_Line_Shapefile = parameters[0].valueAsText
Input_Points = parameters[1].valueAsText
Trasect_Distance = parameters[2].valueAsText
Output_Station_Lines= parameters[3].valueAsText
WorkingDir = parameters[4].valueAsText
arcpy.AddMessage (Input_Line_Shapefile + " Added to Inputs")
arcpy.AddMessage (Input_Points + " Added to Inputs")
arcpy.AddMessage (Trasect_Distance + " Added to Inputs")
arcpy.AddMessage (Output_Station_Lines + " Added to Inputs")
Output_Features = Input_Points
points = Output_Features
Trial_FeatureVerticesToPoint = points
splitline_shp = WorkingDir + "splitline.shp"
Output_Feature_Class = WorkingDir + "azimuth.shp"
copy_Select = Output_Feature_Class
copy_Select__2_ = copy_Select
splitline_shp__6_ = copy_Select__2_
splitline_shp__5_ = splitline_shp__6_
spatjoin_shp = WorkingDir + "spatjoin.shp"
Left = WorkingDir + "spatjoin_BearingDistanceToLi.shp"
Right = WorkingDir + "spatjoin_BearingDistanceToLi1.shp"
mergedata = WorkingDir + "merge.shp"
# Process: Add XY Coordinates
arcpy.AddXY_management(Input_Points)
arcpy.AddMessage ("XY Added")
# Process: Add Field (3)
arcpy.AddField_management(Output_Features, "Dist", "LONG", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Calculate Field (3)
arcpy.CalculateField_management(points, "Dist", Trasect_Distance, "VB", "")
arcpy.AddMessage ("Calcs Done")
# Process: Split Line At Vertices
arcpy.SplitLine_management(Input_Line_Shapefile, splitline_shp)
arcpy.AddMessage ("Line split")
#Azimuth added
Input_Line_Features = splitline_shp
Output_Feature_Class = WorkingDir + "azimuth.shp"
# Local variables:
Converted_Graphics_7 = Input_Line_Features
Converted_Graphics_7__2_ = Converted_Graphics_7
Converted_Graphics_7__3_ = Converted_Graphics_7__2_
Converted_Graphics_7__4_ = Converted_Graphics_7__3_
Converted_Graphics_7__6_ = Converted_Graphics_7__4_
Converted_Graphics_7__9_ = Converted_Graphics_7__6_
Converted_Graphics_7__5_ = Converted_Graphics_7__9_
Converted_Graphics_7__8_ = Converted_Graphics_7__5_
Converted_Graphics_7__10_ = Converted_Graphics_7__8_
Converted_Graphics_7__7_ = Converted_Graphics_7__10_
Converted_Graphics_7__13_ = Converted_Graphics_7__7_
Converted_Graphics_7__12_ = Converted_Graphics_7__13_
Converted_Graphics_7__15_ = Converted_Graphics_7__12_
Converted_Graphics_7__11_ = Converted_Graphics_7__15_
Converted_Graphics_7__17_ = Converted_Graphics_7__11_
Converted_Graphics_7__16_ = Converted_Graphics_7__17_
Converted_Graphics_7__19_ = Converted_Graphics_7__16_
Output_Layer = "copy_Layer"
Export_Output_3_Layer = Output_Layer
Export_Output_3_Layer__3_ = Export_Output_3_Layer
Export_Output_3_Layer__4_ = Export_Output_3_Layer__3_
Export_Output_3_Layer__2_ = Export_Output_3_Layer__4_
Export_Output_3_Layer__6_ = Export_Output_3_Layer__2_
Export_Output_3_Layer__5_ = Export_Output_3_Layer__6_
Export_Output_3_Layer__7_ = Export_Output_3_Layer__5_
Export_Output_3_Layer__9_ = Export_Output_3_Layer__7_
Export_Output_3_Layer__11_ = Export_Output_3_Layer__9_
Export_Output_3_Layer__8_ = Export_Output_3_Layer__11_
Output_stuff = Export_Output_3_Layer__8_
copy_Layer = Output_stuff
# Process: Add Field
arcpy.AddField_management(Input_Line_Features, "StartX", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Add Field (2)
arcpy.AddField_management(Converted_Graphics_7, "StartY", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Add Field (3)
arcpy.AddField_management(Converted_Graphics_7__2_, "EndX", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Add Field (4)
arcpy.AddField_management(Converted_Graphics_7__3_, "EndY", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Calculate Field
arcpy.CalculateField_management(Converted_Graphics_7__4_, "StartX", "!Shape!.firstpoint.X", "PYTHON_9.3", "")
# Process: Calculate Field (2)
arcpy.CalculateField_management(Converted_Graphics_7__6_, "StartY", "!shape.firstpoint.y!", "PYTHON_9.3", "")
# Process: Calculate Field (3)
arcpy.CalculateField_management(Converted_Graphics_7__9_, "EndX", "!shape.lastpoint.x!", "PYTHON_9.3", "")
# Process: Calculate Field (4)
arcpy.CalculateField_management(Converted_Graphics_7__5_, "EndY", "!shape.lastpoint.y!", "PYTHON_9.3", "")
# Process: Add Field (5)
arcpy.AddField_management(Converted_Graphics_7__8_, "rad", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Calculate Field (5)
arcpy.CalculateField_management(Converted_Graphics_7__10_, "rad", "Atn(( [StartX] - [EndX]) / ( [StartY] - [EndY] ))", "VB", "")
# Process: Add Field (6)
arcpy.AddField_management(Converted_Graphics_7__7_, "Angle", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Calculate Field (6)
arcpy.CalculateField_management(Converted_Graphics_7__13_, "Angle", "[rad] * (180 / 3.14159265)", "VB", "")
# Process: Add Field (7)
arcpy.AddField_management(Converted_Graphics_7__12_, "EastWest", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Calculate Field (7)
arcpy.CalculateField_management(Converted_Graphics_7__15_, "EastWest", "[StartX] - [EndX]", "VB", "")
# Process: Add Field (8)
arcpy.AddField_management(Converted_Graphics_7__11_, "NorthSouth", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Calculate Field (8)
arcpy.CalculateField_management(Converted_Graphics_7__17_, "NorthSouth", "[StartY] - [EndY]", "VB", "")
# Process: Add Field (9)
arcpy.AddField_management(Converted_Graphics_7__16_, "Azimuth", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Make Feature Layer
arcpy.MakeFeatureLayer_management(Converted_Graphics_7__19_, Output_Layer, "", "", "FID FID VISIBLE NONE;Shape Shape VISIBLE NONE;OBJECTID OBJECTID VISIBLE NONE;ARCID ARCID VISIBLE NONE;GRID_CODE GRID_CODE VISIBLE NONE;FROM_NODE FROM_NODE VISIBLE NONE;TO_NODE TO_NODE VISIBLE NONE;ET_ID ET_ID VISIBLE NONE;Shape_Le_1 Shape_Le_1 VISIBLE NONE;Year_ Year_ VISIBLE NONE;Shape_Leng Shape_Leng VISIBLE NONE;Name Name VISIBLE NONE;Azimuth Azimuth VISIBLE NONE;StartX StartX VISIBLE NONE;StartY StartY VISIBLE NONE;EndX EndX VISIBLE NONE;EndY EndY VISIBLE NONE;rad rad VISIBLE NONE;Angle Angle VISIBLE NONE;EastWest EastWest VISIBLE NONE;NorthSouth NorthSouth VISIBLE NONE")
# Process: Select Layer By Attribute
arcpy.SelectLayerByAttribute_management(Output_Layer, "NEW_SELECTION", "\"NorthSouth\" > 0")
# Process: Calculate Field (9)
arcpy.CalculateField_management(Export_Output_3_Layer, "Azimuth", "[Angle] + 180", "VB", "")
# Process: Select Layer By Attribute (2)
arcpy.SelectLayerByAttribute_management(Export_Output_3_Layer__3_, "NEW_SELECTION", "\"NorthSouth\" < 0 and \"EastWest\" > 0")
# Process: Calculate Field (10)
arcpy.CalculateField_management(Export_Output_3_Layer__4_, "Azimuth", "[Angle] + 360", "VB", "")
# Process: Select Layer By Attribute (3)
arcpy.SelectLayerByAttribute_management(Export_Output_3_Layer__2_, "NEW_SELECTION", "\"NorthSouth\" < 0 and \"EastWest\" < 0")
# Process: Calculate Field (11)
arcpy.CalculateField_management(Export_Output_3_Layer__6_, "Azimuth", "[Angle]", "VB", "")
# Process: Select Layer By Attribute (4)
arcpy.SelectLayerByAttribute_management(Export_Output_3_Layer__5_, "NEW_SELECTION", "\"NorthSouth\" = 0 and \"EastWest\" > 0")
# Process: Calculate Field (12)
arcpy.CalculateField_management(Export_Output_3_Layer__7_, "Azimuth", "270", "VB", "")
# Process: Select Layer By Attribute (5)
arcpy.SelectLayerByAttribute_management(Export_Output_3_Layer__9_, "NEW_SELECTION", "\"NorthSouth\" = 0 and \"EastWest\" < 0")
# Process: Calculate Field (13)
arcpy.CalculateField_management(Export_Output_3_Layer__11_, "Azimuth", "90", "VB", "")
# Process: Delete Field
arcpy.DeleteField_management(Export_Output_3_Layer__8_, "StartX;StartY;EndX;EndY;rad;Angle;EastWest;NorthSouth")
# Process: Select Layer By Attribute (6)
arcpy.SelectLayerByAttribute_management(Output_stuff, "NEW_SELECTION", "\"Azimuth\" < 365")
# Process: Select
arcpy.Select_analysis(copy_Layer, Output_Feature_Class, "Azimuth <= 365")
arcpy.AddMessage ("Azimuth calculated")
#back
# Process: Add Field
arcpy.AddField_management(Output_Feature_Class, "left", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Add Field (2)
arcpy.AddField_management(copy_Select, "right", "DOUBLE", "", "", "", "", "NON_NULLABLE", "NON_REQUIRED", "")
# Process: Calculate Field
arcpy.CalculateField_management(copy_Select__2_, "right", "[Azimuth] + 90", "VB", "")
# Process: Calculate Field (2)
arcpy.CalculateField_management(splitline_shp__6_, "left", "[Azimuth] - 90", "VB", "")
# Process: Spatial Join
arcpy.SpatialJoin_analysis(Trial_FeatureVerticesToPoint, splitline_shp__5_, spatjoin_shp, "JOIN_ONE_TO_ONE", "KEEP_ALL", "OBJECTID \"OBJECTID\" true true false 10 Long 0 10 ,First,#,vertex,OBJECTID,-1,-1;POINT_X \"POINT_X\" true true false 0 Double 0 0 ,First,#,vertex,POINT_X,-1,-1;POINT_Y \"POINT_Y\" true true false 0 Double 0 0 ,First,#,vertex,POINT_Y,-1,-1;POINT_Z \"POINT_Z\" true true false 0 Double 0 0 ,First,#,vertex,POINT_Z,-1,-1;POINT_M \"POINT_M\" true true false 0 Double 0 0 ,First,#,vertex,POINT_M,-1,-1;Dist \"Dist\" true true false 0 Long 0 0 ,First,#,vertex,Dist,-1,-1;Id \"Id\" true true false 10 Long 0 10 ,First,#,C:\\temp\\azimuth.shp,Id,-1,-1;NEAR_FID \"NEAR_FID\" true true false 10 Long 0 10 ,First,#,C:\\temp\\azimuth.shp,NEAR_FID,-1,-1;NEAR_DIST \"NEAR_DIST\" true true false 19 Double 0 0 ,First,#,C:\\temp\\azimuth.shp,NEAR_DIST,-1,-1;NEAR_X \"NEAR_X\" true true false 19 Double 0 0 ,First,#,C:\\temp\\azimuth.shp,NEAR_X,-1,-1;NEAR_Y \"NEAR_Y\" true true false 19 Double 0 0 ,First,#,C:\\temp\\azimuth.shp,NEAR_Y,-1,-1;Azimuth \"Azimuth\" true true false 19 Double 0 0 ,First,#,C:\\temp\\azimuth.shp,Azimuth,-1,-1;left \"left\" true true false 19 Double 0 0 ,First,#,C:\\temp\\azimuth.shp,left,-1,-1;right \"right\" true true false 19 Double 0 0 ,First,#,C:\\temp\\azimuth.shp,right,-1,-1", "INTERSECT", "", "")
# Process: Bearing Distance To Line
arcpy.BearingDistanceToLine_management(spatjoin_shp, Left, "POINT_X", "POINT_Y", "Dist", "9001", "left", "9102", "0", "TARGET_FID", "PROJCS['Hartebeeshoek94_Lo31',GEOGCS['GCS_Hartebeesthoek_1994',DATUM['D_Hartebeesthoek_1994',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Transverse_Mercator'],PARAMETER['False_Easting',0.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',31.0],PARAMETER['Scale_Factor',1.0],PARAMETER['Latitude_Of_Origin',0.0],UNIT['Meter',1.0]];-5623200 -10002100 10000;-100000 10000;-100000 10000;0.001;0.001;0.001;IsHighPrecision")
# Process: Bearing Distance To Line (2)
arcpy.BearingDistanceToLine_management(spatjoin_shp, Right, "POINT_X", "POINT_Y", "Dist", "9001", "right", "9102", "0", "TARGET_FID", "PROJCS['Hartebeeshoek94_Lo31',GEOGCS['GCS_Hartebeesthoek_1994',DATUM['D_Hartebeesthoek_1994',SPHEROID['WGS_1984',6378137.0,298.257223563]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]],PROJECTION['Transverse_Mercator'],PARAMETER['False_Easting',0.0],PARAMETER['False_Northing',0.0],PARAMETER['Central_Meridian',31.0],PARAMETER['Scale_Factor',1.0],PARAMETER['Latitude_Of_Origin',0.0],UNIT['Meter',1.0]];-5623200 -10002100 10000;-100000 10000;-100000 10000;0.001;0.001;0.001;IsHighPrecision")
# Process: Merge
# Process: Merge
arcpy.Merge_management(WorkingDir + "spatjoin_BearingDistanceToLi.shp" + ";" + WorkingDir + "spatjoin_BearingDistanceToLi1.shp", mergedata, "POINT_X \"POINT_X\" true true false 0 Double 0 0 ,First,#,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi.shp,POINT_X,-1,-1,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi1.shp,POINT_X,-1,-1;POINT_Y \"POINT_Y\" true true false 0 Double 0 0 ,First,#,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi.shp,POINT_Y,-1,-1,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi1.shp,POINT_Y,-1,-1;Dist \"Dist\" true true false 0 Double 0 0 ,First,#,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi.shp,Dist,-1,-1,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi1.shp,Dist,-1,-1;left \"left\" true true false 0 Double 0 0 ,First,#,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi.shp,left,-1,-1;TARGET_FID \"TARGET_FID\" true true false 0 Double 0 0 ,First,#,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi.shp,TARGET_FID,-1,-1,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi1.shp,TARGET_FID,-1,-1;right \"right\" true true false 0 Double 0 0 ,First,#,C:\\temp\\DDP\\spatjoin_BearingDistanceToLi1.shp,right,-1,-1")
# Process: Dissolve
arcpy.Dissolve_management(mergedata, Output_Station_Lines, "TARGET_FID", "", "MULTI_PART", "DISSOLVE_LINES")
return
NOTE: Do not house the information in a Geodatabase. The source of all information must be a folder on a local drive.
This tool needs an Advanced Licence
You can copy this code into IDLE and save it as a PYT file. THis can then be added directly into ArcMap.