Add geopandas stubs (#12990)

This commit is contained in:
Ali Hamdan
2025-01-19 19:19:43 +01:00
committed by GitHub
parent 31bff4a503
commit c01e731dd1
30 changed files with 1911 additions and 0 deletions

View File

@@ -9,6 +9,7 @@
// Stubs that don't work in all Python versions
"stubs/seaborn",
"stubs/shapely",
"stubs/geopandas",
// test cases use a custom config file
"**/@tests/test_cases",
],

View File

@@ -49,6 +49,7 @@
"stubs/Flask-SocketIO",
"stubs/fpdf2",
"stubs/gdb",
"stubs/geopandas",
"stubs/google-cloud-ndb",
"stubs/hdbcli/hdbcli/dbapi.pyi",
"stubs/html5lib",

View File

@@ -0,0 +1,24 @@
# Stub missing OK
geopandas\.conftest
geopandas\.(.*\.)?tests.*
geopandas\.array\.(type_mapping|geometry_type_ids|geometry_type_values)
geopandas\.io\.file\.(FIONA|PYOGRIO)_GE_.*
geopandas\.io\.file\.(fiona|pyogrio)(_env|_import_error)?
geopandas\.io\.util
geopandas\.datasets\.*
# Inconsistent OK
geopandas\.(geodataframe\.)?GeoDataFrame\.plot
# Failed to import OK (require extra dependencies)
geopandas\.io\._geoarrow
geopandas\._exports
# Not present in stub OK (do not work at runtime, to be removed from geopandas)
geopandas\.(geoseries\.)?GeoSeries\.append # https://github.com/geopandas/geopandas/pull/3460
geopandas\.(geoseries\.)?GeoSeries\.select # https://github.com/geopandas/geopandas/pull/3394
# Inconsistent (TODO)
geopandas\.(geoseries\.)?GeoSeries\.apply
geopandas\.(geoseries\.)?GeoSeries\.fillna
geopandas\.(geoseries\.)?GeoSeries\.sort_index

View File

@@ -0,0 +1,4 @@
version = "1.0.1"
# Requires a version of numpy with a `py.typed` file
requires = ["numpy>=1.20", "pandas-stubs", "types-shapely", "pyproj"]
upstream_repository = "https://github.com/geopandas/geopandas"

View File

@@ -0,0 +1,20 @@
from typing import Final
from ._config import options as options
from ._exports import (
gpd as gpd,
list_layers as list_layers,
np as np,
pd as pd,
read_feather as read_feather,
read_file as read_file,
read_parquet as read_parquet,
read_postgis as read_postgis,
)
from .array import points_from_xy as points_from_xy
from .geodataframe import GeoDataFrame as GeoDataFrame
from .geoseries import GeoSeries as GeoSeries
from .tools import clip as clip, overlay as overlay, sjoin as sjoin, sjoin_nearest as sjoin_nearest
from .tools._show_versions import show_versions as show_versions
__version__: Final[str]

View File

@@ -0,0 +1,21 @@
from _typeshed import SupportsItems, Unused
from collections.abc import Callable
from typing import Any, NamedTuple
class Option(NamedTuple):
key: str
default_value: Any # Can be "any" type
doc: str
validator: Callable[[object], Unused]
callback: Callable[[str, object], Unused] | None
class Options:
def __init__(self, options: SupportsItems[str, Option]) -> None: ...
# Accept and return arbitrary values
def __setattr__(self, key: str, value: Any) -> None: ...
def __getattr__(self, key: str) -> Any: ...
display_precision: Option
use_pygeos: Option
io_engine: Option
options: Options

View File

@@ -0,0 +1,21 @@
from collections.abc import Callable
from typing import TypeVar, overload
from typing_extensions import TypeAlias
_AnyCallable: TypeAlias = Callable[..., object]
_Func = TypeVar("_Func", bound=_AnyCallable)
# We (ab)use this decorator to also copy the signature of the source function (overload 1)
# The advantages are:
# - avoid copying all parameters and types manually while conserving type safety
# - signature properly handeled in IDEs (at least with Pylance)
# - docstring from the original function properly displayed (at least with Pylance)
# Using the other overloads returns the signature of the decorated function instead
@overload
def doc(func: _Func, /, **params: object) -> Callable[[_AnyCallable], _Func]: ...
@overload
def doc(docstring: str, /, *docstrings: str | _AnyCallable, **params: object) -> Callable[[_Func], _Func]: ...
@overload
def doc(
docstring1: str | _AnyCallable, docstring2: str | _AnyCallable, /, *docstrings: str | _AnyCallable, **params: object
) -> Callable[[_Func], _Func]: ...

View File

@@ -0,0 +1,21 @@
# Type checking-only module to export public symbols with a different name in __init__.pyi
import geopandas as gpd
import numpy as np
import pandas as pd
from geopandas.io.arrow import _read_feather as read_feather, _read_parquet as read_parquet
from geopandas.io.file import _list_layers as list_layers, _read_file as read_file
from geopandas.io.sql import _read_postgis as read_postgis
__all__ = [
# IO functions
"read_file",
"read_feather",
"read_parquet",
"read_postgis",
"list_layers",
# Modules for interactive use
"np",
"pd",
"gpd",
]

View File

@@ -0,0 +1,244 @@
import builtins
from _typeshed import Incomplete, Unused
from collections.abc import Callable, Sequence
from typing import Any, ClassVar, Literal, NoReturn, SupportsIndex, TypeVar, overload
from typing_extensions import Self, TypeAlias, deprecated
import numpy as np
import pandas as pd
from numpy.typing import ArrayLike, DTypeLike, NDArray
from pandas.api.extensions import ExtensionArray, ExtensionDtype
from pyproj import CRS, Transformer
from shapely import Geometry
from shapely.geometry.base import BaseGeometry
from .base import _AffinityOrigin, _ConvertibleToCRS
from .sindex import SpatialIndex
_ScalarType = TypeVar("_ScalarType", bound=np.generic)
_Array1D: TypeAlias = np.ndarray[tuple[int], np.dtype[_ScalarType]]
_Array2D: TypeAlias = np.ndarray[tuple[int, int], np.dtype[_ScalarType]]
_ArrayOrGeom: TypeAlias = GeometryArray | ArrayLike | Geometry
TransformerFromCRS = Transformer.from_crs
class GeometryDtype(ExtensionDtype):
type: ClassVar[type[BaseGeometry]]
name: ClassVar[str]
na_value: float
@classmethod
def construct_from_string(cls, string: str) -> Self: ...
@classmethod
def construct_array_type(cls) -> builtins.type[GeometryArray]: ...
def isna(value: object) -> bool: ...
def from_shapely(data, crs: _ConvertibleToCRS | None = None) -> GeometryArray: ...
def to_shapely(geoms: GeometryArray) -> _Array1D[np.object_]: ...
def from_wkb(
data, crs: _ConvertibleToCRS | None = None, on_invalid: Literal["raise", "warn", "ignore"] = "raise"
) -> GeometryArray: ...
@overload
def to_wkb(geoms: GeometryArray, hex: Literal[False] = False, **kwargs) -> _Array1D[np.bytes_]: ...
@overload
def to_wkb(geoms: GeometryArray, hex: Literal[True], **kwargs) -> _Array1D[np.str_]: ...
def from_wkt(
data, crs: _ConvertibleToCRS | None = None, on_invalid: Literal["raise", "warn", "ignore"] = "raise"
) -> GeometryArray: ...
def to_wkt(geoms: GeometryArray, **kwargs) -> _Array1D[np.str_]: ...
def points_from_xy(
x: ArrayLike, y: ArrayLike, z: ArrayLike | None = None, crs: _ConvertibleToCRS | None = None
) -> GeometryArray: ...
class GeometryArray(ExtensionArray):
def __init__(self, data: GeometryArray | NDArray[np.object_], crs: _ConvertibleToCRS | None = None) -> None: ...
@property
def sindex(self) -> SpatialIndex: ...
@property
def has_sindex(self) -> bool: ...
@property
def crs(self) -> CRS | None: ...
@crs.setter
def crs(self, value: _ConvertibleToCRS | None) -> None: ...
def check_geographic_crs(self, stacklevel: int) -> None: ...
@property
def dtype(self) -> GeometryDtype: ...
def __len__(self) -> int: ...
# np.integer[Any] because precision is not important
@overload
def __getitem__(self, idx: int | np.integer[Any]) -> BaseGeometry: ... # Always 1-D, doesn't accept tuple
@overload
def __getitem__(
self, idx: slice | Sequence[SupportsIndex] | NDArray[np.bool_] | NDArray[np.integer[Any]]
) -> GeometryArray: ...
@overload
def __getitem__(
self, idx: int | np.integer[Any] | slice | Sequence[int] | NDArray[np.bool_] | NDArray[np.integer[Any]]
) -> BaseGeometry | GeometryArray: ...
def __setitem__(
self, key, value: _ArrayOrGeom | pd.DataFrame | pd.Series[Any] # Cannot use pd.Series[BaseGeometry]
) -> None: ...
@property
def is_valid(self) -> _Array1D[np.bool_]: ...
def is_valid_reason(self) -> _Array1D[np.object_]: ...
@property
def is_empty(self) -> _Array1D[np.bool_]: ...
@property
def is_simple(self) -> _Array1D[np.bool_]: ...
@property
def is_ring(self) -> _Array1D[np.bool_]: ...
@property
def is_closed(self) -> _Array1D[np.bool_]: ...
@property
def is_ccw(self) -> _Array1D[np.bool_]: ...
@property
def has_z(self) -> _Array1D[np.bool_]: ...
@property
def geom_type(self) -> _Array1D[np.str_]: ...
@property
def area(self) -> _Array1D[np.float64]: ...
@property
def length(self) -> _Array1D[np.float64]: ...
def count_coordinates(self) -> _Array1D[np.int32]: ...
def count_geometries(self) -> _Array1D[np.int32]: ...
def count_interior_rings(self) -> _Array1D[np.int32]: ...
def get_precision(self) -> _Array1D[np.float64]: ...
def get_geometry(self, index: SupportsIndex | ArrayLike) -> _Array1D[np.object_]: ...
@property
def boundary(self) -> GeometryArray: ...
@property
def centroid(self) -> GeometryArray: ...
def concave_hull(self, ratio: float, allow_holes: bool) -> _Array1D[np.object_]: ...
@property
def convex_hull(self) -> GeometryArray: ...
@property
def envelope(self) -> GeometryArray: ...
def minimum_rotated_rectangle(self) -> GeometryArray: ...
@property
def exterior(self) -> GeometryArray: ...
def extract_unique_points(self) -> GeometryArray: ...
def offset_curve(
self,
distance: float | ArrayLike,
quad_segs: int = 8,
join_style: Literal["round", "bevel", "mitre"] = "round",
mitre_limit: float = 5.0,
) -> GeometryArray: ...
@property
def interiors(self) -> _Array1D[np.object_]: ...
def remove_repeated_points(self, tolerance: float | ArrayLike = 0.0) -> GeometryArray: ...
def representative_point(self) -> GeometryArray: ...
def minimum_bounding_circle(self) -> GeometryArray: ...
def minimum_bounding_radius(self) -> _Array1D[np.float64]: ...
def minimum_clearance(self) -> _Array1D[np.float64]: ...
def normalize(self) -> GeometryArray: ...
def make_valid(self) -> GeometryArray: ...
def reverse(self) -> GeometryArray: ...
def segmentize(self, max_segment_length: float | ArrayLike) -> GeometryArray: ...
def force_2d(self) -> GeometryArray: ...
def force_3d(self, z: float | ArrayLike = 0) -> GeometryArray: ...
def transform(
self, transformation: Callable[[NDArray[np.float64]], NDArray[np.float64]], include_z: bool = False
) -> GeometryArray: ...
def line_merge(self, directed: bool = False) -> GeometryArray: ...
def set_precision(
self, grid_size: float, mode: Literal["valid_output", "pointwise", "keep_collapsed", 0, 1, 2] = "valid_output"
) -> GeometryArray: ...
def covers(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def covered_by(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def contains(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def contains_properly(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def crosses(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def disjoint(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def geom_equals(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def intersects(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def overlaps(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def touches(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def within(self, other: _ArrayOrGeom) -> _Array1D[np.bool_]: ...
def dwithin(self, other: _ArrayOrGeom, distance: float) -> _Array1D[np.bool_]: ...
def geom_equals_exact(self, other: _ArrayOrGeom, tolerance: float | ArrayLike) -> _Array1D[np.bool_]: ...
@deprecated("Use method `geom_equals_exact` instead.")
def geom_almost_equals(self, other: _ArrayOrGeom, decimal: float) -> _Array1D[np.bool_]: ...
def clip_by_rect(self, xmin: float, ymin: float, xmax: float, ymax: float) -> GeometryArray: ...
def difference(self, other: _ArrayOrGeom) -> GeometryArray: ...
def intersection(self, other: _ArrayOrGeom) -> GeometryArray: ...
def symmetric_difference(self, other: _ArrayOrGeom) -> GeometryArray: ...
def union(self, other: _ArrayOrGeom) -> GeometryArray: ...
def shortest_line(self, other: _ArrayOrGeom) -> GeometryArray: ...
def snap(self, other: _ArrayOrGeom, tolerance: float | ArrayLike) -> GeometryArray: ...
def shared_paths(self, other: _ArrayOrGeom) -> GeometryArray: ...
def distance(self, other: _ArrayOrGeom) -> _Array1D[np.float64]: ...
def hausdorff_distance(self, other: _ArrayOrGeom, **kwargs) -> _Array1D[np.float64]: ...
def frechet_distance(self, other: _ArrayOrGeom, **kwargs) -> _Array1D[np.float64]: ...
def buffer(self, distance: float | ArrayLike, resolution: int = 16, **kwargs) -> GeometryArray: ...
def interpolate(self, distance: float | ArrayLike, normalized: bool = False) -> GeometryArray: ...
def simplify(self, tolerance: float | ArrayLike, preserve_topology: bool = True) -> GeometryArray: ...
def project(self, other: _ArrayOrGeom, normalized: bool = False) -> _Array1D[np.float64]: ...
def relate(self, other: _ArrayOrGeom) -> _Array1D[np.str_]: ...
def relate_pattern(self, other: _ArrayOrGeom, pattern: str) -> _Array1D[np.bool_]: ...
@deprecated("Use method `union_all` instead.")
def unary_union(self) -> BaseGeometry: ...
def union_all(self, method: Literal["coverage", "unary"] = "unary") -> BaseGeometry: ...
def intersection_all(self) -> BaseGeometry: ...
def affine_transform(self, matrix) -> GeometryArray: ...
def translate(self, xoff: float = 0.0, yoff: float = 0.0, zoff: float = 0.0) -> GeometryArray: ...
def rotate(self, angle: float, origin: _AffinityOrigin = "center", use_radians: bool = False) -> GeometryArray: ...
def scale(
self, xfact: float = 1.0, yfact: float = 1.0, zfact: float = 1.0, origin: _AffinityOrigin = "center"
) -> GeometryArray: ...
def skew(
self, xs: float = 0.0, ys: float = 0.0, origin: _AffinityOrigin = "center", use_radians: bool = False
) -> GeometryArray: ...
def to_crs(self, crs: _ConvertibleToCRS | None = None, epsg: int | None = None) -> GeometryArray: ...
def estimate_utm_crs(self, datum_name: str = "WGS 84") -> CRS: ...
@property
def x(self) -> _Array1D[np.float64]: ...
@property
def y(self) -> _Array1D[np.float64]: ...
@property
def z(self) -> _Array1D[np.float64]: ...
@property
def bounds(self) -> _Array2D[np.float64]: ...
@property
def total_bounds(self) -> _Array1D[np.float64]: ...
@property
def size(self) -> int: ...
@property
def shape(self) -> tuple[int]: ... # Always 1-D, this is not a mistake
@property
def ndim(self) -> Literal[1]: ...
def copy(self, *args: Unused, **kwargs: Unused) -> GeometryArray: ...
def take(
self,
indices: Sequence[SupportsIndex] | NDArray[np.integer[Any]], # np.integer[Any] because precision is not important
allow_fill: bool = False,
fill_value: Geometry | None = None,
) -> GeometryArray: ...
def fillna(
self,
value: Geometry | GeometryArray | None = None,
method: Literal["backfill", "bfill", "pad", "ffill"] | None = None,
limit: int | None = None,
copy: bool = True,
) -> GeometryArray: ...
@overload
def astype(self, dtype: GeometryDtype, copy: bool = True) -> GeometryArray: ...
@overload
def astype(self, dtype: ExtensionDtype | Literal["string"], copy: bool = True) -> ExtensionArray: ... # type: ignore[overload-overlap]
@overload
def astype(self, dtype: DTypeLike, copy: bool = True) -> _Array1D[Incomplete]: ...
def isna(self) -> _Array1D[np.bool_]: ...
def value_counts(self, dropna: bool = True) -> pd.Series[int]: ...
def unique(self) -> GeometryArray: ...
@property
def nbytes(self) -> int: ...
def shift(self, periods: int = 1, fill_value: Geometry | None = None) -> GeometryArray: ... # type: ignore[override]
def argmin(self, skipna: bool = True) -> NoReturn: ...
def argmax(self, skipna: bool = True) -> NoReturn: ...
def __array__(self, dtype: DTypeLike | None = None, copy: bool | None = None) -> _Array1D[np.object_]: ...
def __eq__(self, other: object) -> _Array1D[np.bool_]: ... # type: ignore[override]
def __ne__(self, other: object) -> _Array1D[np.bool_]: ... # type: ignore[override]
def __contains__(self, item: object) -> np.bool_: ...
def transform(
data: NDArray[np.object_], func: Callable[[NDArray[np.float64], NDArray[np.float64]], NDArray[np.float64]]
) -> NDArray[np.object_]: ...

View File

@@ -0,0 +1,228 @@
from _typeshed import Incomplete, SupportsGetItem
from collections.abc import Callable, Hashable, Iterable, Mapping, Sequence
from typing import Any, Literal, Protocol, SupportsIndex, overload, type_check_only
from typing_extensions import Self, TypeAlias, deprecated
import numpy as np
import pandas as pd
from numpy.random import BitGenerator, Generator as RandomGenerator, SeedSequence
from numpy.typing import ArrayLike, NDArray
from pandas._typing import ListLikeU
from pandas.core.base import IndexOpsMixin
from pyproj import CRS
from shapely import Geometry, MultiPolygon, Point, Polygon
from shapely.geometry.base import BaseGeometry
from .array import GeometryArray, _Array1D
from .geodataframe import GeoDataFrame
from .geoseries import GeoSeries
from .sindex import SpatialIndex
@type_check_only
class _SupportsToWkt(Protocol):
def to_wkt(self) -> str: ...
@type_check_only
class _SupportsGeoInterface(Protocol): # noqa: Y046
@property
def __geo_interface__(self) -> dict[str, Any]: ... # values are arbitrary
_ConvertibleToCRS: TypeAlias = str | int | tuple[str, str] | list[str] | dict[str, Incomplete] | _SupportsToWkt
_AffinityOrigin: TypeAlias = Literal["center", "centroid"] | Point | tuple[float, float] | tuple[float, float, float]
_ClipMask: TypeAlias = GeoDataFrame | GeoSeries | Polygon | MultiPolygon | tuple[float, float, float, float] # noqa: Y047
# np.floating[Any] because precision is not important
_BboxLike: TypeAlias = Sequence[float] | NDArray[np.floating[Any]] | Geometry | GeoDataFrame | GeoSeries # noqa: Y047
_MaskLike: TypeAlias = dict[str, Incomplete] | Geometry | GeoDataFrame | GeoSeries # noqa: Y047
# Cannot use IndexOpsMixin[Geometry] because of IndexOpsMixin type variable bounds
_GeoListLike: TypeAlias = ArrayLike | Sequence[Geometry] | IndexOpsMixin[Any]
_ConvertibleToGeoSeries: TypeAlias = Geometry | Mapping[int, Geometry] | Mapping[str, Geometry] | _GeoListLike # noqa: Y047
# Cannot use pd.Series[Geometry] because of pd.Series type variable bounds
_GeomSeq: TypeAlias = Sequence[Geometry] | NDArray[np.object_] | pd.Series[Any] | GeometryArray | GeoSeries
_GeomCol: TypeAlias = Hashable | _GeomSeq # name of column or column values # noqa: Y047
# dict[Any, Any] because of variance issues
_ConvertibleToDataFrame: TypeAlias = ( # noqa: Y047
ListLikeU | pd.DataFrame | dict[Any, Any] | Iterable[ListLikeU | tuple[Hashable, ListLikeU] | dict[Any, Any]]
)
def is_geometry_type(data: object) -> bool: ...
class GeoPandasBase:
@property
def area(self) -> pd.Series[float]: ...
@property
def crs(self) -> CRS | None: ...
@crs.setter
def crs(self, value: _ConvertibleToCRS | None) -> None: ...
@property
def geom_type(self) -> pd.Series[str]: ...
@property
def type(self) -> pd.Series[str]: ...
@property
def length(self) -> pd.Series[float]: ...
@property
def is_valid(self) -> pd.Series[bool]: ...
def is_valid_reason(self) -> pd.Series[str]: ...
@property
def is_empty(self) -> pd.Series[bool]: ...
def count_coordinates(self) -> pd.Series[int]: ...
def count_geometries(self) -> pd.Series[int]: ...
def count_interior_rings(self) -> pd.Series[int]: ...
@property
def is_simple(self) -> pd.Series[bool]: ...
@property
def is_ring(self) -> pd.Series[bool]: ...
@property
def is_ccw(self) -> pd.Series[bool]: ...
@property
def is_closed(self) -> pd.Series[bool]: ...
@property
def has_z(self) -> pd.Series[bool]: ...
def get_precision(self) -> pd.Series[float]: ...
def get_geometry(self, index: SupportsIndex | ArrayLike) -> GeoSeries: ...
@property
def boundary(self) -> GeoSeries: ...
@property
def centroid(self) -> GeoSeries: ...
def concave_hull(self, ratio: float = 0.0, allow_holes: bool = False) -> GeoSeries: ...
@property
def convex_hull(self) -> GeoSeries: ...
def delaunay_triangles(self, tolerance: float | ArrayLike = 0.0, only_edges: bool | ArrayLike = False) -> GeoSeries: ...
def voronoi_polygons(
self, tolerance: float | ArrayLike = 0.0, extend_to: Geometry | None = None, only_edges: bool = False
) -> GeoSeries: ...
@property
def envelope(self) -> GeoSeries: ...
def minimum_rotated_rectangle(self) -> GeoSeries: ...
@property
def exterior(self) -> GeoSeries: ...
def extract_unique_points(self) -> GeoSeries: ...
def offset_curve(
self,
distance: float | ArrayLike,
quad_segs: int = 8,
join_style: Literal["round", "bevel", "mitre"] = "round",
mitre_limit: float = 5.0,
) -> GeoSeries: ...
@property
def interiors(self) -> pd.Series[Any]: ... # Cannot use pd.Series[BaseGeometry]
def remove_repeated_points(self, tolerance: float = 0.0) -> GeoSeries: ...
def set_precision(
self, grid_size: float, mode: Literal["valid_output", "pointwise", "keep_collapsed"] = "valid_output"
) -> GeoSeries: ...
def representative_point(self) -> GeoSeries: ...
def minimum_bounding_circle(self) -> GeoSeries: ...
def minimum_bounding_radius(self) -> pd.Series[float]: ...
def minimum_clearance(self) -> pd.Series[float]: ...
def normalize(self) -> GeoSeries: ...
def make_valid(self) -> GeoSeries: ...
def reverse(self) -> GeoSeries: ...
def segmentize(self, max_segment_length: float | ArrayLike) -> GeoSeries: ...
def transform(
self, transformation: Callable[[NDArray[np.float64]], NDArray[np.float64]], include_z: bool = False
) -> GeoSeries: ...
def force_2d(self) -> GeoSeries: ...
def force_3d(self, z: float | ArrayLike = 0) -> GeoSeries: ...
def line_merge(self, directed: bool = False) -> GeoSeries: ...
@property
def unary_union(self) -> BaseGeometry: ...
def union_all(self, method: Literal["coverage", "unary"] = "unary") -> BaseGeometry: ...
def intersection_all(self) -> BaseGeometry: ...
def contains(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def contains_properly(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def dwithin(self, other: GeoSeries | Geometry, distance: float | ArrayLike, align: bool | None = None) -> pd.Series[bool]: ...
def geom_equals(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
@deprecated("Use method `geom_equals_exact` instead.")
def geom_almost_equals(self, other: GeoSeries | Geometry, decimal: int = 6, align: bool | None = None) -> pd.Series[bool]: ...
def geom_equals_exact(
self, other: GeoSeries | Geometry, tolerance: float | ArrayLike, align: bool | None = None
) -> pd.Series[bool]: ...
def crosses(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def disjoint(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def intersects(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def overlaps(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def touches(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def within(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def covers(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def covered_by(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[bool]: ...
def distance(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[float]: ...
def hausdorff_distance(
self, other: GeoSeries | Geometry, align: bool | None = None, densify: float | ArrayLike | None = None
) -> pd.Series[float]: ...
def frechet_distance(
self, other: GeoSeries | Geometry, align: bool | None = None, densify: float | ArrayLike | None = None
) -> pd.Series[float]: ...
def difference(self, other: GeoSeries | Geometry, align: bool | None = None) -> GeoSeries: ...
def symmetric_difference(self, other: GeoSeries | Geometry, align: bool | None = None) -> GeoSeries: ...
def union(self, other: GeoSeries | Geometry, align: bool | None = None) -> GeoSeries: ...
def intersection(self, other: GeoSeries | Geometry, align: bool | None = None) -> GeoSeries: ...
def clip_by_rect(self, xmin: float, ymin: float, xmax: float, ymax: float) -> GeoSeries: ...
def shortest_line(self, other: GeoSeries | Geometry, align: bool | None = None) -> GeoSeries: ...
def snap(self, other: GeoSeries | Geometry, tolerance: float | ArrayLike, align: bool | None = None) -> GeoSeries: ...
def shared_paths(self, other: GeoSeries | Geometry, align: bool | None = None): ...
@property
def bounds(self) -> pd.DataFrame: ...
@property
def total_bounds(self) -> _Array1D[np.float64]: ...
@property
def sindex(self) -> SpatialIndex: ...
@property
def has_sindex(self) -> bool: ...
def buffer(
self,
distance: float | ArrayLike,
resolution: int = 16,
cap_style: Literal["round", "square", "flat"] = "round",
join_style: Literal["round", "mitre", "bevel"] = "round",
mitre_limit: float = 5.0,
single_sided: bool = False,
**kwargs,
) -> GeoSeries: ...
def simplify(self, tolerance: float | ArrayLike, preserve_topology: bool = True) -> GeoSeries: ...
def relate(self, other: GeoSeries | Geometry, align: bool | None = None) -> pd.Series[str]: ...
def relate_pattern(self, other: GeoSeries | Geometry, pattern: str, align: bool | None = None) -> pd.Series[bool]: ...
def project(self, other: GeoSeries | Geometry, normalized: bool = False, align: bool | None = None) -> pd.Series[float]: ...
def interpolate(self, distance: float | ArrayLike, normalized: bool = False) -> GeoSeries: ...
def affine_transform(self, matrix) -> GeoSeries: ...
def translate(self, xoff: float = 0.0, yoff: float = 0.0, zoff: float = 0.0) -> GeoSeries: ...
def rotate(self, angle: float, origin: _AffinityOrigin = "center", use_radians: bool = False) -> GeoSeries: ...
def scale(
self, xfact: float = 1.0, yfact: float = 1.0, zfact: float = 1.0, origin: _AffinityOrigin = "center"
) -> GeoSeries: ...
def skew(
self, xs: float = 0.0, ys: float = 0.0, origin: _AffinityOrigin = "center", use_radians: bool = False
) -> GeoSeries: ...
@property
def cx(self) -> SupportsGetItem[tuple[SupportsIndex | slice, SupportsIndex | slice], Self]: ...
def get_coordinates(self, include_z: bool = False, ignore_index: bool = False, index_parts: bool = False) -> pd.DataFrame: ...
def hilbert_distance(
self, total_bounds: tuple[float, float, float, float] | Iterable[float] | None = None, level: int = 16
) -> pd.Series[int]: ...
@overload
def sample_points(
self,
size: int | ArrayLike,
method: str = "uniform",
seed: None = None,
rng: int | ArrayLike | SeedSequence | BitGenerator | RandomGenerator | None = None,
**kwargs,
) -> GeoSeries: ...
@overload
@deprecated("Parameter `seed` is deprecated. Use `rng` instead.")
def sample_points(
self,
size: int | ArrayLike,
method: str = "uniform",
*,
seed: int | ArrayLike | SeedSequence | BitGenerator | RandomGenerator,
rng: int | ArrayLike | SeedSequence | BitGenerator | RandomGenerator | None = None,
**kwargs,
) -> GeoSeries: ...
def build_area(self, node: bool = True) -> GeoSeries: ...
@overload
def polygonize(self, node: bool = True, full: Literal[False] = False) -> GeoSeries: ...
@overload
def polygonize(self, node: bool = True, *, full: Literal[True]) -> tuple[GeoSeries, GeoSeries, GeoSeries, GeoSeries]: ...
@overload
def polygonize(self, node: bool, full: Literal[True]) -> tuple[GeoSeries, GeoSeries, GeoSeries, GeoSeries]: ...

View File

@@ -0,0 +1,65 @@
from collections.abc import Callable, Hashable, MutableMapping, Sequence
from typing import Any
import branca # type: ignore[import-not-found] # pyright: ignore[reportMissingImports]
import folium # type: ignore[import-not-found] # pyright: ignore[reportMissingImports]
import pandas as pd
import xyzservices # type: ignore[import-not-found] # pyright: ignore[reportMissingImports]
from matplotlib.colors import Colormap # type: ignore[import-not-found]
from numpy.typing import ArrayLike, NDArray
from .geodataframe import GeoDataFrame
from .geoseries import GeoSeries
def _explore(
df: GeoDataFrame,
column: Hashable | NDArray[Any] | pd.Series[Any] | None = None, # Accepts "any" array or series
cmap: str | Colormap | branca.colormap.ColorMap | Sequence[str] | Callable[[Any], str] | None = None, # accepts "any" object
color: str | ArrayLike | None = None,
m: folium.Map | None = None,
tiles: str | folium.TileLayer | xyzservices.TileProvider | None = "OpenStreetMap",
attr: str | None = None,
tooltip: bool = True,
popup: bool = False,
highlight: bool = True,
categorical: bool = False,
legend: bool = True,
scheme: str | None = None,
k: int = 5,
vmin: float | None = None,
vmax: float | None = None,
width: float | str = "100%",
height: float | str = "100%",
categories: Sequence[Any] | NDArray[Any] | pd.Series[Any] | pd.Index[Any] | None = None, # categories can have "any" type
classification_kwds: MutableMapping[str, Any] | None = None,
control_scale: bool = True,
marker_type: str | folium.Marker | None = None,
# The following kwds will never be typed more precisely than "Any"
marker_kwds: MutableMapping[str, Any] = {},
style_kwds: MutableMapping[str, Any] = {},
highlight_kwds: MutableMapping[str, Any] = {},
missing_kwds: MutableMapping[str, Any] = {},
tooltip_kwds: MutableMapping[str, Any] = {},
popup_kwds: MutableMapping[str, Any] = {},
legend_kwds: MutableMapping[str, Any] = {},
map_kwds: MutableMapping[str, Any] = {},
**kwargs,
) -> folium.Map: ...
def _explore_geoseries(
s: GeoSeries,
color: str | ArrayLike | None = None,
m: folium.Map | None = None,
tiles: str | folium.TileLayer | xyzservices.TileProvider | None = "OpenStreetMap",
attr: str | None = None,
highlight: bool = True,
width: float | str = "100%",
height: float | str = "100%",
control_scale: bool = True,
marker_type: str | folium.Marker | None = None,
# The following kwds will never be typed more precisely than "Any"
marker_kwds: MutableMapping[str, Any] = {},
style_kwds: MutableMapping[str, Any] = {},
highlight_kwds: MutableMapping[str, Any] = {},
map_kwds: MutableMapping[str, Any] = {},
**kwargs,
) -> folium.Map: ...

View File

@@ -0,0 +1,357 @@
import io
import os
from _typeshed import Incomplete, SupportsGetItem, SupportsLenAndGetItem, SupportsRead, SupportsWrite
from collections.abc import Callable, Container, Hashable, Iterable, Iterator, Mapping
from json import JSONEncoder
from typing import Any, Literal, overload
from typing_extensions import Self
import pandas as pd
from numpy.typing import ArrayLike
from pandas._typing import AggFuncTypeFrame, AstypeArg, Axes, Axis, Dtype, GroupByObject, IndexLabel, Scalar
from pyproj import CRS
from ._decorator import doc
from .base import (
GeoPandasBase,
_BboxLike,
_ClipMask,
_ConvertibleToCRS,
_ConvertibleToDataFrame,
_GeomCol,
_GeomSeq,
_MaskLike,
_SupportsGeoInterface,
)
from .explore import _explore
from .geoseries import GeoSeries
from .io._geoarrow import ArrowTable, _GeomEncoding
from .io.sql import _SQLConnection
from .plotting import GeoplotAccessor
crs_mismatch_error: str
class GeoDataFrame(GeoPandasBase, pd.DataFrame): # type: ignore[misc]
# Override the weird annotation of DataFrame.__new__ in pandas-stubs
@overload
def __new__(
cls,
data: _ConvertibleToDataFrame | None = None,
index: Axes | None = None,
columns: Axes | None = None,
dtype: Dtype | None = None,
copy: bool | None = None,
*,
geometry: _GeomCol | None = None,
crs: _ConvertibleToCRS | None = None,
) -> Self: ...
@overload
def __new__(
cls,
data: Scalar,
index: Axes,
columns: Axes,
dtype: Dtype | None = None,
copy: bool | None = None,
*,
geometry: _GeomCol | None = None,
crs: _ConvertibleToCRS | None = None,
) -> Self: ...
def __init__(
self,
data: _ConvertibleToDataFrame | None = None,
index: Axes | None = None,
columns: Axes | None = None,
dtype: Dtype | None = None,
copy: bool | None = None,
*,
geometry: _GeomCol | None = None,
crs: _ConvertibleToCRS | None = None,
) -> None: ...
def __setattr__(self, attr: str, val: Any) -> None: ... # Can set arbitrary objects
@property
def geometry(self) -> GeoSeries: ...
@geometry.setter
def geometry(self, col: _GeomSeq) -> None: ...
@overload
def set_geometry(
self, col: _GeomCol, drop: bool | None = None, inplace: Literal[False] = False, crs: _ConvertibleToCRS | None = None
) -> Self: ...
@overload
def set_geometry(
self, col: _GeomCol, drop: bool | None = None, *, inplace: Literal[True], crs: _ConvertibleToCRS | None = None
) -> None: ...
@overload
def set_geometry(
self, col: _GeomCol, drop: bool | None, inplace: Literal[True], crs: _ConvertibleToCRS | None = None
) -> None: ...
@overload
def rename_geometry(self, col: Hashable, inplace: Literal[False] = False) -> Self: ...
@overload
def rename_geometry(self, col: Hashable, inplace: Literal[True]) -> None: ...
@property
def active_geometry_name(self) -> str | None: ...
@property
def crs(self) -> CRS | None: ...
@crs.setter
def crs(self, value: _ConvertibleToCRS | None) -> None: ...
@classmethod
def from_dict( # type: ignore[override]
# Mapping[Any, Any] because of invariance keys and arbitrary values
cls,
data: Mapping[Any, Any],
geometry: _GeomCol | None = None,
crs: _ConvertibleToCRS | None = None,
**kwargs,
) -> Self: ...
# Keep inline with GeoSeries.from_file and geopandas.io.file._read_file
@classmethod
def from_file(
cls,
filename: str | os.PathLike[str] | SupportsRead[Incomplete],
*,
bbox: _BboxLike | None = None,
mask: _MaskLike | None = None,
rows: int | slice | None = None,
engine: Literal["fiona", "pyogrio"] | None = None,
ignore_geometry: Literal[False] = False,
layer: int | str | None = None,
encoding: str | None = None,
**kwargs, # engine dependent
) -> Self: ...
@classmethod
def from_features(
cls,
features: (
_SupportsGeoInterface
| Mapping[str, _SupportsGeoInterface | SupportsGetItem[str, Incomplete]]
| Iterable[_SupportsGeoInterface | SupportsGetItem[str, Incomplete]]
),
crs: _ConvertibleToCRS | None = None,
columns: Axes | None = None,
) -> Self: ...
@overload
@classmethod
def from_postgis(
cls,
sql: str,
con: _SQLConnection,
geom_col: str = "geom",
crs: _ConvertibleToCRS | None = None,
index_col: str | list[str] | None = None,
coerce_float: bool = True,
parse_dates: Container[str | Mapping[str, Incomplete]] | Mapping[str, str | Mapping[str, Incomplete]] | None = None,
params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None,
*,
chunksize: int,
) -> Iterator[GeoDataFrame]: ...
@overload
@classmethod
def from_postgis(
cls,
sql: str,
con: _SQLConnection,
geom_col: str = "geom",
crs: _ConvertibleToCRS | None = None,
index_col: str | list[str] | None = None,
coerce_float: bool = True,
parse_dates: Container[str | Mapping[str, Incomplete]] | Mapping[str, str | Mapping[str, Incomplete]] | None = None,
params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None,
chunksize: None = None,
) -> GeoDataFrame: ...
@classmethod
def from_arrow(cls, table, geometry: str | None = None) -> GeoDataFrame: ... # table: pyarrow.Table
def to_json( # type: ignore[override]
self,
na: str = "null",
show_bbox: bool = False,
drop_id: bool = False,
to_wgs84: bool = False,
*,
# json.dumps kwargs
skipkeys: bool = False,
ensure_ascii: bool = True,
check_circular: bool = True,
allow_nan: bool = True,
cls: type[JSONEncoder] | None = None,
indent: int | str | None = None,
separators: tuple[str, str] | None = None,
default: Callable[..., Any] | None = None, # as typed in the json stdlib module
sort_keys: bool = False,
**kwargs,
) -> str: ...
@property
def __geo_interface__(self) -> dict[str, Any]: ... # values are arbitrary
def iterfeatures(
self, na: str = "null", show_bbox: bool = False, drop_id: bool = False
) -> Iterator[dict[str, Incomplete]]: ...
def to_geo_dict(self, na: str = "null", show_bbox: bool = False, drop_id: bool = False) -> dict[str, Incomplete]: ...
def to_wkb(
self,
hex: bool = False,
*,
# shapely kwargs
output_dimension: int = ...,
byte_order: int = ...,
include_srid: bool = ...,
flavor: Literal["iso", "extended"] = ...,
**kwargs,
) -> pd.DataFrame: ...
def to_wkt(
self,
*,
# shapely kwargs
rounding_precision: int = ...,
trim: bool = ...,
output_dimension: int = ...,
old_3d: bool = ...,
**kwargs,
) -> pd.DataFrame: ...
def to_arrow(
self,
*,
index: bool | None = None,
geometry_encoding: _GeomEncoding = "WKB",
interleaved: bool = True,
include_z: bool | None = None,
) -> ArrowTable: ...
def to_parquet( # type: ignore[override]
self,
path: str | os.PathLike[str] | SupportsWrite[Incomplete],
index: bool | None = None,
compression: Literal["snappy", "gzip", "brotli"] | None = "snappy",
geometry_encoding: _GeomEncoding = "WKB",
write_covering_bbox: bool = False,
schema_version: str | None = None,
*,
engine: Literal["auto", "pyarrow"] = "auto", # Only these engines are supported, unlike pandas
**kwargs,
) -> None: ...
def to_feather(
self,
path: str | os.PathLike[str] | SupportsWrite[Incomplete],
index: bool | None = None,
compression: Literal["zstd", "lz4", "uncompressed"] | None = None,
schema_version: str | None = None,
**kwargs,
) -> None: ...
# Keep method to_file roughly in line with GeoSeries.to_file
def to_file(
self,
filename: str | os.PathLike[str] | io.BytesIO,
driver: str | None = None,
schema: dict[str, Incomplete] | None = None,
index: bool | None = None,
*,
# kwargs from `_to_file` function
mode: Literal["w", "a"] = "w",
crs: _ConvertibleToCRS | None = None,
engine: Literal["fiona", "pyogrio"] | None = None,
metadata: dict[str, str] | None = None,
# kwargs extracted from engines
layer: int | str | None = None,
encoding: str | None = None,
overwrite: bool | None = ...,
**kwargs, # engine and driver dependent
) -> None: ...
@overload
def set_crs(
self, crs: _ConvertibleToCRS, epsg: int | None = None, inplace: bool = False, allow_override: bool = False
) -> Self: ...
@overload
def set_crs(
self, crs: _ConvertibleToCRS | None = None, *, epsg: int, inplace: bool = False, allow_override: bool = False
) -> Self: ...
@overload
def set_crs(self, crs: _ConvertibleToCRS | None, epsg: int, inplace: bool = False, allow_override: bool = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS, epsg: int | None = None, inplace: Literal[False] = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None = None, *, epsg: int, inplace: Literal[False] = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None, epsg: int, inplace: Literal[False] = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS, epsg: int | None = None, *, inplace: Literal[True]) -> None: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS, epsg: int | None, inplace: Literal[True]) -> None: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None = None, *, epsg: int, inplace: Literal[True]) -> None: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None, epsg: int, inplace: Literal[True]) -> None: ...
def estimate_utm_crs(self, datum_name: str = "WGS 84") -> CRS: ...
# def __getitem__(self, key): ...
# def __setitem__(self, key, value) -> None: ...
def copy(self, deep: bool = True) -> Self: ...
# def merge(self, *args, **kwargs) -> GeoDataFrame | pd.DataFrame: ...
def apply( # type: ignore[override]
self,
func: Callable[..., Incomplete],
axis: Axis = 0,
raw: bool = False,
result_type: Literal["expand", "reduce", "broadcast"] | None = None,
args: tuple[Any, ...] = (), # type inexpressible in the typing system
*,
by_row: Literal[False, "compat"] = "compat",
engine: Literal["python", "numba"] = "python",
engine_kwargs: dict[str, bool] | None = None,
**kwargs,
) -> pd.DataFrame | pd.Series[Incomplete]: ...
def __finalize__(self, other, method: str | None = None, **kwargs) -> Self: ...
def dissolve(
self,
by: GroupByObject | None = None,
aggfunc: AggFuncTypeFrame = "first",
as_index: bool = True,
level: IndexLabel | None = None,
sort: bool = True,
observed: bool = False,
dropna: bool = True,
method: Literal["coverage", "unary"] = "unary",
**kwargs,
) -> GeoDataFrame: ...
def explode(self, column: IndexLabel | None = None, ignore_index: bool = False, index_parts: bool = False) -> Self: ...
def astype(
self,
dtype: AstypeArg | Mapping[Any, Dtype] | pd.Series[Any], # any because of mapping invariance and series typevar bounds
copy: bool | None = None,
errors: Literal["ignore", "raise"] = "raise",
) -> GeoDataFrame | pd.DataFrame: ...
def to_postgis(
self,
name: str,
con: _SQLConnection,
schema: str | None = None,
if_exists: Literal["fail", "replace", "append"] = "fail",
index: bool = False,
index_label: IndexLabel | None = None,
chunksize: int | None = None,
dtype: dict[Any, Incomplete] | None = None, # columns can be of "any" type
) -> None: ...
@property
def plot(self) -> GeoplotAccessor: ...
@doc(_explore) # pyright: ignore[reportUnknownArgumentType]
def explore(self, *args, **kwargs): ... # signature of `_explore` copied in `@doc`
def sjoin(
self,
df: GeoDataFrame,
# *args, **kwargs passed to geopandas.sjoin
how: Literal["left", "right", "inner"] = "inner",
predicate: str = "intersects",
lsuffix: str = "left",
rsuffix: str = "right",
distance: float | ArrayLike | None = None,
) -> GeoDataFrame: ...
def sjoin_nearest(
self,
right: GeoDataFrame,
how: Literal["left", "right", "inner"] = "inner",
max_distance: float | None = None,
lsuffix: str = "left",
rsuffix: str = "right",
distance_col: str | None = None,
exclusive: bool = False,
) -> GeoDataFrame: ...
def clip(self, mask: _ClipMask, keep_geom_type: bool = False, sort: bool = False) -> GeoDataFrame: ... # type: ignore[override]
def overlay(
self, right: GeoDataFrame, how: str = "intersection", keep_geom_type: bool | None = None, make_valid: bool = True
) -> GeoDataFrame: ...

View File

@@ -0,0 +1,215 @@
import io
import json
import os
from _typeshed import Incomplete, SupportsRead, Unused
from collections.abc import Callable, Hashable
from typing import Any, Literal, final, overload
from typing_extensions import Self
import pandas as pd
from numpy.typing import ArrayLike
from pandas._typing import Axes, AxisIndex, Dtype
from pyproj import CRS
from shapely.geometry.base import BaseGeometry
from ._decorator import doc
from .array import GeometryArray
from .base import GeoPandasBase, _BboxLike, _ClipMask, _ConvertibleToCRS, _ConvertibleToGeoSeries, _MaskLike
from .explore import _explore_geoseries
from .io._geoarrow import GeoArrowArray
from .plotting import plot_series
class GeoSeries(GeoPandasBase, pd.Series[BaseGeometry]): # type: ignore[type-var,misc] # pyright: ignore[reportInvalidTypeArguments]
# Override the weird annotation of Series.__new__ in pandas-stubs
def __new__(
self,
data: _ConvertibleToGeoSeries | None = None,
index: Axes | None = None,
crs: _ConvertibleToCRS | None = None,
*,
dtype: Dtype | None = None,
name: Hashable = None,
copy: bool | None = None,
fastpath: bool = False,
) -> Self: ...
def __init__(
self,
data: _ConvertibleToGeoSeries | None = None,
index: Axes | None = None,
crs: _ConvertibleToCRS | None = None,
*,
dtype: Dtype | None = None,
name: Hashable = None,
copy: bool | None = None,
fastpath: bool = False,
) -> None: ...
@final
def copy(self, deep: bool = True) -> Self: ... # to override pandas definition
@property
def values(self) -> GeometryArray: ...
@property
def geometry(self) -> Self: ...
@property
def x(self) -> pd.Series[float]: ...
@property
def y(self) -> pd.Series[float]: ...
@property
def z(self) -> pd.Series[float]: ...
# Keep inline with GeoDataFrame.from_file and geopandas.io.file._read_file
@classmethod
def from_file(
cls,
filename: str | os.PathLike[str] | SupportsRead[Incomplete],
*,
bbox: _BboxLike | None = None,
mask: _MaskLike | None = None,
rows: int | slice | None = None,
engine: Literal["fiona", "pyogrio"] | None = None,
ignore_geometry: Literal[False] = False,
layer: int | str | None = None,
encoding: str | None = None,
**kwargs, # engine dependent
) -> GeoSeries: ...
@classmethod
def from_wkb(
cls,
data: ArrayLike, # array-like of bytes handled by shapely.from_wkb(data)
index: Axes | None = None,
crs: _ConvertibleToCRS | None = None,
on_invalid: Literal["raise", "warn", "ignore"] = "raise",
*,
dtype: Dtype | None = None,
name: Hashable = None,
copy: bool | None = None,
fastpath: bool = False,
) -> Self: ...
@classmethod
def from_wkt(
cls,
data: ArrayLike, # array-like of str handled by shapely.from_wkt(data)
index: Axes | None = None,
crs: _ConvertibleToCRS | None = None,
on_invalid: Literal["raise", "warn", "ignore"] = "raise",
*,
dtype: Dtype | None = None,
name: Hashable = None,
copy: bool | None = None,
fastpath: bool = False,
) -> Self: ...
@classmethod
def from_xy(
cls,
# x, y, z: array-like of floats handled by np.asarray(..., dtype="float64")
x: ArrayLike,
y: ArrayLike,
z: ArrayLike | None = None,
index: Axes | None = None,
crs: _ConvertibleToCRS | None = None,
*,
dtype: Dtype | None = None,
name: Hashable = None,
copy: bool | None = None,
fastpath: bool = False,
) -> Self: ...
@classmethod
def from_arrow(
cls,
arr,
*,
# GeoSeries constructor kwargs
index: Axes | None = None,
crs: _ConvertibleToCRS | None = None,
dtype: Dtype | None = None,
name: Hashable = None,
copy: bool | None = None,
fastpath: bool = False,
) -> Self: ...
@property
def __geo_interface__(self) -> dict[str, Any]: ... # values are arbitrary
# Keep method to_file roughly in line with GeoDataFrame.to_file
def to_file(
self,
filename: str | os.PathLike[str] | io.BytesIO,
driver: str | None = None,
index: bool | None = None,
*,
# kwargs from `_to_file` function
schema: dict[str, Incomplete] | None = None,
mode: Literal["w", "a"] = "w",
crs: _ConvertibleToCRS | None = None,
engine: Literal["fiona", "pyogrio"] | None = None,
metadata: dict[str, str] | None = None,
# kwargs extracted from engines
layer: int | str | None = None,
encoding: str | None = None,
overwrite: bool | None = ...,
**kwargs, # engine and driver dependent
) -> None: ...
# *** TODO: compare `__getitem__` with pandas-stubs ***
# def __getitem__(self, key): ...
# *** `sort_index` is annotated with `-> Self` in pandas-stubs; no need to override it ***
# def sort_index(self, *args, **kwargs): ...
def take(self, indices: ArrayLike, axis: AxisIndex = 0, **kwargs: Unused) -> GeoSeries: ...
# *** `apply` annotation in pandas-stubs is compatible except for deprecated `convert_dtype` argument ***
# def apply(self, func, convert_dtype: bool | None = None, args=(), **kwargs): ...
def isna(self) -> pd.Series[bool]: ...
def isnull(self) -> pd.Series[bool]: ...
def notna(self) -> pd.Series[bool]: ...
def notnull(self) -> pd.Series[bool]: ...
# *** TODO: `fillna` annotation in pandas-stubs is NOT compatible; must `-> Self` ***
# def fillna(self, value=None, method: FillnaOptions | None = None, inplace: bool = False, **kwargs): ...
def __contains__(self, other: object) -> bool: ...
@doc(plot_series)
def plot(self, *args, **kwargs): ... # signature of `plot_series` copied in `@doc`
@doc(_explore_geoseries) # pyright: ignore[reportUnknownArgumentType]
def explore(self, *args, **kwargs): ... # signature of `_explore_geoseries` copied in `@doc`
def explode(self, ignore_index: bool = False, index_parts: bool = False) -> GeoSeries: ...
@overload
def set_crs(
self, crs: _ConvertibleToCRS, epsg: int | None = None, inplace: bool = False, allow_override: bool = False
) -> Self: ...
@overload
def set_crs(
self, crs: _ConvertibleToCRS | None = None, *, epsg: int, inplace: bool = False, allow_override: bool = False
) -> Self: ...
@overload
def set_crs(self, crs: _ConvertibleToCRS | None, epsg: int, inplace: bool = False, allow_override: bool = False) -> Self: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS, epsg: int | None = None) -> GeoSeries: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None = None, *, epsg: int) -> GeoSeries: ...
@overload
def to_crs(self, crs: _ConvertibleToCRS | None, epsg: int) -> GeoSeries: ...
def estimate_utm_crs(self, datum_name: str = "WGS 84") -> CRS: ...
def to_json( # type: ignore[override]
self,
show_bbox: bool = True,
drop_id: bool = False,
to_wgs84: bool = False,
*,
# Keywords from json.dumps
skipkeys: bool = False,
ensure_ascii: bool = True,
check_circular: bool = True,
allow_nan: bool = True,
cls: type[json.JSONEncoder] | None = None,
indent: None | int | str = None,
separators: tuple[str, str] | None = None,
default: Callable[..., Any] | None = None, # as typed in the json stdlib module
sort_keys: bool = False,
**kwds,
) -> str: ...
@overload
def to_wkb(self, hex: Literal[False] = False, **kwargs) -> pd.Series[bytes]: ...
@overload
def to_wkb(self, hex: Literal[True], **kwargs) -> pd.Series[str]: ...
@overload
def to_wkb(self, hex: bool = False, **kwargs) -> pd.Series[str] | pd.Series[bytes]: ...
def to_wkt(self, **kwargs) -> pd.Series[str]: ...
def to_arrow(
self,
geometry_encoding: Literal["WKB", "geoarrow", "wkb", "GeoArrow"] = "WKB",
interleaved: bool | None = True,
include_z: bool | None = None,
) -> GeoArrowArray: ...
def clip(self, mask: _ClipMask, keep_geom_type: bool = False, sort: bool = False) -> GeoSeries: ... # type: ignore[override]

View File

@@ -0,0 +1 @@
from . import arrow as arrow, file as file, sql as sql

View File

@@ -0,0 +1,48 @@
from _typeshed import Incomplete
from typing import Literal
from typing_extensions import TypeAlias
import numpy as np
from numpy.typing import NDArray
from ..array import GeometryArray
from ..geodataframe import GeoDataFrame
_PATable: TypeAlias = Incomplete
_PAField: TypeAlias = Incomplete
_PAArray: TypeAlias = Incomplete
# Literal for language server completions and str because runtime normalizes to lowercase
_GeomEncoding: TypeAlias = Literal["WKB", "geoarrow"] | str # noqa: Y051
GEOARROW_ENCODINGS: list[str]
class ArrowTable:
def __init__(self, pa_table: _PATable) -> None: ...
def __arrow_c_stream__(self, requested_schema=None): ...
class GeoArrowArray:
def __init__(self, pa_field: _PAField, pa_array: _PAArray) -> None: ...
def __arrow_c_array__(self, requested_schema=None) -> tuple[Incomplete, Incomplete]: ...
def geopandas_to_arrow(
df: GeoDataFrame,
index: bool | None = None,
geometry_encoding: _GeomEncoding = "WKB",
interleaved: bool = True,
include_z: bool | None = None,
) -> tuple[_PATable, dict[str, str]]: ...
def construct_wkb_array(
shapely_arr: NDArray[np.object_], *, field_name: str = "geometry", crs: str | None = None
) -> tuple[_PAField, _PAArray]: ...
def construct_geometry_array(
shapely_arr: NDArray[np.object_],
include_z: bool | None = None,
*,
field_name: str = "geometry",
crs: str | None = None,
interleaved: bool = True,
) -> tuple[_PAField, _PAArray]: ...
def arrow_to_geopandas(table, geometry: str | None = None) -> GeoDataFrame: ...
def arrow_to_geometry_array(arr) -> GeometryArray: ...
def construct_shapely_array(arr: _PAArray, extension_name: str) -> NDArray[np.object_]: ...

View File

@@ -0,0 +1,22 @@
import os
from _typeshed import SupportsGetItem, SupportsKeysAndGetItem
from collections.abc import Iterable
from typing import Any, Final
from ..geodataframe import GeoDataFrame
METADATA_VERSION: Final[str]
SUPPORTED_VERSIONS: Final[list[str]]
GEOARROW_ENCODINGS: Final[list[str]]
SUPPORTED_ENCODINGS: Final[list[str]]
def _read_parquet(
path: str | os.PathLike[str],
columns: Iterable[str] | None = None,
storage_options: SupportsKeysAndGetItem[str, Any] | None = None, # type depend on the connection
bbox: SupportsGetItem[int, float] | None = None,
**kwargs, # kwargs passed to pyarrow.parquet.read_table
) -> GeoDataFrame: ...
def _read_feather(
path: str | os.PathLike[str], columns: Iterable[str] | None = None, **kwargs # kwargs passed to pyarrow.feather.read_table
) -> GeoDataFrame: ...

View File

@@ -0,0 +1,47 @@
import os
from _typeshed import Incomplete, SupportsRead
from collections import OrderedDict
from typing import Literal, TypedDict, overload
import pandas as pd
from pandas._typing import Axes
from ..base import _BboxLike, _MaskLike
from ..geodataframe import GeoDataFrame
# Keep inline with GeoDataFrame.from_file and GeoSeries.from_file
@overload
def _read_file(
filename: str | os.PathLike[str] | SupportsRead[Incomplete],
bbox: _BboxLike | None = None,
mask: _MaskLike | None = None,
columns: Axes | None = None,
rows: int | slice | None = None,
engine: Literal["fiona", "pyogrio"] | None = None,
*,
ignore_geometry: Literal[False] = False,
layer: int | str | None = None,
encoding: str | None = None,
**kwargs, # depend on engine
) -> GeoDataFrame: ...
@overload
def _read_file(
filename: str | os.PathLike[str] | SupportsRead[Incomplete],
bbox: _BboxLike | None = None,
mask: _MaskLike | None = None,
columns: Axes | None = None,
rows: int | slice | None = None,
engine: Literal["fiona", "pyogrio"] | None = None,
*,
ignore_geometry: Literal[True],
layer: int | str | None = None,
encoding: str | None = None,
**kwargs, # depend on engine
) -> pd.DataFrame: ...
class _Schema(TypedDict):
geometry: str | list[str]
properties: OrderedDict[str, str]
def infer_schema(df: GeoDataFrame) -> _Schema: ...
def _list_layers(filename: str | bytes | os.PathLike[str] | os.PathLike[bytes] | SupportsRead[Incomplete]) -> pd.DataFrame: ...

View File

@@ -0,0 +1,117 @@
import sqlite3
from _typeshed import Incomplete, SupportsLenAndGetItem
from collections.abc import Container, Iterator, Mapping
from contextlib import AbstractContextManager
from typing import Any, Protocol, overload
from typing_extensions import TypeAlias
from pandas._typing import Scalar
from ..base import _ConvertibleToCRS
from ..geodataframe import GeoDataFrame
# inline ruff noqa at _SqlalchemyConnectionLike.__enter__ confuses flake8
# ruff: noqa: PYI034
# Start SQLAlchemy hack
# ---------------------
# The code actually explicitly checks for SQLAlchemy's `Connection` and `Engine` with
# isinstance checks. However to avoid a dependency on SQLAlchemy, we use "good-enough"
# protocols that match as much as possible the SQLAlchemy implementation. This makes it
# very hard for someone to pass in the wrong object.
class _SqlalchemyTransactionLike(Protocol):
# is_active: bool
# connection: _SqlalchemyConnectionLike
# def __init__(self, connection: _SqlalchemyConnectionLike): ...
# @property
# def is_valid(self) -> bool: ...
def close(self) -> None: ...
def rollback(self) -> None: ...
def commit(self) -> None: ...
# `Any` is used in places where it would require to copy a lot of types from sqlalchemy
class _SqlAlchemyEventTarget(Protocol):
dispatch: Any
class _SqlalchemyConnectionLike(_SqlAlchemyEventTarget, Protocol):
engine: Any
@property
def closed(self) -> bool: ...
@property
def invalidated(self) -> bool: ...
def __enter__(self) -> _SqlalchemyConnectionLike: ... # noqa: Y034
def __exit__(self, type_, value, traceback, /) -> None: ...
@property
def info(self) -> dict[Any, Any]: ...
def invalidate(self, exception: BaseException | None = None) -> None: ...
def detach(self) -> None: ...
def begin(self) -> _SqlalchemyTransactionLike: ...
def commit(self) -> None: ...
def rollback(self) -> None: ...
def recover_twophase(self) -> list[Any]: ...
def rollback_prepared(self, xid: Any, recover: bool = ...) -> None: ...
def commit_prepared(self, xid: Any, recover: bool = ...) -> None: ...
def in_transaction(self) -> bool: ...
def in_nested_transaction(self) -> bool: ...
def close(self) -> None: ...
class _SqlalchemyEngineLike(_SqlAlchemyEventTarget, Protocol):
dialect: Any
pool: Any
url: Any
hide_parameters: bool
@property
def engine(self) -> _SqlalchemyEngineLike: ...
def clear_compiled_cache(self) -> None: ...
def update_execution_options(self, **opt: Any) -> None: ...
@property
def name(self) -> str: ...
@property
def driver(self) -> str: ...
def dispose(self, close: bool = True) -> None: ...
def begin(self) -> AbstractContextManager[Any]: ...
def connect(self) -> Any: ...
_SqlalchemyConnectableLike: TypeAlias = _SqlalchemyConnectionLike | _SqlalchemyEngineLike
# ---------------------
# End SQLAlchemy hack
_SQLConnection: TypeAlias = str | _SqlalchemyConnectableLike | sqlite3.Connection # coppied from pandas.io.sql
@overload
def _read_postgis(
sql: str,
con: _SQLConnection,
geom_col: str = "geom",
crs: _ConvertibleToCRS | None = None,
index_col: str | Container[str] | None = None,
coerce_float: bool = True,
parse_dates: Container[str | Mapping[str, Incomplete]] | Mapping[str, str | Mapping[str, Incomplete]] | None = None,
params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None,
*,
chunksize: int,
) -> Iterator[GeoDataFrame]: ...
@overload
def _read_postgis(
sql: str,
con: _SQLConnection,
geom_col: str = "geom",
crs: _ConvertibleToCRS | None = None,
index_col: str | Container[str] | None = None,
coerce_float: bool = True,
parse_dates: Container[str | Mapping[str, Incomplete]] | Mapping[str, str | Mapping[str, Incomplete]] | None = None,
params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None,
chunksize: None = None,
) -> GeoDataFrame: ...
@overload
def _read_postgis(
sql: str,
con: _SQLConnection,
geom_col: str = "geom",
crs: _ConvertibleToCRS | None = None,
index_col: str | Container[str] | None = None,
coerce_float: bool = True,
parse_dates: Container[str | Mapping[str, Incomplete]] | Mapping[str, str | Mapping[str, Incomplete]] | None = None,
params: SupportsLenAndGetItem[Scalar] | Mapping[str, Scalar] | None = None,
chunksize: int | None = None,
) -> GeoDataFrame | Iterator[GeoDataFrame]: ...

View File

@@ -0,0 +1,259 @@
from _typeshed import Incomplete
from collections.abc import Collection, Hashable, Iterable, Mapping, Sequence
from typing import Literal, overload
from typing_extensions import TypeAlias
import numpy as np
import pandas as pd
from matplotlib.axes import Axes # type: ignore[import-not-found]
from matplotlib.colors import Colormap, Normalize # type: ignore[import-not-found]
from matplotlib.typing import ColorType # type: ignore[import-not-found]
from numpy.typing import ArrayLike, NDArray
from pandas.plotting import PlotAccessor
from .geodataframe import GeoDataFrame
from .geoseries import GeoSeries
_ColorOrColors: TypeAlias = ColorType | Sequence[ColorType] | ArrayLike
def plot_series(
s: GeoSeries,
cmap: str | Colormap | None = None,
color: _ColorOrColors | None = None,
ax: Axes | None = None,
figsize: tuple[float, float] | None = None,
aspect: Literal["auto", "equal"] | float | None = "auto",
autolim: bool = True,
*,
# Extracted from `**style_kwds`
vmin: float = ...,
vmax: float = ...,
facecolor: _ColorOrColors | None = None,
norm: Normalize | None = None,
**style_kwds,
) -> Axes: ...
# IMPORTANT: keep roughly in sync with `GeoplotAccessor` methods below
def plot_dataframe(
df: GeoDataFrame,
column: Hashable | None = None,
cmap: str | Colormap | None = None,
color: _ColorOrColors | None = None,
ax: Axes | None = None,
cax: Axes | None = None,
categorical: bool = False,
legend: bool = False,
scheme: str | None = None,
k: int = 5,
vmin: float | None = None,
vmax: float | None = None,
markersize: str | float | Iterable[float] | ArrayLike | None = None,
figsize: tuple[float, float] | None = None,
legend_kwds: dict[str, Incomplete] | None = None,
categories: Iterable[Hashable] | None = None,
classification_kwds: dict[str, Incomplete] | None = None,
missing_kwds: dict[str, Incomplete] | None = None,
aspect: Literal["auto", "equal"] | float | None = "auto",
autolim: bool = True,
*,
# Extracted from `**style_kwds`
norm: Normalize | None = None,
alpha: float = 1,
facecolor: _ColorOrColors | None = None,
edgecolor: _ColorOrColors | None = None,
linewidth: float = ...,
label: str = "NaN",
**style_kwds,
) -> Axes: ...
# IMPORTANT: keep roughly in sync with `plot_dataframe`
class GeoplotAccessor(PlotAccessor):
# The first 3 overloads of calls are from pandas, the last overload is geopandas specific
@overload # type: ignore[override]
def __call__(
self,
x: Hashable = ...,
y: Hashable | Sequence[Hashable] = ...,
*,
kind: Literal["line", "bar", "barh", "hist", "box", "kde", "density", "area", "pie", "scatter", "hexbin"],
ax: Axes | None = None,
subplots: Literal[False] = False,
sharex: bool | None = None,
sharey: bool | None = None,
layout: tuple[int, int] | None = None,
figsize: tuple[float, float] | None = None,
use_index: bool = True,
title: str | None = None,
grid: bool | None = None,
legend: bool | Literal["reverse"] = True,
style: str | Sequence[str] | Mapping[Incomplete, str] | None = None,
logx: bool | Literal["sym"] = False,
logy: bool | Literal["sym"] = False,
loglog: bool | Literal["sym"] = False,
xticks: Sequence[float] | None = None,
yticks: Sequence[float] | None = None,
xlim: tuple[float, float] | list[float] | None = None,
ylim: tuple[float, float] | list[float] | None = None,
xlabel: str | None = None,
ylabel: str | None = None,
rot: float | None = None,
fontsize: float | None = None,
cmap: str | Colormap | None = None, # also accepts `colormap` but plot_dataframe uses `cmap`
colorbar: bool | None = None,
position: float = 0.5,
table: bool | pd.Series[Incomplete] | pd.DataFrame = False,
yerr: pd.DataFrame | pd.Series[float] | ArrayLike | Mapping[Incomplete, ArrayLike] | str = ...,
xerr: pd.DataFrame | pd.Series[float] | ArrayLike | Mapping[Incomplete, ArrayLike] | str = ...,
stacked: bool = ..., # default value depends on kind
secondary_y: bool | Sequence[Hashable] = False,
mark_right: bool = True,
include_bool: bool = False,
backend: str | None = None,
**kwargs,
) -> Axes: ...
@overload
def __call__(
self,
x: Hashable = ...,
y: Hashable | Sequence[Hashable] = ...,
*,
kind: Literal["line", "bar", "barh", "hist", "kde", "density", "area", "pie", "scatter", "hexbin"],
ax: Sequence[Axes] | None = None,
subplots: Literal[True] | Iterable[Iterable[Hashable]],
sharex: bool | None = None,
sharey: bool | None = None,
layout: tuple[int, int] | None = None,
figsize: tuple[float, float] | None = None,
use_index: bool = True,
title: str | Collection[str] | None = None,
grid: bool | None = None,
legend: bool | Literal["reverse"] = True,
style: str | Sequence[str] | Mapping[Incomplete, str] | None = None,
logx: bool | Literal["sym"] = False,
logy: bool | Literal["sym"] = False,
loglog: bool | Literal["sym"] = False,
xticks: Sequence[float] | None = None,
yticks: Sequence[float] | None = None,
xlim: tuple[float, float] | list[float] | None = None,
ylim: tuple[float, float] | list[float] | None = None,
xlabel: str | None = None,
ylabel: str | None = None,
rot: float | None = None,
fontsize: float | None = None,
cmap: str | Colormap | None = None, # also accepts `colormap` but plot_dataframe uses `cmap`
colorbar: bool | None = None,
position: float = 0.5,
table: bool | pd.Series[Incomplete] | pd.DataFrame = False,
yerr: pd.DataFrame | pd.Series[float] | ArrayLike | Mapping[Incomplete, ArrayLike] | str = ...,
xerr: pd.DataFrame | pd.Series[float] | ArrayLike | Mapping[Incomplete, ArrayLike] | str = ...,
stacked: bool = ..., # default value depends on kind
secondary_y: bool | Sequence[Hashable] = False,
mark_right: bool = True,
include_bool: bool = False,
backend: str | None = None,
**kwargs,
) -> NDArray[np.object_]: ... # should be NDArray[Axes] but it is not supported
@overload
def __call__(
self,
x: Hashable = ...,
y: Hashable | Sequence[Hashable] = ...,
*,
kind: Literal["box"],
ax: Sequence[Axes] | None = None,
subplots: Literal[True] | Iterable[Iterable[Hashable]],
sharex: bool | None = None,
sharey: bool | None = None,
layout: tuple[int, int] | None = None,
figsize: tuple[float, float] | None = None,
use_index: bool = True,
title: str | Collection[str] | None = None,
grid: bool | None = None,
legend: bool | Literal["reverse"] = True,
style: str | Sequence[str] | Mapping[Incomplete, str] | None = None,
logx: bool | Literal["sym"] = False,
logy: bool | Literal["sym"] = False,
loglog: bool | Literal["sym"] = False,
xticks: Sequence[float] | None = None,
yticks: Sequence[float] | None = None,
xlim: tuple[float, float] | list[float] | None = None,
ylim: tuple[float, float] | list[float] | None = None,
xlabel: str | None = None,
ylabel: str | None = None,
rot: float | None = None,
fontsize: float | None = None,
cmap: str | Colormap | None = None, # also accepts `colormap` but plot_dataframe uses `cmap`
colorbar: bool | None = None,
position: float = 0.5,
table: bool | pd.Series[Incomplete] | pd.DataFrame = False,
yerr: pd.DataFrame | pd.Series[float] | ArrayLike | Mapping[Incomplete, ArrayLike] | str = ...,
xerr: pd.DataFrame | pd.Series[float] | ArrayLike | Mapping[Incomplete, ArrayLike] | str = ...,
stacked: bool = ..., # default value depends on kind
secondary_y: bool | Sequence[Hashable] = False,
mark_right: bool = True,
include_bool: bool = False,
backend: str | None = None,
**kwargs,
) -> pd.Series[Axes]: ... # type: ignore[type-var] # pyright: ignore[reportInvalidTypeArguments]
@overload
def __call__(
self,
column: Hashable | None = None,
cmap: str | Colormap | None = None,
color: _ColorOrColors | None = None,
ax: Axes | None = None,
cax: Axes | None = None,
categorical: bool = False,
legend: bool = False,
scheme: str | None = None,
k: int = 5,
vmin: float | None = None,
vmax: float | None = None,
markersize: str | float | Iterable[float] | ArrayLike | None = None,
figsize: tuple[float, float] | None = None,
legend_kwds: dict[str, Incomplete] | None = None,
categories: Iterable[Hashable] | None = None,
classification_kwds: dict[str, Incomplete] | None = None,
missing_kwds: dict[str, Incomplete] | None = None,
aspect: Literal["auto", "equal"] | float | None = "auto",
*,
kind: Literal["geo"] = "geo",
# Extracted from `**style_kwds`
norm: Normalize | None = None,
alpha: float = 1,
facecolor: _ColorOrColors | None = None,
edgecolor: _ColorOrColors | None = None,
linewidth: float = ...,
label: str = "NaN",
**style_kwds,
) -> Axes: ...
def geo(
self,
column: Hashable | None = None,
cmap: str | Colormap | None = None,
color: _ColorOrColors | None = None,
ax: Axes | None = None,
cax: Axes | None = None,
categorical: bool = False,
legend: bool = False,
scheme: str | None = None,
k: int = 5,
vmin: float | None = None,
vmax: float | None = None,
markersize: str | float | Iterable[float] | ArrayLike | None = None,
figsize: tuple[float, float] | None = None,
legend_kwds: dict[str, Incomplete] | None = None,
categories: Iterable[Hashable] | None = None,
classification_kwds: dict[str, Incomplete] | None = None,
missing_kwds: dict[str, Incomplete] | None = None,
aspect: Literal["auto", "equal"] | float | None = "auto",
*,
# Extracted from `**style_kwds`
norm: Normalize | None = None,
alpha: float = 1,
facecolor: _ColorOrColors | None = None,
edgecolor: _ColorOrColors | None = None,
linewidth: float = ...,
label: str = "NaN",
**style_kwds,
) -> Axes: ...

View File

@@ -0,0 +1,79 @@
from collections.abc import Iterable
from typing import Any, Final, Literal, overload
import numpy as np
from numpy.typing import ArrayLike, NDArray
from shapely import Geometry
from .array import _Array1D, _Array2D
PREDICATES: Final[set[str | None]]
class SpatialIndex:
geometries: NDArray[np.object_]
def __init__(self, geometry: NDArray[np.object_]) -> None: ...
@property
def valid_query_predicates(self) -> set[str | None]: ...
@overload
def query(
self,
geometry: Geometry | ArrayLike,
predicate: str | None = None,
sort: bool = False,
distance: float | ArrayLike | None = None,
output_format: Literal["tuple"] = "tuple",
) -> NDArray[np.int64]: ...
@overload
def query(
self,
geometry: Geometry | ArrayLike,
predicate: str | None = None,
sort: bool = False,
distance: float | ArrayLike | None = None,
*,
output_format: Literal["dense"],
) -> NDArray[np.bool_]: ...
@overload
def query(
self,
geometry: Geometry | ArrayLike,
predicate: str | None = None,
sort: bool = False,
distance: float | ArrayLike | None = None,
*,
output_format: Literal["sparse"],
) -> Any: ... # returns scipy coo_array but we don't depend on scipy
@overload
def nearest(
self,
geometry,
return_all: bool = True,
max_distance: float | None = None,
return_distance: Literal[False] = False,
exclusive: bool = False,
) -> _Array2D[np.int64]: ...
@overload
def nearest(
self,
geometry,
return_all: bool = True,
max_distance: float | None = None,
*,
return_distance: Literal[True],
exclusive: bool = False,
) -> tuple[_Array2D[np.int64], _Array1D[np.float64]]: ...
@overload
def nearest(
self,
geometry,
return_all: bool = True,
max_distance: float | None = None,
return_distance: bool = False,
exclusive: bool = False,
) -> _Array2D[np.int64] | tuple[_Array2D[np.int64], _Array1D[np.float64]]: ...
def intersection(self, coordinates: Iterable[float]) -> _Array1D[np.int64]: ...
@property
def size(self) -> int: ...
@property
def is_empty(self) -> bool: ...
def __len__(self) -> int: ...

View File

@@ -0,0 +1,33 @@
from typing import Literal
from .array import GeometryArray
from .base import GeoPandasBase
from .geodataframe import GeoDataFrame
from .geoseries import GeoSeries
def geom_equals(this: GeoPandasBase | GeometryArray, that: GeoPandasBase | GeometryArray) -> bool: ...
def geom_almost_equals(this: GeoPandasBase | GeometryArray, that: GeoPandasBase | GeometryArray) -> bool: ...
def assert_geoseries_equal(
left: GeoSeries,
right: GeoSeries,
check_dtype: bool = True,
check_index_type: bool = False,
check_series_type: bool = True,
check_less_precise: bool = False,
check_geom_type: bool = False,
check_crs: bool = True,
normalize: bool = False,
) -> None: ...
def assert_geodataframe_equal(
left: GeoDataFrame,
right: GeoDataFrame,
check_dtype: bool = True,
check_index_type: bool | Literal["equiv"] = "equiv",
check_column_type: bool | Literal["equiv"] = "equiv",
check_frame_type: bool = True,
check_like: bool = False,
check_less_precise: bool = False,
check_geom_type: bool = False,
check_crs: bool = True,
normalize: bool = False,
) -> None: ...

View File

@@ -0,0 +1,7 @@
from .clip import clip as clip
from .geocoding import geocode as geocode, reverse_geocode as reverse_geocode
from .overlay import overlay as overlay
from .sjoin import sjoin as sjoin, sjoin_nearest as sjoin_nearest
from .util import collect as collect
__all__ = ["collect", "geocode", "overlay", "reverse_geocode", "sjoin", "sjoin_nearest", "clip"]

View File

@@ -0,0 +1 @@
def show_versions() -> None: ...

View File

@@ -0,0 +1,9 @@
from typing import TypeVar
from ..base import _ClipMask
from ..geodataframe import GeoDataFrame
from ..geoseries import GeoSeries
_G = TypeVar("_G", GeoDataFrame, GeoSeries)
def clip(gdf: _G, mask: _ClipMask, keep_geom_type: bool = False, sort: bool = False) -> _G: ...

View File

@@ -0,0 +1,18 @@
from collections.abc import Callable, Iterable
from typing import Protocol, type_check_only
from ..base import _ConvertibleToGeoSeries
from ..geodataframe import GeoDataFrame
@type_check_only
class _GeoCoder(Protocol):
# Represents a geopy.geocoders.base.GeoCoder subclass without actually depending on geopy
def geocode(self, query: str, /): ...
def reverse(self, coords, /, exactly_one: bool = ...): ...
# TODO Use something like `provider: Callable[P, _GeoCoder], **kwargs: P.kwargs` in the functions
# below if this ever becomes a thing
def geocode(strings: Iterable[str], provider: str | Callable[..., _GeoCoder] | None = None, **kwargs) -> GeoDataFrame: ...
def reverse_geocode(
points: _ConvertibleToGeoSeries, provider: str | Callable[..., _GeoCoder] | None = None, **kwargs
) -> GeoDataFrame: ...

View File

@@ -0,0 +1 @@
MAX_LEVEL: int

View File

@@ -0,0 +1,5 @@
from ..geodataframe import GeoDataFrame
def overlay(
df1: GeoDataFrame, df2: GeoDataFrame, how: str = "intersection", keep_geom_type: bool | None = None, make_valid: bool = True
) -> GeoDataFrame: ...

View File

@@ -0,0 +1,26 @@
from typing import Literal
from numpy.typing import ArrayLike
from ..geodataframe import GeoDataFrame
def sjoin(
left_df: GeoDataFrame,
right_df: GeoDataFrame,
how: Literal["left", "right", "inner"] = "inner",
predicate: str = "intersects",
lsuffix: str = "left",
rsuffix: str = "right",
distance: float | ArrayLike | None = None,
on_attribute: str | tuple[str, ...] | list[str] | None = None,
) -> GeoDataFrame: ...
def sjoin_nearest(
left_df: GeoDataFrame,
right_df: GeoDataFrame,
how: Literal["left", "right", "inner"] = "inner",
max_distance: float | None = None,
lsuffix: str = "left",
rsuffix: str = "right",
distance_col: str | None = None,
exclusive: bool = False,
) -> GeoDataFrame: ...

View File

@@ -0,0 +1,12 @@
from collections.abc import Collection
from typing import Any
import pandas as pd
from shapely import Geometry
from shapely.geometry.base import BaseGeometry
from ..geoseries import GeoSeries
def collect(
x: Collection[Geometry] | GeoSeries | pd.Series[Any] | Geometry, multi: bool = False # Cannot use pd.Series[BaseGeometry]
) -> BaseGeometry: ...

View File

@@ -18,3 +18,7 @@ stubs/openpyxl/openpyxl/descriptors/nested.pyi
# matplotlib not installed during tests
stubs/shapely/shapely/plotting.pyi
# matplotlib et al not installed during tests
stubs/geopandas/geopandas/plotting.pyi
stubs/geopandas/geopandas/explore.pyi