Como yo actualmente sólo se necesita todos los caminos más cortos entre dos conjuntos de puntos, terminé por calcular las rutas más cortas en mi propio con el Python de unión de la igraph de la biblioteca. Lo que tengo es un conjunto de datos de entrada con los puntos y un conjunto de datos con la red de la calle como un conjunto de polilíneas con nodo de inicio, nodo final y la longitud. Yo lo que hago es primero encontrar para cada punto de datos en el punto más cercano de la red de carreteras. Entonces puedo crear el gráfico de la red de carreteras. Para cada punto de datos, añado dos nuevas aristas al grafo. Esta es en realidad la mayor parte del código. Tal vez existen más elegante y versiones más cortas. Sé que para cada punto de datos el id de la polilínea más cercano a ella. Para cada polilínea me iterar a través de los segmentos y comprobar si el punto más cercano del punto de datos en el segmento o los puntos intermedios.
'''
Created on 13.05.2013
Create graph from road network dataset and find shortest path
'''
import arcpy
import igraph
from collections import defaultdict
poi_layer = 1 # Layer with points of interests.
street_layer = 2 # Layer with streets as polylines. Start and end vertex ids in fields
# Find for every poi closest point on road entwork
arcpy.analysis.Near(poi_layer, street_layer, location="LOCATION")
# Set of ids of all polylines containing a nearest point
intersect_points = defaultdict(set)
with arcpy.da.SearchCursor(poi_layer, ("SHAPE@", "NEAR_FID", "NEAR_DIST", "NEAR_X", "NEAR_Y", "OBJECTID")) as cursor:
for row in cursor:
near_fid = row[1]
near_dist = row[2]
near_x = row[3]
near_y = row[4]
objectId = row[5]
id = str(objectId)
intersect_points[near_fid].add(
(near_x,
near_y,
near_dist,
id,
objectId))
del row
del cursor
# Create Road Network
vertices = set()
edges, weights = [], []
fields = ["FNODE_", "TNODE_", "SHAPE@", "LENGTH", "OBJECTID_1"]
with arcpy.da.SearchCursor(street_layer, fields) as cursor:
for row in cursor:
s = str(int(row[0])) # Start node id
t = str(int(row[1])) # End node id
line = row[2] # Polyline object of road
length = row[3] # Road length
lineid = row[4] # Road id
vertices.add(s)
vertices.add(t)
# Check if road near to some data points
if lineid in intersect_points:
# For each intersection point
for ip in intersect_points[lineid]:
ip_near_distance = ip[2]
ip_source_id = ip[3]
intersect_point = arcpy.Point(ip[0], ip[1])
last_point = None
found = False
length_from = 0.0
length_to = 0.0
# Check for each line segment if it intersects
for part in line:
for current_point in part:
current_point_pg = arcpy.PointGeometry(current_point)
# Check if intersection point is on line point
if current_point_pg.contains(intersect_point):
found = True
length_from += ip_near_distance
length_to = ip_near_distance
if last_point is not None:
# Create line segment
array = arcpy.Array()
array.add(last_point)
array.add(current_point)
last_point_pg = arcpy.PointGeometry(last_point)
segment = arcpy.Polyline(array)
# Check if intersection point is on line segment
if not found and segment.contains(intersect_point):
found = True
length_from += ip_near_distance + \
last_point_pg.distanceTo(intersect_point)
length_to = ip_near_distance + \
current_point_pg.distanceTo(
intersect_point)
last_point = current_point
continue
if found:
length_to += segment.length
else:
length_from += segment.length
last_point = current_point
if not found:
print "Int point not found!"
# If interection point found road, add new node to
# network
else:
vertices.add(ip_source_id)
# Add edge from start node to data point
edges.append((s, ip_source_id))
weights.append(length_from)
# Add edge from data point to end node
edges.append((ip_source_id, t))
weights.append(length_to)
# Add road to network
e = (s, t)
w = length
edges.append(e)
weights.append(w)
del row
del cursor
# Create road network graph
g = igraph.Graph()
for v in vertices:
g.add_vertex(v)
for e in edges:
g.add_edge(e[0], e[1])
g.es["weight"] = weights
# Find location points
sources = # List of vertices ids
targets = # List of vertices ids
# Find shortest paths
shortest_paths = g.shortest_paths(
sources,
targets,
weights="weight",
mode="ALL")