https://rawgithub.com/The-Politico/src/master/images/logo/badge.png https://badge.fury.io/py/politico-civic-geography.svg

politico-civic-geography documentation

_images/admin.png

Why this?

Geography is the foundation of almost all civic data. This app models geographic data for U.S. political divisions, including states, congressional districts, counties and townships. It also includes loaders to bootstrap your database, sourced from U.S. Census cartographic boundary files, and exporters to build out a full set of boundary files in TopoJSON format, which we use at POLITICO to create data maps.

In short, politico-civic-geography is a one-stop shop for creating and managing political geography and maps. That’s why we use it as the basis for our election rig, dataviz apps and other political projects. With it we keep a consistent source of geographic data from the Census and can easily update across our applications each year when new boundary files are released.

While politico-civic-geography is focused primarily on U.S. political divisions, its data model borrows heavily from more generic specifications, especially the Open Civic Data project. (We welcome contributions of loaders for other political contexts!)

This app is part of our larger politico-civic project. Read the docs for more information.

Quickstart

Requirements

  • topojson
  • PostgreSQL ≥ 9.4
  • Django ≥ 2.0

Install

$ pip install politico-civic-geography

Configure

  1. Add the app and Django Rest Framework to the installed apps in your project settings and configure app specific settings.
# settings.py

INSTALLED_APPS = [
    # ...
    "rest_framework",
    "geography",
]

CENSUS_API_KEY = os.getenv("CENSUS_API_KEY")
GEOGRAPHY_AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
GEOGRAPHY_AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
GEOGRAPHY_AWS_S3_BUCKET = os.getenv("AWS_S3_BUCKET")
GEOGRAPHY_AWS_REGION = "us-east-1" # default
GEOGRAPHY_AWS_S3_UPLOAD_ROOT = "elections" # default
GEOGRAPHY_AWS_ACL = "public-read" # default
GEOGRAPHY_AWS_CACHE_HEADER = "max-age=3600" # default
GEOGRAPHY_API_AUTHENTICATION_CLASS = "rest_framework.authentication.BasicAuthentication" # default
GEOGRAPHY_API_PERMISSION_CLASS = "rest_framework.permissions.IsAdminUser" # default
GEOGRAPHY_API_PAGINATION_CLASS = "geography.pagination.ResultsPagination" # default
  1. Add the app to your project’s urlconf.
# urls.py

urlpatterns = [
    # ...
    path('geography', include('geography.urls')),
]
  1. Migrate you DB.
$ python manage.py migrate

Bootstrap

Bootstrap your database with geographic data from the U.S. Census Bureau. Running this command will create Geography and Geometry fixtures for states, counties, congressional districts and townships.

$ python manage.py bootstrap_geography

See Management for more details on using this command and on baking geometry TopoJSON files to AWS S3.

_images/bootstrap.png

Run

Start the server to see your new fixtures in Django’s admin.

$ python manage.py runserver
_images/admin.png

Models

Geography models represent all geographic political divisions in the United States, their relationships and their geometric boundaries.

Division

class geography.models.Division(*args, **kwargs)

A political or administrative geography.

For example, a particular state, county, district, precinct or municipality.

Parameters:
  • id (UUIDField) – Id
  • uid (CharField) – Uid
  • slug (SlugField) – Slug
  • name (CharField) – Name
  • label (CharField) – Label
  • short_label (CharField) – Short label
  • parent (ForeignKey to Division) – Parent
  • level (ForeignKey to DivisionLevel) – Level
  • code (CharField) – Code representing a geography: FIPS code for states and counties, district number for districts, precinct number for precincts, etc.
  • code_components (JSONField) – Component parts of code
  • effective (BooleanField) – Effective
  • effective_start (DateTimeField) – Effective start
  • effective_end (DateTimeField) – Effective end
  • intersecting (ManyToManyField) – Intersecting divisions intersect this one geographically but do not necessarily have a parent/child relationship. The relationship between a congressional district and a precinct is an example of an intersecting relationship.

DivisionLevel

class geography.models.DivisionLevel(*args, **kwargs)

Level of government or administration at which a division exists.

For example, federal, state, district, county, precinct, municipal.

Parameters:
  • id (UUIDField) – Id
  • uid (CharField) – Uid
  • slug (SlugField) – Slug
  • name (CharField) – Name
  • parent (ForeignKey to DivisionLevel) – Parent

Geometry

class geography.models.Geometry(*args, **kwargs)

The spatial representation (in topoJSON) of a Division.

Parameters:
  • id (UUIDField) – Id
  • division (ForeignKey to Division) – Division
  • subdivision_level (ForeignKey to DivisionLevel) – Subdivision level
  • simplification (FloatField) – Minimum quantile of planar triangle areas for simplfying topojson.
  • topojson (JSONField) – Topojson
  • source (URLField) – Link to the source of this geography data.
  • series (CharField) – Year of boundary series, e.g., 2016 TIGER/Line files.
  • effective (BooleanField) – Effective
  • effective_start (DateField) – Effective start
  • effective_end (DateField) – Effective end

IntersectRelationship

class geography.models.IntersectRelationship(*args, **kwargs)

Each IntersectRelationship instance represents one side of a paired relationship between intersecting divisions.

The intersection field represents the decimal proportion of the to_division that intersects with the from_division. It’s useful for apportioning counts between the areas, for example, population statistics from census data.

Parameters:
  • id (AutoField) – Id
  • from_division (ForeignKey to Division) – From division
  • to_division (ForeignKey to Division) – To division
  • intersection (DecimalField) – The portion of the to_division that intersects this division.

Point

class geography.models.Point(*args, **kwargs)

A point is a city.

Parameters:
  • id (AutoField) – Id
  • geometry (ForeignKey to Geometry) – Geometry
  • lat (FloatField) – Latitude coordinate in decimal degrees.
  • lon (FloatField) – Longitude coordinate in decimal degrees.
  • attributes (JSONField) – Miscellaneous attributes on the point.
  • threshold (PositiveSmallIntegerField) – A threshold in pixels above which to display this point.
  • label (CharField) – Label

PointLabelOffset

class geography.models.PointLabelOffset(*args, **kwargs)

Offsets used to display a Point’s label.

Parameters:
  • id (AutoField) – Id
  • point (ForeignKey to Point) – Point
  • x (SmallIntegerField) – Lateral offset in pixels.
  • y (SmallIntegerField) – Vertical offset in pixels.
  • threshold (PositiveSmallIntegerField) – A threshold in pixels above which to apply this offset.

Management

bootstrap_geography

This command will download shapefiles from the U.S. Census Bureau, process them and create a complete set of Geography and Geometry fixtures for states, congressional districts, counties and townships in your database.

usage: manage.py bootstrap_geography [-h] [--year YEAR] [--congress CONGRESS]
                                     [--nationThreshold NATIONTHRESHOLD]
                                     [--stateThreshold STATETHRESHOLD]
                                     [--districtThreshold DISTRICTTHRESHOLD]
                                     [--countyThreshold COUNTYTHRESHOLD]
                                     [--version] [-v {0,1,2,3}]
                                     [--settings SETTINGS]
                                     [--pythonpath PYTHONPATH] [--traceback]
                                     [--no-color]

Downloads and bootstraps geographic data for states, congressional districts,
counties and townships from the U.S. Census Bureau simplified cartographic
boundary files.

optional arguments:
  -h, --help            show this help message and exit
  --year YEAR           Specify year of shapefile series (default, 2017)
  --congress CONGRESS   Specify congress of district shapefile series
                        (default, 115)
  --nationThreshold NATIONTHRESHOLD
                        Simplification threshold value for nation topojson
                        (default, 0.005)
  --stateThreshold STATETHRESHOLD
                        Simplification threshold value for state topojson
                        (default, 0.05)
  --districtThreshold DISTRICTTHRESHOLD
                        Simplification threshold value for district topojson
                        (default, 0.08)
  --countyThreshold COUNTYTHRESHOLD
                        Simplification threshold value for county topojson
                        (default, 0.075)
  --version             show program's version number and exit
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output,
                        2=verbose output, 3=very verbose output
  --settings SETTINGS   The Python path to a settings module, e.g.
                        "myproject.settings.main". If this isn't provided, the
                        DJANGO_SETTINGS_MODULE environment variable will be
                        used.
  --pythonpath PYTHONPATH
                        A directory to add to the Python path, e.g.
                        "/home/djangoprojects/myproject".
  --traceback           Raise on CommandError exceptions
  --no-color            Don't colorize the command output.

Overriding bootstrapped geometry

In some cases, we need to overwrite geometry. In those cases, we generally package source shapefiles with this module and write an additional management command to be run after bootstrapping geography from the Census.

Those commands are called by the format: bootstrap_geom_<id>

bake_geography

This command will export state and congressional district boundary files in TopoJSON to an AWS S3 bucket.

usage: manage.py bake_geography [-h] [--year YEAR] [--version] [-v {0,1,2,3}]
                                [--settings SETTINGS]
                                [--pythonpath PYTHONPATH] [--traceback]
                                [--no-color]
                                states [states ...]

Uploads topojson files by state and district to an Amazon S3 bucket.

positional arguments:
  states                States to export by FIPS code. Use 00 to export all
                        geographies.

optional arguments:
  -h, --help            show this help message and exit
  --year YEAR           Specify year of shapefile series (default, 2017)
  --version             show program's version number and exit
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output,
                        2=verbose output, 3=very verbose output
  --settings SETTINGS   The Python path to a settings module, e.g.
                        "myproject.settings.main". If this isn't provided, the
                        DJANGO_SETTINGS_MODULE environment variable will be
                        used.
  --pythonpath PYTHONPATH
                        A directory to add to the Python path, e.g.
                        "/home/djangoprojects/myproject".
  --traceback           Raise on CommandError exceptions
  --no-color            Don't colorize the command output.