-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Implement length with tests * Implement along with tests * Fix export added functions * Document along behaviour when distance is outside line length range * Format along test * Change length and along to accept Feature<LineString> instead of LineString * Change length to never return null. To my understanding, the reason why segmentReduce in its signature may return null is due to initialValue may be null, but in length() we supply 0.0 as the default. * Change along to throw Exception when empty line is passed instead of returning null It appears to be more in line with how turf.js operates and also existing error handling in turf_dart. * Change along to count from back when distance is negative I raised an issue with turf.js about behavour being undefined when distance is zero and they where in favour of counting from back behavour over clamping to the end. I think it is best to use same behavour as upstream turf.js so changing to their solution. * Update along test for negative distance * Fix along test for negative distance * Add along test using default unit * Add test of length() using default unit * Fix docs for along() when distance is negative * Change along() implementation to handle travelled == distance eagerly
- Loading branch information
1 parent
c3537d6
commit bec5af9
Showing
8 changed files
with
214 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
library turf_along; | ||
|
||
export "src/along.dart"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
library turf_length; | ||
|
||
export "src/length.dart"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import 'dart:math'; | ||
|
||
import 'package:turf/bearing.dart'; | ||
import 'package:turf/destination.dart'; | ||
import 'package:turf/helpers.dart'; | ||
import 'package:turf/length.dart'; | ||
import 'package:turf/src/distance.dart' as measure_distance; | ||
import 'package:turf/src/invariant.dart'; | ||
|
||
/// Takes a [line] and returns a [Point] at a specified [distance] along the line. | ||
/// | ||
/// If [distance] is less than 0, it will count distance along the line from end | ||
/// to start of line. If negative [distance] overshoots the length of the line, | ||
/// the start point of the line is returned. | ||
/// If [distance] is larger than line length, the end point is returned | ||
/// If [line] have no geometry or coordinates, an Exception is thrown | ||
Point along(Feature<LineString> line, num distance, | ||
[Unit unit = Unit.kilometers]) { | ||
// Get Coords | ||
final coords = getCoords(line); | ||
if (coords.isEmpty) { | ||
throw Exception('line must contain at least one coordinate'); | ||
} | ||
if (distance < 0) { | ||
distance = max(0, length(line, unit) + distance); | ||
} | ||
num travelled = 0; | ||
for (int i = 0; i < coords.length; i++) { | ||
if (distance >= travelled && i == coords.length - 1) { | ||
break; | ||
} | ||
if (travelled == distance) { | ||
return Point(coordinates: coords[i]); | ||
} | ||
if (travelled > distance) { | ||
final overshot = distance - travelled; | ||
final direction = bearing(Point(coordinates: coords[i]), | ||
Point(coordinates: coords[i - 1])) - | ||
180; | ||
final interpolated = destination( | ||
Point(coordinates: coords[i]), | ||
overshot, | ||
direction, | ||
unit, | ||
); | ||
return interpolated; | ||
} else { | ||
travelled += measure_distance.distance(Point(coordinates: coords[i]), | ||
Point(coordinates: coords[i + 1]), unit); | ||
} | ||
} | ||
return Point(coordinates: coords[coords.length - 1]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import 'package:turf/distance.dart'; | ||
import 'package:turf/helpers.dart'; | ||
import 'package:turf/line_segment.dart'; | ||
|
||
/// Takes a [line] and measures its length in the specified [unit]. | ||
num length(Feature<LineString> line, [Unit unit = Unit.kilometers]) { | ||
return segmentReduce<num>(line, ( | ||
previousValue, | ||
currentSegment, | ||
initialValue, | ||
featureIndex, | ||
multiFeatureIndex, | ||
geometryIndex, | ||
segmentIndex, | ||
) { | ||
final coords = currentSegment.geometry!.coordinates; | ||
return previousValue! + | ||
distance( | ||
Point(coordinates: coords[0]), | ||
Point(coordinates: coords[1]), | ||
unit, | ||
); | ||
}, 0.0) ?? | ||
0.0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import 'package:test/test.dart'; | ||
import 'package:turf/along.dart'; | ||
import 'package:turf/distance.dart'; | ||
import 'package:turf/helpers.dart'; | ||
import 'package:turf/length.dart'; | ||
|
||
void main() { | ||
test('along - negative distance should count backwards', () { | ||
final viaToEndDistance = | ||
distance(Point(coordinates: via), Point(coordinates: end), Unit.meters); | ||
expect(viaToEndDistance.round(), equals(198)); | ||
final resolvedViaPoint = along(line, -1 * viaToEndDistance, Unit.meters); | ||
expect(resolvedViaPoint.coordinates, equals(via)); | ||
}); | ||
test('along - to start point', () { | ||
final resolvedStartPoint = along(line, 0, Unit.meters); | ||
expect(resolvedStartPoint.coordinates, equals(start)); | ||
}); | ||
test('along - to point between start and via', () { | ||
final startToViaDistance = distance( | ||
Point(coordinates: start), Point(coordinates: via), Unit.meters); | ||
expect(startToViaDistance.round(), equals(57)); | ||
final resolvedViaPoint = along(line, startToViaDistance / 2, Unit.meters); | ||
expect(resolvedViaPoint.coordinates.lat.toStringAsFixed(6), | ||
equals('55.709028')); | ||
expect(resolvedViaPoint.coordinates.lng.toStringAsFixed(6), | ||
equals('13.185096')); | ||
}); | ||
test('along - to via point', () { | ||
final startToViaDistance = distance( | ||
Point(coordinates: start), Point(coordinates: via), Unit.meters); | ||
expect(startToViaDistance.round(), equals(57)); | ||
final resolvedViaPoint = along(line, startToViaDistance, Unit.meters); | ||
expect(resolvedViaPoint.coordinates, equals(via)); | ||
}); | ||
test('along - to point between via and end', () { | ||
final startToViaDistance = distance( | ||
Point(coordinates: start), Point(coordinates: via), Unit.meters); | ||
final viaToEndDistance = | ||
distance(Point(coordinates: via), Point(coordinates: end), Unit.meters); | ||
expect(startToViaDistance.round(), equals(57)); | ||
expect(viaToEndDistance.round(), equals(198)); | ||
final resolvedViaPoint = | ||
along(line, startToViaDistance + viaToEndDistance / 2, Unit.meters); | ||
expect(resolvedViaPoint.coordinates.lat.toStringAsFixed(6), | ||
equals('55.708330')); | ||
expect(resolvedViaPoint.coordinates.lng.toStringAsFixed(6), | ||
equals('13.186555')); | ||
}); | ||
test('along - to end point', () { | ||
final len = length(line, Unit.meters); | ||
expect(len.round(), equals(254)); | ||
final resolvedEndPoint = along(line, len, Unit.meters); | ||
expect(resolvedEndPoint.coordinates, equals(end)); | ||
}); | ||
test('along - to end point - default unit (km)', () { | ||
final len = length(line); | ||
expect((len * 1000).round(), equals(254)); | ||
final resolvedEndPoint = along(line, len); | ||
expect(resolvedEndPoint.coordinates, equals(end)); | ||
}); | ||
test('along - beyond end point', () { | ||
final len = length(line, Unit.meters); | ||
expect(len.round(), equals(254)); | ||
final resolvedEndPoint = along(line, len + 100, Unit.meters); | ||
expect(resolvedEndPoint.coordinates, equals(end)); | ||
}); | ||
} | ||
|
||
final start = Position.named( | ||
lat: 55.7090430186194, | ||
lng: 13.184645393920405, | ||
); | ||
final via = Position.named( | ||
lat: 55.70901279569489, | ||
lng: 13.185546616182755, | ||
); | ||
final end = Position.named( | ||
lat: 55.70764669578079, | ||
lng: 13.187563637197076, | ||
); | ||
final line = Feature<LineString>( | ||
geometry: LineString( | ||
coordinates: [ | ||
start, | ||
via, | ||
end, | ||
], | ||
), | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import 'package:test/test.dart'; | ||
import 'package:turf/helpers.dart'; | ||
import 'package:turf/length.dart'; | ||
|
||
void main() { | ||
test('length - in meters', () { | ||
final len = length(line, Unit.meters); | ||
expect(len.round(), equals(254)); | ||
}); | ||
test('length - default unit (km)', () { | ||
final len = length(line); | ||
expect((len * 1000).round(), equals(254)); | ||
}); | ||
} | ||
|
||
final start = Position.named( | ||
lat: 55.7090430186194, | ||
lng: 13.184645393920405, | ||
); | ||
final via = Position.named( | ||
lat: 55.70901279569489, | ||
lng: 13.185546616182755, | ||
); | ||
final end = Position.named( | ||
lat: 55.70764669578079, | ||
lng: 13.187563637197076, | ||
); | ||
final line = Feature<LineString>( | ||
geometry: LineString( | ||
coordinates: [ | ||
start, | ||
via, | ||
end, | ||
], | ||
), | ||
); |