diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 119fce0..42a00ff 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: timeout-minutes: 40 defaults: run: - shell: bash -l {0} + shell: bash -l {0} env: PYTHON_VERSION: ${{ matrix.python-version }} CHANS_DEV: "-c pyviz/label/dev" @@ -64,7 +64,7 @@ jobs: conda activate test-environment conda list doit develop_install ${{ env.CHANS_DEV }} -o tests - pip install hilbertcurve + pip install hilbertcurve - name: doit env_capture run: | eval "$(conda shell.bash hook)" diff --git a/.gitignore b/.gitignore index 95817c3..21d2227 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,9 @@ venv.bak/ *.parq .idea/ spatialpandas/.version + +.vscode/ + +monkeytype.sqlite3 + +.doit.db diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 0000000..d985c00 --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,7 @@ +[settings] +multi_line_output=3 +include_trailing_comma=True +force_grid_wrap=0 +use_parentheses=True +known_local_folder=spatialpandas +known_first_party=spatialpandas diff --git a/CHANGELOG.md b/CHANGELOG.md index c52ee9a..a1780cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,25 @@ +Version 0.4.0 +============= + +### Added + - Add HoloViz build infrastructure. ([#50](https://github.com/holoviz/spatialpandas/pull/50)) + - Add `--skip-slow` and `--run-slow` options, slow tests are still run by default. ([#60](https://github.com/holoviz/spatialpandas/pull/60)) + - Add some type hints to parquet functions. ([#60](https://github.com/holoviz/spatialpandas/pull/60)) + +### Fixed + - Fix compatibility with latest pandas. ([#55](https://github.com/holoviz/spatialpandas/pull/55)) + - Fix certain tests fail due to hypothesis health check. ([#60](https://github.com/holoviz/spatialpandas/pull/60)) + - Pin numpy and dask on MacOS to pass tests. ([#60](https://github.com/holoviz/spatialpandas/pull/60)) + + +### Updated + - Allow using cx indexer without spatial index. ([#54](https://github.com/holoviz/spatialpandas/pull/54)) + - Switch to GitHub Actions. ([#55](https://github.com/holoviz/spatialpandas/pull/55)) + - Updated Geometry class __eq__ method so that if other object is a container, the equality method on the container is called, so now performing an equality check between a geometry object and a geometry array should return correct results, which should be a bool array, whereas previously it would simply return False because the objects were not the same immediate type. ([#60](https://github.com/holoviz/spatialpandas/pull/60)) + - Update GeometryArray class __eq__ method to allow comparison of an individual element to all objects in the array, returning an array of bool. ([#60](https://github.com/holoviz/spatialpandas/pull/60)) + - Add NotImplementedError for __contains__ method. ([#60](https://github.com/holoviz/spatialpandas/pull/60)) + + Version 0.3.6 ============= diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..dec2071 --- /dev/null +++ b/conftest.py @@ -0,0 +1,33 @@ +"""Configuration for pytest.""" +import pytest + + +_DEFAULT_SKIPSLOW = False + + +def pytest_addoption(parser): + """Add command-line flags for pytest.""" + parser.addoption( + "--skip-slow", + action="store_true", + help="skips slow tests", + default=_DEFAULT_SKIPSLOW, + ) + parser.addoption( + "--run-slow", + action="store_true", + default=False, # Only used for cli override + help="run slow tests", + ) + + +def pytest_configure(config): + config.addinivalue_line("markers", "slow: mark test as slow to run") + + +def pytest_collection_modifyitems(config, items): + if not config.getoption("--run-slow") and config.getoption("--skip-slow"): + skip_slow = pytest.mark.skip(reason="Skipping slow tests") + for item in items: + if "slow" in item.keywords: + item.add_marker(skip_slow) diff --git a/setup.py b/setup.py index 5dd972c..5203923 100644 --- a/setup.py +++ b/setup.py @@ -1,41 +1,58 @@ -from setuptools import setup, find_packages +import sys + import param +from setuptools import find_packages, setup extras_require = { 'tests': [ - 'pytest', 'codecov', - 'pytest-cov', 'flake8', + 'geopandas', 'hypothesis', + 'pytest-cov', + 'pytest', 'scipy', 'shapely', - 'geopandas', ], 'examples': [ - 'geopandas', - 'matplotlib', - 'descartes', 'datashader', + 'descartes', + 'geopandas', 'holoviews', + 'matplotlib', ] } install_requires = [ - 'pandas>=0.25', - 'dask[complete] >=2.0', + 'fsspec', 'numba', - 'numpy', - 'pyarrow>=0.15', + 'pandas>=0.25', 'param', - 'fsspec', + 'pyarrow>=0.15', 'retrying', + 'snappy', ] +# Checking for platform explicitly because +# pyctdev does not handle dependency conditions +# such as 'numpy<1.20;platform_system=="Darwin"' +if sys.platform == 'darwin': + install_requires.extend([ + 'dask[complete]>=2.0,<2020.12', + 'numpy<1.20', + ]) +else: + install_requires.extend([ + 'dask[complete]>=2.0', + 'numpy', + ]) + setup_args = dict( name='spatialpandas', version=param.version.get_setup_version( - __file__, "spatialpandas", archive_commit="$Format:%h$" + __file__, + "spatialpandas", + archive_commit="$Format:%h$", ), description='Pandas extension arrays for spatial/geometric operations', long_description=open("README.md").read(), @@ -49,9 +66,8 @@ tests_require=extras_require['tests'], license='BSD-2-Clause', packages=find_packages(exclude=('tests', 'tests.*')), - include_package_data=True + include_package_data=True, ) if __name__ == '__main__': setup(**setup_args) - diff --git a/spatialpandas/__init__.py b/spatialpandas/__init__.py index fa93eee..a85694b 100644 --- a/spatialpandas/__init__.py +++ b/spatialpandas/__init__.py @@ -1,17 +1,21 @@ -from . import geometry, spatialindex, tools # noqa -from .geoseries import GeoSeries # noqa -from .geodataframe import GeoDataFrame # noqa -from .tools.sjoin import sjoin # noqa import param as _param +from . import geometry, spatialindex, tools # noqa +from .geodataframe import GeoDataFrame # noqa +from .geoseries import GeoSeries # noqa +from .tools.sjoin import sjoin # noqa + try: - import dask.dataframe # noqa + import dask.dataframe # noqa # Import to trigger registration of types with Dask - import spatialpandas.dask # noqa + import spatialpandas.dask # noqa except ImportError: # Dask dataframe not available pass -__version__ = str(_param.version.Version( - fpath=__file__, archive_commit="$Format:%h$", reponame="spatialpandas") -) +__version__ = str( + _param.version.Version( + fpath=__file__, + archive_commit="$Format:%h$", + reponame="spatialpandas", + )) diff --git a/spatialpandas/dask.py b/spatialpandas/dask.py index 4fa3305..c09f76e 100644 --- a/spatialpandas/dask.py +++ b/spatialpandas/dask.py @@ -1,24 +1,26 @@ +import copy +import json +import os +import uuid +from inspect import signature + +import numpy as np +import pandas as pd +import pyarrow as pa +import pyarrow.parquet as pq +from retrying import retry + +import dask import dask.dataframe as dd from dask import delayed +from dask.dataframe.core import get_parallel_type from dask.dataframe.partitionquantiles import partition_quantiles +from dask.dataframe.utils import make_array_nonempty, make_meta, meta_nonempty -from spatialpandas.geometry.base import _BaseCoordinateIndexer, GeometryDtype -from spatialpandas.spatialindex import HilbertRtree -from .geoseries import GeoSeries from .geodataframe import GeoDataFrame -import dask -from dask.dataframe.core import get_parallel_type -from dask.dataframe.utils import make_meta, meta_nonempty, make_array_nonempty -import pandas as pd -import numpy as np -import pyarrow.parquet as pq -import pyarrow as pa -import os -import uuid -import json -import copy -from inspect import signature -from retrying import retry +from .geometry.base import GeometryDtype, _BaseCoordinateIndexer +from .geoseries import GeoSeries +from .spatialindex import HilbertRtree class DaskGeoSeries(dd.Series): diff --git a/spatialpandas/geodataframe.py b/spatialpandas/geodataframe.py index 42f50d9..663b5c8 100644 --- a/spatialpandas/geodataframe.py +++ b/spatialpandas/geodataframe.py @@ -1,7 +1,8 @@ import pandas as pd + +from ._optional_imports import gp from .geometry import GeometryDtype from .geoseries import GeoSeries, _MaybeGeoSeries -from ._optional_imports import gp class _MaybeGeoDataFrame(pd.DataFrame): diff --git a/spatialpandas/geometry/__init__.py b/spatialpandas/geometry/__init__.py index 6c7c957..ddf1344 100644 --- a/spatialpandas/geometry/__init__.py +++ b/spatialpandas/geometry/__init__.py @@ -1,4 +1,4 @@ -from .polygon import Polygon, PolygonArray, PolygonDtype # noqa +from .polygon import Polygon, PolygonArray, PolygonDtype # noqa from .multipolygon import ( # noqa MultiPolygon, MultiPolygonArray, MultiPolygonDtype ) diff --git a/spatialpandas/geometry/_algorithms/bounds.py b/spatialpandas/geometry/_algorithms/bounds.py index b5776b2..5abcec4 100644 --- a/spatialpandas/geometry/_algorithms/bounds.py +++ b/spatialpandas/geometry/_algorithms/bounds.py @@ -1,6 +1,6 @@ import numpy as np -from spatialpandas.utils import ngjit +from ...utils import ngjit @ngjit diff --git a/spatialpandas/geometry/_algorithms/intersection.py b/spatialpandas/geometry/_algorithms/intersection.py index d6d2af3..4529718 100644 --- a/spatialpandas/geometry/_algorithms/intersection.py +++ b/spatialpandas/geometry/_algorithms/intersection.py @@ -1,10 +1,10 @@ import numpy as np - -from spatialpandas.geometry._algorithms.bounds import total_bounds_interleaved -from spatialpandas.geometry._algorithms.orientation import triangle_orientation -from spatialpandas.utils import ngjit, ngpjit from numba import prange +from ...geometry._algorithms.bounds import total_bounds_interleaved +from ...geometry._algorithms.orientation import triangle_orientation +from ...utils import ngjit, ngpjit + @ngjit def segment_intersects_point(ax0, ay0, ax1, ay1, bx, by): diff --git a/spatialpandas/geometry/_algorithms/measures.py b/spatialpandas/geometry/_algorithms/measures.py index 7e7b6a5..0bea180 100644 --- a/spatialpandas/geometry/_algorithms/measures.py +++ b/spatialpandas/geometry/_algorithms/measures.py @@ -2,7 +2,7 @@ import numpy as np -from spatialpandas.utils import ngjit +from ...utils import ngjit @ngjit diff --git a/spatialpandas/geometry/_algorithms/orientation.py b/spatialpandas/geometry/_algorithms/orientation.py index 44ca832..2687c50 100644 --- a/spatialpandas/geometry/_algorithms/orientation.py +++ b/spatialpandas/geometry/_algorithms/orientation.py @@ -1,7 +1,8 @@ -from spatialpandas.geometry._algorithms.measures import compute_area -from spatialpandas.utils import ngjit import numpy as np +from ...geometry._algorithms.measures import compute_area +from ...utils import ngjit + @ngjit def triangle_orientation(ax, ay, bx, by, cx, cy): diff --git a/spatialpandas/geometry/base.py b/spatialpandas/geometry/base.py index bc16412..949f36a 100644 --- a/spatialpandas/geometry/base.py +++ b/spatialpandas/geometry/base.py @@ -1,5 +1,6 @@ +import re +from collections.abc import Container, Iterable from numbers import Integral -from collections.abc import Iterable import numpy as np import pandas as pd @@ -7,12 +8,10 @@ from pandas.api.extensions import ExtensionArray, ExtensionDtype from pandas.api.types import is_array_like -from spatialpandas.spatialindex import HilbertRtree -from spatialpandas.spatialindex.rtree import _distances_from_bounds -import re - -from spatialpandas.utils import ngjit -from .._optional_imports import sg, gp +from .._optional_imports import gp, sg +from ..spatialindex import HilbertRtree +from ..spatialindex.rtree import _distances_from_bounds +from ..utils import ngjit def _unwrap_geometry(a, element_dtype): @@ -144,6 +143,8 @@ def __hash__(self): return hash((self.__class__, np.array(self.data.as_py()).tobytes())) def __eq__(self, other): + if isinstance(other, Container): + return other == self if type(other) is not type(self): return False return self.data == other.data @@ -336,11 +337,18 @@ def __eq__(self, other): for i in range(len(self)): result[i] = self[i] == other[i] return result - else: - raise ValueError(""" + if isinstance(other, (self.dtype.type, type(None))): + result = np.zeros(len(self), dtype=np.bool_) + for i in range(len(self)): + result[i] = self[i] == other + return result + raise ValueError(""" Cannot check equality of {typ} of length {a_len} with: {other}""".format(typ=type(self).__name__, a_len=len(self), other=repr(other))) + def __contains__(self, item) -> bool: + raise NotImplementedError + def __len__(self): return len(self.data) @@ -499,8 +507,8 @@ def _concat_same_type(cls, to_concat): def fillna(self, value=None, method=None, limit=None): from pandas.api.types import is_array_like - from pandas.util._validators import validate_fillna_kwargs from pandas.core.missing import get_fill_func + from pandas.util._validators import validate_fillna_kwargs value, method = validate_fillna_kwargs(value, method) @@ -766,10 +774,8 @@ def is_geometry_array(data): def to_geometry_array(data, dtype=None): - from . import ( - PointArray, MultiPointArray, LineArray, RingArray, - MultiLineArray, PolygonArray, MultiPolygonArray - ) + from . import (LineArray, MultiLineArray, MultiPointArray, + MultiPolygonArray, PointArray, PolygonArray, RingArray) if sg is not None: shapely_to_spatialpandas = { sg.Point: PointArray, diff --git a/spatialpandas/geometry/basefixed.py b/spatialpandas/geometry/basefixed.py index 12439d3..d575689 100644 --- a/spatialpandas/geometry/basefixed.py +++ b/spatialpandas/geometry/basefixed.py @@ -1,12 +1,12 @@ from functools import total_ordering -import pyarrow as pa + import numpy as np +import pyarrow as pa -from spatialpandas.geometry.base import Geometry, GeometryArray, GeometryDtype -from spatialpandas.geometry.baselist import _lexographic_lt -from ._algorithms.bounds import ( - total_bounds_interleaved, total_bounds_interleaved_1d, bounds_interleaved -) +from ..geometry.base import Geometry, GeometryArray, GeometryDtype +from ..geometry.baselist import _lexographic_lt +from ._algorithms.bounds import (bounds_interleaved, total_bounds_interleaved, + total_bounds_interleaved_1d) @total_ordering diff --git a/spatialpandas/geometry/baselist.py b/spatialpandas/geometry/baselist.py index 494524f..64700be 100644 --- a/spatialpandas/geometry/baselist.py +++ b/spatialpandas/geometry/baselist.py @@ -1,13 +1,12 @@ from functools import total_ordering -import pyarrow as pa -import numpy as np +import numpy as np +import pyarrow as pa from numba import jit, prange -from spatialpandas.geometry.base import Geometry, GeometryArray -from ._algorithms.bounds import ( - total_bounds_interleaved, total_bounds_interleaved_1d, bounds_interleaved -) +from ..geometry.base import Geometry, GeometryArray +from ._algorithms.bounds import (bounds_interleaved, total_bounds_interleaved, + total_bounds_interleaved_1d) def _validate_nested_arrow_type(nesting_levels, pyarrow_type): @@ -273,10 +272,10 @@ def _lexographic_lt0(a1, a2): def _lexographic_lt(a1, a2): - if a1.dtype != np.object and a1.dtype != np.object: + if a1.dtype != np.dtype(object) and a1.dtype != np.dtype(object): # a1 and a2 primitive return _lexographic_lt0(a1, a2) - elif a1.dtype == np.object and a1.dtype == np.object: + elif a1.dtype == np.dtype(object) and a1.dtype == np.dtype(object): # a1 and a2 object, process recursively for e1, e2 in zip(a1, a2): if _lexographic_lt(e1, e2): @@ -284,7 +283,7 @@ def _lexographic_lt(a1, a2): elif _lexographic_lt(e2, e1): return False return len(a1) < len(a2) - elif a1.dtype != np.object: + elif a1.dtype != np.dtype(object): # a2 is object array, a1 primitive return True else: @@ -333,5 +332,3 @@ def _geometry_map_nested3( start = value_offsets1[value_offsets0[i]] stop = value_offsets1[value_offsets0[i + 1]] result[i] = fn(values, value_offsets2[start:stop + 1]) - - diff --git a/spatialpandas/geometry/line.py b/spatialpandas/geometry/line.py index 2e22a26..caaaa04 100644 --- a/spatialpandas/geometry/line.py +++ b/spatialpandas/geometry/line.py @@ -1,14 +1,12 @@ -from pandas.core.dtypes.dtypes import register_extension_dtype - -from spatialpandas.geometry._algorithms.intersection import lines_intersect_bounds -from spatialpandas.geometry._algorithms.measures import compute_line_length -from spatialpandas.geometry.base import GeometryDtype - -from spatialpandas.geometry.baselist import ( - GeometryListArray, GeometryList, _geometry_map_nested1 -) import numpy as np from dask.dataframe.extensions import make_array_nonempty +from pandas.core.dtypes.dtypes import register_extension_dtype + +from ..geometry._algorithms.intersection import lines_intersect_bounds +from ..geometry._algorithms.measures import compute_line_length +from ..geometry.base import GeometryDtype +from ..geometry.baselist import (GeometryList, GeometryListArray, + _geometry_map_nested1) @register_extension_dtype diff --git a/spatialpandas/geometry/multiline.py b/spatialpandas/geometry/multiline.py index f667d13..631673f 100644 --- a/spatialpandas/geometry/multiline.py +++ b/spatialpandas/geometry/multiline.py @@ -1,17 +1,13 @@ -from pandas.core.dtypes.dtypes import register_extension_dtype - -from spatialpandas.geometry._algorithms.intersection import ( - lines_intersect_bounds, multilines_intersect_bounds -) -from spatialpandas.geometry.base import ( - GeometryDtype -) -from spatialpandas.geometry.baselist import ( - GeometryListArray, GeometryList, _geometry_map_nested2 -) import numpy as np -from spatialpandas.geometry._algorithms.measures import compute_line_length from dask.dataframe.extensions import make_array_nonempty +from pandas.core.dtypes.dtypes import register_extension_dtype + +from ..geometry._algorithms.intersection import (lines_intersect_bounds, + multilines_intersect_bounds) +from ..geometry._algorithms.measures import compute_line_length +from ..geometry.base import GeometryDtype +from ..geometry.baselist import (GeometryList, GeometryListArray, + _geometry_map_nested2) @register_extension_dtype diff --git a/spatialpandas/geometry/multipoint.py b/spatialpandas/geometry/multipoint.py index 4cde3bf..0a16b76 100644 --- a/spatialpandas/geometry/multipoint.py +++ b/spatialpandas/geometry/multipoint.py @@ -1,10 +1,10 @@ import numpy as np +from dask.dataframe.extensions import make_array_nonempty from pandas.core.dtypes.dtypes import register_extension_dtype -from spatialpandas.geometry._algorithms.intersection import multipoints_intersect_bounds -from spatialpandas.geometry.base import GeometryDtype -from spatialpandas.geometry.baselist import GeometryListArray, GeometryList -from dask.dataframe.extensions import make_array_nonempty +from ..geometry._algorithms.intersection import multipoints_intersect_bounds +from ..geometry.base import GeometryDtype +from ..geometry.baselist import GeometryList, GeometryListArray @register_extension_dtype diff --git a/spatialpandas/geometry/multipolygon.py b/spatialpandas/geometry/multipolygon.py index 14d7176..2f9b306 100644 --- a/spatialpandas/geometry/multipolygon.py +++ b/spatialpandas/geometry/multipolygon.py @@ -1,22 +1,19 @@ import numpy as np import pyarrow as pa +from dask.dataframe.extensions import make_array_nonempty from pandas.core.dtypes.dtypes import register_extension_dtype -from spatialpandas.geometry import Polygon -from spatialpandas.geometry._algorithms.intersection import ( - multipolygons_intersect_bounds -) -from spatialpandas.geometry._algorithms.orientation import orient_polygons -from spatialpandas.geometry.base import GeometryDtype -from spatialpandas.geometry.baselist import ( - GeometryListArray, GeometryList, _geometry_map_nested3 -) -from spatialpandas.geometry.multiline import MultiLineArray, MultiLine -from spatialpandas.geometry._algorithms.measures import ( - compute_line_length, compute_area +from ..geometry import Polygon +from ..geometry._algorithms.intersection import multipolygons_intersect_bounds +from ..geometry._algorithms.measures import compute_area, compute_line_length +from ..geometry._algorithms.orientation import orient_polygons +from ..geometry.base import GeometryDtype +from ..geometry.baselist import ( + GeometryList, + GeometryListArray, + _geometry_map_nested3, ) - -from dask.dataframe.extensions import make_array_nonempty +from ..geometry.multiline import MultiLine, MultiLineArray @register_extension_dtype diff --git a/spatialpandas/geometry/point.py b/spatialpandas/geometry/point.py index ff629eb..eaa1ede 100644 --- a/spatialpandas/geometry/point.py +++ b/spatialpandas/geometry/point.py @@ -1,12 +1,12 @@ import numpy as np +from dask.dataframe.extensions import make_array_nonempty from pandas.core.dtypes.dtypes import register_extension_dtype -from spatialpandas.geometry._algorithms.intersection import segment_intersects_point, \ - point_intersects_polygon -from spatialpandas.geometry.base import GeometryDtype -from spatialpandas.geometry.basefixed import GeometryFixed, GeometryFixedArray -from dask.dataframe.extensions import make_array_nonempty -from spatialpandas.utils import ngpjit +from ..geometry._algorithms.intersection import (point_intersects_polygon, + segment_intersects_point) +from ..geometry.base import GeometryDtype +from ..geometry.basefixed import GeometryFixed, GeometryFixedArray +from ..utils import ngpjit @register_extension_dtype @@ -133,7 +133,7 @@ def _intersects_polygon(self, polygon): ) def intersects(self, shape): - from . import MultiPoint, Line, MultiLine, Polygon, MultiPolygon + from . import Line, MultiLine, MultiPoint, MultiPolygon, Polygon if isinstance(shape, Point): return self._intersects_point(shape) elif isinstance(shape, MultiPoint): @@ -239,7 +239,7 @@ def _intersects_polygon(self, polygon, inds): ) def intersects(self, shape, inds=None): - from . import MultiPoint, Line, MultiLine, Polygon, MultiPolygon + from . import Line, MultiLine, MultiPoint, MultiPolygon, Polygon if isinstance(shape, Point): return self._intersects_point(shape, inds) elif isinstance(shape, MultiPoint): diff --git a/spatialpandas/geometry/polygon.py b/spatialpandas/geometry/polygon.py index a518b4d..bf8ac06 100644 --- a/spatialpandas/geometry/polygon.py +++ b/spatialpandas/geometry/polygon.py @@ -1,19 +1,18 @@ +import numpy as np +import pyarrow as pa +from dask.dataframe.extensions import make_array_nonempty from pandas.core.dtypes.dtypes import register_extension_dtype -from spatialpandas.geometry._algorithms.intersection import polygons_intersect_bounds -from spatialpandas.geometry._algorithms.orientation import orient_polygons -from spatialpandas.geometry.base import GeometryDtype - -from spatialpandas.geometry.baselist import ( - GeometryListArray, GeometryList, _geometry_map_nested2 +from ..geometry._algorithms.intersection import polygons_intersect_bounds +from ..geometry._algorithms.measures import compute_area, compute_line_length +from ..geometry._algorithms.orientation import orient_polygons +from ..geometry.base import GeometryDtype +from ..geometry.baselist import ( + GeometryList, + GeometryListArray, + _geometry_map_nested2, ) -from spatialpandas.geometry.multiline import MultiLineArray, MultiLine -import numpy as np -from spatialpandas.geometry._algorithms.measures import ( - compute_line_length, compute_area -) -from dask.dataframe.extensions import make_array_nonempty -import pyarrow as pa +from ..geometry.multiline import MultiLine, MultiLineArray @register_extension_dtype diff --git a/spatialpandas/geometry/ring.py b/spatialpandas/geometry/ring.py index cfa73b5..7eac35b 100644 --- a/spatialpandas/geometry/ring.py +++ b/spatialpandas/geometry/ring.py @@ -1,9 +1,8 @@ -from pandas.core.dtypes.dtypes import register_extension_dtype import numpy as np -from spatialpandas.geometry.line import ( - LineDtype, Line, LineArray -) from dask.dataframe.extensions import make_array_nonempty +from pandas.core.dtypes.dtypes import register_extension_dtype + +from ..geometry.line import Line, LineArray, LineDtype @register_extension_dtype diff --git a/spatialpandas/io/parquet.py b/spatialpandas/io/parquet.py index 443e565..8f02045 100644 --- a/spatialpandas/io/parquet.py +++ b/spatialpandas/io/parquet.py @@ -2,29 +2,27 @@ import json import pathlib from functools import reduce +from numbers import Number +from typing import Any, Dict, Iterable, List, Optional, Tuple, Union +import fsspec import pandas as pd +import pyarrow as pa from dask import delayed -from dask.dataframe import ( # noqa - to_parquet as dd_to_parquet, read_parquet as dd_read_parquet, - from_delayed, from_pandas, -) +from dask.dataframe import from_delayed, from_pandas +from dask.dataframe import read_parquet as dd_read_parquet +from dask.dataframe import to_parquet as dd_to_parquet # noqa from dask.utils import natural_sort_key - -from pandas.io.parquet import ( - to_parquet as pd_to_parquet, -) - -import pyarrow as pa +from pandas.io.parquet import to_parquet as pd_to_parquet from pyarrow import parquet as pq -from spatialpandas.io.utils import validate_coerce_filesystem -from spatialpandas import GeoDataFrame -from spatialpandas.dask import DaskGeoDataFrame -from spatialpandas.geometry.base import to_geometry_array -from spatialpandas.geometry import ( - PointDtype, MultiPointDtype, RingDtype, LineDtype, - MultiLineDtype, PolygonDtype, MultiPolygonDtype, GeometryDtype -) + +from .. import GeoDataFrame +from ..dask import DaskGeoDataFrame +from ..geometry import (GeometryDtype, LineDtype, MultiLineDtype, + MultiPointDtype, MultiPolygonDtype, + PointDtype, PolygonDtype, RingDtype) +from ..geometry.base import to_geometry_array +from ..io.utils import validate_coerce_filesystem _geometry_dtypes = [ PointDtype, MultiPointDtype, RingDtype, LineDtype, @@ -86,19 +84,28 @@ def _get_geometry_columns(pandas_metadata): def to_parquet( - df, + df: GeoDataFrame, fname, - compression="snappy", - index=None, - **kwargs -): + compression: Optional[str] = "snappy", + index: Optional[bool] = None, + **kwargs, +) -> None: # Standard pandas to_parquet with pyarrow engine pd_to_parquet( - df, fname, engine="pyarrow", compression=compression, index=index, **kwargs + df, + fname, + engine="pyarrow", + compression=compression, + index=index, + **kwargs, ) -def read_parquet(path, columns=None, filesystem=None): +def read_parquet( + path: str, + columns: Optional[Iterable[str]] = None, + filesystem: Optional[fsspec.spec.AbstractFileSystem] = None, +) -> GeoDataFrame: filesystem = validate_coerce_filesystem(path, filesystem) # Load pandas parquet metadata @@ -136,16 +143,25 @@ def read_parquet(path, columns=None, filesystem=None): def to_parquet_dask( - ddf, path, compression="snappy", filesystem=None, storage_options=None, **kwargs -): + ddf: DaskGeoDataFrame, + path, + compression: Optional[str] = "snappy", + filesystem: Optional[fsspec.spec.AbstractFileSystem] = None, + storage_options: Optional[Dict[str, Any]] = None, + **kwargs, +) -> None: assert isinstance(ddf, DaskGeoDataFrame) filesystem = validate_coerce_filesystem(path, filesystem) if path and filesystem.isdir(path): filesystem.rm(path, recursive=True) dd_to_parquet( - ddf, path, engine="pyarrow", compression=compression, - storage_options=storage_options, **kwargs + ddf, + path, + engine="pyarrow", + compression=compression, + storage_options=storage_options, + **kwargs, ) # Write partition bounding boxes to the _metadata file @@ -178,12 +194,19 @@ def to_parquet_dask( def read_parquet_dask( - path, columns=None, filesystem=None, load_divisions=False, - geometry=None, bounds=None, categories=None, build_sindex=False -): - """ - Read spatialpandas parquet dataset(s) as DaskGeoDataFrame. Datasets are assumed to - have been written with the DaskGeoDataFrame.to_parquet or + path: str, + columns: Optional[Iterable[str]] = None, + filesystem: Optional[fsspec.spec.AbstractFileSystem] = None, + load_divisions: Optional[bool] = False, + geometry: Optional[str] = None, + bounds: Optional[Tuple[Number, Number, Number, Number]] = None, + categories: Optional[Union[List[str], Dict[str, str]]] = None, + build_sindex: Optional[bool] = False, +) -> DaskGeoDataFrame: + """Read spatialpandas parquet dataset(s) as DaskGeoDataFrame. + + Datasets are assumed to have been written with the + DaskGeoDataFrame.to_parquet or DaskGeoDataFrame.pack_partitions_to_parquet methods. Args: diff --git a/spatialpandas/spatialindex/hilbert_curve.py b/spatialpandas/spatialindex/hilbert_curve.py index 21e2fa3..7c5a8b7 100644 --- a/spatialpandas/spatialindex/hilbert_curve.py +++ b/spatialpandas/spatialindex/hilbert_curve.py @@ -1,5 +1,6 @@ import numpy as np -from spatialpandas.utils import ngjit + +from ..utils import ngjit """ Initially based on https://github.com/galtay/hilbert_curve, but specialized diff --git a/spatialpandas/spatialindex/rtree.py b/spatialpandas/spatialindex/rtree.py index bc13714..3b45640 100644 --- a/spatialpandas/spatialindex/rtree.py +++ b/spatialpandas/spatialindex/rtree.py @@ -1,15 +1,13 @@ import numpy as np -from numba import int64, float64 +from numba import float64, int64 try: from numba.experimental import jitclass except ImportError: from numba import jitclass -from spatialpandas.spatialindex.hilbert_curve import ( - distances_from_coordinates -) -from spatialpandas.utils import ngjit, _data2coord +from ..spatialindex.hilbert_curve import distances_from_coordinates +from ..utils import _data2coord, ngjit @ngjit diff --git a/spatialpandas/tests/geometry/algorithms/test_intersection.py b/spatialpandas/tests/geometry/algorithms/test_intersection.py index 9a8c630..884de67 100644 --- a/spatialpandas/tests/geometry/algorithms/test_intersection.py +++ b/spatialpandas/tests/geometry/algorithms/test_intersection.py @@ -1,21 +1,34 @@ import numpy as np - -from hypothesis import given, example +import pytest +from hypothesis import example, given from shapely import geometry as sg +from ..strategies import ( + coord, + hyp_settings, + st_bounds, + st_line_array, + st_multiline_array, + st_multipoint_array, + st_multipolygon_array, + st_point_array, + st_points, + st_polygon, + st_polygon_array, +) from spatialpandas.geometry import ( - Polygon, MultiPointArray, LineArray, MultiLineArray, PolygonArray, - MultiPolygonArray, PointArray + LineArray, + MultiLineArray, + MultiPointArray, + MultiPolygonArray, + PointArray, + Polygon, + PolygonArray, ) from spatialpandas.geometry._algorithms.intersection import ( - segments_intersect, point_intersects_polygon, - segment_intersects_point -) - -from ..strategies import ( - st_polygon, st_multipoint_array, st_bounds, st_line_array, - st_multiline_array, st_polygon_array, st_multipolygon_array, - hyp_settings, coord, st_points, st_point_array + point_intersects_polygon, + segment_intersects_point, + segments_intersect, ) @@ -164,6 +177,7 @@ def test_multiline_intersects_rect(gp_multiline, rect): np.testing.assert_equal(result, expected) +@pytest.mark.slow @given( st_polygon_array(), st_bounds( @@ -193,6 +207,7 @@ def test_polygon_intersects_rect(gp_polygon, rect): np.testing.assert_equal(result, expected) +@pytest.mark.slow @given( st_multipolygon_array(), st_bounds( diff --git a/spatialpandas/tests/geometry/algorithms/test_measures.py b/spatialpandas/tests/geometry/algorithms/test_measures.py index a0602c7..8cfb85e 100644 --- a/spatialpandas/tests/geometry/algorithms/test_measures.py +++ b/spatialpandas/tests/geometry/algorithms/test_measures.py @@ -1,13 +1,12 @@ import numpy as np - +import pytest from hypothesis import given -from spatialpandas.geometry import MultiPolygonArray, PolygonArray -from ..strategies import ( - st_multipolygon_array, hyp_settings, st_polygon_array -) +from ..strategies import hyp_settings, st_multipolygon_array, st_polygon_array +from spatialpandas.geometry import MultiPolygonArray, PolygonArray +@pytest.mark.slow @given(st_polygon_array()) @hyp_settings def test_polygon_area(gp_polygon): @@ -17,6 +16,7 @@ def test_polygon_area(gp_polygon): np.testing.assert_allclose(area, expected_area) +@pytest.mark.slow @given(st_multipolygon_array()) @hyp_settings def test_multipolygon_area(gp_multipolygon): diff --git a/spatialpandas/tests/geometry/algorithms/test_orientation.py b/spatialpandas/tests/geometry/algorithms/test_orientation.py index 92d6c3d..18ca8a0 100644 --- a/spatialpandas/tests/geometry/algorithms/test_orientation.py +++ b/spatialpandas/tests/geometry/algorithms/test_orientation.py @@ -1,10 +1,9 @@ from hypothesis import given from shapely import geometry as sg +from ..strategies import coord, hyp_settings from spatialpandas.geometry._algorithms.orientation import triangle_orientation -from ..strategies import hyp_settings, coord - @given(coord, coord, coord, coord, coord, coord) @hyp_settings diff --git a/spatialpandas/tests/geometry/intersection/test_point_intersection.py b/spatialpandas/tests/geometry/intersection/test_point_intersection.py index eff8d32..efaf0df 100644 --- a/spatialpandas/tests/geometry/intersection/test_point_intersection.py +++ b/spatialpandas/tests/geometry/intersection/test_point_intersection.py @@ -1,19 +1,29 @@ -import shapely.geometry as sg import numpy as np import pandas as pd - +import shapely.geometry as sg from geopandas.array import from_shapely -from hypothesis import given, example, strategies as st +from hypothesis import example, given +from hypothesis import strategies as st + +from ..strategies import ( + hyp_settings, + st_line_array, + st_multipoint_array, + st_multipolygon_array, + st_point_array, + st_polygon_array, +) from spatialpandas import GeoSeries from spatialpandas.geometry import ( - PointArray, Point, MultiPoint, Line, MultiLine, Polygon, - MultiPolygon + Line, + MultiLine, + MultiPoint, + MultiPolygon, + Point, + PointArray, + Polygon, ) -from ..strategies import ( - st_point_array, st_multipoint_array, hyp_settings, st_line_array, - st_polygon_array, st_multipolygon_array -) @given(st_point_array(), st_point_array(min_size=1, max_size=1)) @hyp_settings diff --git a/spatialpandas/tests/geometry/strategies.py b/spatialpandas/tests/geometry/strategies.py index 7d4d4af..ac810e9 100644 --- a/spatialpandas/tests/geometry/strategies.py +++ b/spatialpandas/tests/geometry/strategies.py @@ -1,15 +1,19 @@ import numpy as np from geopandas import GeoSeries from geopandas.array import from_shapely -from hypothesis import strategies as st, settings +from hypothesis import HealthCheck, settings +from hypothesis import strategies as st from hypothesis.extra.numpy import arrays from scipy.spatial.qhull import Voronoi from shapely import geometry as sg from shapely.affinity import scale, translate from shapely.ops import cascaded_union, polygonize - -hyp_settings = settings(deadline=None, max_examples=500) +hyp_settings = settings( + deadline=None, + max_examples=500, + suppress_health_check=[HealthCheck.too_slow], +) coord = st.floats( allow_infinity=False, allow_nan=False, max_value=1000, min_value=-1000 diff --git a/spatialpandas/tests/geometry/test_construction.py b/spatialpandas/tests/geometry/test_construction.py index cd52278..7b418ce 100644 --- a/spatialpandas/tests/geometry/test_construction.py +++ b/spatialpandas/tests/geometry/test_construction.py @@ -1,6 +1,7 @@ -from spatialpandas.geometry import PointArray import numpy as np +from spatialpandas.geometry import PointArray + def test_construct_pointarray_interleaved(): src_array = np.array([0, 1, 2, 3, 4, 5, 6, 7], dtype=np.float32) diff --git a/spatialpandas/tests/geometry/test_cx.py b/spatialpandas/tests/geometry/test_cx.py index bea7b29..b3db000 100644 --- a/spatialpandas/tests/geometry/test_cx.py +++ b/spatialpandas/tests/geometry/test_cx.py @@ -1,17 +1,26 @@ import dask.dataframe as dd - +import pytest from hypothesis import given -from pandas.testing import assert_series_equal, assert_frame_equal -from spatialpandas import GeoSeries, GeoDataFrame -from spatialpandas.geometry import ( - MultiPointArray, LineArray, MultiLineArray, PolygonArray, - MultiPolygonArray, PointArray -) +from pandas.testing import assert_frame_equal, assert_series_equal from .strategies import ( - st_multipoint_array, st_bounds, st_line_array, st_multiline_array, - st_polygon_array, st_multipolygon_array, hyp_settings, - st_point_array + hyp_settings, + st_bounds, + st_line_array, + st_multiline_array, + st_multipoint_array, + st_multipolygon_array, + st_point_array, + st_polygon_array, +) +from spatialpandas import GeoDataFrame, GeoSeries +from spatialpandas.geometry import ( + LineArray, + MultiLineArray, + MultiPointArray, + MultiPolygonArray, + PointArray, + PolygonArray, ) @@ -19,6 +28,7 @@ def get_slices(v0, v1): return [slice(v0, v1), slice(None, v1), slice(v0, None), slice(None, None)] +@pytest.mark.slow @given(st_point_array(min_size=1, geoseries=True), st_bounds(orient=True)) @hyp_settings def test_point_cx_selection(gp_point, rect): @@ -30,6 +40,7 @@ def test_point_cx_selection(gp_point, rect): assert all(expected == result) +@pytest.mark.slow @given(st_multipoint_array(min_size=1, geoseries=True), st_bounds(orient=True)) @hyp_settings def test_multipoint_cx_selection(gp_multipoint, rect): @@ -41,6 +52,7 @@ def test_multipoint_cx_selection(gp_multipoint, rect): assert all(expected == result) +@pytest.mark.slow @given(st_line_array(min_size=1, geoseries=True), st_bounds(orient=True)) @hyp_settings def test_line_cx_selection(gp_line, rect): @@ -52,6 +64,7 @@ def test_line_cx_selection(gp_line, rect): assert all(expected == result) +@pytest.mark.slow @given(st_multiline_array(min_size=1, geoseries=True), st_bounds(orient=True)) @hyp_settings def test_multiline_cx_selection(gp_multiline, rect): @@ -63,6 +76,7 @@ def test_multiline_cx_selection(gp_multiline, rect): assert all(expected == result) +@pytest.mark.slow @given( st_polygon_array(min_size=1, geoseries=True), st_bounds( @@ -79,6 +93,7 @@ def test_polygon_cx_selection(gp_polygon, rect): assert all(expected == result) +@pytest.mark.slow @given( st_multipolygon_array(min_size=1, geoseries=True), st_bounds( @@ -110,6 +125,7 @@ def test_multipoint_cx_series_selection(gp_multipoint, rect): assert_series_equal(expected, result, obj='GeoSeries') +@pytest.mark.slow @given(st_multipoint_array(min_size=6, geoseries=True), st_bounds(orient=True)) @hyp_settings def test_multipoint_cx_series_selection_dask(gp_multipoint, rect): @@ -134,6 +150,7 @@ def test_multipoint_cx_frame_selection(gp_multipoint, rect): assert_frame_equal(expected, result, obj='GeoDataFrame') +@pytest.mark.slow @given(st_multipoint_array(min_size=6, geoseries=True), st_bounds(orient=True)) @hyp_settings def test_multipoint_cx_frame_selection_dask(gp_multipoint, rect): diff --git a/spatialpandas/tests/geometry/test_geometry.py b/spatialpandas/tests/geometry/test_geometry.py index f655f4a..df8154a 100644 --- a/spatialpandas/tests/geometry/test_geometry.py +++ b/spatialpandas/tests/geometry/test_geometry.py @@ -1,7 +1,17 @@ import numpy as np + from spatialpandas.geometry import ( - Point, PointArray, MultiPoint, MultiPointArray, Line, LineArray, - Polygon, PolygonArray, Ring, MultiPolygon, MultiPolygonArray + Line, + LineArray, + MultiPoint, + MultiPointArray, + MultiPolygon, + MultiPolygonArray, + Point, + PointArray, + Polygon, + PolygonArray, + Ring, ) unit_square_cw = np.array([1, 1, 1, 2, 2, 2, 2, 1, 1, 1], dtype='float64') diff --git a/spatialpandas/tests/geometry/test_to_geopandas.py b/spatialpandas/tests/geometry/test_to_geopandas.py index edd5b89..66663e0 100644 --- a/spatialpandas/tests/geometry/test_to_geopandas.py +++ b/spatialpandas/tests/geometry/test_to_geopandas.py @@ -1,12 +1,18 @@ +import pytest from hypothesis import given from pandas.testing import assert_series_equal -from spatialpandas import GeoSeries from .strategies import ( - st_multipoint_array, st_line_array, st_multiline_array, - st_ring_array, st_polygon_array, st_multipolygon_array, - hyp_settings, st_point_array + hyp_settings, + st_line_array, + st_multiline_array, + st_multipoint_array, + st_multipolygon_array, + st_point_array, + st_polygon_array, + st_ring_array, ) +from spatialpandas import GeoSeries @given(st_point_array(geoseries=True)) @@ -44,6 +50,7 @@ def test_multiline_array_to_geopandas(gp_multiline): assert_series_equal(result, gp_multiline) +@pytest.mark.slow @given(st_polygon_array(geoseries=True)) @hyp_settings def test_polygon_array_to_geopandas(gp_polygon): @@ -51,9 +58,9 @@ def test_polygon_array_to_geopandas(gp_polygon): assert_series_equal(result, gp_polygon) +@pytest.mark.slow @given(st_multipolygon_array(geoseries=True)) @hyp_settings def test_multipolygon_array_to_geopandas(gp_multipolygon): result = GeoSeries(gp_multipolygon, dtype='multipolygon').to_geopandas() assert_series_equal(result, gp_multipolygon) - diff --git a/spatialpandas/tests/spatialindex/test_hilbert_curve.py b/spatialpandas/tests/spatialindex/test_hilbert_curve.py index 59bc989..421cd03 100644 --- a/spatialpandas/tests/spatialindex/test_hilbert_curve.py +++ b/spatialpandas/tests/spatialindex/test_hilbert_curve.py @@ -1,9 +1,9 @@ -from hypothesis import given -import hypothesis.strategies as st -from hypothesis import settings from itertools import product + +import hypothesis.strategies as st import numpy as np import pytest +from hypothesis import given, settings try: from hilbertcurve.hilbertcurve import HilbertCurve @@ -12,8 +12,11 @@ # ### hypothesis settings ### from spatialpandas.spatialindex.hilbert_curve import ( - coordinates_from_distances, distances_from_coordinates, - distance_from_coordinate, coordinate_from_distance) + coordinate_from_distance, + coordinates_from_distances, + distance_from_coordinate, + distances_from_coordinates, +) hyp_settings = settings(deadline=None) diff --git a/spatialpandas/tests/spatialindex/test_rtree.py b/spatialpandas/tests/spatialindex/test_rtree.py index 43f5431..78a6b2c 100644 --- a/spatialpandas/tests/spatialindex/test_rtree.py +++ b/spatialpandas/tests/spatialindex/test_rtree.py @@ -1,10 +1,12 @@ -from hypothesis import given +import pickle + import hypothesis.strategies as st -from hypothesis import settings -from hypothesis.extra.numpy import arrays import numpy as np +import pytest +from hypothesis import given, settings +from hypothesis.extra.numpy import arrays + from spatialpandas.spatialindex import HilbertRtree -import pickle # ### hypothesis settings ### hyp_settings = settings(deadline=None) @@ -169,6 +171,7 @@ def test_rtree_intersects_none(bounds_array, page_size): assert intersected == set() +@pytest.mark.slow @given(st_bounds_array(), st_page_size) @hyp_settings def test_rtree_covers_overlaps_input_bounds(bounds_array, page_size): diff --git a/spatialpandas/tests/test_dask_autoimport.py b/spatialpandas/tests/test_dask_autoimport.py index 156a6b1..c104b5c 100644 --- a/spatialpandas/tests/test_dask_autoimport.py +++ b/spatialpandas/tests/test_dask_autoimport.py @@ -1,7 +1,8 @@ -import spatialpandas as sp import dask.dataframe as dd import pandas as pd +import spatialpandas as sp + def test_dask_registration(): ddf = dd.from_pandas(sp.GeoDataFrame({ @@ -10,4 +11,3 @@ def test_dask_registration(): 'v': [1, 2, 3] }), npartitions=3) assert isinstance(ddf, sp.dask.DaskGeoDataFrame) - diff --git a/spatialpandas/tests/test_fixedextensionarray.py b/spatialpandas/tests/test_fixedextensionarray.py index 273d8ba..cad0e58 100644 --- a/spatialpandas/tests/test_fixedextensionarray.py +++ b/spatialpandas/tests/test_fixedextensionarray.py @@ -1,5 +1,6 @@ import pandas.tests.extension.base as eb import pytest + from spatialpandas.geometry import PointArray, PointDtype diff --git a/spatialpandas/tests/test_geodataframe.py b/spatialpandas/tests/test_geodataframe.py index 360e734..648bda8 100644 --- a/spatialpandas/tests/test_geodataframe.py +++ b/spatialpandas/tests/test_geodataframe.py @@ -1,14 +1,15 @@ -from spatialpandas import GeoDataFrame, GeoSeries -import pandas as pd from collections import OrderedDict -import pytest -import dask.dataframe as dd -import dask -import spatialpandas as sp +import dask +import dask.dataframe as dd import geopandas as gp +import pandas as pd +import pytest import shapely.geometry as sg +import spatialpandas as sp +from spatialpandas import GeoDataFrame, GeoSeries + dask.config.set(scheduler="single-threaded") diff --git a/spatialpandas/tests/test_listextensionarray.py b/spatialpandas/tests/test_listextensionarray.py index 5373ac9..88d19f2 100644 --- a/spatialpandas/tests/test_listextensionarray.py +++ b/spatialpandas/tests/test_listextensionarray.py @@ -1,5 +1,6 @@ import pandas.tests.extension.base as eb import pytest + from spatialpandas.geometry import LineArray, LineDtype diff --git a/spatialpandas/tests/test_parquet.py b/spatialpandas/tests/test_parquet.py index 0296d3e..282e43a 100644 --- a/spatialpandas/tests/test_parquet.py +++ b/spatialpandas/tests/test_parquet.py @@ -3,23 +3,25 @@ import hypothesis.strategies as hs import numpy as np import pandas as pd - -from hypothesis import given, settings, HealthCheck, Phase, Verbosity - -from spatialpandas import GeoSeries, GeoDataFrame -from spatialpandas.dask import DaskGeoDataFrame -from spatialpandas.io import ( - to_parquet, read_parquet, read_parquet_dask -) +import pytest +from hypothesis import HealthCheck, Phase, Verbosity, given, settings from .geometry.strategies import ( - st_multipoint_array, st_multiline_array, st_point_array, st_bounds + st_bounds, + st_multiline_array, + st_multipoint_array, + st_point_array, ) +from spatialpandas import GeoDataFrame, GeoSeries +from spatialpandas.dask import DaskGeoDataFrame +from spatialpandas.io import read_parquet, read_parquet_dask, to_parquet dask.config.set(scheduler="single-threaded") hyp_settings = settings( - deadline=None, max_examples=100, suppress_health_check=[HealthCheck.too_slow] + deadline=None, + max_examples=100, + suppress_health_check=[HealthCheck.too_slow], ) @@ -161,6 +163,7 @@ def test_pack_partitions(gp_multipoint, gp_multiline): np.testing.assert_equal(expected_distances, hilbert_distances) +@pytest.mark.slow @given( gp_multipoint=st_multipoint_array(min_size=60, max_size=100, geoseries=True), gp_multiline=st_multiline_array(min_size=60, max_size=100, geoseries=True), @@ -235,6 +238,7 @@ def test_pack_partitions_to_parquet(gp_multipoint, gp_multiline, ) +@pytest.mark.slow @given( gp_multipoint1=st_multipoint_array(min_size=10, max_size=40, geoseries=True), gp_multiline1=st_multiline_array(min_size=10, max_size=40, geoseries=True), @@ -303,6 +307,7 @@ def test_pack_partitions_to_parquet_glob(gp_multipoint1, gp_multiline1, assert ddf_globbed.geometry.name == 'lines' +@pytest.mark.slow @given( gp_multipoint1=st_multipoint_array(min_size=10, max_size=40, geoseries=True), gp_multiline1=st_multiline_array(min_size=10, max_size=40, geoseries=True), diff --git a/spatialpandas/tests/tools/test_sjoin.py b/spatialpandas/tests/tools/test_sjoin.py index f758b22..57390ed 100644 --- a/spatialpandas/tests/tools/test_sjoin.py +++ b/spatialpandas/tests/tools/test_sjoin.py @@ -4,22 +4,20 @@ import numpy as np import pandas as pd import pytest - from hypothesis import given import spatialpandas as sp -from spatialpandas import GeoDataFrame -from spatialpandas.dask import DaskGeoDataFrame - from ..geometry.strategies import st_point_array, st_polygon_array from ..test_parquet import hyp_settings +from spatialpandas import GeoDataFrame +from spatialpandas.dask import DaskGeoDataFrame try: - from geopandas._compat import USE_PYGEOS, HAS_RTREE + from geopandas._compat import HAS_RTREE, USE_PYGEOS gpd_spatialindex = USE_PYGEOS or HAS_RTREE except: try: - import rtree # noqa + import rtree # noqa gpd_spatialindex = rtree except Exception: gpd_spatialindex = False diff --git a/spatialpandas/tools/sjoin.py b/spatialpandas/tools/sjoin.py index 52843fe..b97f4b4 100644 --- a/spatialpandas/tools/sjoin.py +++ b/spatialpandas/tools/sjoin.py @@ -43,9 +43,9 @@ def sjoin( Returns: GeoDataFrame or DaskGeoDataFrame (same type as left_df argument) """ - from spatialpandas import GeoDataFrame + from .. import GeoDataFrame try: - from spatialpandas.dask import DaskGeoDataFrame + from ..dask import DaskGeoDataFrame except ImportError: DaskGeoDataFrame = type(None) @@ -137,7 +137,7 @@ def _sjoin_pandas_pandas( left_df, right_df, how="inner", op="intersects", lsuffix="left", rsuffix="right" ): - from spatialpandas import GeoDataFrame + from .. import GeoDataFrame # Record original index name(s), generate new index name(s), reset index column(s) original_right_df = right_df