diff --git a/doc/source/_static/code/buffer.py b/doc/source/_static/code/buffer.py new file mode 100644 index 0000000..cda8556 --- /dev/null +++ b/doc/source/_static/code/buffer.py @@ -0,0 +1,43 @@ +""" +Create an illustrative figure for different kwargs +in buffer method. +""" + + +import geopandas +import matplotlib.pyplot as plt + +from shapely.geometry import Point, LineString, Polygon + +s = geopandas.GeoSeries( + [ + Point(0, 0), + LineString([(1, -1), (1, 0), (2, 0), (2, 1)]), + Polygon([(3, -1), (4, 0), (3, 1)]), + ] +) + +fix, axs = plt.subplots( + 3, 2, figsize=(12, 12), sharex=True, sharey=True, bbox_inches="tight" +) +for ax in axs.flatten(): + s.plot(ax=ax) + ax.set(xticks=[], yticks=[]) + +s.buffer(0.2).plot(ax=axs[0, 0], alpha=0.6) +axs[0, 0].set_title("s.buffer(0.2)") + +s.buffer(0.2, resolution=2).plot(ax=axs[0, 1], alpha=0.6) +axs[0, 1].set_title("s.buffer(0.2, resolution=2)") + +s.buffer(0.2, cap_style=2).plot(ax=axs[1, 0], alpha=0.6) +axs[1, 0].set_title("s.buffer(0.2, cap_style=2)") + +s.buffer(0.2, cap_style=3).plot(ax=axs[1, 1], alpha=0.6) +axs[1, 1].set_title("s.buffer(0.2, cap_style=3)") + +s.buffer(0.2, join_style=2).plot(ax=axs[2, 0], alpha=0.6) +axs[2, 0].set_title("s.buffer(0.2, join_style=2)") + +s.buffer(0.2, join_style=3).plot(ax=axs[2, 1], alpha=0.6) +axs[2, 1].set_title("s.buffer(0.2, join_style=3)") diff --git a/doc/source/conf.py b/doc/source/conf.py index 2be0bc0..5f211f3 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -36,6 +36,7 @@ extensions = [ "myst_nb", "numpydoc", 'sphinx_toggleprompt', + "matplotlib.sphinxext.plot_directive" ] # continue doc build and only print warnings/errors in examples diff --git a/geopandas/base.py b/geopandas/base.py index e675a51..f9401c0 100644 --- a/geopandas/base.py +++ b/geopandas/base.py @@ -996,7 +996,7 @@ GeometryCollection def buffer(self, distance, resolution=16, **kwargs): """Returns a ``GeoSeries`` of geometries representing all points within - a given `distance` of each geometric object. + a given ``distance`` of each geometric object. See http://shapely.readthedocs.io/en/latest/manual.html#object.buffer for details. @@ -1006,9 +1006,38 @@ GeometryCollection distance : float, np.array, pd.Series The radius of the buffer. If np.array or pd.Series are used then it must have same length as the GeoSeries. - resolution: int - Optional, the resolution of the buffer around each vertex. + resolution : int (optional, default 16) + The resolution of the buffer around each vertex. + + Examples + -------- + >>> from shapely.geometry import Point, LineString, Polygon + >>> s = geopandas.GeoSeries( + ... [ + ... Point(0, 0), + ... LineString([(1, -1), (1, 0), (2, 0), (2, 1)]), + ... Polygon([(3, -1), (4, 0), (3, 1)]), + ... ] + ... ) + >>> s + 0 POINT (0.00000 0.00000) + 1 LINESTRING (1.00000 -1.00000, 1.00000 0.00000,... + 2 POLYGON ((3.00000 -1.00000, 4.00000 0.00000, 3... + dtype: geometry + + >>> s.buffer(0.2) + 0 POLYGON ((0.20000 0.00000, 0.19904 -0.01960, 0... + 1 POLYGON ((0.80000 0.00000, 0.80096 0.01960, 0.... + 2 POLYGON ((2.80000 -1.00000, 2.80000 1.00000, 2... + dtype: geometry + + ``**kwargs`` accept further specification as ``join_style`` and ``cap_style``. + See the following illustration of different options. + + .. plot:: _static/code/buffer.py + """ + # TODO: update docstring based on pygeos after shapely 2.0 if isinstance(distance, pd.Series): if not self.index.equals(distance.index): raise ValueError( @@ -1033,9 +1062,32 @@ GeometryCollection tolerance : float All points in a simplified geometry will be no more than `tolerance` distance from the original. - preserve_topology: bool + preserve_topology: bool (default True) False uses a quicker algorithm, but may produce self-intersecting or otherwise invalid geometries. + + Notes + ----- + Invalid geometric objects may result from simplification that does not + preserve topology and simplification may be sensitive to the order of + coordinates: two geometries differing only in order of coordinates may be + simplified differently. + + Examples + -------- + >>> from shapely.geometry import Point, LineString + >>> s = geopandas.GeoSeries( + ... [Point(0, 0).buffer(1), LineString([(0, 0), (1, 10), (0, 20)])] + ... ) + >>> s + 0 POLYGON ((1.00000 0.00000, 0.99518 -0.09802, 0... + 1 LINESTRING (0.00000 0.00000, 1.00000 10.00000,... + dtype: geometry + + >>> s.simplify(1) + 0 POLYGON ((1.00000 0.00000, 0.00000 -1.00000, -... + 1 LINESTRING (0.00000 0.00000, 0.00000 20.00000) + dtype: geometry """ return _delegate_geo_method("simplify", self, *args, **kwargs) @@ -1108,10 +1160,35 @@ GeometryCollection ---------- matrix: List or tuple 6 or 12 items for 2D or 3D transformations respectively. + For 2D affine transformations, - the 6 parameter matrix is [a, b, d, e, xoff, yoff] + the 6 parameter matrix is ``[a, b, d, e, xoff, yoff]`` + For 3D affine transformations, - the 12 parameter matrix is [a, b, c, d, e, f, g, h, i, xoff, yoff, zoff] + the 12 parameter matrix is ``[a, b, c, d, e, f, g, h, i, xoff, yoff, zoff]`` + + Examples + -------- + >>> from shapely.geometry import Point, LineString, Polygon + >>> s = geopandas.GeoSeries( + ... [ + ... Point(1, 1), + ... LineString([(1, -1), (1, 0)]), + ... Polygon([(3, -1), (4, 0), (3, 1)]), + ... ] + ... ) + >>> s + 0 POINT (1.00000 1.00000) + 1 LINESTRING (1.00000 -1.00000, 1.00000 0.00000) + 2 POLYGON ((3.00000 -1.00000, 4.00000 0.00000, 3... + dtype: geometry + + >>> s.affine_transform([2, 3, 2, 4, 5, 2]) + 0 POINT (10.00000 8.00000) + 1 LINESTRING (4.00000 0.00000, 7.00000 4.00000) + 2 POLYGON ((8.00000 4.00000, 13.00000 10.00000, ... + dtype: geometry + """ # noqa (E501 link is longer than max line length) return _delegate_geo_method("affine_transform", self, matrix) @@ -1127,6 +1204,29 @@ GeometryCollection Amount of offset along each dimension. xoff, yoff, and zoff for translation along the x, y, and z dimensions respectively. + + Examples + -------- + >>> from shapely.geometry import Point, LineString, Polygon + >>> s = geopandas.GeoSeries( + ... [ + ... Point(1, 1), + ... LineString([(1, -1), (1, 0)]), + ... Polygon([(3, -1), (4, 0), (3, 1)]), + ... ] + ... ) + >>> s + 0 POINT (1.00000 1.00000) + 1 LINESTRING (1.00000 -1.00000, 1.00000 0.00000) + 2 POLYGON ((3.00000 -1.00000, 4.00000 0.00000, 3... + dtype: geometry + + >>> s.translate(2, 3) + 0 POINT (3.00000 4.00000) + 1 LINESTRING (3.00000 2.00000, 3.00000 3.00000) + 2 POLYGON ((5.00000 2.00000, 6.00000 3.00000, 5.... + dtype: geometry + """ # noqa (E501 link is longer than max line length) return _delegate_geo_method("translate", self, xoff, yoff, zoff) @@ -1148,6 +1248,35 @@ GeometryCollection object or a coordinate tuple (x, y). use_radians : boolean Whether to interpret the angle of rotation as degrees or radians + + Examples + -------- + >>> from shapely.geometry import Point, LineString, Polygon + >>> s = geopandas.GeoSeries( + ... [ + ... Point(1, 1), + ... LineString([(1, -1), (1, 0)]), + ... Polygon([(3, -1), (4, 0), (3, 1)]), + ... ] + ... ) + >>> s + 0 POINT (1.00000 1.00000) + 1 LINESTRING (1.00000 -1.00000, 1.00000 0.00000) + 2 POLYGON ((3.00000 -1.00000, 4.00000 0.00000, 3... + dtype: geometry + + >>> s.rotate(90) + 0 POINT (1.00000 1.00000) + 1 LINESTRING (1.50000 -0.50000, 0.50000 -0.50000) + 2 POLYGON ((4.50000 -0.50000, 3.50000 0.50000, 2... + dtype: geometry + + >>> s.rotate(90, origin=(0, 0)) + 0 POINT (-1.00000 1.00000) + 1 LINESTRING (1.00000 1.00000, 0.00000 1.00000) + 2 POLYGON ((1.00000 3.00000, 0.00000 4.00000, -1... + dtype: geometry + """ return _delegate_geo_method( "rotate", self, angle, origin=origin, use_radians=use_radians @@ -1170,6 +1299,34 @@ GeometryCollection The point of origin can be a keyword 'center' for the 2D bounding box center (default), 'centroid' for the geometry's 2D centroid, a Point object or a coordinate tuple (x, y, z). + + Examples + -------- + >>> from shapely.geometry import Point, LineString, Polygon + >>> s = geopandas.GeoSeries( + ... [ + ... Point(1, 1), + ... LineString([(1, -1), (1, 0)]), + ... Polygon([(3, -1), (4, 0), (3, 1)]), + ... ] + ... ) + >>> s + 0 POINT (1.00000 1.00000) + 1 LINESTRING (1.00000 -1.00000, 1.00000 0.00000) + 2 POLYGON ((3.00000 -1.00000, 4.00000 0.00000, 3... + dtype: geometry + + >>> s.scale(2, 3) + 0 POINT (1.00000 1.00000) + 1 LINESTRING (1.00000 -2.00000, 1.00000 1.00000) + 2 POLYGON ((2.50000 -3.00000, 4.50000 0.00000, 2... + dtype: geometry + + >>> s.scale(2, 3, origin=(0, 0)) + 0 POINT (2.00000 3.00000) + 1 LINESTRING (2.00000 -3.00000, 2.00000 0.00000) + 2 POLYGON ((6.00000 -3.00000, 8.00000 0.00000, 6... + dtype: geometry """ return _delegate_geo_method("scale", self, xfact, yfact, zfact, origin=origin) @@ -1193,6 +1350,34 @@ GeometryCollection object or a coordinate tuple (x, y). use_radians : boolean Whether to interpret the shear angle(s) as degrees or radians + + Examples + -------- + >>> from shapely.geometry import Point, LineString, Polygon + >>> s = geopandas.GeoSeries( + ... [ + ... Point(1, 1), + ... LineString([(1, -1), (1, 0)]), + ... Polygon([(3, -1), (4, 0), (3, 1)]), + ... ] + ... ) + >>> s + 0 POINT (1.00000 1.00000) + 1 LINESTRING (1.00000 -1.00000, 1.00000 0.00000) + 2 POLYGON ((3.00000 -1.00000, 4.00000 0.00000, 3... + dtype: geometry + + >>> s.skew(45, 30) + 0 POINT (1.00000 1.00000) + 1 LINESTRING (0.50000 -1.00000, 1.50000 0.00000) + 2 POLYGON ((2.00000 -1.28868, 4.00000 0.28868, 4... + dtype: geometry + + >>> s.skew(45, 30, origin=(0, 0)) + 0 POINT (2.00000 1.57735) + 1 LINESTRING (0.00000 -0.42265, 1.00000 0.57735) + 2 POLYGON ((2.00000 0.73205, 4.00000 2.30940, 4.... + dtype: geometry """ return _delegate_geo_method( "skew", self, xs, ys, origin=origin, use_radians=use_radians diff --git a/geopandas/geodataframe.py b/geopandas/geodataframe.py index d122e53..507da60 100644 --- a/geopandas/geodataframe.py +++ b/geopandas/geodataframe.py @@ -578,11 +578,28 @@ class GeoDataFrame(GeoPandasBase, DataFrame): Examples -------- + PostGIS + + >>> from sqlalchemy import create_engine # doctest: +SKIP + >>> db_connection_url = "postgres://myusername:mypassword@myhost:5432/mydb" + >>> con = create_engine(db_connection_url) # doctest: +SKIP >>> sql = "SELECT geom, highway FROM roads" + >>> df = geopandas.GeoDataFrame.from_postgis(sql, con) # doctest: +SKIP SpatiaLite + >>> sql = "SELECT ST_Binary(geom) AS geom, highway FROM roads" >>> df = geopandas.GeoDataFrame.from_postgis(sql, con) # doctest: +SKIP + + The recommended method of reading from PostGIS is + :func:`geopandas.read_postgis`: + + >>> df = geopandas.read_postgis(sql, con) # doctest: +SKIP + + See also + -------- + geopandas.read_postgis + """ df = geopandas.io.sql._read_postgis( diff --git a/geopandas/geoseries.py b/geopandas/geoseries.py index e671808..59b6d92 100644 --- a/geopandas/geoseries.py +++ b/geopandas/geoseries.py @@ -91,6 +91,47 @@ class GeoSeries(GeoPandasBase, Series): 2 POINT (3.00000 3.00000) dtype: geometry + >>> s = geopandas.GeoSeries( + ... [Point(1, 1), Point(2, 2), Point(3, 3)], crs="EPSG:3857" + ... ) + >>> s.crs # doctest: +SKIP + + Name: WGS 84 / Pseudo-Mercator + Axis Info [cartesian]: + - X[east]: Easting (metre) + - Y[north]: Northing (metre) + Area of Use: + - name: World - 85°S to 85°N + - bounds: (-180.0, -85.06, 180.0, 85.06) + Coordinate Operation: + - name: Popular Visualisation Pseudo-Mercator + - method: Popular Visualisation Pseudo Mercator + Datum: World Geodetic System 1984 + - Ellipsoid: WGS 84 + - Prime Meridian: Greenwich + + >>> s = geopandas.GeoSeries( + ... [Point(1, 1), Point(2, 2), Point(3, 3)], index=["a", "b", "c"], crs=4326 + ... ) + >>> s + a POINT (1.00000 1.00000) + b POINT (2.00000 2.00000) + c POINT (3.00000 3.00000) + dtype: geometry + + >>> s.crs + + Name: WGS 84 + Axis Info [ellipsoidal]: + - Lat[north]: Geodetic latitude (degree) + - Lon[east]: Geodetic longitude (degree) + Area of Use: + - name: World + - bounds: (-180.0, -90.0, 180.0, 90.0) + Datum: World Geodetic System 1984 + - Ellipsoid: WGS 84 + - Prime Meridian: Greenwich + See Also -------- GeoDataFrame diff --git a/geopandas/io/arrow.py b/geopandas/io/arrow.py index acd574f..014d0da 100644 --- a/geopandas/io/arrow.py +++ b/geopandas/io/arrow.py @@ -394,6 +394,17 @@ def _read_parquet(path, columns=None, **kwargs): Returns ------- GeoDataFrame + + Examples + -------- + >>> df = geopandas.read_parquet("data.parquet") # doctest: +SKIP + + Specifying columns to read: + + >>> df = geopandas.read_parquet( + ... "data.parquet", + ... columns=["geometry", "pop_est"] + ... ) # doctest: +SKIP """ parquet = import_optional_dependency( @@ -439,6 +450,17 @@ def _read_feather(path, columns=None, **kwargs): Returns ------- GeoDataFrame + + Examples + -------- + >>> df = geopandas.read_feather("data.feather") # doctest: +SKIP + + Specifying columns to read: + + >>> df = geopandas.read_feather( + ... "data.feather", + ... columns=["geometry", "pop_est"] + ... ) # doctest: +SKIP """ feather = import_optional_dependency( diff --git a/geopandas/io/file.py b/geopandas/io/file.py index 4f98e69..2ce09bc 100644 --- a/geopandas/io/file.py +++ b/geopandas/io/file.py @@ -79,6 +79,22 @@ def _read_file(filename, bbox=None, mask=None, rows=None, **kwargs): -------- >>> df = geopandas.read_file("nybb.shp") # doctest: +SKIP + Specifying layer of GPKG: + + >>> df = geopandas.read_file("file.gpkg", layer='cities') # doctest: +SKIP + + Reading only first 10 rows: + + >>> df = geopandas.read_file("nybb.shp", rows=10) # doctest: +SKIP + + Reading only geometries intersecting ``mask``: + + >>> df = geopandas.read_file("nybb.shp", mask=polygon) # doctest: +SKIP + + Reading only geometries intersecting ``bbox``: + + >>> df = geopandas.read_file("nybb.shp", bbox=(0, 10, 0, 20)) # doctest: +SKIP + Returns ------- :obj:`geopandas.GeoDataFrame` or :obj:`pandas.DataFrame` : diff --git a/geopandas/io/sql.py b/geopandas/io/sql.py index a833867..66c9d85 100644 --- a/geopandas/io/sql.py +++ b/geopandas/io/sql.py @@ -106,10 +106,16 @@ def _read_postgis( Examples -------- PostGIS - >>> sql = "SELECT geom, kind FROM polygons" + + >>> from sqlalchemy import create_engine # doctest: +SKIP + >>> db_connection_url = "postgres://myusername:mypassword@myhost:5432/mydatabase" + >>> con = create_engine(db_connection_url) # doctest: +SKIP + >>> sql = "SELECT geom, highway FROM roads" + >>> df = geopandas.read_postgis(sql, con) # doctest: +SKIP SpatiaLite - >>> sql = "SELECT ST_AsBinary(geom) AS geom, kind FROM polygons" + + >>> sql = "SELECT ST_Binary(geom) AS geom, highway FROM roads" >>> df = geopandas.read_postgis(sql, con) # doctest: +SKIP """