Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Functional distribution #588

Merged
merged 11 commits into from
Jun 12, 2024
37 changes: 37 additions & 0 deletions momepy/functional/_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import shapely
from geopandas import GeoDataFrame, GeoSeries
from libpysal.graph import Graph
from numpy.typing import NDArray
from packaging.version import Version
from pandas import Series
from scipy import sparse
Expand All @@ -16,6 +17,7 @@
"building_adjacency",
"neighbors",
"street_alignment",
"cell_alignment",
]

GPD_GE_013 = Version(gpd.__version__) >= Version("0.13.0")
Expand Down Expand Up @@ -339,3 +341,38 @@ def street_alignment(
Series
"""
return (building_orientation - street_orientation.loc[street_index].values).abs()


def cell_alignment(
martinfleis marked this conversation as resolved.
Show resolved Hide resolved
left_orientation: NDArray[np.float64] | Series,
right_orientation: NDArray[np.float64] | Series,
) -> Series:
"""
Calculate the difference between cell orientation and the orientation of object.

.. math::
\\left|{\\textit{building orientation} - \\textit{cell orientation}}\\right|

Notes
-----
``left_orientation`` and ``right_orientation`` must be aligned or have an index.

Parameters
----------
left_orientation : np.array, pd.Series
The ``np.array``, or `pd.Series`` with orientation of cells.
This can be calculated using :func:`orientation`.
right_orientation : np.array, pd.Series
The ``np.array`` or ``pd.Series`` with orientation of objects.
This can be calculated using :func:`orientation`.

Returns
-------
Series
"""

if not isinstance(left_orientation, Series):
left_orientation = Series(left_orientation)
if not isinstance(right_orientation, Series):
right_orientation = Series(right_orientation)
return (left_orientation - right_orientation).abs()
31 changes: 31 additions & 0 deletions momepy/functional/tests/test_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ def test_street_alignment(self):
r = mm.street_alignment(building_orientation, street_orientation, street_index)
assert_result(r, expected, self.df_buildings)

def test_cell_alignment(self):
df_buildings = self.df_buildings.reset_index()
df_tessellation = self.df_tessellation.reset_index()
blgori = mm.orientation(df_buildings)
tessori = mm.orientation(df_tessellation)

align = mm.cell_alignment(blgori, tessori)
align2 = mm.cell_alignment(blgori.values, tessori.values)
align_expected = {
"count": 144,
"mean": 2.604808585700,
"max": 33.201625570390746,
"min": 1.722848278973288e-05,
}
assert_result(align, align_expected, df_buildings)
assert_series_equal(align, align2, check_names=False)


class TestEquality:
def setup_method(self):
Expand Down Expand Up @@ -220,3 +237,17 @@ def test_street_alignment(self):
right_network_id="index",
).series
assert_series_equal(new, old, check_names=False, check_index=False)

def test_cell_alignment(self):
df_buildings = self.df_buildings.reset_index()
df_tessellation = self.df_tessellation.reset_index()
df_buildings["orient"] = blgori = mm.orientation(df_buildings)
df_tessellation["orient"] = tessori = mm.orientation(df_tessellation)

align_new = mm.cell_alignment(blgori, tessori)

align_old = mm.CellAlignment(
df_buildings, df_tessellation, "orient", "orient", "uID", "uID"
).series

assert_series_equal(align_new, align_old, check_names=False, check_dtype=False)