/networker

Network Planning Library

Primary LanguagePython

Networker

Networker contains tools for planning distribution networks from supply and demand data.

Build Status

Coverage Status

It relies on numpy, networkx and also utilizes several spatial indexes.

Overview

The main interfaces for generating networks are the following classes:

  • NetworkerRunner: Assumes a pre-computed budget for each node. It follows networkx output conventions for spatial data.
  • NetworkPlannerRunner: Uses existing networkplanner econometric models to compute nodal budget (aka mvMax). It's output follows networkplanner conventions.

Included are wrapper scripts for leveraging these classes from the command line.

Examples

Once installed with source, navigate to the top level source directory and activate your environment via source activate networker.

Networker

> python scripts/run_networker.py test/networker_config_max100.json -o output

Once run, you should see an output directory with edges and nodes shapefiles (with supporting files). This particular example had sufficient nodal "budget" for the resulting network to be a minimum spanning tree.

From within python, you can run this via the NetworkerRunner class and work directly with the resulting GeoGraph (subtype of networkx Graph):

from networker import networker_runner
import json

# load demand nodes and generate geograph
cfg = json.load(open("test/networker_config_max100.json"))
nr = networker_runner.NetworkerRunner(cfg)
geograph = nr.build_network()

# plot it
import matplotlib.pyplot as plt
from networker import utils

utils.draw_geograph(geograph)
plt.show()

geograph image

NetworkPlanner

If you want to leverage the econometric models from networkplanner to compute the budget (aka mvMax) values for nodes, use the NetworkPlannerRunner class.
This will also generate outputs that are consistent with networkplanner.
A script to run this is included. Here's a sample run:

> python scripts/run_networkplanner.py test/networkplanner_config_leona_net.json -o output

Once complete, the output directory should contain a dataset.db and networks-proposed shapefiles (along with addtional networkplanner outputs).

Other tools

The scripts directory contains various other useful tools for working with geographic nodes and networks. Below is a sample script demonstrating these tools. Change the number of nodes to test performance at scale.

Pass --help to any tool to get detailed help on its parameters.

# generate random demand nodes within bounds [-1, -1], [1, 1] into a csv
cat <(echo "x,y") <(python scripts/generate_random_nodes.py -x -1 1 -y -1 1 5) > demand_nodes.csv

# generate a random minimum spanning tree within the same bounds into a networkx json file
python scripts/generate_random_nodes.py -x -1 1 -y -1 1 30 | python scripts/generate_mst.py > mst.json

# project the nodes onto the nearest segment in the mst 
# (network goes into output/projected.json)
python scripts/project_onto.py -x x -y y -r -j -o output demand_nodes.csv mst.json

# render the network and projections to a png
python scripts/draw_geograph.py -n 50 -o mst.png mst.json output/projected.json

Minimum Spanning Tree from above geograph image

5 random nodes and shortest edges to the MST as plotted via draw_geograph.py above geograph image

Configuration

Both NetworkerRunner and NetworkPlannerRunner take json configuration files which define their inputs and how they should run. Annotated schemas for these configuration files are:

NetworkRunner Config

NetworkPlannerRunner Config

Installation

These instructions should work for linux-64 and osx-64 platforms.

The simplest method of installation is via conda.

Once conda is installed (guide here), setup a new python 2.7 environment via:

conda create -n networker python=2.7

and source it to subsequently install libraries in that environment:

source activate networker

To use the NetworkPlannerRunner, you will need the networkplanner library installed in this environment:

conda install -c conda-forge -c sel networkplanner-metrics

Now install the networker library

conda install -c conda-forge -c sel networker

On OSX, there appears to be an issue related to this and this where the libspatialindex library cannot be found. As a workaround, you can do the following from within your networker environment before running any scripts (this is not ideal...alternative approaches appreciated):

# OSX Only
export LD_LIBRARY_PATH=~/anaconda/envs/networker/lib
# to unset when done do
# unset LD_LIBRARY_PATH

Similar issues may occur on Ubuntu/Debian. You can check whether libspatialindex can be found via the following:

ldconfig -p 2>/dev/null | grep spatial

The issue can be resolved by adding your conda lib directory to the ldconfig cache via:

ldconfig ~/anaconda/envs/networker/lib

Development Setup

To setup a development environment

clone this repository or fork to your own repo and then clone:

cd <src_dir>
git clone <repo_name>/networker.git 

In order to develop/test against the source directory, you'll need to install it's dependencies (and remove networker from the conda environment if it already exists).

source activate networker
cd <src_dir>/networker
conda remove networker # if already installed
# networkplanner-metrics is only needed if you reference
# legacy networkplanner libraries (see networkplanner_runner.py)
conda install -c conda-forge -c sel networkplanner-metrics
conda install -c conda-forge --file requirements.txt

At this point, you should be ready to develop against local source.

See our style guide for how we develop.

Testing

Once setup for development, run nosetests from the top level repo directory.