graph-from-osm
v1.0.0
Published
JavaScript minimalistic module to import data from OSM and transform it into geoJSON-format graph structured data.
Downloads
4
Maintainers
Readme
Graph From OSM
Introduction
Here is a minimalistic (npm) JavaScript module that can dynamically generate a script to perform OSM queries (to https://overpass-api.de/api/interpreter) and download data about the routing-network. Then it transforms it to a Graph-structured data in geoJSON format. It is possible to specify the geographical region and the type of roads to download.
What is a geoJSON format? It is a common JSON based format to represent geographical data with large ecosystem of libraries and softwares able to work with it. It can be easily visualized for example on geojson.io or on softwares such as Q-GIS.
What is Graph-structured? By graph structured I refer to a mathematical (directed) graph structure, which is basically a set of nodes (also called vertices) connected by links (also called edges). So, in this case, each road is a link and each intersection is a node.
Here is a visualization of the result, (image generated with geojson.io)
Usage as a npm module
1) Installation
$ npm install graph-from-osm
2) Usage
This module expose the object graphFromOsm
which contains two functions getOsmData
(asynchrone) and generateGraph
(synchrone). Here is an example of how to use them:
const graphFromOsm = require('graph-from-osm'); // Import module
const generateGraph = async (settings) => {
const osmData = await graphFromOsm.getOsmData(settings); // Import OSM raw data
const graph = graphFromOsm.osmDataToGraph(osmData) // Here is your graph
}
const mySettings = { // Define my settings
bbox: [4.3841, 50.8127, 4.3920, 50.8182],
highways: ["primary", "secondary", "tertiary", "residential"],
timeout: 600000000, maxContentLength: 1500000000
}
generateGraph(mySettings);
Usage as a node.js app
1) Installation
- First you have to install node.js and npm on your computer.
- Download this project in a local directory.
- Then initialize (it installs all the dependencies) the module with the command
$ npm install
2) Usage
Just run the command
$ npm run generate
Congratulation, you have obtained you graph!!
- OSM script in
./data/script.txt
- OSM raw data in
./data/osm-raw-data.json
- graph in
./data/graph.json
Or you can use the following functions (exposed in index.js
) in you own code:
getOsmData
: settings → OSM row DataosmDataToGraph
: OSM raw Data → Graph
You can see an example of how to use these function in the script ./generate.js
.
Make your own query
By modifying the file settings.json
, you can specify:
1) The geographical region
Represented as a bbox (bounding box), which is an array of length 4 with float values:
settings.bbox = [longitude_1, latitude_1, longitude_2, latitude_2]
where [longitude_1, latitude_1]
is the bottom-left corner of the box and [longitude_2, latitude_2]
is the top-right corner of the box. The 4 values should be valid geographical coordinates in degrees.
For example, the following bbox is defined by the array [4.3777, 50.8132, 4.3969, 50.8223]
.
(image generated with geojson.io)
2) The type of roads
OSM data is based on a system of tags. Each data element possess a set of tags which is a system of key-value pairs. The tag key used to "identify any kind of road, street or path" is highway. So, by defining the value of the highway tag, you can choose the type of roads you need in your data. For example, you can consider only high speed highways for car with that tag highway: motorway
. Refer to the previous web link to determine what king or highway tag you need.
So settings.highways
should be a non-zero-length array of strings or ="ALL"
.
Here is an example of query (or you can just see the template in ./settings.json
)
{
bbox: [ 4.3772, 50.8106, 4.3945, 50.8200 ],
highways: [ "primary", "secondary", "tertiary" ]
}
3) The timeout and maxContentLength
There are time and size limitations for the query. Note that the smaller are these number, the higher is the priority of your query for OSM.
Remarks
1) OSM raw data do not have a graph structure
In OSM raw data, a node element do not always corresponds to an intersection of roads. Moreover, a link can possess multiple intersection in its middle, which should not be the case in a graph. In order to give to the data a graph structure, these links should be separated in multiples links whose two extremities corresponds to its only intersections. This is one thing that this module do. So, the graph data file possess generally fewer nodes and more links than the OMS raw data file. Here you can see an illustration of this transformation.
2) Id system of the graph data
Due to the remark (1), the OSM links ids of the graph may not be unique, so a new system of ids is generated for this data (access id by myFeature.id
). The old OSM ids are still saved in myFeature.properties.osmId
.
3) Reconstruct the graph topology
In order to reconstruct the graph structure of the geojson graph data (./data/graph.json
). Each link (LineString-type geojson object) possess properties .src
and .tgt
which reference the id of a node in .id
. This information defines the topology of the graph. Note that in roads networks, a node can be linked to itself (link.src = link.tgt
) and two nodes can be related by multiples links (link_1.id != link_2.id
but still link_1.src = link_2.src
and link_1.tgt = link_2.tgt
).
4) OSM tags
Note that in graph data (./data/graph.json
), the features keep the initial OSM tags in .properties.tags
so that you can infer additional information about this feature form its OSM tags (maximal speed, incline, one ways, ...).
Warning
For the sake of simplicity and minimalism and in order to limit the number of dependencies, this module do not uses any DataBase or other tool to manage memory. Consequently, if the amount of data you want to download exceeds you node.js capacity, the execution will crash.
Author: Matsvei Tsishyn ([email protected])