Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shortest path, distance + cumulative elev change #29

Open
kylebarron opened this issue Dec 6, 2019 · 0 comments
Open

Shortest path, distance + cumulative elev change #29

kylebarron opened this issue Dec 6, 2019 · 0 comments

Comments

@kylebarron
Copy link
Member

GeoJSON Path finder is very helpful.

Usage

var helpers = require("@turf/helpers");
var length = require('@turf/length').default
var PathFinder = require("geojson-path-finder");
var geojson = require("./data/CA_Sec_A_tracks.json");
// Each degree of latitude is 111km, so precision of .001 snaps vertices within 100m
var pathFinder = new PathFinder(geojson, { precision: 0.001 });

// Same line
var start = Point([-116.467875, 32.590604]);
var end = Point([-116.503565, 32.607618]);
var path = pathFinder.findPath(start, end);

// # Different routes
var start = Point([-116.467078, 32.593434]);
var end = Point([-116.523801, 32.979053]);
var path = pathFinder.findPath(start, end);

I found that the default precision (.00001) was too small. I think precision of .001 degrees should be fine, although it would be ideal if alternates had an exact point where they intersected the PCT line.

By default, geojson-path-finder uses turf.distance as the weight function, and the returned distance is in kilometers.

Didn't check start/end points far off the tracks in the GeoJSON.

The difference between turf.length (on the resulting LineString of path.path's coordinates) and path.weight is like .6%, which might just be from floating point rounding? Not sure, but it's close enough to definitely not calculate path length again.

Cumulative elevation change

path.path reports the same coordinates that are passed into it. So if there are elevation values in the original GeoJSON LineStrings, there will be elevation values in the returned coordinates. This means that the easiest way to get cumulative elevation gain/loss to a point is to sum up the third values of the coords.

Here's JS code to calculate elevation change from an array of coordinates, where each coordinate is an array of [lon, lat, elevation]. elevChangeReduce should be faster than elevChangeFilter because the former only makes two passes through the list of coordinates instead of 4. After finding out the importance of setting the initial value in Array.prototype.reduce, they give the same result.

// Given an array of coordinates, find the marginal elevation
// gain/loss of each segment
// [1, 3, 2, 5] -> [2, -1, 3]
function getIncrementalDifference(coords) {
  const changes = coords.map((point, index) => {
    const nextPoint = coords[index + 1];
    if (nextPoint) {
      return nextPoint[2] - point[2]
    }
  })
  return changes;
}

function elevChangeReduce(coords) {
  const changes = getIncrementalDifference(coords)
  const positiveReducer = (acc, cur) => {
    if (cur > 0) {
      return acc + cur
    }
    else {
      return acc
    }
  }
  const negativeReducer = (acc, cur) => {
    if (cur < 0) {
      return acc + cur
    }
    else {
      return acc
    }
  }
  // Note: You need to set 0 as the initial value, or else the initial value is the first element!
  positiveSum = changes.reduce(positiveReducer, 0)
  negativeSum = changes.reduce(negativeReducer, 0)
  return [positiveSum, negativeSum]
}

function elevChangeFilter(coords) {
  const changes = getIncrementalDifference(coords)
  const positiveVals = changes.filter(val => val > 0)
  const negativeVals = changes.filter(val => val < 0)
  const positiveSum = positiveVals.reduce((acc, cur) => acc + cur)
  const negativeSum = negativeVals.reduce((acc, cur) => acc + cur)
  return [positiveSum, negativeSum]
}

elevChangeReduce(coords) // -> [ 2875.0599999999995, -2209.789999999999 ]
elevChangeFilter(coords) // -> [ 2875.0599999999995, -2209.789999999999 ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant