osm2ch

package module
v1.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 16, 2026 License: Apache-2.0 Imports: 20 Imported by: 1

README

GoDoc Build Status Sourcegraph Go Report Card GitHub tag

osm2ch

Convert *.osm.pbf files to CSV for contraction hierarchies library

About

With this CLI tool you can convert *.osm.pbf (Compressed Open Street Map) file to CSV (Comma-Separated Values) file, which is used in our contraction hierarchies library.

Under the hood it uses osm2gmns library (Go port of osm2gmns) to build a macroscopic graph with turning movements, then this CLI performs edge expansion and contraction hierarchies.

What it does:

  • Builds macroscopic network from OSM via osm2gmns;
  • Generates turning movements at intersections;
  • Performs edge expansion (each macro link becomes a vertex, movements become edges);
  • Filters U-turns;
  • Supported types of restrictions (internally processed in osm2gmns): - only_left_turn; - only_right_turn; - only_straight_on; - no_left_turn; - no_right_turn; - no_straight_on.
  • Prepares contraction hierarchies;
  • Outputs CSV files with geometry in WKT or GeoJSON format.
  • Optionally exports the underlying GMNS networks (macro, movement, meso, micro) as CSV, just like osm2gmns.

Agent type filtering is handled by osm2gmns (e.g. auto, bike, walk).

PRs are welcome!

Installation

  • Via 'go install':

    go install github.com/LdDl/osm2ch/cmd/osm2ch@latest
    

    After installation step is complete you can call 'osm2ch' from any place in your system.

  • Or download prebuilt binary from Releases and add it to your PATH.

  • Docker:

    docker pull dimahkiin/osm2ch:latest
    

Usage

osm2ch -h

Output:

Usage of osm2ch:
  -file string
        Filename of *.osm.pbf file (it has to be compressed) (default "my_graph.osm.pbf")
  -out string
        Filename of 'Comma-Separated Values' (CSV) formatted file (default "my_graph.csv")
        E.g.: if file name is 'map.csv' then 3 files will be produced: 'map.csv' (edges), 'map_vertices.csv', 'map_shortcuts.csv'
  -geomf string
        Format of output geometry. Expected values: wkt / geojson (default "wkt")
  -agents string
        Comma-separated list of agent types. Expected values: auto,bike,walk (default "auto")
  -gmns string
        Optional comma-separated list of GMNS network levels to export as CSV. Expected values: macro,movement,meso,micro. Empty (default) disables GMNS export
  -gmns-dir string
        Output directory for the exported GMNS CSV files (used only when -gmns is set) (default ".")

Example

You can find example file of *.osm.pbf file in nested child /example_data.

If you want WKT format for output geometry and auto agent type:

osm2ch --file example_data/moscow_center_reduced.osm.pbf --out graph.csv --geomf wkt --agents auto

If you want GeoJSON format for output geometry and auto agent type:

osm2ch --file example_data/moscow_center_reduced.osm.pbf --out graph.csv --geomf geojson --agents auto

After that 3 files will be created: graph.csv (edges), graph_vertices.csv, graph_shortcuts.csv.

Exporting GMNS networks (optional)

In addition to the contraction-hierarchies CSV files, you can optionally export the underlying GMNS networks - the same way osm2gmns does. Pick any combination of network levels via -gmns (comma-separated): macro, movement, meso, micro.

osm2ch --file example_data/moscow_center_reduced.osm.pbf --out graph.csv --gmns macro,movement,meso,micro --gmns-dir ./gmns_out

Notes:

  • meso and micro are generated on demand (the meso network is built once and reused by micro), so requesting only macro,movement is fast and skips the heavier passes.

  • The OSM file is parsed only once: the macro network and movements used for contraction hierarchies are reused for the GMNS export.

  • Files written into -gmns-dir (osm2gmns naming convention):

    Level Files
    macro node.csv, link.csv
    movement movement.csv
    meso mesonode.csv, mesolink.csv
    micro micronode.csv, microlink.csv

Output format

Edges CSV

Header: from_vertex_id;to_vertex_id;length_meters;free_speed;geom;was_one_way;edge_id;osm_way_from;osm_way_to;osm_way_from_source_node;osm_way_from_target_node;osm_way_to_source_node;osm_way_to_target_node;macro_node_from_source;macro_node_from_target;macro_node_to_source;macro_node_to_target

Column Type Description
from_vertex_id int64 Source vertex in edge-expanded graph (= source macro link ID)
to_vertex_id int64 Target vertex in edge-expanded graph (= target macro link ID)
length_meters float64 Length of the expanded edge in meters (sum of the second half of the incoming macro link and the first half of the outgoing one)
free_speed float64 Free-flow speed in km/h - see note below
geom string Geometry (LineString) in WKT or GeoJSON format
was_one_way bool True if the source OSM way was one-way
edge_id int64 ID of the expanded edge
osm_way_from int64 OSM Way ID of the source (income) macro link
osm_way_to int64 OSM Way ID of the target (outcome) macro link
osm_way_from_source_node int64 OSM Node ID at the start of the source macro link
osm_way_from_target_node int64 OSM Node ID at the end of the source macro link
osm_way_to_source_node int64 OSM Node ID at the start of the target macro link
osm_way_to_target_node int64 OSM Node ID at the end of the target macro link
macro_node_from_source int GMNS macro node ID at the start of the source macro link
macro_node_from_target int GMNS macro node ID at the end of the source macro link
macro_node_to_source int GMNS macro node ID at the start of the target macro link
macro_node_to_target int GMNS macro node ID at the end of the target macro link
Vertices CSV

Header: vertex_id;order_pos;importance;geom

Column Type Description
vertex_id int64 Vertex ID (= macro link ID)
order_pos int Order position in contraction hierarchies
importance int Importance of vertex in contraction hierarchies
geom string Geometry (Point) in WKT or GeoJSON format
Shortcuts CSV

Header: from_vertex_id;to_vertex_id;weight;via_vertex_id

Column Type Description
from_vertex_id int64 Source vertex
to_vertex_id int64 Target vertex
weight float64 Shortcut cost in seconds (travel time)
via_vertex_id int64 Intermediate vertex

Contraction hierarchies are built using travel time (seconds) as the cost metric: length_meters / (free_speed_kmh / 3.6). Shortcut costs are also in seconds.

Note on free_speed. An expanded edge is assembled from two halves of two adjacent macro links (the second half of the incoming link + the first half of the outgoing one), which may have different free-flow speeds. To keep the total travel time physically consistent, free_speed is computed as a length-weighted harmonic mean of the two macro speeds:

free_speed = (inHalf + outHalf) / (inHalf / inSpeed + outHalf / outSpeed)

This guarantees that length_meters / free_speed equals the sum of the travel times across the two halves. A plain arithmetic mean would over-estimate the effective speed when the two halves differ significantly (e.g. a motorway_link at 30 km/h followed by a motorway at 100 km/h). If one of the macro links has a missing / zero speed, the other one is used as-is.

Worked example. Suppose the incoming macro link is a motorway_link of length 60 m at 30 km/h, and the outgoing one is a motorway of length 100 m at 100 km/h. Then:

inHalf  = 60 / 2  = 30 m
outHalf = 100 / 2 = 50 m
totalLength = 30 + 50 = 80 m

True travel time across the expanded edge (physically correct reference):

t_in  = 30 m / (30  km/h / 3.6) = 30 * 3.6 /  30 = 3.6 s
t_out = 50 m / (100 km/h / 3.6) = 50 * 3.6 / 100 = 1.8 s
t_true = t_in + t_out = 5.4 s

Arithmetic mean (the old formula) would give free_speed = (30 + 100) / 2 = 65 km/h, implying a travel time of 80 * 3.6 / 65 ~= 4.43 s - which is under-estimated by approximately 18%.

Length-weighted harmonic mean (the current formula):

free_speed = (30 + 50) / (30/30 + 50/100)
           = 80 / (1.0 + 0.5)
           = 80 / 1.5
           ~= 53.33 km/h

Sanity-check: 80 * 3.6 / 53.33 = 5.4 s - matches t_true exactly, as required.

If you need route distance in meters (e.g. for map matching transition probabilities), sum up length_meters of each edge along the CH path.

Now you can use this graph in contraction hierarchies library.

Dependencies

License

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExportGMNS added in v1.7.0

func ExportGMNS(nets *GMNSNetworks, levels []GMNSLevel, outputDir string) error

ExportGMNS writes the requested GMNS network levels as CSV files into outputDir.

The macro network and movements come straight from nets. The meso network is generated on demand (it is required by both the "meso" and "micro" levels), and the micro network is generated from the macro + meso networks and movements.

Produced files (osm2gmns naming convention):

  • macro: node.csv, link.csv
  • movement: movement.csv
  • meso: mesonode.csv, mesolink.csv
  • micro: micronode.csv, microlink.csv

func ImportFromGMNSWithNetworks added in v1.7.0

func ImportFromGMNSWithNetworks(fileName string, agentTypes []types.AgentType) ([]ExpandedEdge, *GMNSNetworks, error)

ImportFromGMNSWithNetworks behaves like ImportFromGMNS but additionally returns the underlying GMNS networks (macro network and movements) so the caller can optionally export them as GMNS CSV files.

func PrepareGeoJSONLinestring

func PrepareGeoJSONLinestring(pts []GeoPoint) string

PrepareGeoJSONLinestring returns GeoJSON representation of LineString

func PrepareGeoJSONPoint added in v1.3.0

func PrepareGeoJSONPoint(pt GeoPoint) string

PrepareGeoJSONPoint returns GeoJSON representation of Point

func PrepareWKTLinestring

func PrepareWKTLinestring(pts []GeoPoint) string

PrepareWKTLinestring returns WKT representation of LineString

func PrepareWKTPoint added in v1.3.0

func PrepareWKTPoint(pt GeoPoint) string

PrepareWKTPoint returns WKT representation of Point

Types

type Edge added in v1.5.0

type Edge struct {
	ID              EdgeID
	WayID           osm.WayID
	SourceNodeID    gmns.NodeID // macro graph node ID
	TargetNodeID    gmns.NodeID // macro graph node ID
	SourceOSMNodeID osm.NodeID
	TargetOSMNodeID osm.NodeID
	WasOneway       bool
	LengthMeters    float64
	FreeSpeed       float64
	Geom            []GeoPoint
}

type EdgeID added in v1.5.0

type EdgeID int64

type ExpandedEdge added in v1.5.0

type ExpandedEdge struct {
	ID              int64
	Source          EdgeID
	Target          EdgeID
	SourceOSMWayID  osm.WayID
	TargetOSMWayID  osm.WayID
	SourceComponent expandedEdgeComponent
	TargeComponent  expandedEdgeComponent
	WasOneway       bool
	LengthMeters    float64
	FreeSpeed       float64
	Geom            []GeoPoint
}

ExpandedEdge represents an edge in the edge-expanded graph. Source and Target are IDs of the original macro links (edges).

func ImportFromGMNS added in v1.6.0

func ImportFromGMNS(fileName string, agentTypes []types.AgentType) ([]ExpandedEdge, error)

ImportFromGMNS imports graph using osm2gmns library to build macro network + movements, then performs edge expansion based on movements.

type GMNSLevel added in v1.7.0

type GMNSLevel string

GMNSLevel enumerates the GMNS network levels that can be exported.

const (
	GMNSMacro    GMNSLevel = "macro"
	GMNSMovement GMNSLevel = "movement"
	GMNSMeso     GMNSLevel = "meso"
	GMNSMicro    GMNSLevel = "micro"
)

func ParseGMNSLevels added in v1.7.0

func ParseGMNSLevels(s string) []GMNSLevel

ParseGMNSLevels parses a comma-separated list of GMNS network levels (e.g. "macro,movement,meso,micro"). Unknown tokens are reported and skipped. The returned slice is empty when nothing valid was requested.

type GMNSNetworks added in v1.7.0

type GMNSNetworks struct {
	Macro     *macro.Net
	Movements movement.MovementsStorage
}

GMNSNetworks holds the intermediate GMNS networks produced while building the expanded graph. They are exposed so callers can optionally export GMNS CSV files (macro / movement) or generate and export the derived meso / micro networks without re-parsing the OSM data.

type GeoPoint added in v1.3.0

type GeoPoint struct {
	Lat float64
	Lon float64
}

GeoPoint representation of point on Earth

func (GeoPoint) String added in v1.3.0

func (gp GeoPoint) String() string

String returns pretty printed value for for GeoPoint

Directories

Path Synopsis
cmd
osm2ch command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL