core-lens 0.1.dev130__tar.gz → 0.1.dev132__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/PKG-INFO +1 -1
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/_version.py +2 -2
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/aoi.py +25 -2
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/base/view.py +14 -24
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/schema/detection.py +36 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/schema/profile.py +6 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/utils/spatial.py +28 -17
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.github/ISSUE_TEMPLATE/blank-proposal.yaml +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.github/ISSUE_TEMPLATE/bug-report.yaml +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.github/ISSUE_TEMPLATE/feature-request.yaml +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.github/pull_request_template.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.github/workflows/ci.yml +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.github/workflows/gh-pages.yml +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.github/workflows/pre-release.yml +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.github/workflows/release.yml +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.gitignore +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.gitmessage +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.pre-commit-config.yaml +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/.python-version +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/CONTRIBUTING.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/LICENSE +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/README.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/SKILLS.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/README.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/bench_aoi.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/bench_export.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/bench_polars_utils.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/bench_result.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/bench_schema.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/bench_season.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/bench_spatial.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/bench_view.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/benchmarks/run_all.sh +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/Makefile +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/make.bat +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/concepts.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/conf.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/export.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/index.rst +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/intro.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/logging.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/plots.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/plugins.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/queries.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/quickstart.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/docs/source/stats.md +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/examples/demo_mws.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/examples/demo_tehsil.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/hooks/mypy.sh +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/hooks/no-parquet-outside-fixtures.sh +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/hooks/pytest.sh +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/pyproject.toml +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/__init__.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/__main__.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/base/__init__.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/base/entity.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/base/namespaces/__init__.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/base/namespaces/plot.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/base/namespaces/stats.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/base/result.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/entities/__init__.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/entities/mws.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/entities/tehsil.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/entities/waterbody.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/export/__init__.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/export/formats.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/py.typed +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/schema/__init__.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/utils/__init__.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/utils/paths.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/utils/polars_utils.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/src/core_lens/utils/season.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/fixtures/generate_fixtures.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/conftest.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_aoi.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_entities.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_entity.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_export.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_main.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_plot.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_polars_utils.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_profile.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_result.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_schema_detection.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_schema_profile.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_season.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_season_config.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_spatial.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_stats.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/tests/unit/test_view.py +0 -0
- {core_lens-0.1.dev130 → core_lens-0.1.dev132}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: core-lens
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.dev132
|
|
4
4
|
Summary: Query, analyse, and visualise CoreStack's microwatershed and Earth science data through a clean, composable Python API.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ApoorvaKashyap/core-lens
|
|
6
6
|
Project-URL: Issues, https://github.com/ApoorvaKashyap/core-lens/issues
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.1.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 1, '
|
|
21
|
+
__version__ = version = '0.1.dev132'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 'dev132')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -22,7 +22,7 @@ if TYPE_CHECKING:
|
|
|
22
22
|
from core_lens.base.view import View
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
@dataclass
|
|
25
|
+
@dataclass(frozen=True)
|
|
26
26
|
class SeasonConfig:
|
|
27
27
|
"""Date-range definitions for the three Indian crop seasons.
|
|
28
28
|
|
|
@@ -96,6 +96,29 @@ def _md_in_range(md: str, start: str, end: str) -> bool:
|
|
|
96
96
|
return md >= start or md <= end
|
|
97
97
|
|
|
98
98
|
|
|
99
|
+
# Singleton for the default SeasonConfig — constructed once per process.
|
|
100
|
+
# SeasonConfig.__post_init__ runs 6× datetime.strptime calls for validation;
|
|
101
|
+
# sharing the default instance eliminates that cost for every AoI() call
|
|
102
|
+
# that does not supply a custom season config.
|
|
103
|
+
_DEFAULT_SEASON_CONFIG: SeasonConfig | None = None
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _default_season_config() -> SeasonConfig:
|
|
107
|
+
"""Return the shared default :class:`SeasonConfig` instance.
|
|
108
|
+
|
|
109
|
+
Constructed once per process and reused thereafter. Callers that need
|
|
110
|
+
a custom config should construct their own :class:`SeasonConfig` and
|
|
111
|
+
pass it to :class:`AoI`.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
SeasonConfig: The shared default instance.
|
|
115
|
+
"""
|
|
116
|
+
global _DEFAULT_SEASON_CONFIG
|
|
117
|
+
if _DEFAULT_SEASON_CONFIG is None:
|
|
118
|
+
_DEFAULT_SEASON_CONFIG = SeasonConfig()
|
|
119
|
+
return _DEFAULT_SEASON_CONFIG
|
|
120
|
+
|
|
121
|
+
|
|
99
122
|
# Class-level registry: entity name → entity **class**.
|
|
100
123
|
# Shared across all AoI instances in a process. Explicit registration is
|
|
101
124
|
# required; there is no auto-discovery (design §6.1).
|
|
@@ -191,7 +214,7 @@ class AoI:
|
|
|
191
214
|
self.data_root = pathlib.Path(data_root_str).resolve()
|
|
192
215
|
|
|
193
216
|
self._storage_options: dict[str, Any] = storage_options or {}
|
|
194
|
-
self.seasons: SeasonConfig = seasons or
|
|
217
|
+
self.seasons: SeasonConfig = seasons or _default_season_config()
|
|
195
218
|
logger.info("Initializing AoI with data_root={}", self.data_root)
|
|
196
219
|
|
|
197
220
|
n_modes = sum(
|
|
@@ -407,28 +407,18 @@ class View:
|
|
|
407
407
|
if time_col is not None:
|
|
408
408
|
from core_lens.utils.season import resolve_time_filter
|
|
409
409
|
|
|
410
|
-
# Fall back to
|
|
411
|
-
from core_lens.aoi import
|
|
412
|
-
|
|
413
|
-
season_cfg = self._season_config or
|
|
414
|
-
|
|
415
|
-
#
|
|
416
|
-
#
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
).collect_schema()
|
|
423
|
-
_time_dtype = pq_schema.get(time_col)
|
|
424
|
-
_is_year_col = _time_dtype is not None and _time_dtype in (
|
|
425
|
-
pl.Int32,
|
|
426
|
-
pl.Int64,
|
|
427
|
-
pl.UInt32,
|
|
428
|
-
pl.UInt16,
|
|
429
|
-
)
|
|
430
|
-
except Exception:
|
|
431
|
-
_is_year_col = False
|
|
410
|
+
# Fall back to the default SeasonConfig if none was supplied on this View.
|
|
411
|
+
from core_lens.aoi import _default_season_config
|
|
412
|
+
|
|
413
|
+
season_cfg = self._season_config or _default_season_config()
|
|
414
|
+
|
|
415
|
+
# Read is_year_col from the cached schema profile — populated at
|
|
416
|
+
# detect() time from the Parquet schema, so no extra I/O here.
|
|
417
|
+
_is_year_col: bool | None = (
|
|
418
|
+
profile.annual_is_year_col
|
|
419
|
+
if resolution == Resolution.ANNUAL
|
|
420
|
+
else profile.fortnightly_is_year_col
|
|
421
|
+
)
|
|
432
422
|
|
|
433
423
|
# Pass as a private hint inside the filter dict (non-mutating copy).
|
|
434
424
|
_tf = dict(self.time_filter)
|
|
@@ -454,9 +444,9 @@ class View:
|
|
|
454
444
|
and profile.fortnightly_time_col is not None
|
|
455
445
|
):
|
|
456
446
|
from core_lens.utils.season import add_temporal_columns
|
|
457
|
-
from core_lens.aoi import
|
|
447
|
+
from core_lens.aoi import _default_season_config
|
|
458
448
|
|
|
459
|
-
season_cfg = self._season_config or
|
|
449
|
+
season_cfg = self._season_config or _default_season_config()
|
|
460
450
|
data = add_temporal_columns(data, profile.fortnightly_time_col, season_cfg)
|
|
461
451
|
|
|
462
452
|
if self.join_spec is not None:
|
|
@@ -104,6 +104,7 @@ def detect(
|
|
|
104
104
|
|
|
105
105
|
annual_time_col: str | None = None
|
|
106
106
|
extra_annual_cols: list[str] = []
|
|
107
|
+
annual_is_year_col: bool | None = None
|
|
107
108
|
if annual_path:
|
|
108
109
|
annual_schema = _read_schema(
|
|
109
110
|
annual_path, label="annual", storage_options=_so or None
|
|
@@ -113,9 +114,11 @@ def detect(
|
|
|
113
114
|
{annual_time_col} if annual_time_col else set()
|
|
114
115
|
)
|
|
115
116
|
extra_annual_cols = [c for c in annual_schema if c not in reserved_annual]
|
|
117
|
+
annual_is_year_col = _is_year_col_from_schema(annual_schema, annual_time_col)
|
|
116
118
|
|
|
117
119
|
fortnightly_time_col: str | None = None
|
|
118
120
|
extra_fortnightly_cols: list[str] = []
|
|
121
|
+
fortnightly_is_year_col: bool | None = None
|
|
119
122
|
if fortnightly_path:
|
|
120
123
|
fortnightly_schema = _read_schema(
|
|
121
124
|
fortnightly_path, label="fortnightly", storage_options=_so or None
|
|
@@ -125,6 +128,9 @@ def detect(
|
|
|
125
128
|
{fortnightly_time_col} if fortnightly_time_col else set()
|
|
126
129
|
)
|
|
127
130
|
extra_fortnightly_cols = [c for c in fortnightly_schema if c not in reserved_fn]
|
|
131
|
+
fortnightly_is_year_col = _is_year_col_from_schema(
|
|
132
|
+
fortnightly_schema, fortnightly_time_col
|
|
133
|
+
)
|
|
128
134
|
|
|
129
135
|
return SchemaProfile(
|
|
130
136
|
key_cols=key_cols,
|
|
@@ -136,6 +142,8 @@ def detect(
|
|
|
136
142
|
extra_static_cols=extra_static_cols,
|
|
137
143
|
extra_annual_cols=extra_annual_cols,
|
|
138
144
|
extra_fortnightly_cols=extra_fortnightly_cols,
|
|
145
|
+
annual_is_year_col=annual_is_year_col,
|
|
146
|
+
fortnightly_is_year_col=fortnightly_is_year_col,
|
|
139
147
|
)
|
|
140
148
|
|
|
141
149
|
|
|
@@ -237,3 +245,31 @@ def _infer_time_col(schema: pl.Schema, path: str) -> str | None:
|
|
|
237
245
|
return col
|
|
238
246
|
|
|
239
247
|
return None
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
_YEAR_COL_DTYPES = (pl.Int32, pl.Int64, pl.UInt32, pl.UInt16)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def _is_year_col_from_schema(
|
|
254
|
+
schema: pl.Schema,
|
|
255
|
+
time_col: str | None,
|
|
256
|
+
) -> bool | None:
|
|
257
|
+
"""Return whether *time_col* is an integer-year column, or ``None`` if absent.
|
|
258
|
+
|
|
259
|
+
``True`` — integer dtype (``Int32`` / ``Int64`` / ``UInt32`` / ``UInt16``).
|
|
260
|
+
``False`` — ``Date`` / ``Datetime`` column.
|
|
261
|
+
``None`` — *time_col* is ``None`` or not found in *schema*.
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
schema (pl.Schema): The Parquet schema returned by ``collect_schema()``.
|
|
265
|
+
time_col (str | None): The name of the time column, or ``None``.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
bool | None: ``True`` for integer-year, ``False`` for Date/Datetime, ``None`` if absent.
|
|
269
|
+
"""
|
|
270
|
+
if time_col is None:
|
|
271
|
+
return None
|
|
272
|
+
dtype = schema.get(time_col)
|
|
273
|
+
if dtype is None:
|
|
274
|
+
return None
|
|
275
|
+
return dtype in _YEAR_COL_DTYPES
|
|
@@ -69,6 +69,12 @@ class SchemaProfile(BaseModel):
|
|
|
69
69
|
extra_static_cols: list[str] = []
|
|
70
70
|
extra_annual_cols: list[str] = []
|
|
71
71
|
extra_fortnightly_cols: list[str] = []
|
|
72
|
+
# Whether the time column is an integer-year column (True), a Date/Datetime
|
|
73
|
+
# column (False), or absent/unknown (None). Determined at detect() time from
|
|
74
|
+
# the Parquet schema — eliminates a redundant collect_schema() call in
|
|
75
|
+
# View._materialise for every .annual / .fortnightly access.
|
|
76
|
+
annual_is_year_col: bool | None = None
|
|
77
|
+
fortnightly_is_year_col: bool | None = None
|
|
72
78
|
|
|
73
79
|
@classmethod
|
|
74
80
|
def from_file(cls, path: str | pathlib.Path) -> "SchemaProfile":
|
|
@@ -247,28 +247,39 @@ def exact_spatial_filter(
|
|
|
247
247
|
else:
|
|
248
248
|
geoms = shapely.from_wkt(geom_array)
|
|
249
249
|
|
|
250
|
+
import numpy as np
|
|
251
|
+
|
|
250
252
|
if relationship == "centroid":
|
|
251
253
|
# Centroid mode: entity centroid must lie within the AoI geometry.
|
|
252
|
-
# STRtree
|
|
253
|
-
#
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
254
|
+
# STRtree is overkill for a single-query containment test — building
|
|
255
|
+
# the tree costs O(n log n) with no payoff when there is only one query
|
|
256
|
+
# geometry. Vectorised shapely ops stay in C and avoid the overhead.
|
|
257
|
+
centroids = shapely.centroid(geoms) # vectorised, C-level
|
|
258
|
+
mask = shapely.contains(aoi_geometry, centroids) # vectorised bool array
|
|
259
|
+
hit_indices = np.where(mask)[0].tolist()
|
|
257
260
|
|
|
258
261
|
else: # area mode
|
|
259
|
-
# Area mode: intersection area / entity area
|
|
262
|
+
# Area mode: intersection area / entity area >= threshold.
|
|
263
|
+
# Vectorise: compute all areas and intersections in C via numpy arrays.
|
|
260
264
|
tree = shapely.STRtree(geoms)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if
|
|
271
|
-
hit_indices
|
|
265
|
+
intersect_idx = np.asarray(
|
|
266
|
+
tree.query(aoi_geometry, predicate="intersects"), dtype=np.intp
|
|
267
|
+
)
|
|
268
|
+
if len(intersect_idx) == 0:
|
|
269
|
+
hit_indices = []
|
|
270
|
+
else:
|
|
271
|
+
candidate_geoms = geoms[intersect_idx]
|
|
272
|
+
entity_areas = shapely.area(candidate_geoms) # vectorised
|
|
273
|
+
valid = entity_areas > 0
|
|
274
|
+
if not valid.any():
|
|
275
|
+
hit_indices = []
|
|
276
|
+
else:
|
|
277
|
+
inter_geoms = shapely.intersection(
|
|
278
|
+
candidate_geoms[valid], aoi_geometry
|
|
279
|
+
) # vectorised
|
|
280
|
+
inter_areas = shapely.area(inter_geoms) # vectorised
|
|
281
|
+
ratios = inter_areas / entity_areas[valid]
|
|
282
|
+
hit_indices = intersect_idx[valid][ratios >= threshold].tolist()
|
|
272
283
|
|
|
273
284
|
del geoms # free all decoded Shapely geometries before assembling result
|
|
274
285
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|