From fbda5d35080bee08943f03de25029079af6b7549 Mon Sep 17 00:00:00 2001 From: Nicholas Reinicke Date: Thu, 7 Nov 2024 17:23:34 -0700 Subject: [PATCH] add methods to convert results to geodataframe --- .github/workflows/lint_test.yml | 40 +++++++++++++-------------- .pre-commit-config.yaml | 6 ---- mappymatch/matchers/match_result.py | 43 +++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/.github/workflows/lint_test.yml b/.github/workflows/lint_test.yml index cd10eed..8ccf217 100644 --- a/.github/workflows/lint_test.yml +++ b/.github/workflows/lint_test.yml @@ -1,8 +1,8 @@ -name: Lint & Test +name: Lint & Test on: push: - branches: [ main ] + branches: [main] pull_request: jobs: @@ -11,22 +11,22 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install .[tests] - - name: Run black - run: black . --check - - name: Run ruff - run: ruff check . - - name: Run mypy - run: mypy . - - name: Run Tests - run: pytest tests \ No newline at end of file + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install .[tests] + - name: Run black + run: black . --check + - name: Run ruff + run: ruff check . + - name: Run mypy + run: mypy . + - name: Run Tests + run: pytest tests diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3300d46..1019a83 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,12 +4,6 @@ repos: hooks: - id: black args: [--config, pyproject.toml] -- repo: https://github.com/econchick/interrogate - rev: 1.5.0 - hooks: - - id: interrogate - args: [-c, pyproject.toml] - pass_filenames: false - repo: https://github.com/charliermarsh/ruff-pre-commit rev: v0.0.188 hooks: diff --git a/mappymatch/matchers/match_result.py b/mappymatch/matchers/match_result.py index 5eb89bd..dfb4954 100644 --- a/mappymatch/matchers/match_result.py +++ b/mappymatch/matchers/match_result.py @@ -1,6 +1,7 @@ from dataclasses import dataclass from typing import List, Optional +import geopandas as gpd import numpy as np import pandas as pd @@ -13,6 +14,30 @@ class MatchResult: matches: List[Match] path: Optional[List[Road]] = None + @property + def crs(self): + first_crs = self.matches[0].coordinate.crs + if not all([first_crs.equals(m.coordinate.crs) for m in self.matches]): + raise ValueError( + "Found that there were different CRS within the matches. " + "These must all be equal to use this function" + ) + return first_crs + + def matches_to_geodataframe(self) -> gpd.GeoDataFrame: + """ + Returns a geodataframe with all the coordinates and their resulting match (or NA if no match) in each row + """ + df = self.matches_to_dataframe() + gdf = gpd.GeoDataFrame(df, geometry="geom") + + if len(self.matches) == 0: + return gdf + + gdf = gdf.set_crs(self.crs) + + return gdf + def matches_to_dataframe(self) -> pd.DataFrame: """ Returns a dataframe with all the coordinates and their resulting match (or NA if no match) in each row. @@ -40,3 +65,21 @@ def path_to_dataframe(self) -> pd.DataFrame: df = df.fillna(np.nan) return df + + def path_to_geodataframe(self) -> gpd.GeoDataFrame: + """ + Returns a geodataframe with the resulting estimated trace path through the road network. + The geodataframe is empty if there was no path. + + Returns: + A geopandas geodataframe + """ + if self.path is None: + return gpd.GeoDataFrame() + + df = self.path_to_dataframe() + gdf = gpd.GeoDataFrame(df, geometry="geom") + + gdf = gdf.set_crs(self.crs) + + return gdf