Skip to content

Commit

Permalink
chore: simplify tests (#86)
Browse files Browse the repository at this point in the history
* chore: simplify tests

* chore: add changelog entry

* feat: raise error if provifded geometry filter has no area

* chore: add more docs info
  • Loading branch information
RaczeQ authored Apr 25, 2024
1 parent e151c91 commit 0c099d2
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 423 deletions.
33 changes: 1 addition & 32 deletions .github/workflows/_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install GDAL (linux)
if: matrix.os == 'ubuntu-latest'
run: |
$CONDA/bin/conda install -c conda-forge gdal
$CONDA/bin/ogr2ogr --version
- name: Install GDAL (macos)
if: matrix.os == 'macos-13'
run: |
CONDA=$HOME/miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh
bash Miniconda3-latest-MacOSX-x86_64.sh -b -p $CONDA
$CONDA/bin/conda install -c conda-forge gdal
$CONDA/bin/ogr2ogr --version
- name: Install GDAL (windows)
if: matrix.os == 'windows-latest'
run: |
& $env:CONDA\Scripts\conda.exe install -c conda-forge gdal
& $env:CONDA\Library\bin\ogr2ogr.exe --version
- uses: pdm-project/setup-pdm@v3
name: Setup PDM (Python ${{ matrix.python-version }})
with:
Expand All @@ -64,21 +46,8 @@ jobs:
key: tox-cache-${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('**/pdm.lock') }}
restore-keys: |
tox-cache-${{ matrix.os }}-${{ matrix.python-version }}-
- name: Run tests with tox (linux)
if: matrix.os == 'ubuntu-latest'
run: |
PATH=$CONDA/bin:$PATH
pdm run tox -e python${{ matrix.python-version }}
- name: Run tests with tox (macos)
if: matrix.os == 'macos-13'
run: |
CONDA=$HOME/miniconda
PATH=$CONDA/bin:$PATH
pdm run tox -e python${{ matrix.python-version }}
- name: Run tests with tox (windows)
if: matrix.os == 'windows-latest'
- name: Run tests with tox
run: |
$env:Path = "$env:CONDA\Library\bin;" + $env:Path
pdm run tox -e python${{ matrix.python-version }}
- name: Upload coverage to Codecov
uses: Wandalen/wretry.action@master
Expand Down
48 changes: 1 addition & 47 deletions .github/workflows/manual_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,60 +26,14 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install GDAL (linux)
if: matrix.os == 'ubuntu-latest'
run: |
$CONDA/bin/conda install -c conda-forge gdal
$CONDA/bin/ogr2ogr --version
- name: Install GDAL (macos arm)
if: matrix.os == 'macos-latest'
run: |
CONDA=$HOME/miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh
bash Miniconda3-latest-MacOSX-arm64.sh -b -p $CONDA
$CONDA/bin/conda install -c conda-forge gdal
$CONDA/bin/ogr2ogr --version
- name: Install GDAL (macos x86)
if: matrix.os == 'macos-13'
run: |
CONDA=$HOME/miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh
bash Miniconda3-latest-MacOSX-x86_64.sh -b -p $CONDA
$CONDA/bin/conda install -c conda-forge gdal
$CONDA/bin/ogr2ogr --version
- name: Install GDAL (windows)
if: matrix.os == 'windows-latest'
run: |
& $env:CONDA\Scripts\conda.exe install -c conda-forge gdal
& $env:CONDA\Library\bin\ogr2ogr.exe --version
- name: Install pdm
run: pip install pdm
- name: Generate lock with newest dependencies
run: pdm lock --lockfile pdm.newest.lock --strategy no_cross_platform -dG:all
- name: Install quackosm and tests dependencies
run: pdm install --lockfile pdm.newest.lock -dG:all
- name: Run tests with pytest (linux)
if: matrix.os == 'ubuntu-latest'
run: |
PATH=$CONDA/bin:$PATH
pdm run pytest -v -s --durations=20 --doctest-modules --doctest-continue-on-failure quackosm
pdm run pytest -v -s --durations=20 tests/base
pdm run pytest -v -s --durations=20 tests/optional_imports
pdm run pytest -v -s --durations=20 tests/benchmark
- name: Run tests with pytest (macos)
if: matrix.os == 'macos-latest' || matrix.os == 'macos-13'
run: |
CONDA=$HOME/miniconda
PATH=$CONDA/bin:$PATH
pdm run pytest -v -s --durations=20 --doctest-modules --doctest-continue-on-failure quackosm
pdm run pytest -v -s --durations=20 tests/base
pdm run pytest -v -s --durations=20 tests/optional_imports
pdm run pytest -v -s --durations=20 tests/benchmark
- name: Run tests with pytest (windows)
if: matrix.os == 'windows-latest'
- name: Run tests with pytest
run: |
$env:Path = "$env:CONDA\Library\bin;" + $env:Path
$env:PYTHONIOENCODING = "utf-8"
pdm run pytest -v -s --durations=20 --doctest-modules --doctest-continue-on-failure quackosm
pdm run pytest -v -s --durations=20 tests/base
pdm run pytest -v -s --durations=20 tests/optional_imports
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Simplified GDAL parity tests by precalculating result files and uploading them to additional repository

### Fixed

- Added exception if parts of provided geometry have no area [#85](https://github.com/kraina-ai/quackosm/issues/85)

## [0.7.0] - 2024-04-24

### Added
Expand Down
4 changes: 3 additions & 1 deletion examples/command_line_interface.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@
"- Geohash spatial index\n",
"- S2 spatial index\n",
"\n",
"These filters can also be used to filter out geometries from provided pbf file."
"These filters can also be used to filter out geometries from provided pbf file.\n",
"\n",
"`QuackOSM` will raise an error if provided geometry has parts without area (such as Points, LineStrings or empty geometry)."
]
},
{
Expand Down
35 changes: 1 addition & 34 deletions pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ test = [
"pytest-parametrization",
"pytest-xdist",
"pytest-doctestplus",
"pyogrio",
"srai>=0.6.2",
]
# pdm add -dG docs <library>
Expand Down
3 changes: 3 additions & 0 deletions quackosm/_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ class GeometryNotCoveredWarning(Warning): ...


class GeometryNotCoveredError(Exception): ...


class InvalidGeometryFilter(Exception): ...
4 changes: 2 additions & 2 deletions quackosm/_rich_progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def __init__(
self.major_steps_prefix = ""

if not self.verbosity_mode == "silent":
with suppress(ImportError): # pragma: no cover
with suppress(ImportError): # pragma: no cover
from types import TracebackType
from typing import Union

Expand Down Expand Up @@ -281,7 +281,7 @@ def _check_live_obj(self):
if self.verbosity_mode == "silent":
return

with suppress(ImportError):
with suppress(ImportError): # pragma: no cover
if not self.live or not self.live._started:
from rich.progress import Live

Expand Down
8 changes: 5 additions & 3 deletions quackosm/osm_extracts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,9 +493,11 @@ def _simplify_selected_extracts(
extract_geometry = (
matching_extracts.loc[sorted_extracts_gdf["id"] == extract_id].iloc[0].geometry
)
other_geometries = matching_extracts.loc[
sorted_extracts_gdf["id"] != extract_id
].unary_union
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=FutureWarning)
other_geometries = matching_extracts.loc[
sorted_extracts_gdf["id"] != extract_id
].unary_union
if extract_geometry.covered_by(other_geometries):
extract_to_remove = extract_id
simplify_again = True
Expand Down
3 changes: 2 additions & 1 deletion quackosm/osm_extracts/bbbike.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import requests
from tqdm import tqdm

from quackosm._constants import WGS84_CRS
from quackosm.osm_extracts._poly_parser import parse_polygon_file
from quackosm.osm_extracts.extract import OpenStreetMapExtract

Expand Down Expand Up @@ -46,7 +47,7 @@ def _load_bbbike_index() -> gpd.GeoDataFrame:
extracts = _iterate_bbbike_index()
gdf = gpd.GeoDataFrame(
data=[asdict(extract) for extract in extracts], geometry="geometry"
).set_crs("EPSG:4326")
).set_crs(WGS84_CRS)
gdf["area"] = gdf.geometry.area
gdf.sort_values(by="area", ignore_index=True, inplace=True)

Expand Down
3 changes: 2 additions & 1 deletion quackosm/osm_extracts/osm_fr.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import requests
from tqdm import tqdm

from quackosm._constants import WGS84_CRS
from quackosm.osm_extracts._poly_parser import parse_polygon_file
from quackosm.osm_extracts.extract import OpenStreetMapExtract

Expand Down Expand Up @@ -68,7 +69,7 @@ def _load_openstreetmap_fr_index() -> gpd.GeoDataFrame:
pbar.update()
gdf = gpd.GeoDataFrame(
data=[asdict(extract) for extract in extracts], geometry="geometry"
).set_crs("EPSG:4326")
).set_crs(WGS84_CRS)
gdf["area"] = gdf.geometry.area
gdf.sort_values(by="area", ignore_index=True, inplace=True)

Expand Down
34 changes: 28 additions & 6 deletions quackosm/pbf_file_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from shapely.geometry.base import BaseGeometry, BaseMultipartGeometry

from quackosm._constants import FEATURES_INDEX, GEOMETRY_COLUMN, WGS84_CRS
from quackosm._exceptions import EmptyResultWarning
from quackosm._exceptions import EmptyResultWarning, InvalidGeometryFilter
from quackosm._osm_tags_filters import (
GroupedOsmTagsFilter,
OsmTagsFilter,
Expand Down Expand Up @@ -145,7 +145,13 @@ def __init__(
Verbose leaves all progress outputs in the stdout. Defaults to "transient".
allow_uncovered_geometry (bool): Suppress an error if some geometry parts aren't
covered by any OSM extract. Defaults to `False`.
Raises:
InvalidGeometryFilter: When provided geometry filter has parts without area.
"""
self.geometry_filter = geometry_filter
self._check_if_valid_geometry_filter()

self.tags_filter = tags_filter
self.is_tags_filter_positive = (
check_if_any_osm_tags_filter_value_is_positive(self.tags_filter)
Expand All @@ -154,7 +160,7 @@ def __init__(
)
self.expanded_tags_filter: Optional[Union[GroupedOsmTagsFilter, OsmTagsFilter]] = None
self.merged_tags_filter: Optional[Union[GroupedOsmTagsFilter, OsmTagsFilter]] = None
self.geometry_filter = geometry_filter

self.allow_uncovered_geometry = allow_uncovered_geometry
self.osm_extract_source = osm_extract_source
self.working_directory = Path(working_directory)
Expand Down Expand Up @@ -600,10 +606,7 @@ def _drop_duplicated_features_in_joined_table(
with self.task_progress_tracker.get_basic_spinner("Combining results"):
output_file_name = tmp_dir_path / "joined_features_without_duplicates.parquet"
parquet_relation = connection.read_parquet(
[
str(parsed_geoparquet_file)
for parsed_geoparquet_file in parsed_geoparquet_files
],
[str(parsed_geoparquet_file) for parsed_geoparquet_file in parsed_geoparquet_files],
union_by_name=True,
)
query = f"""
Expand Down Expand Up @@ -838,6 +841,25 @@ def _generate_result_file_path_from_geometry(
)
return Path(self.working_directory) / result_file_name

def _check_if_valid_geometry_filter(self) -> None:
if self.geometry_filter is None:
return

if isinstance(self.geometry_filter, BaseMultipartGeometry):
geometries_to_check = self.geometry_filter.geoms
else:
geometries_to_check = [self.geometry_filter]

if not geometries_to_check:
raise InvalidGeometryFilter("Geometry filter is empty.")

for geometry_to_check in geometries_to_check:
if geometry_to_check.area == 0:
raise InvalidGeometryFilter(
"Detected geometry with area equal to 0."
" Geometry filter cannot contain geometries without area."
)

def _generate_geometry_hash(self) -> str:
clipping_geometry_hash_part = "noclip"
oriented_geometry = self._get_oriented_geometry_filter()
Expand Down
Loading

0 comments on commit 0c099d2

Please sign in to comment.