Skip to content

Commit 8a15cb9

Browse files
committed
Edit docs for graph and meta modules
1 parent 1788e43 commit 8a15cb9

File tree

7 files changed

+328
-81
lines changed

7 files changed

+328
-81
lines changed

docs/_static/shipit-squirrel.png

-198 KB
Binary file not shown.

docs/api.rst

+5-11
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ API Reference
66
.. contents:: Table of Contents
77
:local:
88

9+
10+
.. Only the graph class in intended to be a part of the public API, so
11+
we only document that here.
12+
913
Adjacency graphs
1014
----------------
1115

1216
.. autoclass:: gerrychain.graph.graph.Graph
17+
:members:
1318

1419
Partitions
1520
----------
@@ -36,17 +41,6 @@ Binary constraints
3641
.. automodule:: gerrychain.constraints
3742
:members:
3843

39-
.. autoclass:: gerrychain.constraints.Validator
40-
41-
.. autoclass:: gerrychain.constraints.UpperBound
42-
43-
.. autoclass:: gerrychain.constraints.LowerBound
44-
45-
.. autoclass:: gerrychain.constraints.SelfConfiguringLowerBound
46-
47-
.. autoclass:: gerrychain.constraints.SelfConfiguringUpperBound
48-
49-
.. autoclass:: gerrychain.constraints.WithinPercentRangeOfBounds
5044

5145
Updaters
5246
--------

gerrychain/graph/__init__.py

+15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
"""
2+
This module provides a :class:`~gerrychain.graph.Graph` class that
3+
extends the :class:`networkx.Graph` and includes some useful methods
4+
for working with graphs representing geographic data. The class
5+
:class:`~gerrychain.graph.Graph` is the only part of this module that
6+
is intended to be used directly by users of GerryChain.
7+
8+
The other classes and functions in this module are used internally by
9+
GerryChain. These include the geographic manipulation functions
10+
available in :mod:`gerrychain.graph.geo`, the adjacency functions
11+
in :mod:`gerrychain.graph.adjacency`, and the class
12+
:class:`~gerrychain.graph.FrozenGraph` in the file
13+
:mod:`gerrychain.graph.graph`. See the documentation at the top
14+
of those files for more information.
15+
"""
116
from .adjacency import *
217
from .geo import *
318
from .graph import *

gerrychain/graph/adjacency.py

+66-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
1+
"""
2+
This module provides a set of functions to help determine and
3+
manipulate the adjacency of geometries within a particular
4+
graph. The functions in this module are used internally to ensure
5+
that the geometry data that we are working with is sufficiently
6+
well-defined to be used for analysis.
7+
8+
Some of the type hints in this module are intentionally left
9+
unspecified because of import issues.
10+
"""
11+
112
import warnings
13+
from geopandas import GeoDataFrame
14+
from typing import Dict
215

316

4-
def neighbors(df, adjacency):
17+
def neighbors(df: GeoDataFrame, adjacency: str) -> Dict:
518
if adjacency not in ("rook", "queen"):
619
raise ValueError(
720
"The adjacency parameter provided is not supported. "
@@ -12,8 +25,15 @@ def neighbors(df, adjacency):
1225

1326

1427
def str_tree(geometries):
15-
"""Add ids to geometries and create a STR tree for spatial indexing.
28+
"""
29+
Add ids to geometries and create a STR tree for spatial indexing.
1630
Use this for all spatial operations!
31+
32+
:param geometries: A Shapely geometry object to construct the tree from.
33+
:type geometries: shapely.geometry.BaseGeometry
34+
35+
:returns: A Sort-Tile-Recursive tree for spatial indexing.
36+
:rtype: shapely.strtree.STRtree
1737
"""
1838
from shapely.strtree import STRtree
1939

@@ -25,7 +45,17 @@ def str_tree(geometries):
2545

2646

2747
def neighboring_geometries(geometries, tree=None):
28-
"""Generator yielding tuples of the form (id, (ids of neighbors))."""
48+
"""
49+
Generator yielding tuples of the form (id, (ids of neighbors)).
50+
51+
:param geometries: A Shapeley geometry object to construct the tree from
52+
:type geometries: shapely.geometry.BaseGeometry
53+
:param tree: A Sort-Tile-Recursive tree for spatial indexing. Default is None.
54+
:type tree: shapely.strtree.STRtree, optional
55+
56+
:returns: A generator yielding tuples of the form (id, (ids of neighbors))
57+
:rtype: Generator
58+
"""
2959
if tree is None:
3060
tree = str_tree(geometries)
3161

@@ -40,8 +70,15 @@ def neighboring_geometries(geometries, tree=None):
4070

4171

4272
def intersections_with_neighbors(geometries):
43-
"""Generator yielding tuples of the form (id, {neighbor_id: intersection}).
73+
"""
74+
Generator yielding tuples of the form (id, {neighbor_id: intersection}).
4475
The intersections may be empty!
76+
77+
:param geometries: A Shapeley geometry object.
78+
:type geometries: shapely.geometry.BaseGeometry
79+
80+
:returns: A generator yielding tuples of the form (id, {neighbor_id: intersection})
81+
:rtype: Generator
4582
"""
4683
for i, neighbors in neighboring_geometries(geometries):
4784
intersections = {
@@ -51,6 +88,16 @@ def intersections_with_neighbors(geometries):
5188

5289

5390
def warn_for_overlaps(intersection_pairs):
91+
"""
92+
:param intersection_pairs: An iterable of tuples of
93+
the form (id, {neighbor_id: intersection})
94+
:type intersection_pairs: Iterable
95+
96+
:returns: A generator yielding tuples of intersection pairs
97+
:rtype: Generator
98+
99+
:raises: UserWarning if there are overlaps among the given polygons
100+
"""
54101
overlaps = set()
55102
for i, intersections in intersection_pairs:
56103
overlaps.update(
@@ -70,7 +117,13 @@ def warn_for_overlaps(intersection_pairs):
70117

71118

72119
def queen(geometries):
73-
"""Return queen adjacency dictionary for the given collection of polygons."""
120+
"""
121+
:param geometries: A Shapeley geometry object.
122+
:type geometries: shapely.geometry.BaseGeometry
123+
124+
:returns: The queen adjacency dictionary for the given collection of polygons.
125+
:rtype: Dict
126+
"""
74127
intersection_pairs = warn_for_overlaps(intersections_with_neighbors(geometries))
75128

76129
return {
@@ -84,11 +137,18 @@ def queen(geometries):
84137

85138

86139
def rook(geometries):
87-
"""Return rook adjacency dictionary for the given collection of polygons."""
140+
"""
141+
:param geometries: A Shapeley geometry object.
142+
:type geometries: shapely.geometry.BaseGeometry
143+
144+
:returns: The rook adjacency dictionary for the given collection of polygons.
145+
:rtype: Dict
146+
"""
88147
return {
89148
i: {j: data for j, data in neighbors.items() if data["shared_perim"] > 0}
90149
for i, neighbors in queen(geometries).items()
91150
}
92151

93152

153+
# Dictionary mapping adjacency types to their corresponding functions.
94154
adjacencies = {"rook": rook, "queen": queen}

gerrychain/graph/geo.py

+42-7
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,61 @@
1+
"""
2+
This module contains functions for working with GeoDataFrames and Shapely
3+
geometries. Specifically, it contains functions for handling and reprojecting
4+
the Universal Transverse Mercator projection, and for identifying bad geometries
5+
within a given GeoDataFrame.
6+
"""
7+
18
from collections import Counter
29
from gerrychain.vendor.utm import from_latlon
10+
# from shapely.geometry.base import BaseGeometry
11+
from geopandas import GeoDataFrame
312

413

514
def utm_of_point(point):
15+
"""
16+
Given a point, return the Universal Transverse Mercator zone number
17+
for that point.
18+
"""
619
return from_latlon(point.y, point.x)[2]
720

821

9-
def identify_utm_zone(df):
22+
def identify_utm_zone(df: GeoDataFrame) -> int:
23+
"""
24+
Given a GeoDataFrame, identify the Universal Transverse Mercator zone
25+
number for the centroid of the geometries in the dataframe.
26+
"""
1027
wgs_df = df.to_crs("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
1128
utm_counts = Counter(utm_of_point(point) for point in wgs_df["geometry"].centroid)
1229
# most_common returns a list of tuples, and we want the 0,0th entry
1330
most_common = utm_counts.most_common(1)[0][0]
1431
return most_common
1532

1633

17-
def explain_validity(geo):
18-
"""Given a geometry, explain the validity.
34+
# Explicit type hint intentionally omitted here because of import issues.
35+
def explain_validity(geo) -> str:
36+
"""
37+
Given a geometry that is shapely interpretable, explain the validity.
1938
Light wrapper around shapely's explain_validity.
39+
40+
:param geo: Shapely geometry object
41+
:type geo: shapely.geometry.BaseGeometry
42+
43+
:returns: Explanation for the validity of the geometry
44+
:rtype: str
2045
"""
2146
import shapely.validation
2247
return shapely.validation.explain_validity(geo)
2348

2449

2550
def invalid_geometries(df):
26-
"""Given a GeoDataFrame, returns a list of row indices
51+
"""
52+
Given a GeoDataFrame, returns a list of row indices
2753
with invalid geometries.
2854
29-
:param df: :class:`geopandas.GeoDataFrame`
55+
:param df: The GeoDataFrame to examine
56+
:type df: :class:`geopandas.GeoDataFrame`
57+
58+
:returns: List of row indices with invalid geometries
3059
:rtype: list of int
3160
"""
3261
invalid = []
@@ -38,9 +67,15 @@ def invalid_geometries(df):
3867

3968

4069
def reprojected(df):
41-
"""Returns a copy of `df`, projected into the coordinate reference system of a suitable
70+
"""
71+
Returns a copy of `df`, projected into the coordinate reference system of a suitable
4272
`Universal Transverse Mercator`_ zone.
43-
:param df: :class:`geopandas.GeoDataFrame`
73+
74+
:param df: The GeoDataFrame to reproject
75+
:type df: :class:`geopandas.GeoDataFrame`
76+
77+
:returns: A copy of `df`, projected into the coordinate reference system of a suitable
78+
UTM zone.
4479
:rtype: :class:`geopandas.GeoDataFrame`
4580
4681
.. _`Universal Transverse Mercator`: https://en.wikipedia.org/wiki/UTM_coordinate_system

0 commit comments

Comments
 (0)