We're always looking for more volunteers to add to the Zoning.Space dataset. If you'd like to contribute zoning for an additional city, we welcome your contributions. Step-by-step instructions are below. You'll need some basic experience with GitHub and running applications from the command line.

  1. Fork the Zoning.Space repository to your own GitHub account. This way, you can easily make changes to the repository, and then request that they be merged back into the main Zoning.Space repository.
  2. Clone your forked repo to your local computer, and change your working directory to the repository.
  3. Follow the Installation instructions, if you haven't already.
  4. Activate the appropriate conda environment, by running the command source activate zoning.space (or just activate zoning.space on Windows).
  5. Before expending effort on digitizing the zoning for a city, open an issue in the main Zoning.Space repository (not your fork) with the name of the city you plan to digitize, and assign it to yourself. This allows us to prevent duplicate effort when two individuals may wish to digitize the same city, and provides a place for coordinating efforts and discussing the zoning code. If someone else is already digitizing the city you're interested in, comment on the issue to see if they want any help!
  6. Determine a slug for your city---this is a stylized version of the name that contains no spaces or uppercase letters. For example, the slug for San Diego is sandiego.
  7. Find a shapefile of the zoning code for the city you want to add. Most cities have some sort of open data portal that contains a geospatial dataset that shows where different zoning designations (e.g. R-1, M-1, etc.) apply. For instance, here is the one for San Francisco. Download this dataset, make sure it is formatted as a shapefile, zip it, and place it in data/zoning/<slug>.zip, creating the directories as necessary.
  8. Examine the data in the shapefile (most likely using a GIS such as QGIS) to determine which field or fields determine the zoning for a particular feature.
  9. (Optional, Advanced) If the data need any preprocessing before being processed by Zoning.Space, create a before hook. These are often used to combine multiple datasets that specify different aspects of the zoning code.
  10. Generate the specfile. Each city has a custom specfile, which is a spreadsheet defining how to translate the zoning designations (e.g. R-1) into the machine-readable variables captured by Zoning.Space. An example specfile for Oakland is here. It has a header with a few pieces of basic information about the city to fill out, followed by one or more tables mapping zoning designators to the attributes we collect.

Each table in the specfile starts with one or more columns that match the column names in the shapefile. This is matched to the zoning shapefile using a logical AND; that is, all columns specified (even if they are empty) must match the values in the shapefile for the line to apply. Following the columns that match the shapefile are the columns that specify the values for Zoning.Space variables, such as height or density limits.

The specfile may contain multiple tables; they will be applied sequentially. If the same variable (e.g. height limit) is specified in multiple matching lines of multiple tables, the value from the last table will take precedence. Multiple tables are often useful for overlay zones that override some provision of the underlying zoning, or for very specific zoning designations (for instance, one table of general designations, and a second table that combines the general designations with certain relevant overlay zones).

Writing a specfile by hand is a tedious process. To make it easier, there is a script in the Zoning.Space repo that will pregenerate a template for a particular city. To use it, run

./prepopulateSpecfile.py --drop-small-zones 0.25 <slug>

This will generate a template specfile in src/zoning/specs/<slug>.csv. The --drop-small-zones 0.25 option suppresses output of zoning designators that cover less than 0.25 square kilometers. In order to preserve volunteer time, we generally don't digitize these zoning designators unless they are in areas of particular interest. Another option that may be useful in the United States is --imperial, which will output the specfile using imperial (English) rather than metric units.

The interface is relatively straightforward. You will be presented with a list of columns in the Shapefile; enter those that you want to use as zoning specifiers in the first table in the specfile, separated by commas. You will then be prompted to enter the columns for the second table, and so on; when you don't want any more tables, enter done, press enter, and your specfile will be generated. 1. Edit the specfile. Open the specfile in your favorite spreadsheet software (alternating row coloring and the ability to hide rows and columns is a plus). For each row, enter the appropriate values for that zoning designator into the columns. This will generally be found in the city's planning code. If a particular zoning designator does not restrict a particular variable (for example, areas that have no height limit or density requirement), enter 0 or inf (infinity) as appropriate, to identify the lack of a restriction as opposed to missing data.

To avoid tedious unit conversions, simply change the name of the column to reflect the units that the zoning code is specified in (e.g. Acres, SqFeet, Feet, etc.). The Zoning.Space software stack will perform the appropriate unit conversions automatically. It is even acceptable to have multiple columns for the same variable with different units, although if values are specified in both columns for the same zoning designator, which one will be present in the final output is undefined.

There are three ways to specify density limits: the maximum number of units per hectare/acre, the minimum lot size per unit, or a combination of minimum lot size and maximum number of units per lot. Similarly, there are two ways to specify setbacks (in terms of distance and percent of lots). It is acceptable to enter values for more than one of these variables if they are restricted by the zoning code (for instance, an area that has both a distance and a percentage requirement for setbacks). However, if the zoning code does not specify limits for one or more of these variables, all but one in each category may be left blank.

Sometimes, a zoning code does not contain a single restriction for a variable, but rather a range of restrictions depending on circumstances that are not easily digitized (for example, lot slope or a map that is in the planning code but not available digitally). In these cases, a range should be entered, using a hyphen between the values (for example, 30-40).

The variables singleFamily and multiFamily specify whether single-family and multi-family development, respectively, are allowed in a particular location. You may enter true, yes, y, or 1 if it is, false, no, n, 0 if it is not, and c or conditional if it is conditionally permitted. These variables are not mutually exclusive; an area that permits both multi-family and single-family residences should be coded with a y in each column. These are the only columns where conditionally-permitted restrictions should be considered; in other columns, the restrictions on by-right use should be entered. Since many cities treat them as single-family homes, duplexes should be considered single-family residences for the purposes of these variables.

There is a note column that should be used to enter notes about a particular zone that will be in the final dataset. It is also possible to place comments in the file to explain how something is done, but which will not be present in the final dataset. If the first cell of a row begins with //, that row will be ignored. If a cell begins with #, that cell will be treated as if it were empty. Blank lines delineate table boundaries, and should not occur within a table; if blank space is needed, the first cell should contain //.

There are many assumptions that must be made when trying to standardize something as disparate as zoning data. The general assumptions that we have made across-the-board are here, and should be followed when digitizing new cities. If something is not covered in that file, seems generally applicable in cities other than the one you are digitizing, and it is clear what assumption should be made, enter the assumption into docs/assumptions/index.md so it will be documented. If it is not clear, open an issue to discuss the assumption. If the assumption is specific to the city you are digitizing, please record it in a file docs/assumptions/<slug>.md; this is also a good place to document limitations of the data in that particular city. 1. If any postprocessing of the data is needed (for example, because all areas near rail stations have special case zoning), write an after hook. 1. Once you have a draft of the specfile, you can process the data to produce a GIS-ready data layer. 1. Once you are confident that your specfile and hooks are ready to go, create a pull request to the main zoning.space repository, requesting that your changes be pulled into the main data distribution. Make sure you include your specfile, hookfile if you created one, and any documentation changes (e.g. files in docs/assumptions) in your pull request. Don't include the zip file(s) of zoning data; these should be uploaded to the zoning-data S3 bucket. Please note in pull request that you are willing to license your contributions under the Open Database License (and the Apache 2 license, if you contributed code). Please reference the issue you created for digitizing the city in the pull request, so that it can be closed when the pull request is merged. 1. Another Zoning.Space contributor will review your contribution and either merge it into the Zoning.Space repository, or request changes before merging. 1. Celebrate the addition of another city to Zoning.Space!