Skip to content

Commit

Permalink
shapely v2; rtree syntax; temp ops.substring fix
Browse files Browse the repository at this point in the history
  • Loading branch information
songololo committed Feb 4, 2023
1 parent b98f316 commit 0ac7dd9
Show file tree
Hide file tree
Showing 18 changed files with 476 additions and 353 deletions.
4 changes: 1 addition & 3 deletions cityseer/algos/centrality.py
Original file line number Diff line number Diff line change
Expand Up @@ -587,9 +587,7 @@ def local_segment_centrality(
# i.e. exit impedance minus half segment impedance
ang = m_simpl_dist - seg_ang / 2
# 2) f is the predecessor for e
elif (
m_nd_idx == src_idx or preds[n_nd_idx] == m_nd_idx # pylint: disable=consider-using-in
): # pylint: disable=consider-using-in
elif m_nd_idx == src_idx or preds[n_nd_idx] == m_nd_idx: # pylint: disable=consider-using-in
e = short_dist[m_nd_idx]
f = short_dist[n_nd_idx]
ang = n_simpl_dist - seg_ang / 2 # per above
Expand Down
2 changes: 0 additions & 2 deletions cityseer/algos/common.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# pylint: disable=duplicate-code

from __future__ import annotations

import numpy as np
Expand Down
5 changes: 1 addition & 4 deletions cityseer/algos/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,9 +562,7 @@ def mixed_uses(
qs: npt.NDArray[np.float32] = np.array([], dtype=np.float32),
mixed_use_hill_keys: npt.NDArray[np.int_] = np.array([], dtype=np.int_),
mixed_use_other_keys: npt.NDArray[np.int_] = np.array([], dtype=np.int_),
cl_disparity_wt_matrix: npt.NDArray[np.float32] = np.array(
np.full((0, 0), np.nan), dtype=np.float32
), # pylint: disable=line-too-long
cl_disparity_wt_matrix: npt.NDArray[np.float32] = np.array(np.full((0, 0), np.nan), dtype=np.float32),
jitter_scale: np.float32 = np.float32(0.0),
angular: bool = False,
progress_proxy: Optional[Any] = None,
Expand Down Expand Up @@ -960,7 +958,6 @@ def aggregate_stats(
stats_count_wt[num_idx, d_idx, netw_src_idx],
)

# pylint: disable=duplicate-code
return (
stats_sum,
stats_sum_wt,
Expand Down
2 changes: 1 addition & 1 deletion cityseer/cctypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
int, float, list[Union[int, float]], tuple[Union[int, float]], npt.NDArray[Union[np.int_, np.float32]]
]
BetasType = Union[float, list[float], tuple[float], npt.NDArray[np.float32]]
QsType = Union[ # pylint: disable=invalid-name
QsType = Union[
int,
float,
Union[list[int], list[float]],
Expand Down
24 changes: 10 additions & 14 deletions cityseer/metrics/layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ def compute_accessibilities(
# determine max impedance weights
max_curve_wts = networks.clip_weights_curve(_distances, _betas, spatial_tolerance)
# call the underlying function
# pylint: disable=duplicate-code
accessibility_data, accessibility_data_wt = data.accessibility(
network_structure.nodes.xs,
network_structure.nodes.ys,
Expand Down Expand Up @@ -524,25 +523,23 @@ def compute_mixed_uses(
# extrapolate the requested mixed use measures
mu_hill_keys: list[int] = []
mu_other_keys: list[int] = []
if mixed_use_keys is not None:
for mu in mixed_use_keys:
if mu not in mixed_uses_options:
raise ValueError(f'Invalid mixed-use option: {mu}. Must be one of {", ".join(mixed_uses_options)}.')
idx = mixed_uses_options.index(mu)
if idx < 4:
mu_hill_keys.append(idx)
else:
mu_other_keys.append(idx - 4)
if not config.QUIET_MODE:
logger.info(f'Computing mixed-use measures: {", ".join(mixed_use_keys)}')
for mu in mixed_use_keys:
if mu not in mixed_uses_options:
raise ValueError(f'Invalid mixed-use option: {mu}. Must be one of {", ".join(mixed_uses_options)}.')
idx = mixed_uses_options.index(mu)
if idx < 4:
mu_hill_keys.append(idx)
else:
mu_other_keys.append(idx - 4)
if not config.QUIET_MODE:
logger.info(f'Computing mixed-use measures: {", ".join(mixed_use_keys)}')
if not config.QUIET_MODE:
progress_proxy = ProgressBar(update_interval=0.25, notebook=False, total=network_structure.nodes.count)
else:
progress_proxy = None
# determine max impedance weights
max_curve_wts = networks.clip_weights_curve(_distances, _betas, spatial_tolerance)
# call the underlying function
# pylint: disable=duplicate-code
mixed_use_hill_data, mixed_use_other_data = data.mixed_uses(
network_structure.nodes.xs,
network_structure.nodes.ys,
Expand Down Expand Up @@ -941,7 +938,6 @@ def compute_stats(
progress_proxy = ProgressBar(update_interval=0.25, notebook=False, total=network_structure.nodes.count)
else:
progress_proxy = None
# pylint: disable=duplicate-code
(
stats_sum,
stats_sum_wt,
Expand Down
28 changes: 16 additions & 12 deletions cityseer/metrics/networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@

def _cast_beta(beta: cctypes.BetasType) -> npt.NDArray[np.float32]:
"""Type checks and casts beta parameter to a numpy array of beta."""
if beta is None:
raise TypeError("Expected beta but encountered None value.")
if not isinstance(beta, (list, tuple, np.ndarray)):
beta = [beta]
if len(beta) == 0:
Expand Down Expand Up @@ -181,8 +179,6 @@ def _cast_distance(
distance: cctypes.DistancesType,
) -> npt.NDArray[np.int_]:
"""Type checks and casts distance parameter to a numpy array of distance."""
if distance is None:
raise TypeError("Expected distance but encountered None value.")
# cast to list form
if isinstance(distance, (int, float)):
distance = [distance]
Expand Down Expand Up @@ -483,17 +479,26 @@ def node_centrality(
| node_harmonic | $$\sum_{j\neq{i}}^{n}\frac{1}{Z_{(i,j)}}$$ | Harmonic closeness is an appropriate form
of closeness centrality for localised implementations constrained by the threshold $d_{max}$. |
| node_beta | $$\sum_{j\neq{i}}^{n}\exp(-\beta\cdot d[i,j])$$ | Also known as the gravity index.
This is a spatial impedance metric differentiated from other closeness centralities by the use of an explicit $\beta$ parameter, which can be used to model the decay in walking tolerance as distances increase. | # pylint: disable=line-too-long
| node_betweenness | $$\sum_{j\neq{i}}^{n}\sum_{k\neq{j}\neq{i}}^{n}1$$ | Betweenness centrality summing all shortest-paths traversing each node $i$. | # pylint: disable=line-too-long
| node_betweenness_beta | $$\sum_{j\neq{i}}^{n}\sum_{k\neq{j}\neq{i}}^{n}\exp(-\beta\cdot d[j,k])$$ | Applies a spatial impedance decay function to betweenness centrality. $d$ represents the full distance from any $j$ to $k$ node pair passing through node $i$. | # pylint: disable=line-too-long
This is a spatial impedance metric differentiated from other closeness centralities by the use of an
explicit $\beta$ parameter, which can be used to model the decay in walking tolerance as distances
increase. |
| node_betweenness | $$\sum_{j\neq{i}}^{n}\sum_{k\neq{j}\neq{i}}^{n}1$$ | Betweenness centrality summing all
shortest-paths traversing each node $i$. |
| node_betweenness_beta | $$\sum_{j\neq{i}}^{n}\sum_{k\neq{j}\neq{i}}^{n}\exp(-\beta\cdot d[j,k])$$ | Applies a
spatial impedance decay function to betweenness centrality. $d$ represents the full distance from
any $j$ to $k$ node pair passing through node $i$. |
The following keys use the simplest-path (shortest-angular-path) heuristic, and are available when the `angular`
parameter is explicitly set to `True`:
| key | formula | notes |
| ------------------------ | :-----: | ----- |
| node_harmonic_angular | $$\sum_{j\neq{i}}^{n}\frac{1}{Z_{(i,j)}}$$ | The simplest-path implementation of harmonic closeness uses angular-distances for the impedance parameter. Angular-distances are normalised by 180 and added to 1 to avoid division by zero: ${Z = 1 + (angularchange/180)}$. | # pylint: disable=line-too-long
| node_betweenness_angular | $$\sum_{j\neq{i}}^{n}\sum_{k\neq{j}\neq{i}}^{n}1$$ | The simplest-path version of betweenness centrality. This is distinguished from the shortest-path version by use of a simplest-path heuristic (shortest angular distance). | # pylint: disable=line-too-long
| node_harmonic_angular | $$\sum_{j\neq{i}}^{n}\frac{1}{Z_{(i,j)}}$$ | The simplest-path implementation of
harmonic closeness uses angular-distances for the impedance parameter. Angular-distances are normalised by 180 and
added to 1 to avoid division by zero: ${Z = 1 + (angularchange/180)}$. |
| node_betweenness_angular | $$\sum_{j\neq{i}}^{n}\sum_{k\neq{j}\neq{i}}^{n}1$$ | The simplest-path version of
betweenness centrality. This is distinguished from the shortest-path version by use of a simplest-path heuristic
(shortest angular distance). |
"""
network_structure.validate()
Expand All @@ -502,7 +507,6 @@ def node_centrality(
# typos are caught below
if not angular:
heuristic = "shortest (non-angular)"
# pylint: disable=duplicate-code
options: tuple[str, ...] = (
"node_density",
"node_farness",
Expand All @@ -515,7 +519,7 @@ def node_centrality(
else:
heuristic = "simplest (angular)"
options = ("node_harmonic_angular", "node_betweenness_angular")
if measures is None:
if not measures:
raise ValueError("Please select at least one measure to compute.")
prep_measure_keys: list[str] = []
for measure in measures:
Expand Down Expand Up @@ -653,7 +657,7 @@ def segment_centrality(
else:
heuristic = "simplest (angular)"
options = ("segment_harmonic_hybrid", "segment_betweeness_hybrid")
if measures is None:
if not measures:
raise ValueError("Please select at least one measure to compute.")
prep_measure_keys: list[str] = []
for measure in measures:
Expand Down
4 changes: 2 additions & 2 deletions cityseer/metrics/observe.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def _recurse_edges(
nested_edge_data: graphs.EdgeData = _nx_multigraph[_a_nd_key][_b_nd_key][_edge_idx]
if _method not in nested_edge_data:
raise ValueError(f"Missing target key of {_method}")
nested_match_targets: list[str] = nested_edge_data[_method]
nested_match_targets: list[str | None] = nested_edge_data[_method]
nested_match_targets = [nmt.lower() for nmt in nested_match_targets if nmt is not None]
# bail if this edge info (e.g. street name) doesn't intersect with the previous
if not _match_target.lower() in nested_match_targets:
Expand Down Expand Up @@ -235,7 +235,7 @@ def street_continuity(
if method not in edge_data:
raise ValueError(f"Could not find {method} in edge data for edge: {a_nd_key} - {b_nd_key} idx: {edge_idx}")
# get target values, e.g. street names
match_targets: list[str] = edge_data[method]
match_targets: list[str | None] = edge_data[method]
match_targets = [mt.lower() for mt in match_targets if mt is not None]
# can be multiple values, e.g. route numbers per edge, so explore individually
for match_target in match_targets:
Expand Down
2 changes: 1 addition & 1 deletion cityseer/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ def set_data_point(self, data_idx: int, data_x: np.float32, data_y: np.float32,
raise ValueError(f'Expecting int for "data_id" but encountered {type(data_id)}')
self.xs[data_idx] = data_x
self.ys[data_idx] = data_y
if data_id is not None:
if data_id:
self.data_id[data_idx] = data_id

def x_y(self, data_idx: int) -> npt.NDArray[np.float32]:
Expand Down
Loading

0 comments on commit 0ac7dd9

Please sign in to comment.