Skip to content

Commit

Permalink
Merge 39c145c into 3c5b120
Browse files Browse the repository at this point in the history
  • Loading branch information
sjsrey committed Jun 17, 2015
2 parents 3c5b120 + 39c145c commit 611f075
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 17 deletions.
73 changes: 58 additions & 15 deletions pysal/network/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,16 @@ class Network:
Parameters
-----------
in_shp : string
A topoligically correct input shapefile
input shapefile
node_sig : int
round the x and y coordinates of all nodes to node_sig
significant digits (combined significant digits on left and right
of decimal place); default is 11; set to None for no rounding
unique_segs : boolean
if True (default), keep only unique segments (i.e., prune
out any duplicated segments); if False keep all segments
Attributes
----------
Expand Down Expand Up @@ -65,7 +74,7 @@ class Network:
Instantiate an instance of a network
>>> ntw = network.Network(ps.examples.get_path('geodanet/streets.shp'))
>>> ntw = ps.Network(ps.examples.get_path('geodanet/streets.shp'))
Snap point observations to the network with attribute information
Expand All @@ -77,9 +86,11 @@ class Network:
"""

def __init__(self, in_shp=None):
def __init__(self, in_shp=None, node_sig=11, unique_segs=True):
if in_shp:
self.in_shp = in_shp
self.node_sig = node_sig
self.unique_segs = unique_segs

self.adjacencylist = defaultdict(list)
self.nodes = {}
Expand All @@ -99,6 +110,21 @@ def __init__(self, in_shp=None):

self.node_list = sorted(self.nodes.values())

def _round_sig(self, v):
"""
Used internally to round vertex to a set number of significant
digits. If sig is set to 4, then the following are some possible
results for a coordinate: 0.0xxxx, 0.xxxx, x.xxx, xx.xx, xxx.x,
xxxx.0, xxxx0.0
"""
sig = self.node_sig
if sig is None:
return v
out_v = [val if 0 \
else round(val, -int(math.floor(math.log10(math.fabs(val)))) + (sig-1)) \
for val in v]
return tuple(out_v)

def _extractnetwork(self):
"""
Used internally, to extract a network from a polyline shapefile
Expand All @@ -108,15 +134,17 @@ def _extractnetwork(self):
for shp in shps:
vertices = shp.vertices
for i, v in enumerate(vertices[:-1]):
v = self._round_sig(v)
try:
vid = self.nodes[v]
except:
self.nodes[v] = vid = nodecount
nodecount += 1
v2 = self._round_sig(vertices[i+1])
try:
nvid = self.nodes[vertices[i+1]]
nvid = self.nodes[v2]
except:
self.nodes[vertices[i+1]] = nvid = nodecount
self.nodes[v2] = nvid = nodecount
nodecount += 1

self.adjacencylist[vid].append(nvid)
Expand All @@ -128,6 +156,11 @@ def _extractnetwork(self):
self.edges.append(edge)
length = util.compute_length(v, vertices[i+1])
self.edge_lengths[edge] = length
if self.unique_segs == True:
# remove duplicate edges and duplicate adjacent nodes
self.edges = list(set(self.edges))
for k, v in self.adjacencylist.iteritems():
self.adjacencylist[k] = list(set(v))

def extractgraph(self):
"""
Expand Down Expand Up @@ -241,7 +274,10 @@ def contiguityweights(self, graph=True, weightings=None):
Examples
--------
>>> ntw = ps.Network(ps.examples.get_path('geodanet/streets.shp'))
>>> w = ntw.contiguityweights(graph=False)
>>> ntw.snapobservations(ps.examples.get_path('geodanet/crimes.shp'), 'crimes', attribute=True)
>>> counts = ntw.count_per_edge(ntw.pointpatterns['crimes'].obs_to_edge, graph=False)
Using the W object, access to ESDA functionality is provided. First,
a vector of attributes is created for all edges with observations.
Expand All @@ -250,12 +286,12 @@ def contiguityweights(self, graph=True, weightings=None):
>>> edges = w.neighbors.keys()
>>> y = np.zeros(len(edges))
>>> for i, e in enumerate(edges):
>>> if e in counts.keys():
>>> y[i] = counts[e]
... if e in counts.keys():
... y[i] = counts[e]
Next, a standard call ot Moran is made and the result placed into `res`
>>> res = ps.esda.moran.Moran(y, ntw.w, permutations=99)
>>> res = ps.esda.moran.Moran(y, w, permutations=99)
"""

Expand Down Expand Up @@ -507,8 +543,12 @@ def count_per_edge(self, obs_on_network, graph=True):
Note that this passes the obs_to_edge attribute of a point pattern
snapped to the network.
>>> counts = ntw.count_per_edge(ntw.pointpatterns['crimes'].obs_to_edge,
graph=False)
>>> ntw = ps.Network(ps.examples.get_path('geodanet/streets.shp'))
>>> ntw.snapobservations(ps.examples.get_path('geodanet/crimes.shp'), 'crimes', attribute=True)
>>> counts = ntw.count_per_edge(ntw.pointpatterns['crimes'].obs_to_edge,graph=False)
>>> s = sum([v for v in counts.itervalues()])
>>> s
287
"""
counts = {}
Expand Down Expand Up @@ -564,11 +604,12 @@ def simulate_observations(self, count, distribution='uniform'):
Example
-------
>>> ntw = ps.Network(ps.examples.get_path('geodanet/streets.shp'))
>>> ntw.snapobservations(ps.examples.get_path('geodanet/crimes.shp'), 'crimes', attribute=True)
>>> npts = ntw.pointpatterns['crimes'].npoints
>>> sim = ntw.simulate_observations(npts)
>>> sim
<network.SimulatedPointPattern instance at 0x1133d8710>
>>> isinstance(sim, ps.network.network.SimulatedPointPattern)
True
"""
simpts = SimulatedPointPattern()

Expand Down Expand Up @@ -962,8 +1003,10 @@ def segment_edges(self, distance):
Example
-------
>>> ntw = ps.Network(ps.examples.get_path('geodanet/streets.shp'))
>>> n200 = ntw.segment_edges(200.0)
>>> len(n200.edges)
688
"""

sn = Network()
Expand Down Expand Up @@ -1057,7 +1100,7 @@ def savenetwork(self, filename):
Example
--------
>>> ntw = ps.Network(ps.examples.get_path('geodanet/streets.shp'))
>>> ntw.savenetwork('mynetwork.pkl')
"""
Expand Down
4 changes: 2 additions & 2 deletions pysal/network/tests/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def test_simulate_poisson_observations(self):

def test_all_neighbor_distances(self):
distancematrix = self.ntw.allneighbordistances(self.schools)
self.assertAlmostEqual(np.nansum(distancematrix[0]), 17682.436988, places=5)
self.assertAlmostEqual(np.nansum(distancematrix[0]), 17682.436988, places=4)

for k, (distances, predlist) in self.ntw.alldistances.iteritems():
self.assertEqual(distances[k], 0)
Expand Down Expand Up @@ -126,7 +126,7 @@ def setUp(self):

def test_dijkstra(self):
self.distance, self.pred = util.dijkstra(self.ntw, self.ntw.edge_lengths, 0)
self.assertAlmostEqual(self.distance[196], 5505.668247, places=5)
self.assertAlmostEqual(self.distance[196], 5505.668247, places=4)
self.assertEqual(self.pred[196], 133)


0 comments on commit 611f075

Please sign in to comment.