perliedman / geojson-path-finder

Find shortest path through a network of GeoJSON
https://www.liedman.net/geojson-path-finder/
ISC License
300 stars 86 forks source link

GeoJSON Path Finder

Build status

Find shortest paths through a network of GeoJSON.

Given a network of GeoJSON LineStrings, GeoJSON Path Finder will find the shortest path between two points in the network. This might be useful for automatic route searches in smaller networks, where setting up a real route planner like OSRM is too much work, or you simply need to do everything on the client.

See the GeoJSON Path Finder demo.

Upgrade notice Version 2.0 has been released, which is a TypeScript rewrite - you can still use the module from plain JavaScript, of course. This version also contains some breaking changes regarding option naming; for most common use cases, everything will work as before.

Breaking changes:

Installing

npm install --save geojson-path-finder

API

Detailed (and somewhat experimental) API Docs

Create a path finding object:

import PathFinder from "geojson-path-finder";
import geojson from "./network.json";

const pathFinder = new PathFinder(geojson);

The GeoJSON object should be a FeatureCollection of LineString features. The network will be built into a topology, so that lines that start and end, or cross, at the same coordinate are joined such that you can find a path from one feature to the other.

To find the shortest path between two coordinates:

var path = pathFinder.findPath(start, finish);

Where start and finish are two GeoJSON point features. Note that both points have to be vertices in the routing network; if they are not, no route will be found.

If a route can be found, an object with two properties: path and weight is returned, where path is the coordinates the path runs through, and weight is the total weight (distance in kilometers, if you use the default weight function) of the path.

As a convenience, the function pathToGeoJSON is also exported, it converts the result of a findPath call to a GeoJSON linestring:

import PathFinder, { pathToGeoJSON } from "geojson-path-finder";
const pathFinder = new PathFinder(geojson);
const pathLineString = pathToGeoJSON(pathFinder.findPath(start, finish));

(If findPath does not find a path, pathToGeoJSON will also return undefined.)

PathFinder options

The PathFinder constructor takes an optional seconds parameter containing options that you can use to control the behaviour of the path finder. Available options:

Weight functions

By default, the cost of going from one node in the network to another is determined simply by the geographic distance between the two nodes. This means that, by default, shortest paths will be found. You can however override this by providing a cost calculation function through the weight option:

const pathFinder = new PathFinder(geojson, {
  weight: function (a, b, props) {
    const dx = a[0] - b[0];
    const dy = a[1] - b[1];
    return Math.sqrt(dx * dx + dy * dy);
  },
});

The weight function is passed two coordinate arrays (in GeoJSON axis order), as well as the feature properties that are associated with this feature, and should return either: