I am using ArcView (ArcGIS Desktop Basic) 10.1 and I need to perform a point distance analysis.
What are the steps to determine the distance from A to B-Z, B to A-Z, C to A-Z, etc?
arcgis-10.1arcgis-desktopdistancedistance matrixproximity
I am using ArcView (ArcGIS Desktop Basic) 10.1 and I need to perform a point distance analysis.
What are the steps to determine the distance from A to B-Z, B to A-Z, C to A-Z, etc?
If you have the Spatial Analyst extension, it sounds like you may be able to make use of the Path Distance tool. You will need an elevation raster to serve as input. The tool will output a raster with a value in each cell that represents the shortest distance to one of your points from that cell, taking the topography into account in its calculations.
Of course this is assuming you're looking for overland and not hydrologic distance.
I have taken a slightly different approach than @radouxju. Here is an arcpy based solution I've written really quickly that will split your lines at points. It requires having two feature classes and each of them should have a unique ID field (to uniquely identify each point and each line).
The script logic is as follows: create several dictionaries to store pointID and lineID and each feature geometry in arcpy.Geometry() instance >> evaluate whether a point is located on the line and if yes, split it. I have not built in yet the searching algorithm that will look around for the closest point yet. The output child lines will inherit all the attributes their parents have (no attribute splitting logic exists either). The output feature class will contain only those lines which had points located on them. You can use simple Select By Location to select and merge with the rest of lines if needed.
The script uses heavily arcpy.Geometry()
methods which turned out to be really fast and powerful. For instance, symmetrical difference method that can be initiated on a geometry object in any license, is exposed as a GP tool only in ArcGIS Desktop Advanced.
The geometry of output lines will be practically identical to the source ones. The point located on a line will be buffered and then the result polygon is used to intersect the line and then resulted sublines are integrated to share the same vertex. The smaller buffer zone you create, the more precise the output splitted lines will be with the respect to the source line geometry. Running a buffer of just several cm zone will be more than enough for most applications (unless you are dealing with submillimeter precision data used in civil engineering for constructing bridges or something).
import arcpy
arcpy.env.overwriteOutput = True
line_fc = r"C:\GIS\Temp\test.gdb\Lines"
point_fc = r"C:\GIS\Temp\test.gdb\Points"
point_fc_desc = arcpy.Describe(point_fc)
in_spatial_reference = point_fc_desc.spatialReference
#can use CopyFeatures to write the geometries to disk when troubleshooting
#buffered_point_fc = r"C:\GIS\Temp\test.gdb\PointsBuffered"
#intersected_line_fc = r"C:\GIS\Temp\test.gdb\LineIntersected"
#symmetrical_difference_line_fc = r"C:\GIS\Temp\test.gdb\LineIntersectedSymmDiff"
single_part_splitted_lines = r"C:\GIS\Temp\test.gdb\SplittedLines"
total_splitted_lines = r"C:\GIS\Temp\test.gdb\TotalSplittedLines"
total_splitted_lines_attributed = r"C:\GIS\Temp\test.gdb\TotalSplittedLinesAttributed"
arcpy.TruncateTable_management(total_splitted_lines)
#--- reference dictionaries ----------------#
points_id_geometry_dict = {} #{pointID: pointGeometry}
lines_id_geometry_dict = {} #{lineID: lineGeometry}
search_cursor = arcpy.da.SearchCursor(point_fc,["PointID","SHAPE@"])
for point_feature in search_cursor:
points_id_geometry_dict[point_feature[0]] = point_feature[1]
del search_cursor
search_cursor = arcpy.da.SearchCursor(line_fc,["LineID","SHAPE@"])
for line_feature in search_cursor:
lines_id_geometry_dict[line_feature[0]] = line_feature[1]
del search_cursor
#-------------------------------------------#
points_list =[]
lines_list = []
dictionary_lines_points = {} #{lineID: pointID} or {lineID: (pointID, pointID,...)}
point_cursor = arcpy.da.SearchCursor(point_fc,["SHAPE@","PointID"])
line_cursor = arcpy.da.SearchCursor(line_fc,["SHAPE@","LineID"])
for point in point_cursor:
point_geom_and_id = [point[0],point[1]]
points_list.append(point_geom_and_id)
for line in line_cursor:
line_geom_and_id = [line[0],line[1]]
lines_list.append(line_geom_and_id)
del point_cursor
del line_cursor
for line in lines_list:
for point in points_list:
if line[0].contains(point[0]): #finding what points are on what lines
print "LineID:", line[1], "PointID:", point[1]
if not line[1] in dictionary_lines_points: #handling situations when multiple points are on the same line
dictionary_lines_points[line[1]] = point[1] #lineid is key, point ids is value (can be a tuple)
else:
dictionary_lines_points[line[1]] = (dictionary_lines_points[line[1]],point[1]) #making tuple for "" line: (point ids) ""
for key_line in dictionary_lines_points.keys(): #iterating each line in the line_fc
pointID = dictionary_lines_points.get(key_line) #getting what PointID have match to lineID
if not isinstance(pointID,tuple):
input_point_geom_object = points_id_geometry_dict.get(pointID) #obtain point geometry based on pointID
multipoints = input_point_geom_object
else:
merged_point_geometries = arcpy.Array() #constructing a multipoint (if multiple points are on the same line)
for pointID_element in pointID:
input_point_geom_object = points_id_geometry_dict.get(pointID_element)
merged_point_geometries.add(input_point_geom_object.centroid) #creating array of points
multipoints = arcpy.Multipoint(merged_point_geometries,in_spatial_reference)
line_geometry_object = lines_id_geometry_dict.get(key_line) #obtain line geometry based on LineID
buffered_point = multipoints.buffer(0.1) #same units as the geometry
intersected_line = buffered_point.intersect(line_geometry_object,2) #2 - polyline returned
symmetrical_difference_line = intersected_line.symmetricDifference(line_geometry_object)
arcpy.MultipartToSinglepart_management(symmetrical_difference_line,single_part_splitted_lines)
arcpy.Integrate_management(single_part_splitted_lines,"0.1 Meters")
arcpy.Append_management(single_part_splitted_lines,total_splitted_lines,"NO_TEST")
arcpy.Delete_management(single_part_splitted_lines)
arcpy.SpatialJoin_analysis(target_features=total_splitted_lines,
join_features=line_fc,
out_feature_class=total_splitted_lines_attributed,
join_operation="JOIN_ONE_TO_ONE",join_type="KEEP_ALL",
match_option="INTERSECT",search_radius="#",distance_field_name="#")
##TODO
#iterate through line features that did not have any points located on them (distanceTo geometry method / select by location)
#if there are any points located within the search distance >> move them on line and run the logic >> append to the output fc
#if no point features are located within the search distance >> append them directly to the output fc
Best Answer
The following code is not polished but should work to create the same output table as the Point Distance tool but requires ArcGIS 10.1 (or later) for Desktop and only a Basic level license: