Skip to content

Commit

Permalink
Merge pull request #116 from jGaboardi/pp_shortestpath_lookup
Browse files Browse the repository at this point in the history
adding shortest path traceback for point patterns
  • Loading branch information
jGaboardi committed Sep 17, 2018
2 parents 739a37c + 0f11da3 commit 7eb73fe
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 41 deletions.
38 changes: 29 additions & 9 deletions spaghetti/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,9 @@ def allneighbordistances(self, sourcepattern, destpattern=None,
nearest : numpy.ndarray
An array of shape (n,n) storing distances between all points.
tree_nearest : dict
nearest network node to point pattern node shortest path lookup
Examples
--------
Expand All @@ -906,6 +909,12 @@ def allneighbordistances(self, sourcepattern, destpattern=None,
... destpattern='schools')
>>> s2d_dist[0,0], s2d_dist[1,0]
(4520.72353741989, 6340.422971967316)
>>> s2d_dist, tree = ntw.allneighbordistances('schools',
... gen_tree=True)
>>> tree[(6, 7)]
(173, 64)
"""

if not hasattr(self, 'alldistances'):
Expand Down Expand Up @@ -942,6 +951,7 @@ def allneighbordistances(self, sourcepattern, destpattern=None,
# Output setup
nearest = np.empty((nsource_pts, ndest_pts))
nearest[:] = np.inf
tree_nearest = {}

for p1 in src_indices:
# Get the source nodes and dist to source nodes.
Expand All @@ -964,18 +974,20 @@ def allneighbordistances(self, sourcepattern, destpattern=None,

else:
ddist1, ddist2 = dest_dist_to_node[p2].values()
d11 = self.alldistances[source1][0][dest1]
d21 = self.alldistances[source2][0][dest1]
d12 = self.alldistances[source1][0][dest2]
d22 = self.alldistances[source2][0][dest2]
d11 = self.distancematrix[source1][dest1]
d21 = self.distancematrix[source2][dest1]
d12 = self.distancematrix[source1][dest2]
d22 = self.distancematrix[source2][dest2]

# Find the shortest distance from the path passing
# through each of the two origin nodes to the first
# destination node.
sd_1 = d11 + sdist1
sd_21 = d21 + sdist2
sp_combo1 = source1, dest1
if sd_1 > sd_21:
sd_1 = sd_21
sp_combo1 = source2, dest1
# Now add the point to node one distance on
# the destination edge.
len_1 = sd_1 + ddist1
Expand All @@ -984,31 +996,39 @@ def allneighbordistances(self, sourcepattern, destpattern=None,
# at the second node of the second edge.
sd_2 = d12 + sdist1
sd_22 = d22 + sdist2
b = 0
sp_combo2 = source1, dest2
if sd_2 > sd_22:
sd_2 = sd_22
b = 1
sp_combo2 = source2, dest2
len_2 = sd_2 + ddist2

# Now find the shortest distance path between point
# 1 on edge 1 and point 2 on edge 2, and assign.
sp_12 = len_1
s_node, d_node = sp_combo1
if len_1 > len_2:
sp_12 = len_2
s_node, d_node = sp_combo2

nearest[p1, p2] = sp_12
tree_nearest[p1, p2] = (s_node, d_node)

if symmetric:
# Mirror the upper and lower triangle
# when symmetric.
nearest[p2, p1] = nearest[p1, p2]

# Populate the main diagonal when symmetric.
if symmetric:
if fill_diagonal is None:
np.fill_diagonal(nearest, np.nan)
else:
np.fill_diagonal(nearest, fill_diagonal)

return nearest

if gen_tree:
return nearest, tree_nearest
else:
return nearest


def nearestneighbordistances(self, sourcepattern, destpattern=None,
Expand Down
19 changes: 11 additions & 8 deletions spaghetti/tests/test_network_api_from_gdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,22 @@ def test_simulate_poisson_observations(self):
self.assertEqual(npoints, sim.npoints)

def test_all_neighbor_distances(self):
distancematrix_1 = self.ntw.allneighbordistances(self.schools,
gen_tree=True)
self.assertAlmostEqual(np.nansum(distancematrix_1[0]),
17682.436988, places=4)
matrix1, tree = self.ntw.allneighbordistances('schools', gen_tree=True)
known_mtx_val = 17682.436988
known_tree_val = (173, 64)

self.assertAlmostEqual(np.nansum(matrix1[0]), known_mtx_val, places=4)
self.assertEqual(tree[(6, 7)], known_tree_val)

for k, (distances, predlist) in self.ntw.alldistances.items():
self.assertEqual(distances[k], 0)
for p, plists in predlist.items():
self.assertEqual(plists[-1], k)
self.assertEqual(self.ntw.node_list, list(predlist.keys()))
distancematrix_2 = self.ntw.allneighbordistances(self.schools,
fill_diagonal=0.)
observed = distancematrix_2.diagonal()
known = np.zeros(distancematrix_2.shape[0])
matrix2 = self.ntw.allneighbordistances('schools', fill_diagonal=0.)
observed = matrix2.diagonal()
known = np.zeros(matrix2.shape[0])
self.assertEqual(observed.all(), known.all())

def test_nearest_neighbor_distances(self):
Expand Down
19 changes: 11 additions & 8 deletions spaghetti/tests/test_network_api_from_shp.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,22 @@ def test_simulate_poisson_observations(self):
self.assertEqual(npoints, sim.npoints)

def test_all_neighbor_distances(self):
distancematrix_1 = self.ntw.allneighbordistances(self.schools,
gen_tree=True)
self.assertAlmostEqual(np.nansum(distancematrix_1[0]),
17682.436988, places=4)
matrix1, tree = self.ntw.allneighbordistances('schools', gen_tree=True)
known_mtx_val = 17682.436988
known_tree_val = (173, 64)

self.assertAlmostEqual(np.nansum(matrix1[0]), known_mtx_val, places=4)
self.assertEqual(tree[(6, 7)], known_tree_val)

for k, (distances, predlist) in self.ntw.alldistances.items():
self.assertEqual(distances[k], 0)
for p, plists in predlist.items():
self.assertEqual(plists[-1], k)
self.assertEqual(self.ntw.node_list, list(predlist.keys()))
distancematrix_2 = self.ntw.allneighbordistances(self.schools,
fill_diagonal=0.)
observed = distancematrix_2.diagonal()
known = np.zeros(distancematrix_2.shape[0])
matrix2 = self.ntw.allneighbordistances('schools', fill_diagonal=0.)
observed = matrix2.diagonal()
known = np.zeros(matrix2.shape[0])
self.assertEqual(observed.all(), known.all())

def test_nearest_neighbor_distances(self):
Expand Down
19 changes: 11 additions & 8 deletions spaghetti/tests/test_network_from_gdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,19 +104,22 @@ def test_simulate_poisson_observations(self):
self.assertEqual(npoints, sim.npoints)

def test_all_neighbor_distances(self):
distancematrix_1 = self.ntw.allneighbordistances(self.schools,
gen_tree=True)
self.assertAlmostEqual(np.nansum(distancematrix_1[0]),
17682.436988, places=4)
matrix1, tree = self.ntw.allneighbordistances('schools', gen_tree=True)
known_mtx_val = 17682.436988
known_tree_val = (173, 64)

self.assertAlmostEqual(np.nansum(matrix1[0]), known_mtx_val, places=4)
self.assertEqual(tree[(6, 7)], known_tree_val)

for k, (distances, predlist) in self.ntw.alldistances.items():
self.assertEqual(distances[k], 0)
for p, plists in predlist.items():
self.assertEqual(plists[-1], k)
self.assertEqual(self.ntw.node_list, list(predlist.keys()))
distancematrix_2 = self.ntw.allneighbordistances(self.schools,
fill_diagonal=0.)
observed = distancematrix_2.diagonal()
known = np.zeros(distancematrix_2.shape[0])
matrix2 = self.ntw.allneighbordistances('schools', fill_diagonal=0.)
observed = matrix2.diagonal()
known = np.zeros(matrix2.shape[0])
self.assertEqual(observed.all(), known.all())

def test_nearest_neighbor_distances(self):
Expand Down
18 changes: 10 additions & 8 deletions spaghetti/tests/test_network_from_shp.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,22 @@ def test_simulate_poisson_observations(self):
self.assertEqual(npoints, sim.npoints)

def test_all_neighbor_distances(self):
distancematrix_1 = self.ntw.allneighbordistances('schools',
gen_tree=True)
self.assertAlmostEqual(np.nansum(distancematrix_1[0]),
17682.436988, places=4)
matrix1, tree = self.ntw.allneighbordistances('schools', gen_tree=True)
known_mtx_val = 17682.436988
known_tree_val = (173, 64)

self.assertAlmostEqual(np.nansum(matrix1[0]), known_mtx_val, places=4)
self.assertEqual(tree[(6, 7)], known_tree_val)

for k, (distances, predlist) in self.ntw.alldistances.items():
self.assertEqual(distances[k], 0)
for p, plists in predlist.items():
self.assertEqual(plists[-1], k)
self.assertEqual(self.ntw.node_list, list(predlist.keys()))

distancematrix_2 = self.ntw.allneighbordistances('schools',
fill_diagonal=0.)
observed = distancematrix_2.diagonal()
known = np.zeros(distancematrix_2.shape[0])
matrix2 = self.ntw.allneighbordistances('schools', fill_diagonal=0.)
observed = matrix2.diagonal()
known = np.zeros(matrix2.shape[0])
self.assertEqual(observed.all(), known.all())

def test_nearest_neighbor_distances(self):
Expand Down

0 comments on commit 7eb73fe

Please sign in to comment.