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

New segmentEach & segmentReduce (@turf/meta) #863

Merged
merged 7 commits into from
Jul 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions packages/turf-line-distance/bench.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const fs = require('fs');
const path = require('path');
const load = require('load-json-file');
const Benchmark = require('benchmark');
const fs = require('fs');
const lineDistance = require('./');

// Define fixtures
Expand All @@ -17,12 +17,12 @@ const fixtures = fs.readdirSync(directory).map(filename => {
/**
* Benmark Results
*
* feature-collection x 274,292 ops/sec ±6.58% (75 runs sampled)
* multi-linestring x 606,888 ops/sec ±1.65% (87 runs sampled)
* multi-polygon x 425,090 ops/sec ±4.51% (80 runs sampled)
* polygon x 617,824 ops/sec ±4.31% (76 runs sampled)
* route1 x 1,234 ops/sec ±0.89% (87 runs sampled)
* route2 x 1,356 ops/sec ±0.89% (90 runs sampled)
* feature-collection x 240,519 ops/sec ±2.55% (83 runs sampled)
* multi-linestring x 352,542 ops/sec ±8.44% (76 runs sampled)
* multi-polygon x 308,500 ops/sec ±3.92% (83 runs sampled)
* polygon x 534,768 ops/sec ±1.29% (84 runs sampled)
* route1 x 1,280 ops/sec ±1.23% (89 runs sampled)
* route2 x 1,452 ops/sec ±1.57% (87 runs sampled)
*/

// Define benchmark
Expand Down
7 changes: 3 additions & 4 deletions packages/turf-line-distance/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
/// <reference types="geojson" />

type Geometry = GeoJSON.Polygon | GeoJSON.LineString | GeoJSON.MultiLineString | GeoJSON.MultiPolygon
type Feature = GeoJSON.Feature<GeoJSON.Polygon | GeoJSON.LineString | GeoJSON.MultiLineString | GeoJSON.MultiPolygon>
type Features = GeoJSON.FeatureCollection<GeoJSON.Polygon | GeoJSON.LineString | GeoJSON.MultiLineString | GeoJSON.MultiPolygon>
import {Units} from '@turf/helpers'
type Input = GeoJSON.Feature<any> | GeoJSON.FeatureCollection<any> | GeoJSON.GeometryObject | GeoJSON.GeometryCollection

/**
* http://turfjs.org/docs/#linedistance
*/
declare function lineDistance(features: Geometry | Feature | Features, units?: string): number;
declare function lineDistance(geojson: Input, units?: Units): number;
declare namespace lineDistance { }
export = lineDistance;
88 changes: 6 additions & 82 deletions packages/turf-line-distance/index.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
var flatten = require('@turf/flatten');
var distance = require('@turf/distance');
var meta = require('@turf/meta');
var geomEach = meta.geomEach;
var featureEach = meta.featureEach;
var coordReduce = meta.coordReduce;
var helpers = require('@turf/helpers');
var point = helpers.point;
var lineString = helpers.lineString;
var segmentReduce = require('@turf/meta').segmentReduce;

/**
* Takes a {@link LineString} or {@link Polygon} and measures its length in the specified units.
* Takes a {@link GeoJSON} and measures its length in the specified units, {@link (Multi)Point|Point}'s distance are ignored.
*
* @name lineDistance
* @param {Feature<(LineString|Polygon)>|FeatureCollection<(LineString|Polygon)>} geojson feature to measure
* @param {FeatureCollection|Feature|Geometry} geojson GeoJSON to measure
* @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
* @returns {number} length feature
* @returns {number} length of GeoJSON
* @example
* var line = turf.lineString([
* [-77.031669, 38.878605],
* [-77.029609, 38.881946],
* [-77.020339, 38.884084],
* [-77.025661, 38.885821],
* [-77.021884, 38.889563],
* [-77.019824, 38.892368]
* ]);
*
* var line = turf.lineString([[115, -32], [131, -22], [143, -25], [150, -34]]);
* var length = turf.lineDistance(line, 'miles');
*
* //addToMap
Expand All @@ -34,71 +19,10 @@ var lineString = helpers.lineString;
module.exports = function lineDistance(geojson, units) {
// Input Validation
if (!geojson) throw new Error('geojson is required');
geomEach(geojson, function (geometry) {
if (geometry.type === 'Point') throw new Error('geojson cannot be a Point');
if (geometry.type === 'MultiPoint') throw new Error('geojson cannot be a MultiPoint');
});

// Calculate distance from 2-vertex line segements
return segmentReduce(geojson, function (previousValue, segment) {
var coords = segment.geometry.coordinates;
var start = point(coords[0]);
var end = point(coords[1]);
return previousValue + distance(start, end, units);
return previousValue + distance(coords[0], coords[1], units);
}, 0);
};

/**
* Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()
*
* @private
* @param {FeatureCollection|Feature<any>} geojson any GeoJSON
* @param {Function} callback a method that takes (currentSegment, currentIndex)
* @returns {void}
* @example
* var polygon = {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Polygon",
* "coordinates": [[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]
* }
* }
* turf.segmentEach(polygon, function (segment) {
* //= segment
* });
*/
function segmentEach(geojson, callback) {
var count = 0;
featureEach(geojson, function (multiFeature) {
featureEach(flatten(multiFeature), function (feature) {
coordReduce(feature, function (previousCoords, currentCoords) {
var line = lineString([previousCoords, currentCoords], feature.properties);
callback(line, count);
count++;
return currentCoords;
});
});
});
}

/**
* Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()
*
* @private
* @param {FeatureCollection|Feature<any>} geojson any GeoJSON
* @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)
* @param {*} [initialValue] Value to use as the first argument to the first call of the callback.
* @returns {void}
*/
function segmentReduce(geojson, callback, initialValue) {
var previousValue = initialValue;
segmentEach(geojson, function (currentSegment, currentIndex) {
if (currentIndex === 0 && initialValue === undefined) {
previousValue = currentSegment;
} else {
previousValue = callback(previousValue, currentSegment, currentIndex);
}
});
return previousValue;
}
5 changes: 4 additions & 1 deletion packages/turf-line-distance/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
"gis"
],
"author": "Turf Authors",
"contributors": [
"Denis Carriere <@DenisCarriere>",
"Tom MacWright <@tmcw>"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/Turfjs/turf/issues"
Expand All @@ -38,7 +42,6 @@
},
"dependencies": {
"@turf/distance": "^4.5.2",
"@turf/flatten": "^4.5.2",
"@turf/helpers": "^4.5.2",
"@turf/meta": "^4.5.2"
}
Expand Down
9 changes: 1 addition & 8 deletions packages/turf-line-distance/test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
const test = require('tape');
const fs = require('fs');
const test = require('tape');
const path = require('path');
const load = require('load-json-file');
const write = require('write-json-file');
const {point, multiPoint} = require('@turf/helpers');
const lineDistance = require('./');

const directories = {
Expand All @@ -27,9 +26,3 @@ test('turf-line-distance', t => {
}
t.end();
});

test('turf-line-distance -- throws', t => {
t.throws(() => lineDistance(point([110, 60])), 'point');
t.throws(() => lineDistance(multiPoint([[-120, 40], [110, 60]])), 'multiPoint');
t.end();
});
8 changes: 8 additions & 0 deletions packages/turf-line-distance/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {lineString} from '@turf/helpers'
import * as lineDistance from './'

var line = lineString([[115, -32], [131, -22], [143, -25], [150, -34]]);
var length = lineDistance(line, 'miles');

lineDistance(line, 'kilometers');
lineDistance(line);
Loading