Giter VIP home page Giter VIP logo

tesspy's People

Contributors

jgaboardi avatar johamann avatar siavash-saki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

tesspy's Issues

[JOSS] State of the field / References

xref openjournals/joss-reviews#4620 #12

State of the field

[JOSS] Test suite failing

xref openjournals/joss-reviews#4620

I ran tests with pytest locally twice, each time failed with different output.The test suite fails with the following output:

Test run 1
========================================================================= test session starts =========================================================================
platform darwin -- Python 3.10.5, pytest-7.1.2, pluggy-1.0.0 -- /Users/user/miniconda3/envs/py310_tesspy/bin/python
cachedir: .pytest_cache
rootdir: /Users/user/tesspy
plugins: cov-3.0.0
collected 25 items                                                                                                                                                    

tests/test_poi_data.py::test_osm_primary_features PASSED                                                                                                        [  4%]
tests/test_poi_data.py::test_create_overpass_query_string PASSED                                                                                                [  8%]
tests/test_poi_data.py::test_get_poi_data PASSED                                                                                                                [ 12%]
tests/test_poi_data.py::test_osm_highway_types PASSED                                                                                                           [ 16%]
tests/test_poi_data.py::test_create_custom_filter PASSED                                                                                                        [ 20%]
tests/test_poi_data.py::test_get_road_network FAILED                                                                                                            [ 24%]
tests/test_tessellation.py::test_squares PASSED                                                                                                                 [ 28%]
tests/test_tessellation.py::test_hexagons PASSED                                                                                                                [ 32%]
tests/test_tessellation.py::test_adaptive_squares PASSED                                                                                                        [ 36%]
tests/test_tessellation.py::test_voronoi FAILED                                                                                                                 [ 40%]
tests/test_tessellation.py::test_city_blocks Fatal Python error: Segmentation fault

Current thread 0x00000001169ff600 (most recent call first):
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/shapely/ops.py", line 160 in unary_union
  File "/Users/user/tesspy/tesspy/tessellation_functions.py", line 422 in get_rest_polygon
  File "/Users/user/tesspy/tesspy/tessellation.py", line 615 in city_blocks
  File "/Users/user/tesspy/tests/test_tessellation.py", line 84 in test_city_blocks
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/python.py", line 192 in pytest_pyfunc_call
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/python.py", line 1761 in runtest
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/runner.py", line 166 in pytest_runtest_call
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/runner.py", line 259 in <lambda>
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/runner.py", line 338 in from_call
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/runner.py", line 258 in call_runtest_hook
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/runner.py", line 219 in call_and_report
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/runner.py", line 130 in runtestprotocol
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/runner.py", line 111 in pytest_runtest_protocol
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/main.py", line 347 in pytest_runtestloop
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/main.py", line 322 in _main
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/main.py", line 268 in wrap_session
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/main.py", line 315 in pytest_cmdline_main
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_callers.py", line 39 in _multicall
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_manager.py", line 80 in _hookexec
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pluggy/_hooks.py", line 265 in __call__
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/config/__init__.py", line 164 in main
  File "/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/_pytest/config/__init__.py", line 187 in console_main
  File "/Users/user/miniconda3/envs/py310_tesspy/bin/pytest", line 11 in <module>

Extension modules: numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, pandas._libs.tslibs.dtypes, pandas._libs.tslibs.base, pandas._libs.tslibs.np_datetime, pandas._libs.tslibs.nattype, pandas._libs.tslibs.timezones, pandas._libs.tslibs.ccalendar, pandas._libs.tslibs.tzconversion, pandas._libs.tslibs.strptime, pandas._libs.tslibs.fields, pandas._libs.tslibs.timedeltas, pandas._libs.tslibs.timestamps, pandas._libs.properties, pandas._libs.tslibs.offsets, pandas._libs.tslibs.parsing, pandas._libs.tslibs.conversion, pandas._libs.tslibs.period, pandas._libs.tslibs.vectorized, pandas._libs.ops_dispatch, pandas._libs.missing, pandas._libs.hashtable, pandas._libs.algos, pandas._libs.interval, pandas._libs.tslib, pandas._libs.lib, pandas._libs.hashing, pandas._libs.ops, pandas._libs.arrays, pandas._libs.index, pandas._libs.join, pandas._libs.sparse, pandas._libs.reduction, pandas._libs.indexing, pandas._libs.internals, pandas._libs.writers, pandas._libs.window.aggregations, pandas._libs.window.indexers, pandas._libs.reshape, pandas._libs.groupby, pandas._libs.testing, pandas._libs.parsers, pandas._libs.json, pyproj._compat, pyproj._datadir, pyproj._network, pyproj._geod, pyproj.list, pyproj._crs, pyproj._transformer, pyproj.database, pyproj._sync, pygeos.lib, pygeos._geos, pygeos._geometry, shapely.speedups._speedups, sklearn.__check_build._check_build, scipy._lib._ccallback_c, scipy.sparse._sparsetools, scipy.sparse._csparsetools, scipy.sparse.linalg._isolve._iterative, scipy.linalg._fblas, scipy.linalg._flapack, scipy.linalg._cythonized_array_utils, scipy.linalg._flinalg, scipy.linalg._solve_toeplitz, scipy.linalg._matfuncs_sqrtm_triu, scipy.linalg.cython_lapack, scipy.linalg.cython_blas, scipy.linalg._matfuncs_expm, scipy.linalg._decomp_update, scipy.sparse.linalg._dsolve._superlu, scipy.sparse.linalg._eigen.arpack._arpack, scipy.sparse.csgraph._tools, scipy.sparse.csgraph._shortest_path, scipy.sparse.csgraph._traversal, scipy.sparse.csgraph._min_spanning_tree, scipy.sparse.csgraph._flow, scipy.sparse.csgraph._matching, scipy.sparse.csgraph._reordering, sklearn.utils.murmurhash, psutil._psutil_osx, psutil._psutil_posix, numpy.linalg.lapack_lite, scipy.spatial._ckdtree, scipy._lib.messagestream, scipy.spatial._qhull, scipy.spatial._voronoi, scipy.spatial._distance_wrap, scipy.spatial._hausdorff, scipy.special._ufuncs_cxx, scipy.special._ufuncs, scipy.special._specfun, scipy.special._comb, scipy.special._ellip_harm_2, scipy.spatial.transform._rotation, scipy.ndimage._nd_image, _ni_label, scipy.ndimage._ni_label, scipy.optimize._minpack2, scipy.optimize._group_columns, scipy.optimize._trlib._trlib, scipy.optimize._lbfgsb, _moduleTNC, scipy.optimize._moduleTNC, scipy.optimize._cobyla, scipy.optimize._slsqp, scipy.optimize._minpack, scipy.optimize._lsq.givens_elimination, scipy.optimize._zeros, scipy.optimize.__nnls, scipy.optimize._highs.cython.src._highs_wrapper, scipy.optimize._highs._highs_wrapper, scipy.optimize._highs.cython.src._highs_constants, scipy.optimize._highs._highs_constants, scipy.linalg._interpolative, scipy.optimize._bglu_dense, scipy.optimize._lsap, scipy.optimize._direct, scipy.integrate._odepack, scipy.integrate._quadpack, scipy.integrate._vode, scipy.integrate._dop, scipy.integrate._lsoda, scipy.special.cython_special, scipy.stats._stats, beta_ufunc, scipy.stats._boost.beta_ufunc, binom_ufunc, scipy.stats._boost.binom_ufunc, nbinom_ufunc, scipy.stats._boost.nbinom_ufunc, hypergeom_ufunc, scipy.stats._boost.hypergeom_ufunc, ncf_ufunc, scipy.stats._boost.ncf_ufunc, scipy.interpolate._fitpack, scipy.interpolate.dfitpack, scipy.interpolate._bspl, scipy.interpolate._ppoly, scipy.interpolate.interpnd, scipy.interpolate._rbfinterp_pythran, scipy.stats._biasedurn, scipy.stats._levy_stable.levyst, scipy._lib._uarray._uarray, scipy.stats._hypotests_pythran, scipy.stats._statlib, scipy.stats._mvn, scipy.stats._sobol, scipy.stats._qmc_cy, scipy.stats._unuran.unuran_wrapper, sklearn.utils._openmp_helpers, sklearn.utils._logistic_sigmoid, sklearn.utils.sparsefuncs_fast, sklearn.preprocessing._csr_polynomial_expansion, sklearn.utils._typedefs, sklearn.utils._readonly_array_wrapper, sklearn.metrics._dist_metrics, sklearn.metrics.cluster._expected_mutual_info_fast, sklearn.utils._cython_blas, sklearn.utils._heap, sklearn.utils._sorting, sklearn.utils._vector_sentinel, sklearn.metrics._pairwise_distances_reduction, sklearn.metrics._pairwise_fast, sklearn.neighbors._partition_nodes, sklearn.neighbors._ball_tree, sklearn.neighbors._kd_tree, sklearn.decomposition._cdnmf_fast, sklearn.utils._random, sklearn.utils._seq_dataset, sklearn.utils.arrayfuncs, sklearn.linear_model._cd_fast, sklearn._loss._loss, sklearn.utils._weight_vector, sklearn.linear_model._sgd_fast, sklearn.linear_model._sag_fast, sklearn.svm._libsvm, sklearn.svm._liblinear, sklearn.svm._libsvm_sparse, sklearn.decomposition._online_lda_fast, sklearn._isotonic, sklearn.manifold._utils, sklearn.tree._utils, sklearn.tree._tree, sklearn.tree._splitter, sklearn.tree._criterion, sklearn.neighbors._quad_tree, sklearn.manifold._barnes_hut_tsne, sklearn.cluster._k_means_common, sklearn.cluster._k_means_minibatch, sklearn.cluster._k_means_lloyd, sklearn.cluster._k_means_elkan, sklearn.utils._fast_dict, sklearn.cluster._hierarchical_fast, sklearn.cluster._dbscan_inner, hdbscan.dist_metrics, hdbscan._hdbscan_linkage, hdbscan._hdbscan_tree, hdbscan._hdbscan_reachability, hdbscan._hdbscan_boruvka, scipy.cluster._vq, scipy.cluster._hierarchy, scipy.cluster._optimal_leaf_ordering, hdbscan._prediction_utils, h3._cy.util, h3._cy.cells, h3._cy.edges, h3._cy.geo, h3._cy.to_multipoly, matplotlib._c_internal_utils, PIL._imaging, matplotlib._path, kiwisolver._cext, matplotlib._image, _cffi_backend, unicodedata2, rasterio._version, rasterio._err, rasterio._filepath, rasterio._env, rasterio._transform, rasterio._base, rasterio.crs, rasterio._features, rasterio._warp, rasterio._io, osgeo._gdal, osgeo._gdalconst, osgeo._ogr, osgeo._osr, markupsafe._speedups (total: 243)
Segmentation fault: 11
Test run 2
========================================================================= test session starts =========================================================================
platform darwin -- Python 3.10.5, pytest-7.1.2, pluggy-1.0.0 -- /Users/user/miniconda3/envs/py_tesspy/bin/python
cachedir: .pytest_cache
rootdir: /Users/user/tesspy
plugins: cov-3.0.0
collected 25 items                                                                                                                                                    

tests/test_poi_data.py::test_osm_primary_features PASSED                                                                                                        [  4%]
tests/test_poi_data.py::test_create_overpass_query_string PASSED                                                                                                [  8%]
tests/test_poi_data.py::test_get_poi_data PASSED                                                                                                                [ 12%]
tests/test_poi_data.py::test_osm_highway_types PASSED                                                                                                           [ 16%]
tests/test_poi_data.py::test_create_custom_filter PASSED                                                                                                        [ 20%]
tests/test_poi_data.py::test_get_road_network FAILED                                                                                                            [ 24%]
tests/test_tessellation.py::test_squares PASSED                                                                                                                 [ 28%]
tests/test_tessellation.py::test_hexagons PASSED                                                                                                                [ 32%]
tests/test_tessellation.py::test_adaptive_squares PASSED                                                                                                        [ 36%]
tests/test_tessellation.py::test_voronoi FAILED                                                                                                                 [ 40%]
tests/test_tessellation.py::test_city_blocks PASSED                                                                                                             [ 44%]
tests/test_tessellation.py::test_new_shapely PASSED                                                                                                             [ 48%]
tests/test_tessellation.py::test_index_methods PASSED                                                                                                           [ 52%]
tests/test_tessellation.py::test_count_lgu_function_short_version FAILED                                                                                        [ 56%]
tests/test_tessellation.py::test_count_lgu_function_different_city_inputs FAILED                                                                                [ 60%]
tests/test_tessellation.py::test_count_lgu_function_invalid_inputs_city PASSED                                                                                  [ 64%]
tests/test_tessellation.py::test_count_lgu_function_invalid_inputs_gdf PASSED                                                                                   [ 68%]
tests/test_tessellation.py::test_count_lgu_function_invalid_inputs_method PASSED                                                                                [ 72%]
tests/test_tessellation.py::test_count_lgu_function_invalid_inputs_poi PASSED                                                                                   [ 76%]
tests/test_tessellation.py::test_count_lgu_function_different_poi FAILED                                                                                        [ 80%]
tests/test_tessellation.py::test_count_lgu_function FAILED                                                                                                      [ 84%]
tests/test_tessellation.py::test_poi_collection FAILED                                                                                                          [ 88%]
tests/test_tessellation_functions.py::test_count_poi FAILED                                                                                                     [ 92%]
tests/test_tessellation_functions.py::test_get_adaptive_squares FAILED                                                                                          [ 96%]
tests/test_tessellation_functions.py::test_split_linestring FAILED                                                                                              [100%]

============================================================================== FAILURES ===============================================================================
________________________________________________________________________ test_get_road_network ________________________________________________________________________

    def test_get_road_network():
        city = Tessellation("Johannesburg").get_polygon()
        split_road_data = RoadData(city, split_roads=True, verbose=True).get_road_network()
        road_data = RoadData(city, split_roads=False, verbose=True).get_road_network()
        assert len(split_road_data) > 0
        assert len(road_data) > 0
>       assert len(split_road_data) > len(road_data)
E       assert 170 > 170
E        +  where 170 = len(                                            osmid     ref  ... lanes maxspeed\nu          v          key                                  ...               \n87962180   88830454   0                  10429208  CR 391  ...   NaN      NaN\n           89202585   0                  10429208  CR 391  ...   NaN      NaN\n           5762605634 0                 608171338     NaN  ...   NaN      NaN\n88830454   88845187   0                  80565315  CR 391  ...   NaN      NaN\n           564390667  0                  10408441     NaN  ...   NaN      NaN\n...                                           ...     ...  ...   ...      ...\n5764378908 5764378910 0                 608431386     NaN  ...   NaN      NaN\n           5764378921 0    [608431390, 608431391]     NaN  ...   NaN      NaN\n5764378922 5764378921 0                 608431391     NaN  ...   NaN      NaN\n           5764378925 0                 608431397     NaN  ...   NaN      NaN\n5764378921 5764378925 0                 608431393     NaN  ...   NaN      NaN\n\n[170 rows x 10 columns])
E        +  and   170 = len(                                            osmid     ref  ... lanes maxspeed\nu          v          key                                  ...               \n87962180   88830454   0                  10429208  CR 391  ...   NaN      NaN\n           89202585   0                  10429208  CR 391  ...   NaN      NaN\n           5762605634 0                 608171338     NaN  ...   NaN      NaN\n88830454   88845187   0                  80565315  CR 391  ...   NaN      NaN\n           564390667  0                  10408441     NaN  ...   NaN      NaN\n...                                           ...     ...  ...   ...      ...\n5764378908 5764378910 0                 608431386     NaN  ...   NaN      NaN\n           5764378921 0    [608431390, 608431391]     NaN  ...   NaN      NaN\n5764378922 5764378921 0                 608431391     NaN  ...   NaN      NaN\n           5764378925 0                 608431397     NaN  ...   NaN      NaN\n5764378921 5764378925 0                 608431393     NaN  ...   NaN      NaN\n\n[170 rows x 10 columns])

tests/test_poi_data.py:90: AssertionError
------------------------------------------------------------------------ Captured stdout call -------------------------------------------------------------------------
Selected highway type(s) are ['highway'~'motorway|trunk|primary|secondary|tertiary|residential|unclassified|motorway_link|trunk_link|primary_link|secondary_link|living_street|pedestrian|track|bus_guideway|footway|path|service|cycleway']
Collecting road network data...
Collected data has 170 street segments.
Selected highway type(s) are ['highway'~'motorway|trunk|primary|secondary|tertiary|residential|unclassified|motorway_link|trunk_link|primary_link|secondary_link|living_street|pedestrian|track|bus_guideway|footway|path|service|cycleway']
Collecting road network data...
Collected data has 170 street segments.
____________________________________________________________________________ test_voronoi _____________________________________________________________________________

    def test_voronoi():
        city = Tessellation("Buenos Aires")
        city_km = city.voronoi(cluster_algo="k-means",
                               poi_categories=["amenity"],
                               timeout=60,
                               n_polygons=300,
                               verbose=False)
>       assert len(city_km) <= 300
E       assert 311 <= 300
E        +  where 311 = len(       voronoi_id                                           geometry\n0      voronoiID0  POLYGON ((-58.39767 -34.65513, -58.39347 -34.6...\n1      voronoiID1  POLYGON ((-58.46076 -34.56834, -58.45698 -34.5...\n2      voronoiID2  POLYGON ((-58.52287 -34.64816, -58.52391 -34.6...\n3      voronoiID3  POLYGON ((-58.39650 -34.58418, -58.39398 -34.5...\n4      voronoiID4  POLYGON ((-58.46027 -34.63412, -58.45995 -34.6...\n..            ...                                                ...\n306  voronoiID306  POLYGON ((-58.36622 -34.59270, -58.36704 -34.5...\n307  voronoiID307  POLYGON ((-58.36935 -34.57830, -58.36795 -34.5...\n308  voronoiID308  POLYGON ((-58.41963 -34.59848, -58.41803 -34.6...\n309  voronoiID309  POLYGON ((-58.39687 -34.63459, -58.39851 -34.6...\n310  voronoiID310  POLYGON ((-58.38743 -34.58682, -58.38620 -34.5...\n\n[311 rows x 2 columns])

tests/test_tessellation.py:68: AssertionError
------------------------------------------------------------------------ Captured stdout call -------------------------------------------------------------------------
MultiPolygon found. Splitting it up...
________________________________________________________________ test_count_lgu_function_short_version ________________________________________________________________

    def test_count_lgu_function_short_version():
        city = Tessellation("Paris")
        poi_categories2 = ["amenity", "building"]
    
        df_squares = city.squares(resolution=14)
>       df_squares = count_poi_per_tile(city, df_squares, method="squares", poi_categories=poi_categories2)

tests/test_tessellation.py:118: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

city = <tesspy.tessellation.Tessellation object at 0x16c46b100>
gdf =                                              geometry         quadkey
0   POLYGON ((2.24121 48.86471, 2.24121 48.87917...83580, ...  12022001110220
61  POLYGON ((2.48291 48.80686, 2.48291 48.82133, ...  12022001110222

[62 rows x 2 columns]
method = 'squares', poi_categories = ['amenity', 'building'], timeout = 120

    def count_poi_per_tile(city,
                           gdf,
                           method,
                           poi_categories=['amenity', 'building'],
                           timeout=120):
        """
        Counts different POI-categories per tile. For each POI-categories an additional column is added to the Tessellation
        GeoDataFrame (gdf). After counting each POI-category the final Tessellation GeoDataFrame with the additional count-
        columns is returned.
    
        Parameters
        ----------
        city: Tessellation object or string of the underlying city
        gdf : GeoDataFrame of the Tessellation for the underlying city
        method: method used to tessellate the city polygon. It's used to create the index, the POI and Tessellation-datasets
            will be joined on
        poi_categories: POI which will be count per tile. These POI may differ from the POI used to create the tessellation
        timeout: time to wait for OSM to return POI data
    
        Returns
        --------
        gdf : GeoDataFrame - Tessellation GeoDataFrame with additional columns (count_poi-columns are added)
        """
    
        if type(city) == str:
            city = Tessellation(city)
        # Only str input for now
        # elif type(city) == Tessellation:
        #    city = city
        # elif type(city) == tesspy.tessellation.Tessellation:
        #    city = city
        else:
>           raise ValueError('Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct or String')
E           ValueError: Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct or String

tesspy/tessellation.py:135: ValueError
____________________________________________________________ test_count_lgu_function_different_city_inputs ____________________________________________________________

    def test_count_lgu_function_different_city_inputs():
        city = Tessellation("Paris")
        city_2 = "Paris"
        poi_categories2 = ["amenity", "building"]
    
        df_squares = city.squares(resolution=14)
>       df_squares = count_poi_per_tile(city, df_squares, method="squares", poi_categories=poi_categories2)

tests/test_tessellation.py:131: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

city = <tesspy.tessellation.Tessellation object at 0x16dbc5ed0>
gdf =                                              geometry         quadkey
0   POLYGON ((2.24121 48.86471, 2.24121 48.87917...83580, ...  12022001110220
61  POLYGON ((2.48291 48.80686, 2.48291 48.82133, ...  12022001110222

[62 rows x 2 columns]
method = 'squares', poi_categories = ['amenity', 'building'], timeout = 120

    def count_poi_per_tile(city,
                           gdf,
                           method,
                           poi_categories=['amenity', 'building'],
                           timeout=120):
        """
        Counts different POI-categories per tile. For each POI-categories an additional column is added to the Tessellation
        GeoDataFrame (gdf). After counting each POI-category the final Tessellation GeoDataFrame with the additional count-
        columns is returned.
    
        Parameters
        ----------
        city: Tessellation object or string of the underlying city
        gdf : GeoDataFrame of the Tessellation for the underlying city
        method: method used to tessellate the city polygon. It's used to create the index, the POI and Tessellation-datasets
            will be joined on
        poi_categories: POI which will be count per tile. These POI may differ from the POI used to create the tessellation
        timeout: time to wait for OSM to return POI data
    
        Returns
        --------
        gdf : GeoDataFrame - Tessellation GeoDataFrame with additional columns (count_poi-columns are added)
        """
    
        if type(city) == str:
            city = Tessellation(city)
        # Only str input for now
        # elif type(city) == Tessellation:
        #    city = city
        # elif type(city) == tesspy.tessellation.Tessellation:
        #    city = city
        else:
>           raise ValueError('Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct or String')
E           ValueError: Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct or String

tesspy/tessellation.py:135: ValueError
________________________________________________________________ test_count_lgu_function_different_poi ________________________________________________________________

    def test_count_lgu_function_different_poi():
        city = Tessellation("Paris")
        poi_categories1 = "amenity"
        poi_categories2 = ["amenity"]
        poi_categories3 = ["amenity", "building"]
    
        df_squares1 = city.squares(resolution=14)
        df_squares2 = city.squares(resolution=14)
        df_squares3 = city.squares(resolution=14)
    
>       df_squares1 = count_poi_per_tile(city, df_squares1, method="squares", poi_categories=poi_categories1)

tests/test_tessellation.py:208: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

city = <tesspy.tessellation.Tessellation object at 0x165244c40>
gdf =                                              geometry         quadkey
0   POLYGON ((2.24121 48.86471, 2.24121 48.87917...83580, ...  12022001110220
61  POLYGON ((2.48291 48.80686, 2.48291 48.82133, ...  12022001110222

[62 rows x 2 columns]
method = 'squares', poi_categories = 'amenity', timeout = 120

    def count_poi_per_tile(city,
                           gdf,
                           method,
                           poi_categories=['amenity', 'building'],
                           timeout=120):
        """
        Counts different POI-categories per tile. For each POI-categories an additional column is added to the Tessellation
        GeoDataFrame (gdf). After counting each POI-category the final Tessellation GeoDataFrame with the additional count-
        columns is returned.
    
        Parameters
        ----------
        city: Tessellation object or string of the underlying city
        gdf : GeoDataFrame of the Tessellation for the underlying city
        method: method used to tessellate the city polygon. It's used to create the index, the POI and Tessellation-datasets
            will be joined on
        poi_categories: POI which will be count per tile. These POI may differ from the POI used to create the tessellation
        timeout: time to wait for OSM to return POI data
    
        Returns
        --------
        gdf : GeoDataFrame - Tessellation GeoDataFrame with additional columns (count_poi-columns are added)
        """
    
        if type(city) == str:
            city = Tessellation(city)
        # Only str input for now
        # elif type(city) == Tessellation:
        #    city = city
        # elif type(city) == tesspy.tessellation.Tessellation:
        #    city = city
        else:
>           raise ValueError('Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct or String')
E           ValueError: Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct or String

tesspy/tessellation.py:135: ValueError
_______________________________________________________________________ test_count_lgu_function _______________________________________________________________________

    def test_count_lgu_function():
        city = Tessellation("Paris")
        poi_categories1 = ["amenity"]
        poi_categories2 = ["amenity", "building"]
    
        df_squares = city.squares(resolution=14)
>       df_squares = count_poi_per_tile(city, df_squares, method="squares", poi_categories=poi_categories1)

tests/test_tessellation.py:226: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

city = <tesspy.tessellation.Tessellation object at 0x16fcd8250>
gdf =                                              geometry         quadkey
0   POLYGON ((2.24121 48.86471, 2.24121 48.87917...83580, ...  12022001110220
61  POLYGON ((2.48291 48.80686, 2.48291 48.82133, ...  12022001110222

[62 rows x 2 columns]
method = 'squares', poi_categories = ['amenity'], timeout = 120

    def count_poi_per_tile(city,
                           gdf,
                           method,
                           poi_categories=['amenity', 'building'],
                           timeout=120):
        """
        Counts different POI-categories per tile. For each POI-categories an additional column is added to the Tessellation
        GeoDataFrame (gdf). After counting each POI-category the final Tessellation GeoDataFrame with the additional count-
        columns is returned.
    
        Parameters
        ----------
        city: Tessellation object or string of the underlying city
        gdf : GeoDataFrame of the Tessellation for the underlying city
        method: method used to tessellate the city polygon. It's used to create the index, the POI and Tessellation-datasets
            will be joined on
        poi_categories: POI which will be count per tile. These POI may differ from the POI used to create the tessellation
        timeout: time to wait for OSM to return POI data
    
        Returns
        --------
        gdf : GeoDataFrame - Tessellation GeoDataFrame with additional columns (count_poi-columns are added)
        """
    
        if type(city) == str:
            city = Tessellation(city)
        # Only str input for now
        # elif type(city) == Tessellation:
        #    city = city
        # elif type(city) == tesspy.tessellation.Tessellation:
        #    city = city
        else:
>           raise ValueError('Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct or String')
E           ValueError: Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct or String

tesspy/tessellation.py:135: ValueError
_________________________________________________________________________ test_poi_collection _________________________________________________________________________

    def test_poi_collection():
        city = Tessellation("Frankfurt")
        poi_data_1 = POIdata(city.get_polygon(),
                             poi_categories=["aerialway"],
                             timeout=60,
>                            verbose=True).get_poi_data()

tests/test_tessellation.py:263: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <tesspy.poi_data.POIdata object at 0x181d24eb0>

    def get_poi_data(self):
        """
        sends the query to osm using the overpass API and gets the data
    
        Returns
        --------
        poi_df : pandas.DataFrame
            A dataframe containing the POI, POI type, and coordinates
        """
    
        query_string = self.create_overpass_query_string()
        request_header = "https://overpass-api.de/api/interpreter?data="
    
        if self.verbose:
            print('Getting data from OSM...')
    
        # sending the request
        # todo: polygon instead bbox??
        # resp = requests.get("https://overpass-api.de/api/interpreter", data=query_string)
        resp = requests.get(url=request_header + query_string)
        if resp.status_code == 429:
            raise RuntimeError("429 Too Many Requests:\n"
                               "You have sent multiple requests from the same "
                               "IP and passed the passed the fair use policy. "
                               "Please wait a couple of minutes and then try again.")
        elif resp.status_code == 504:
            raise RuntimeError("504 Gateway Timeout:\n"
                               "the server has already so much load that"
                               " the request cannot be executed."
                               "Please try again later")
        elif resp.status_code != 200:
            raise RuntimeError("Bad Request!")
        else:
            resp = json.loads(resp.text)
    
        if self.verbose:
            print('Creating POI DataFrame...')
    
        lst_nodes = []
        lst_ways = []
    
        generator = resp['elements']
        for item in generator:
    
            for cat in self.poi_categories:
                if cat in item['tags'].keys():
                    item[cat] = True
            if item['type'] == 'node':
                lst_nodes.append(item)
            elif item['type'] == 'way':
                item['center_latitude'] = np.mean([point['lat'] for point in item['geometry']])
                item['center_longitude'] = np.mean([point['lon'] for point in item['geometry']])
                lst_ways.append(item)
            else:
                continue
    
        if self.verbose:
            print('Cleaning POI DataFrame...')
    
        nodes_df = pd.DataFrame(lst_nodes)
        ways_df = pd.DataFrame(lst_ways)
    
        if len(nodes_df) > 0 and len(ways_df) > 0:
            if self.verbose:
                print("Joining nodes and ways")
    
            nodes_df['geometry'] = nodes_df[['lon', 'lat']].apply(lambda p: [{'lat': p['lat'],
                                                                              'lon': p['lon']}],
                                                                  axis=1)
            nodes_df = nodes_df.rename(columns={'lat': 'center_latitude',
                                                'lon': 'center_longitude'})
            nodes_df = nodes_df.drop(columns=['id'])
            ways_df = ways_df.drop(columns=['id',
                                            'bounds',
                                            'nodes'])
    
            poi_df = pd.concat([ways_df, nodes_df]).fillna(False)
    
        elif len(nodes_df) == 0 and len(ways_df) > 0:
            if self.verbose:
                print("No nodes found. Return ways only.")
    
            ways_df = ways_df.drop(columns=['id',
                                            'bounds',
                                            'nodes'])
            poi_df = ways_df.fillna(False)
    
        elif len(nodes_df) > 0 and len(ways_df) == 0:
            if self.verbose:
                print("No ways found returning nodes only")
    
            nodes_df['geometry'] = nodes_df[['lon', 'lat']]\
                                        .apply(lambda p: [{'lat': p['lat'],
                                                           'lon': p['lon']}],
                                               axis=1)
    
            nodes_df = nodes_df.rename(columns={'lat': 'center_latitude',
                                                'lon': 'center_longitude'})
            nodes_df = nodes_df.drop(columns=['id'])
            poi_df = nodes_df.fillna(False)
        else:
            raise ValueError("No POI data for the inserted poi-category/categories and area.")
    
    
        # add POI categories with no data to poi_df
        for poi_category in self.poi_categories:
            if not hasattr(poi_df, poi_category):
                poi_df[poi_category] = False
    
        # prettify poi_df by sorting columns
        first_cols = ['type',
                      'geometry',
                      'tags',
                      'center_latitude',
                      'center_longitude']
    
        second_cols = sorted(poi_df.columns.drop(first_cols))
        poi_df = poi_df[first_cols + second_cols]
        poi_df = poi_df.reset_index(drop=True)
    
        # Keep only the POI within the area
        geometry_column = [Point(coords) for coords in poi_df[['center_longitude', 'center_latitude']].values]
        poi_geo_df = gpd.GeoDataFrame(geometry = geometry_column,
                                        crs='EPSG:4326')
        area_buffered_gdf = gpd.GeoDataFrame(geometry=self.area_buffered, crs='epsg:4326')
        idx_to_keep = gpd.sjoin(poi_geo_df,
                                area_buffered_gdf,
                                predicate='within').index
        poi_df = poi_df.loc[idx_to_keep]
    
        if len(poi_df) == 0:
>           raise ValueError("No poi data found that is within the area.")
E           ValueError: No poi data found that is within the area.

tesspy/poi_data.py:286: ValueError
------------------------------------------------------------------------ Captured stdout call -------------------------------------------------------------------------
Getting data from OSM...
Creating POI DataFrame...
Cleaning POI DataFrame...
No nodes found. Return ways only.
___________________________________________________________________________ test_count_poi ____________________________________________________________________________

    def test_count_poi():
        city = Tessellation("Berlin")
        city_polygon = city.get_polygon()
        city_poi = POIdata(city_polygon, poi_categories=["leisure"], timeout=60, verbose=False).get_poi_data()
        points_geom = city_poi[['center_longitude', 'center_latitude']]\
            .apply(lambda p: Point(p['center_longitude'], p['center_latitude']), axis=1)
        tess_data = gpd.GeoDataFrame(geometry=points_geom,
                                     crs='EPSG:4326')
        city_squares = city.squares(14)
>       count1 = count_poi(city_squares, tess_data)

tests/test_tessellation_functions.py:15: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tesspy/tessellation_functions.py:54: in count_poi
    final_gdf = final_df[['quadkey',
../miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pandas/core/frame.py:3511: in __getitem__
    indexer = self.columns._get_indexer_strict(key, "columns")[1]
../miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pandas/core/indexes/base.py:5782: in _get_indexer_strict
    self._raise_if_missing(keyarr, indexer, axis_name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = Index(['quadkey', 'count', 'index', 'geometry'], dtype='object'), key = Index(['quadkey', 'count', 'geometry', 'children_id'], dtype='object')
indexer = array([ 0,  1,  3, -1]), axis_name = 'columns'

    def _raise_if_missing(self, key, indexer, axis_name: str_t) -> None:
        """
        Check that indexer can be used to return a result.
    
        e.g. at least one element was found,
        unless the list of keys was actually empty.
    
        Parameters
        ----------
        key : list-like
            Targeted labels (only used to show correct error message).
        indexer: array-like of booleans
            Indices corresponding to the key,
            (with -1 indicating not found).
        axis_name : str
    
        Raises
        ------
        KeyError
            If at least one key was requested but none was found.
        """
        if len(key) == 0:
            return
    
        # Count missing values
        missing_mask = indexer < 0
        nmissing = missing_mask.sum()
    
        if nmissing:
    
            # TODO: remove special-case; this is just to keep exception
            #  message tests from raising while debugging
            use_interval_msg = is_interval_dtype(self.dtype) or (
                is_categorical_dtype(self.dtype)
                # "Index" has no attribute "categories"  [attr-defined]
                and is_interval_dtype(
                    self.categories.dtype  # type: ignore[attr-defined]
                )
            )
    
            if nmissing == len(indexer):
                if use_interval_msg:
                    key = list(key)
                raise KeyError(f"None of [{key}] are in the [{axis_name}]")
    
            not_found = list(ensure_index(key)[missing_mask.nonzero()[0]].unique())
>           raise KeyError(f"{not_found} not in index")
E           KeyError: "['children_id'] not in index"

../miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pandas/core/indexes/base.py:5845: KeyError
______________________________________________________________________ test_get_adaptive_squares ______________________________________________________________________

    def test_get_adaptive_squares():
        city = Tessellation("San Diego")
        city_poi = POIdata(city.get_polygon(), poi_categories=["leisure"], timeout=60, verbose=False).get_poi_data()
        points_geom = city_poi[['center_longitude', 'center_latitude']] \
            .apply(lambda p: Point(p['center_longitude'], p['center_latitude']), axis=1)
        tess_data = gpd.GeoDataFrame(geometry=points_geom,
                                     crs='EPSG:4326')
        city_squares = city.squares(14)
>       count1 = count_poi(city_squares, tess_data)

tests/test_tessellation_functions.py:28: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tesspy/tessellation_functions.py:54: in count_poi
    final_gdf = final_df[['quadkey',
../miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pandas/core/frame.py:3511: in __getitem__
    indexer = self.columns._get_indexer_strict(key, "columns")[1]
../miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pandas/core/indexes/base.py:5782: in _get_indexer_strict
    self._raise_if_missing(keyarr, indexer, axis_name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = Index(['quadkey', 'count', 'index', 'geometry'], dtype='object'), key = Index(['quadkey', 'count', 'geometry', 'children_id'], dtype='object')
indexer = array([ 0,  1,  3, -1]), axis_name = 'columns'

    def _raise_if_missing(self, key, indexer, axis_name: str_t) -> None:
        """
        Check that indexer can be used to return a result.
    
        e.g. at least one element was found,
        unless the list of keys was actually empty.
    
        Parameters
        ----------
        key : list-like
            Targeted labels (only used to show correct error message).
        indexer: array-like of booleans
            Indices corresponding to the key,
            (with -1 indicating not found).
        axis_name : str
    
        Raises
        ------
        KeyError
            If at least one key was requested but none was found.
        """
        if len(key) == 0:
            return
    
        # Count missing values
        missing_mask = indexer < 0
        nmissing = missing_mask.sum()
    
        if nmissing:
    
            # TODO: remove special-case; this is just to keep exception
            #  message tests from raising while debugging
            use_interval_msg = is_interval_dtype(self.dtype) or (
                is_categorical_dtype(self.dtype)
                # "Index" has no attribute "categories"  [attr-defined]
                and is_interval_dtype(
                    self.categories.dtype  # type: ignore[attr-defined]
                )
            )
    
            if nmissing == len(indexer):
                if use_interval_msg:
                    key = list(key)
                raise KeyError(f"None of [{key}] are in the [{axis_name}]")
    
            not_found = list(ensure_index(key)[missing_mask.nonzero()[0]].unique())
>           raise KeyError(f"{not_found} not in index")
E           KeyError: "['children_id'] not in index"

../miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pandas/core/indexes/base.py:5845: KeyError
________________________________________________________________________ test_split_linestring ________________________________________________________________________

    def test_split_linestring():
        city = Tessellation("Lille")
        road_data = RoadData(city.get_polygon(), split_roads=False, verbose=True).get_road_network()
        road_data2 = RoadData(city.get_polygon(), split_roads=True, verbose=False).get_road_network()
        split_road_data = split_linestring(road_data)
        assert len(split_road_data) > len(road_data)
>       assert len(split_road_data) == road_data2

tests/test_tessellation_functions.py:40: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self =                            osmid  oneway  lanes  highway  maxspeed  reversed  length  geometry    ref   name  bridge  ...lse   False     False  False  False   False    False   False   False  False     False  False

[28859 rows x 17 columns]

    @final
    def __nonzero__(self):
>       raise ValueError(
            f"The truth value of a {type(self).__name__} is ambiguous. "
            "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
        )
E       ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

../miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pandas/core/generic.py:1527: ValueError
------------------------------------------------------------------------ Captured stdout call -------------------------------------------------------------------------
Selected highway type(s) are ['highway'~'motorway|trunk|primary|secondary|tertiary|residential|unclassified|motorway_link|trunk_link|primary_link|secondary_link|living_street|pedestrian|track|bus_guideway|footway|path|service|cycleway']
Collecting road network data...
Collected data has 28859 street segments.
========================================================================== warnings summary ===========================================================================
tests/test_tessellation.py::test_adaptive_squares
tests/test_tessellation.py::test_adaptive_squares
tests/test_tessellation.py::test_adaptive_squares
tests/test_tessellation.py::test_adaptive_squares
tests/test_tessellation.py::test_new_shapely
tests/test_tessellation_functions.py::test_count_poi
tests/test_tessellation_functions.py::test_get_adaptive_squares
  /Users/user/miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pandas/core/dtypes/cast.py:122: ShapelyDeprecationWarning: The array interface is deprecated and will no longer work in Shapely 2.0. Convert the '.coords' to a numpy array instead.
    arr = construct_1d_object_array_from_listlike(values)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html

---------- coverage: platform darwin, python 3.10.5-final-0 ----------
Name                                                                                               Stmts   Miss  Cover   Missing
--------------------------------------------------------------------------------------------------------------------------------
/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pytest/__init__.py      82     80     2%   2-159, 162-164
/Users/user/miniconda3/envs/py310_tesspy/lib/python3.10/site-packages/pytest/__main__.py       3      3     0%   2-5
/Users/user/miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pytest/__init__.py         82     80     2%   2-159, 162-164
/Users/user/miniconda3/envs/py_tesspy/lib/python3.10/site-packages/pytest/__main__.py          3      3     0%   2-5
tesspy/__init__.py                                                                                     8      8     0%   1-10
tesspy/poi_data.py                                                                                   149    149     0%   1-403
tesspy/tessellation.py                                                                               252    252     0%   1-772
tesspy/tessellation_functions.py                                                                     158    158     0%   1-441
--------------------------------------------------------------------------------------------------------------------------------
TOTAL                                                                                                737    733     1%
Coverage XML written to file coverage.xml

======================================================================= short test summary info =======================================================================
FAILED tests/test_poi_data.py::test_get_road_network - assert 170 > 170
FAILED tests/test_tessellation.py::test_voronoi - assert 311 <= 300
FAILED tests/test_tessellation.py::test_count_lgu_function_short_version - ValueError: Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct ...
FAILED tests/test_tessellation.py::test_count_lgu_function_different_city_inputs - ValueError: Please insert a valid city-type. Valid types are: tesspy.Tessellation...
FAILED tests/test_tessellation.py::test_count_lgu_function_different_poi - ValueError: Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct ...
FAILED tests/test_tessellation.py::test_count_lgu_function - ValueError: Please insert a valid city-type. Valid types are: tesspy.Tessellation Obejct or String
FAILED tests/test_tessellation.py::test_poi_collection - ValueError: No poi data found that is within the area.
FAILED tests/test_tessellation_functions.py::test_count_poi - KeyError: "['children_id'] not in index"
FAILED tests/test_tessellation_functions.py::test_get_adaptive_squares - KeyError: "['children_id'] not in index"
FAILED tests/test_tessellation_functions.py::test_split_linestring - ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any...
======================================================= 10 failed, 15 passed, 7 warnings in 1092.84s (0:18:12) ========================================================

The authors should invest some time into setting up a multi-{platform/version} CI. Two examples that may be beneficial that I am involved in can be found in pysal/spopt and ipums/nhgisxwalk.

Drop the name of returning, only keep type for single returning method

For the returning single data method and specify the name of returning.
It will cause confusion because of missing context.

I got confused when I first saw the documentation.
What is df_qk_squares, df_h3_hexagons, and so on?

I suggest deleting the name of returning.
The user doesn't need to know them. They work for the developer.

Returns
-------
df_qk_squares : pandas.DataFrame
Dataframe containing squares

 Returns 
 ------- 
- df_qk_squares : pandas.DataFrame
+ pandas.DataFrame
     Dataframe containing squares 

PS: the returning type of Tessellation.squares should be GeoDataFrame.

[JOSS] Supported Python versions?

xref #6 openjournals/joss-reviews#4620

tesspy/setup.py

Lines 23 to 28 in d3e662d

classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: BSD License",
"Intended Audience :: Science/Research",
"Operating System :: OS Independent",
"Topic :: Scientific/Engineering :: GIS",

Currently there are no supported Python versions in setup.py. Ideally, this should match the Python version that are being tested against in CI. As an example see setup.py in pysal/momepy.

Tesselate input points

Not necessarily an issue, but a request (if not already possible).

Instead of using the built in POIs dataset, it'd be useful if I was able to pass in my own GeoDataFrame of points to be used in the tessellations.

version release

After the recent changes in the code (e.g., count_poi function), the new version v0.1.1 should be released on PyPi and conda-forge.

Notebooks installation returns errors due to the wrong syntax in requirement.txt

xref openjournals/joss-reviews#4620

During the installation of the requirements_tutorials.txt file using pip install -r requirements_tutorials.txt:

  • an error is raised due to the wrong operator specifying geopandas version
  • h3-py is not existing (I assume this should be replaced by h3)

You should also check this also for the tutorials_env.yaml
By the way there is a typo in the filename, replace tutiruals_env.yaml by tutorials_env

Speed up `Tessellation.squares` on large data

It is hard to work on large data.
The following code block is still running after running for more than 4 min.

import geopandas as gpd

from tesspy import Tessellation

df = (
    gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))
    .query('continent == "Africa"')
    .dissolve()
)

Tessellation(df).squares(15)

Basically, we could simplify get_squares_polyfill method.
First of all, the input of Tessellation only requires one polygon or multi-polygon.
So we could drop a for loop to avoid iteratIng GeoDataFrame.
children_id will be dropped at the latter. So don't generate it at first.

def get_squares_polyfill(polygon, resolution):
    """
    Square tessellation based on the quadKeys concept

    Parameters
    ----------
    polygon : shapely.geometry.Polygon or shapely.geometry.MultiPolygon

    resolution : int

    Returns
    --------
    GeoDataFrame
    """

    tiles = mercantile.tiles(*polygon.bounds, resolution)
    rows = []
    for tile in tiles:
        square = box(*mercantile.bounds(tile))
        if square.intersects(polygon):
            rows.append(dict(geometry=square, quadkey=mercantile.quadkey(tile)))

    # I thought Tessellation would create a new GeoDataFrame and it totally different
    # to the original one. So we could use 'geometry' as the default name.
    return gpd.GeoDataFrame(rows, crs=4326)

[JOSS] Dependencies

xref openjournals/joss-reviews#4620

There are packages used directly in tesspy that are not included in the requirements. Also, There are a handful of packages that are necessary to run the tutorials. While I know they are critical to install tesspy itself, the goal may be to provide a one-stop solution. Maybe adding a requirements_tutorials.txt or requirements_plus.txt files with these.

  • Add to requirements:
    • scikit-learn
    • scipy
  • Needed for tutorials
    • contextlily
    • esda
    • libpysal
    • matplotlib
    • seaborn
    • statsmodels

Will `tesspy` support `GeoSeries`?

Now tesspy only support GeoDataFrame.
Most of all tesspy functions could accept both GeoDataFrame and GeoSeries.
And running without any error. Except count_poi method, sjoin require GeoDataFrame.

Tesselating a set of points

Hi,

I have a set of points and I'm trying to use this library to tessellate them to adaptive (in terms of how many points are per cell) cells.

My geodataframe looks like this:

image

and I run:

df = Tessellation(gdf)

I get the following error:

image

How can I do this with this library?

[JOSS] Paper edits, etc.

xref openjournals/joss-reviews#4620

Paper sections

  • Summary
    • Typos
      • line 11: 'implementations of different methods'
      • line 17/18: 'the overpass API'
    • OSMnx citation
      • line 19: I would keep this JOSS citation and add the add the preferred one:
        • Boeing, G. 2017. OSMnx: New Methods for Acquiring, Constructing, Analyzing, and Visualizing Complex Street Networks. Computers, Environment and Urban Systems 65, 126-139. doi:10.1016/j.compenvurbsys.2017.05.004
      • xref #13
  • Statement of Need
    • Who is the target audience? There is a Statement of Need section, which does an acceptable job at defining the problem, but does not really mention a target audience.
    • line 33: Are the variations actually endless? Maybe something along the lines of 'highly varied flexibility' or the like.
  • Related Software packages
    • There needs to be much more reference to related software projects for tessellation, both in Python and other languages. Here are some examples after a quick search:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.