core-lens 0.1.dev129__tar.gz → 0.1.dev130__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.dev129 → core_lens-0.1.dev130}/PKG-INFO +1 -1
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/_version.py +2 -2
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/base/result.py +4 -2
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/export/formats.py +20 -32
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_export.py +5 -2
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.github/ISSUE_TEMPLATE/blank-proposal.yaml +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.github/ISSUE_TEMPLATE/bug-report.yaml +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.github/ISSUE_TEMPLATE/feature-request.yaml +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.github/pull_request_template.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.github/workflows/ci.yml +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.github/workflows/gh-pages.yml +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.github/workflows/pre-release.yml +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.github/workflows/release.yml +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.gitignore +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.gitmessage +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.pre-commit-config.yaml +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/.python-version +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/CONTRIBUTING.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/LICENSE +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/README.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/SKILLS.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/README.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/bench_aoi.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/bench_export.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/bench_polars_utils.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/bench_result.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/bench_schema.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/bench_season.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/bench_spatial.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/bench_view.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/benchmarks/run_all.sh +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/Makefile +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/make.bat +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/concepts.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/conf.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/export.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/index.rst +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/intro.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/logging.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/plots.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/plugins.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/queries.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/quickstart.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/docs/source/stats.md +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/examples/demo_mws.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/examples/demo_tehsil.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/hooks/mypy.sh +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/hooks/no-parquet-outside-fixtures.sh +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/hooks/pytest.sh +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/pyproject.toml +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/__init__.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/__main__.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/aoi.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/base/__init__.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/base/entity.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/base/namespaces/__init__.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/base/namespaces/plot.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/base/namespaces/stats.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/base/view.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/entities/__init__.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/entities/mws.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/entities/tehsil.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/entities/waterbody.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/export/__init__.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/py.typed +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/schema/__init__.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/schema/detection.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/schema/profile.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/utils/__init__.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/utils/paths.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/utils/polars_utils.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/utils/season.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/src/core_lens/utils/spatial.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/fixtures/generate_fixtures.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/conftest.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_aoi.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_entities.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_entity.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_main.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_plot.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_polars_utils.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_profile.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_result.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_schema_detection.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_schema_profile.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_season.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_season_config.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_spatial.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_stats.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/tests/unit/test_view.py +0 -0
- {core_lens-0.1.dev129 → core_lens-0.1.dev130}/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.dev130
|
|
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.dev130'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 'dev130')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -100,10 +100,12 @@ class Result:
|
|
|
100
100
|
"Call .with_geometry() first to join the static geometry column before extracting GeoDataFrame."
|
|
101
101
|
)
|
|
102
102
|
import geopandas as gpd
|
|
103
|
-
import shapely
|
|
103
|
+
import shapely
|
|
104
104
|
|
|
105
105
|
geometry_col = self.entity.geometry_col
|
|
106
|
-
|
|
106
|
+
# Vectorised C-level decode — shapely.from_wkb operates on the whole
|
|
107
|
+
# numpy array at once, avoiding a Python-loop per row.
|
|
108
|
+
geometries = shapely.from_wkb(self.data[geometry_col].to_numpy())
|
|
107
109
|
geo_series = gpd.GeoSeries(geometries, crs="EPSG:4326")
|
|
108
110
|
return gpd.GeoDataFrame(
|
|
109
111
|
self.data.drop(geometry_col).to_pandas(),
|
|
@@ -162,12 +162,17 @@ def geoparquet(result: "Result", path: str | pathlib.Path, **kwargs: Any) -> Non
|
|
|
162
162
|
def geojson(result: "Result", path: str | pathlib.Path, **kwargs: Any) -> None:
|
|
163
163
|
"""Export the result data to a GeoJSON file.
|
|
164
164
|
|
|
165
|
-
This function uses
|
|
165
|
+
This function uses GeoPandas to write the data frame. It prefers the
|
|
166
|
+
``pyogrio`` engine (faster, C-backed) when available and falls back to
|
|
167
|
+
``fiona`` automatically. The ``engine`` kwarg can override this:
|
|
168
|
+
``engine="fiona"`` or ``engine="pyogrio"``.
|
|
166
169
|
|
|
167
170
|
Args:
|
|
168
171
|
result (Result): The Result object to export.
|
|
169
172
|
path (str | pathlib.Path): Destination path for the GeoJSON file.
|
|
170
|
-
**kwargs (Any): Additional options
|
|
173
|
+
**kwargs (Any): Additional options forwarded to
|
|
174
|
+
``GeoDataFrame.to_file()`` (e.g. ``driver="GeoJSON"``,
|
|
175
|
+
``engine="pyogrio"``).
|
|
171
176
|
|
|
172
177
|
Example:
|
|
173
178
|
>>> from core_lens.export import geojson
|
|
@@ -182,37 +187,20 @@ def geojson(result: "Result", path: str | pathlib.Path, **kwargs: Any) -> None:
|
|
|
182
187
|
"Call .with_geometry() first to join the static geometry column before exporting to geojson."
|
|
183
188
|
)
|
|
184
189
|
|
|
185
|
-
|
|
186
|
-
geom_col = result.entity.geometry_col
|
|
187
|
-
|
|
188
|
-
cols = []
|
|
189
|
-
for c in df.columns:
|
|
190
|
-
if c == geom_col:
|
|
191
|
-
cols.append(f'ST_GeomFromWKB("{c}") AS "{c}"')
|
|
192
|
-
else:
|
|
193
|
-
cols.append(f'"{c}"')
|
|
194
|
-
|
|
195
|
-
select_clause = ", ".join(cols)
|
|
196
|
-
|
|
197
|
-
conn = _get_duckdb_conn()
|
|
190
|
+
gdf = result.gdf()
|
|
198
191
|
|
|
199
|
-
|
|
192
|
+
# Resolve write engine: prefer pyogrio (C-backed, no GDAL Python overhead),
|
|
193
|
+
# fall back to fiona if not installed.
|
|
194
|
+
engine = kwargs.pop("engine", None)
|
|
195
|
+
if engine is None:
|
|
196
|
+
try:
|
|
197
|
+
import pyogrio as _ # type: ignore[import-untyped] # noqa: F401
|
|
200
198
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
options.append(f"{k.upper()} {'TRUE' if v else 'FALSE'}")
|
|
205
|
-
elif isinstance(v, str):
|
|
206
|
-
options.append(f"{k.upper()} '{v}'")
|
|
207
|
-
else:
|
|
208
|
-
options.append(f"{k.upper()} {v}")
|
|
199
|
+
engine = "pyogrio"
|
|
200
|
+
except ModuleNotFoundError:
|
|
201
|
+
engine = "fiona"
|
|
209
202
|
|
|
210
|
-
|
|
203
|
+
# Always write as GeoJSON unless the caller overrides driver.
|
|
204
|
+
kwargs.setdefault("driver", "GeoJSON")
|
|
211
205
|
|
|
212
|
-
|
|
213
|
-
COPY (
|
|
214
|
-
SELECT {select_clause}
|
|
215
|
-
FROM df
|
|
216
|
-
) TO '{path_str}' ({options_str});
|
|
217
|
-
"""
|
|
218
|
-
conn.execute(query)
|
|
206
|
+
gdf.to_file(path, engine=engine, **kwargs)
|
|
@@ -152,8 +152,10 @@ def test_geoparquet_options_partition(
|
|
|
152
152
|
|
|
153
153
|
|
|
154
154
|
def test_geojson_options(sample_result: Result, tmp_path: pathlib.Path) -> None:
|
|
155
|
+
"""Unknown kwargs are forwarded to the write engine; unrecognised ones raise
|
|
156
|
+
ValueError (pyogrio) rather than silently being ignored. The test simply
|
|
157
|
+
verifies the call path is exercised without an unexpected exception type."""
|
|
155
158
|
result_with_geom = sample_result.with_geometry()
|
|
156
|
-
import duckdb
|
|
157
159
|
|
|
158
160
|
out_path = tmp_path / "out_opts.json"
|
|
159
161
|
try:
|
|
@@ -165,5 +167,6 @@ def test_geojson_options(sample_result: Result, tmp_path: pathlib.Path) -> None:
|
|
|
165
167
|
flag=False,
|
|
166
168
|
number=10,
|
|
167
169
|
)
|
|
168
|
-
except
|
|
170
|
+
except ValueError:
|
|
171
|
+
# pyogrio rejects unrecognised driver options — that's expected.
|
|
169
172
|
pass
|
|
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
|
|
File without changes
|
|
File without changes
|