Skip to content

Commit

Permalink
Add networkx output (#70)
Browse files Browse the repository at this point in the history
* refactored and fixed contraction code
* added networkx output
* added example for reading networkx file
  • Loading branch information
AndGem committed May 23, 2020
1 parent 1549351 commit e7a93bc
Show file tree
Hide file tree
Showing 26 changed files with 767 additions and 262 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install networkx
# pip install -r requirements.txt
- name: Lint with flake8
run: |
Expand All @@ -27,7 +28,7 @@ jobs:
- name: Typechecking with mypy
run: |
pip install mypy
mypy .
mypy . --ignore-missing-imports
- name: Test with pytest
run: |
pip install pytest
Expand Down
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,8 @@ ENV/


data/
cover/
cover/

.mypy_cache/
.pyre/
.vscode/
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ install:
- pip install codecov
- pip install pytest
- pip install pytest-cov
- pip install networkx
# command to run tests
script:
- pytest --verbosity=3 --cov=./
Expand Down
103 changes: 63 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,89 +1,112 @@
# OsmToRoadGraph v.0.4.3
# OsmToRoadGraph v.0.5.0

[![Build Status](https://travis-ci.org/AndGem/OsmToRoadGraph.svg?branch=master)](https://travis-ci.org/AndGem/OsmToRoadGraph)
![Python application](https://github.com/AndGem/OsmToRoadGraph/workflows/Python%20application/badge.svg?branch=master)
[![codecov](https://codecov.io/gh/AndGem/OsmToRoadGraph/branch/master/graph/badge.svg)](https://codecov.io/gh/AndGem/OsmToRoadGraph)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

- [OsmToRoadGraph v.0.4.3](#osmtoroadgraph-v043)
- [Introduction](#introduction)
- [Motivation](#motivation)
- [Description](#description)
- [Requirements](#requirements)
- [Older Versions](#older-versions)
- [Usage](#usage)
- [Usage - Explanation](#usage---explanation)
- [Example](#example)
- [Output](#output)
- [Output Format](#output-format)
- [Example Road Network (*.pycgr)](#example-road-network-pycgr)
- [Example Street Names (*.pycgr_names)](#example-street-names-pycgrnames)
- [Configuring the Accepted OSM Highway Types](#configuring-the-accepted-osm-highway-types)
- [Indoor Paths](#indoor-paths)
- [Research](#research)

# Introduction
- [OsmToRoadGraph v.0.5.0](#osmtoroadgraph-v050)
- [Updates](#updates)
- [Introduction](#introduction)
- [Motivation](#motivation)
- [Description](#description)
- [Requirements](#requirements)
- [Older Versions](#older-versions)
- [Usage](#usage)
- [Usage - Explanation](#usage---explanation)
- [Examples](#examples)
- [Output](#output)
- [Output Format](#output-format)
- [Example Road Network (*.pycgr)](#example-road-network-pycgr)
- [Example Street Names (*.pycgr_names)](#example-street-names-pycgrnames)
- [Configuring the Accepted OSM Highway Types](#configuring-the-accepted-osm-highway-types)
- [Indoor Paths](#indoor-paths)
- [Research](#research)

## Updates

**Changelog v.0.4.3 -> v.0.5.0:**

- [x] Added new output option to write NetworkX compatible files
- [x] Fixed bugs in the contraction logic

## Introduction

OSMtoRoadGraph aims to provide a simple tool to allow extraction of the road network of [OpenStreetMap](http://www.openstreetmap.org) files. It differentiates between three transportation networks: car, bicycle, and walking. The output data depends on the chosen parameters (which street highway types to consider, speed, ...).

## Motivation
### Motivation

OpenStreetMap provides free cartographic data to anyone. Data can be added and edited by anyone. However, using the road network contained in the OSM files is not straightforward. This tool aims to reduce the overhead of writing a parser for OSM files.

Below is an example of a visualization of the road network of the city of Bremen, Germany. The darker the shade of the street, the higher the maximum allowed speed.

<img src="https://raw.githubusercontent.com/AndGem/OsmToRoadGraph/master/examples/pycgr-to-png/bremen.png" width="350">

For details on how image was generated take a look into the [examples folder](https://github.com/AndGem/OsmToRoadGraph/tree/master/examples/pycgr-to-png).
For details on how image was generated take a look into the [examples folder](https://github.com/AndGem/OsmToRoadGraph/tree/master/examples/pycgr-to-png).


## Description
### Description

With this tool the data is being converted into easily parsable plaintext files that can be used by any application for further processing. For each transportation network type two output files are generated. One file contains the nodes (with coordinates), and the network edges, with length, direction and maximum speed (according to chosen network type). The second file contains street names that could be extracted for all edges contained in the first file.

## Requirements
As additional feature, and to make interaction easier, it is now supported to output networkx json to directly work with the output graph in networkx (or a library that supports the file format).

### Requirements

- Python 3.6+/PyPy
- An OSM XML file
- [Optional: [networkx](https://networkx.github.io/) as dependency: `pip3 install networkx`]

## Older Versions
### Older Versions

Recently, breaking changes have been applied. If you require older versions please see the [releases](https://github.com/AndGem/OsmToRoadGraph/releases).

## Usage
### Usage

```bash
Usage: run.py [options]
usage: run.py [-h] [-f FILENAME] [-n {p,b,c}] [-l] [-c] [--networkx]

Options:
optional arguments:
-h, --help show this help message and exit
-f FILENAME, --file=FILENAME
-n NETWORK_TYPE, --networkType=NETWORK_TYPE (p)edestrian, (b)icycle, (c)ar, [default: pedestrian]
-f FILENAME, --file FILENAME
-n {p,b,c}, --networkType {p,b,c}
(p)edestrian, (b)icycle, (c)ar, [default: p]
-l, --nolcc
-c, --contract
--networkx enable additional output of JSON format of networkx
[note networkx needs to be installed for this to
work].
```

### Usage - Explanation
#### Usage - Explanation

`-f` points to the input filename; the output files will be created in the same folder and using the name of the input file as prefix and adding information as suffix.

`-n` sets the network type. This influences the maximum speed saved for the edges. If you care only about connectivity set it to pedestrian.

`-l` if you set this option the graph will be output as a whole but _may_ contain unconnected components. By default the largest connected component is determined and the rest is dropped.

`-c` if you specify this option additional to the original graph, a second pair of filenames will be created containing the result of contracting all degree 2 nodes.
`-c` if you specify this flag additional to the original graph, a second pair of filenames will be created containing the result of contracting all degree 2 nodes.

`--networkx` if you specify this flag, an additional output file will be generated using networkx's [networkx.readwrite.json_graph.adjacency_data](https://networkx.github.io/documentation/stable/reference/readwrite/generated/networkx.readwrite.json_graph.adjacency_data.html#networkx.readwrite.json_graph.adjacency_data). This also works with the flag `-c`. Then, a non-contracted and contracted output file compatible to networkx will be generated.

### Example
Example execution:

```bash
python run.py -f data/karlsruhe_small.osm -n p -v
```

### Output
#### Examples

To see what you can do with the output please have a look here:

- [pycgr to png](https://github.com/AndGem/OsmToRoadGraph/tree/master/examples/pycgr-to-png): small python script that loads the output of this program and generates a drawing of a road network
- [shortest distances drawing](https://github.com/AndGem/OsmToRoadGraph/tree/master/examples/shortest-distances-drawing): another python script that loads the **networkx** output of this program and generates a drawing of the road network and uses colors to encode distances.

#### Output

The output will consist of two plaintext files. One file ending in `.pypgr`, `pybgr`, or `pycgr` depending on the network type selected; the other file will have the same ending with a `_names` as additional suffix. The first file contains the graph structure as well as additional information about the edge (length, max speed according to highway type, if it is a one-way street or not). The file ending with `_names` includes the street names for the edges.

#### Output Format
##### Output Format

The structure of the road network output file is the following:

Expand Down Expand Up @@ -118,7 +141,7 @@ Edges of the graph are described by 6 parameters. Each edge is stored in one lin
- `<max_speed>`: maximum allowed speed (if exists) in km/h [note: if no max speed is found a default value will be used]
- `<bidirectional>` indicates if an edge is bidirection. The value is `0` if it is a unidirectional road (from `source_node_id` to `target_node_id`), and otherwise it is `1`.

##### Example Road Network (*.pycgr)
###### Example Road Network (*.pycgr)

```
# Road Graph File v.0.4
Expand Down Expand Up @@ -147,7 +170,7 @@ Edges of the graph are described by 6 parameters. Each edge is stored in one lin
...
```

##### Example Street Names (*.pycgr_names)
###### Example Street Names (*.pycgr_names)

```
Hölderlinstraße
Expand All @@ -164,13 +187,13 @@ Zähringerstraße

Each line consists of a street name. The number in which a line is corresponds to the edges index. In this example this means, that Hölderlinstraße is the street name of edges 0, 1, 2. The absence of a name in line 4 indicates that edge 3 has no street name. Edges 4, 5, 6 have street name Kronenstraße, and so on...

### Configuring the Accepted OSM Highway Types
#### Configuring the Accepted OSM Highway Types

The application comes with a set of standard configuration to parse `only` some OSM ways that have the tag `highway=x` where `x` is a [highway type](https://wiki.openstreetmap.org/wiki/Key:highway) [notable excepting is the `pedestrian_indoors`, see below for an explanation].
You can change the behavior of this program by changing the values (removing unwanted, and adding missing values) in the `configuration.py`.
In this file you can also modify the speed limit that will be written to the output file.

### Indoor Paths
#### Indoor Paths

By default elements tagged by the [Simple Indoor Tagging](https://wiki.openstreetmap.org/wiki/Simple_Indoor_Tagging) approach are being ignored.
To enable to also to extract these paths replace in `configuration.py` the line
Expand All @@ -187,6 +210,6 @@ with

Note that the change is only the addition of `pedestrian_indoor` in this list.

## Research
### Research

[Temporal Map Labeling: A New Unified Framework with Experiments](http://i11www.iti.uni-karlsruhe.de/temporallabeling/)
Binary file modified examples/pycgr-to-png/bremen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions examples/shortest-distances-drawing/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Shortest Distances Drawing

This project is a simple example that illustrates how to **generate a PNG image** file that shows the **shortest distances** from a random/central node of a road network to all other nodes.
Below you see an example of how this can look like. The darker the color, the closer it is to the starting node of the shortest path tree:
![Bremen](./bremen.png)

This example also shows how to use the networkx output of `OSMtoRoadGraph`.

## How to prepare (create a networkx json file)

If you already have a `*.json` file you can move to `How to run`.

1. Download an OSM XML file (e.g., from here http://download.geofabrik.de/europe/germany.html you can download the [.osm.bz2] file)
1. Unzip the file to obtain the pure xml file (e.g., `bremen-latest.osm`)
1. Run `OsmToRoadGraph` by invoking `python3 run.py -f <FILENAME> -n p -c --networkx` (e.g., `python3 run.py -f data/bremen-latest.osm -n p -c --networkx`)
1. This should have created the `*.json` (e.g., `data/bremen-latest.json`)

## How to run

1. Make sure you have a `*.json` file (if not, see the section above)
1. Install the dependencies: `pip3 install -r requirements.txt`
1. Invoke this script as follows:

```bash
python3 shortest-distances-drawing.py -f <INPUT_FILENAME> -o <OUTPUT_FILENAME>
```

For example:

```bash
python3 shortest-distances-drawing.py -f data/bremen-latest.json -o bremen.png
```

**That's it**: This should an output picture of the shortest distances of road network of the input OSM file.

### Further Customizations

This little script offers some more customization options:

```bash
Options:
-h, --help show this help message and exit
-f IN_FILENAME, --file=IN_FILENAME
input networkx JSON file
-o OUT_FILENAME, --out=OUT_FILENAME
output png file
-c, --center set this option to compute the shortest distances from
an approximate center node [default: random node]
-m METRIC, --metric=METRIC
metric for the shortest path algorithm. Either
'length' or 'travel-time' [default: travel-time]
--width=WIDTH image width in px [default=1600]
--height=HEIGHT image height in px [default=1200]
```
Binary file added examples/shortest-distances-drawing/bremen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions examples/shortest-distances-drawing/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
utm==0.5.0
Pillow==7.0.0
tqdm==4.46.0
Loading

0 comments on commit e7a93bc

Please sign in to comment.