Source code for shapelib.adapters.read_file

"""Adapter for reading geospatial files from local or remote storage."""

from pathlib import Path
from typing import Any

from shapelib.core.cloud.cloud_path import CloudPath
from shapelib.core.geometries.base import BaseShapes
from shapelib.factories.geo_file_factory import GeoFileFactory


[docs] def read_file(path: str | Path, *, keep_z: bool = False, **kwargs: Any) -> BaseShapes: """ Read a geospatial file from local or remote storage. This function automatically detects whether the path is a local file or a remote URL and routes to the appropriate handler. Supports local files, HTTPS URLs (including presigned S3 URLs), and s3:// protocol. Parameters ---------- path : str | Path The path to the geospatial file. Can be: - A local file path (string or Path object) - An HTTPS URL (including presigned AWS S3 URLs) - An S3 URL (s3://bucket/key) keep_z : bool, optional Keep the Z coordinate of 3-D geometries. Defaults to False, which flattens every geometry to 2-D. Turn it on when Z is data, such as the elevation of each vertex of a contour line; it is kept by the copies, filters and reprojections of the returned object too. **kwargs : Any Additional arguments passed to the file handler (e.g., layer name for GeoPackage files). Returns ------- BaseShapes A geometry object (Polygons, Lines, Points, or Empty) containing the file's data with full spatial functionality. Raises ------ FileNotFoundError If the file (local or remote) does not exist. ValueError If the file format is not supported. ConnectionError If a remote file cannot be accessed. PermissionError If access to the file is denied. Examples -------- Read a local shapefile: >>> polygons = read_file("/path/to/shapefile.shp") >>> print(polygons.get_total_area()) Read from a presigned S3 URL (streaming for FlatGeobuf): >>> lines = read_file( ... "https://bucket.s3.amazonaws.com/file.fgb?X-Amz-Signature=..." ... ) Read using S3 protocol (requires AWS credentials in environment): >>> points = read_file("s3://my-bucket/data/points.gpkg") Keep the elevation of 3-D contour lines: >>> contours = read_file("/path/to/contours.fgb", keep_z=True) >>> bool(contours.has_z.all()) True Big-O ----- Local: O(n) where n is file size. Remote streaming (.fgb, .gpkg, .geojson): O(n) with range requests. Remote download (.shp, .kml, .sqlite): O(n) + network latency. Notes ----- For remote files, the handler selection is based on file extension: - Streaming (vsicurl): .fgb, .geojson, .json, .gpkg - Download to temp: .shp, .kml, .sqlite AWS credentials for s3:// protocol should be set via environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY. Presigned HTTPS URLs include credentials and don't require env vars. """ cloud_path = CloudPath.from_string(str(path)) if cloud_path.is_remote: return _read_remote(cloud_path, keep_z=keep_z, **kwargs) return GeoFileFactory.get_handler(path=Path(path), keep_z=keep_z, **kwargs)
def _read_remote(cloud_path: CloudPath, *, keep_z: bool = False, **kwargs: Any) -> BaseShapes: """ Read from remote storage using GeoCloudFactory. Parameters ---------- cloud_path : CloudPath The parsed cloud path. keep_z : bool, optional Keep the Z coordinate of 3-D geometries (default False). **kwargs : Any Additional arguments. Returns ------- BaseShapes The geometry object. """ # Import here to trigger handler registration import shapelib.core.cloud.handlers # noqa: F401 - registers handlers from shapelib.factories.geo_cloud_factory import GeoCloudFactory return GeoCloudFactory.get_handler(cloud_path.raw_path, keep_z=keep_z, **kwargs)