Create Line from Point to Nearest Point on a Line in ArcGIS Pro with ArcPy

If you are interested in learning ArcPy, check out this course.

This tool will allow you to create a new linear feature class for the lines or append into the existing linear feature class. Let’s dive straight in.

We import the ArcPy module.

import arcpy

We have a few user inputs to consider as per below.

## input point feature class
pt_features = arcpy.GetParameterAsText(0)

## input linear feature class
ln_features = arcpy.GetParameterAsText(1)

## maximum distance between point and line to consider 
max_distance = arcpy.GetParameterAsText(2)

## Create a new linear feature class or not
create_new_fc = arcpy.GetParameterAsText(3)

## the output feature class if creating a new one
out_feature_class = arcpy.GetParameterAsText(4)

We need a spatial reference so we will use the one set on our input linear feature class.

srs_id = arcpy.Describe(ln_features).spatialReference.factoryCode

Next, we use the Generate Near Table tool and store the output table in the memory workspace.

near_tbl = arcpy.analysis.GenerateNearTable(
                in_features = pt_features,
                near_features = ln_features,
                out_table = "memory\\near_tbl",
                search_radius = max_distance,
                location = "LOCATION",
                angle = "NO_ANGLE",
                closest = "CLOSEST",
                closest_count = 0,
                method = "PLANAR"
)

Our Near Table has four fields of interest; FROM_X, FROM_Y, NEAR_X, NEAR_Y, that allow us to construct our lines.

We can now use the XY to Line tool to create our new linear features. We will create these in the memory workspace which will give us flexibility to either create a new feature class or append the new lines into our existing linear feature class.

near_lines = arcpy.management.XYToLine(
    in_table = near_tbl,
    out_featureclass = "memory\\near_lines",
    startx_field = "FROM_X",
    starty_field = "FROM_Y",
    endx_field = "NEAR_X",
    endy_field = "NEAR_Y",
    line_type = "GEODESIC",
    id_field = "NEAR_FID",
    spatial_reference = srs_id,
    attributes="NO_ATTRIBUTES"
)

Its good to clean up as we go, we no longer require the near table so let’s delete that from the memory workspace.

arcpy.management.Delete(near_tbl)

If the user choose to create a new feature class we use the Export Features tool to commit the lines in memory to disk. Otherwise, we use the Append tool to add the new linear features into our existing linear feature class.

if create_new_fc == "true":
    arcpy.conversion.ExportFeatures(
        in_features = near_lines,
        out_features = out_feature_class
    )

else:
        arcpy.management.Append(
        inputs=near_lines,
        target=ln_features,
        schema_type="NO_TEST"
    )

And of course, we clean up the memory workspace.

arcpy.management.Delete(near_lines)

Save your script and open up ArcGIS Pro. Right-click on your toolbox/toolset of choice and select New > Script. The New Script window will appear. In the General tab set Name to createLineFromPointToNearestLineLabel to Create Line from Point to Nearest Line, and the Description as per below or any description you feel is apt.

Set the Point Features with a Data Type of Feature Layer and set the Filter to Point geometry only (we are not considering Multipoint). Set the Line Features parameter with a Data Type of Feature Layer and set the Filter to Polyline. Set the Maximum Distance with a Data Type of Linear Unit, Type as Optional, and Filter to Meters and Kilometers (or your own choice.) For the Create new feature class? set the Data Type to Boolean and the Type as Optional. And for the Output Feature Class set the Data Type to Feature Class, the Type as Optional, the Direction as Output, and the Filter to Polyline.

In the Execution tab, click the folder icon in the top-right corner and add your saved Python script.

In the Validation tab, update as per below, we do not want the Output Feature Class parameter visible unless the Create new feature class? is checked.

    def initializeParameters(self):
        # Customize parameter properties. This method gets called when the
        # tool is opened.
        self.params[4].enabled = False
        return

    def updateParameters(self):
        # Modify the values and properties of parameters before internal
        # validation is performed.
        if self.params[3].value:
            self.params[4].enabled = True
        else:
            self.params[4].value = ""
            self.params[4].enabled = False
        return

Take the tool for a spin and let me know what you think? You can download the tool and other custom tools over on this page. This tool is in the Custom Tools on a Basic License with ArcPy section.

Subscribe so you never miss out!

Here is the entire code with links to Esri documents for any ArcPy geoprocessing tool, function, or object used.

import arcpy

################################################################################
## Esri Documentation
##  https://pro.arcgis.com/en/pro-app/latest/arcpy/functions/getparameterastext.htm
##  https://pro.arcgis.com/en/pro-app/latest/arcpy/functions/describe.htm
##  https://pro.arcgis.com/en/pro-app/latest/tool-reference/analysis/generate-near-table.htm
##  https://pro.arcgis.com/en/pro-app/latest/tool-reference/data-management/xy-to-line.htm
##  https://pro.arcgis.com/en/pro-app/latest/tool-reference/data-management/delete.htm
##  https://pro.arcgis.com/en/pro-app/latest/tool-reference/conversion/export-features.htm
##  https://pro.arcgis.com/en/pro-app/latest/tool-reference/data-management/append.htm
##
## ArcGIS Pro Version 3.2.0
##
################################################################################

################################################################################
## USER INPUTS

## input point feature class
pt_features = arcpy.GetParameterAsText(0)
## input linear feature class
ln_features = arcpy.GetParameterAsText(1)
## maximum distance to consider
max_distance = arcpy.GetParameterAsText(2)
## Create a new linear feature class or not
create_new_fc = arcpy.GetParameterAsText(3)
## the output feature class if creating a new one
out_feature_class = arcpy.GetParameterAsText(4)

################################################################################
## REQUIRED OBJECTS ############################################################

## srs id of the in_features so we can assign the output the same
srs_id = arcpy.Describe(ln_features).spatialReference.factoryCode

################################################################################
## GENERATE NEAR TABLE #########################################################

near_tbl = arcpy.analysis.GenerateNearTable(
                in_features = pt_features,
                near_features = ln_features,
                out_table = "memory\\near_tbl",
                search_radius = max_distance,
                location = "LOCATION",
                angle = "NO_ANGLE",
                closest = "CLOSEST",
                closest_count = 0,
                method = "PLANAR"
)

################################################################################
## CREATE LINES ################################################################

near_lines = arcpy.management.XYToLine(
    in_table = near_tbl,
    out_featureclass = "memory\\near_lines",
    startx_field = "FROM_X",
    starty_field = "FROM_Y",
    endx_field = "NEAR_X",
    endy_field = "NEAR_Y",
    line_type = "GEODESIC",
    id_field = "NEAR_FID",
    spatial_reference = srs_id,
    attributes="NO_ATTRIBUTES"
)

################################################################################
## CLEANUP MEMORY ##############################################################

arcpy.management.Delete(near_tbl)

################################################################################
## CREATE OUPUT FEATURE CLASS ##################################################

if create_new_fc == "true":
    arcpy.conversion.ExportFeatures(
        in_features = near_lines,
        out_features = out_feature_class
    )

################################################################################
## OR APPEND TO ORIGINAL LINEAR FEATURE CLASS ##################################

else:
        arcpy.management.Append(
        inputs=near_lines,
        target=ln_features,
        schema_type="NO_TEST"
    )

################################################################################
## CLEANUP MEMORY ##############################################################

arcpy.management.Delete(near_lines)

################################################################################

Leave a Comment

Your email address will not be published. Required fields are marked *