-
Notifications
You must be signed in to change notification settings - Fork 87
/
Copy pathcyaccess.pyx
196 lines (169 loc) · 6.43 KB
/
cyaccess.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
cimport cython
from libcpp cimport bool
from libcpp.vector cimport vector
from libcpp.string cimport string
from libcpp.pair cimport pair
import numpy as np
cimport numpy as np
# resources
# http://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html
# http://www.birving.com/blog/2014/05/13/passing-numpy-arrays-between-python-and/
cdef extern from "accessibility.h" namespace "MTC::accessibility":
cdef cppclass Accessibility:
Accessibility(int, vector[vector[long]], vector[vector[double]], bool) except +
vector[string] aggregations
vector[string] decays
void initializeCategory(double, int, string, vector[long])
pair[vector[vector[double]], vector[vector[int]]] findAllNearestPOIs(
float, int, string, int)
void initializeAccVar(string, vector[long], vector[double])
vector[double] getAllAggregateAccessibilityVariables(
float, string, string, string, int)
vector[int] Route(int, int, int)
vector[vector[int]] Routes(vector[long], vector[long], int)
double Distance(int, int, int)
vector[double] Distances(vector[long], vector[long], int)
void precomputeRangeQueries(double)
cdef np.ndarray[double] convert_vector_to_array_dbl(vector[double] vec):
cdef np.ndarray arr = np.zeros(len(vec), dtype="double")
for i in range(len(vec)):
arr[i] = vec[i]
return arr
cdef np.ndarray[double, ndim = 2] convert_2D_vector_to_array_dbl(
vector[vector[double]] vec):
cdef np.ndarray arr = np.empty_like(vec, dtype="double")
for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
arr[i][j] = vec[i][j]
return arr
cdef np.ndarray[int, ndim = 2] convert_2D_vector_to_array_int(
vector[vector[int]] vec):
cdef np.ndarray arr = np.empty_like(vec, dtype="int")
for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
arr[i][j] = vec[i][j]
return arr
cdef class cyaccess:
cdef Accessibility * access
def __cinit__(
self,
np.ndarray[long] node_ids,
np.ndarray[double, ndim=2] node_xys,
np.ndarray[long, ndim=2] edges,
np.ndarray[double, ndim=2] edge_weights,
bool twoway=True
):
"""
node_ids: vector of node identifiers
node_xys: the spatial locations of the same nodes
edges: a pair of node ids which comprise each edge
edge_weights: the weights (impedances) that apply to each edge
twoway: whether the edges should all be two-way or whether they
are directed from the first to the second node
"""
# you're right, neither the node ids nor the location xys are used in here
# anymore - I'm hesitant to out-and-out remove it as we might still use
# it for something someday
self.access = new Accessibility(len(node_ids), edges, edge_weights, twoway)
def __dealloc__(self):
del self.access
def initialize_category(
self,
double maxdist,
int maxitems,
string category,
np.ndarray[long] node_ids
):
"""
maxdist - the maximum distance that will later be used in
find_all_nearest_pois
maxitems - the maximum number of items that will later be requested
in find_all_nearest_pois
category - the category name
node_ids - an array of nodeids which are locations where this poi occurs
"""
self.access.initializeCategory(maxdist, maxitems, category, node_ids)
def find_all_nearest_pois(
self,
double radius,
int num_of_pois,
string category,
int impno=0
):
"""
radius - search radius
num_of_pois - number of pois to search for
category - the category name
impno - the impedance id to use
return_nodeids - whether to return the nodeid locations of the nearest
not just the distances
"""
ret = self.access.findAllNearestPOIs(radius, num_of_pois, category, impno)
return convert_2D_vector_to_array_dbl(ret.first),\
convert_2D_vector_to_array_int(ret.second)
def initialize_access_var(
self,
string category,
np.ndarray[long] node_ids,
np.ndarray[double] values
):
"""
category - category name
node_ids: vector of node identifiers
values: vector of values that are location at the nodes
"""
self.access.initializeAccVar(category, node_ids, values)
def get_available_aggregations(self):
return self.access.aggregations
def get_available_decays(self):
return self.access.decays
def get_all_aggregate_accessibility_variables(
self,
double radius,
category,
aggtyp,
decay,
int impno=0,
):
"""
radius - search radius
category - category name
aggtyp - aggregation type, see docs
decay - decay type, see docs
impno - the impedance id to use
"""
ret = self.access.getAllAggregateAccessibilityVariables(
radius, category, aggtyp, decay, impno)
return convert_vector_to_array_dbl(ret)
def shortest_path(self, int srcnode, int destnode, int impno=0):
"""
srcnode - node id origin
destnode - node id destination
impno - the impedance id to use
"""
return self.access.Route(srcnode, destnode, impno)
def shortest_paths(self, np.ndarray[long] srcnodes,
np.ndarray[long] destnodes, int impno=0):
"""
srcnodes - node ids of origins
destnodes - node ids of destinations
impno - impedance id
"""
return self.access.Routes(srcnodes, destnodes, impno)
def shortest_path_distance(self, int srcnode, int destnode, int impno=0):
"""
srcnode - node id origin
destnode - node id destination
impno - the impedance id to use
"""
return self.access.Distance(srcnode, destnode, impno)
def shortest_path_distances(self, np.ndarray[long] srcnodes,
np.ndarray[long] destnodes, int impno=0):
"""
srcnodes - node ids of origins
destnodes - node ids of destinations
impno - impedance id
"""
return self.access.Distances(srcnodes, destnodes, impno)
def precompute_range(self, double radius):
self.access.precomputeRangeQueries(radius)