Giter Club home page Giter Club logo

multimodal-isochrones's Introduction

multimodal-isochrones

Compute lines of equal travel times (isochrones) in a multimodal transport graph.

Isochrone maps display areas of similar travel time to a selected starting location on the map. There are several algorithms that can be used to compute the minimum travel distance on a graph, however they don't take into account the additional cost of switching traveling mode in a door-to-door approach.

Graphs are usually represented as nodes connected by edges. In a complex transport systems edges can belong to different railway or bus lines and there's usually an additional cost (monetary or travel time) in switching line at any given station (node).

multimodal-isochrones finds the shortest path between a node of the graph and any other node taking into account the travel cost and the cost of transfers.

Node

A node is simply represented by a unique String.

For complex transport networks this could be a single station, regardless of the number of lines that crosses it.

Edge

An edge is a direct connection between two nodes (undirected). It's represented by

  • from the origin node
  • to the destination node
  • line the line identifier
  • time the cost value, the algorithm will try to minimize it

Populate the graph

const isochrones = require('multimodal-isochrones');

/* Generate a graph with two nodes connected by an edge on line1
 * that takes 5 minutes to cross
 */
const graph = isochrones()
  .addEdge({ from: 'node1', to: 'node2', line: 'line1', time: 5 });

You can chain any number of addNode and addEdge, in any order to build your graph, the only constraint is that when creating an edge both nodes must be already added.

You can represent multiple lines and the time it take to transfer between them by calling

const graph = isochrones()
  // fist line, going from north to south
  .addEdge({ from: 'north', to: 'center', line: 'vertical-line', time: 5 })
  .addEdge({ from: 'south', to: 'center', line: 'vertical-line', time: 5 })
  // second line, from east to west
  .addEdge({ from: 'west', to: 'center', line: 'horizontal-line', time: 4 })
  .addEdge({ from: 'east', to: 'center', line: 'horizontal-line', time: 4 })
  // it takes some time to change line at the center
  .addConnection('center', 'vertical-line', 'horizontal-line', 2);

options

The main function isochrones accepts an optional options object with

const graph = isochrones({
  defaultConnectionTime: 4, // Time to transfer line at any node, default 0
});

Query

In order to get a list of nodes you need a query object, that can be constructed calling

const query = graph.from('node1');

const nodes = query.get();

.get() returns all the nodes that match the constraints defined by the query object. The result is an array of objects like

{
  node: 'node2', // the target node
  paths: [ // a list of paths the go from a source node to the target
    {
      from: 'node1', // the source node
      lines: ['line1'], // the list of lines traversed
      time: 5, // total time from source to target
    }
  ],
}

Max travel time

Limit the results by the total travel time calling

const query = graph.from('node1');

const nodes = query.maxTime(30).get();

This will return all nodes reachable in 30 minutes (assuming you count time in minutes) from node1.

Max number of line transfers

Limit the results by the total number of lines that can be crossed

const query = graph.from('node1');

const nodes = query.maxLines(2).get();

This will return all nodes reachable with a maximum of two lines, so the ones on the same line as node1 and the ones that are directly connected to them.

Intersection

A simple query (using .from) returns all nodes reachable from a starting node, for more advanced results you can intersect any arbitrary number of queries.

const intersection = graph.intersect(
  graph.from('node1').maxTime(10).maxLines(1),
  graph.from('node2').maxTime(30).maxLines(2),
  // any number of them
);

const nodes = intersection.get();

The example query above will return all nodes that are reachable from both node1 and node2 with the extra constraints of being within 10 minutes and one line from node1 and 30 minutes and max two lines from node2.

Join

If you have equivalent starting nodes and you want to get the shortest paths from either of them, you can join two queries

const join = graph.join(
  graph.from('node1').maxTime(10),
  graph.from('node2').maxTime(10),
);

const nodes = join.get();

The example will return all nodes that are reachable from eiter node1 or node2 with the desired constraints. Only the shortest path will be included in the results.

join and intersect can be combined

graph.join(
  graph.intersect(
    graph.from('node1').maxTime(10),
    graph.from('node2').maxTime(10),
  ),
  graph.from('node3').maxTime(10),
).get();

// or

graph.intersect(
  graph.join(
    graph.from('node1').maxTime(10),
    graph.from('node2').maxTime(10),
  ),
  graph.from('node3').maxTime(10),
).get();

Utility methods

const isochrones = require('multimodal-isochrones');
const graph = isochrones(); // .addEdge

const lines = isochrones.getTraversedLines(
  graph.from('node1').get()
);
/*
lines contains all line ids included in the result list
 */

Additional data on the paths object

It's possible to assign any additional data to the result paths calling pathData on the query object.

const node = graph.join(
  graph.from('node1').pathData({ cost: 100 }),
  graph.from('node2').pathData({ cost: 200 }),
);
/*
nodes = [
  { node: 'node3', paths: [{ from: 'node1', cost: 100, ... }]},
  ...
]
 */

multimodal-isochrones's People

Contributors

piuccio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.