Skip to content
Open
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
4 changes: 4 additions & 0 deletions lib/random_linestring.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
library turf_random_linestring;

export 'src/random_linestring.dart';
export 'package:geotypes/geotypes.dart';
62 changes: 62 additions & 0 deletions lib/src/random_linestring.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import 'dart:math';
import 'package:turf/turf.dart';

// Takes an optional bbox and a mandatory integer to generate x number of linestrings. Other optional parameters: numVertices, maxLength, maxRotation
// Returns a random linestring

FeatureCollection<LineString> randomLineString(int? count,
{BBox? bbox, numVertices, maxLength, maxRotation}) {
numVertices ??= 10;
maxLength ??= 0.0001;
maxRotation ??= pi / 8;

// Ensure count is +ve value
if (count! <= 0) {
throw ArgumentError(
'Count must be set to a positive integer to return a LineString.');
}

// Returns a random position within Bbox if provided
Position coordInBBox(BBox? bbox) {
return Position(bbox![0]! + Random().nextDouble() * (bbox[2]! - bbox[0]!),
bbox[1]! + Random().nextDouble() * (bbox[3]! - bbox[1]!));
}

// Returns a random position within bbox if provided, else returns a random Position on the globe
Position randomPositionUnchecked(BBox? bbox) {
if (bbox != null) {
return coordInBBox(bbox);
}
return Position(
Random().nextDouble() * 360 - 180, Random().nextDouble() * 180 - 90);
}

// Generate list for all features, and loops through to generate all linestrings
List<Feature<LineString>> features = [];

for (int i = 0; i < count; i++) {
Position startingPos = randomPositionUnchecked(bbox);

List<Position> vertices = [startingPos];

for (int j = 0; j < numVertices - 1; j++) {
double priorAngle = j == 0
? Random().nextDouble() * 2 * pi
: atan((vertices[j][1]! - vertices[j - 1][1]!) /
(vertices[j][0]! - vertices[j - 1][0]!));

double angle =
priorAngle + (Random().nextDouble() - 0.5) * maxRotation * 2;
double distance = Random().nextDouble() * maxLength;

vertices.add(Position(
vertices[j][0]! + distance * cos(angle),
vertices[j][1]! + distance * sin(angle),
));
}

features.add(Feature(geometry: LineString(coordinates: vertices)));
}
//Finally return FeatureCollection
return FeatureCollection(features: features);
}
57 changes: 57 additions & 0 deletions test/components/random_linestring_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:test/test.dart';
import 'package:turf/random_linestring.dart';
import 'dart:math';

void main() {
group('Random linestring tests', () {
test('Returning a valid feature collection', () {
FeatureCollection<LineString> featureCollection = randomLineString(3);

expect(featureCollection, isA<FeatureCollection<LineString>>());
expect(
featureCollection.features
.every((line) => line.geometry is LineString),
isTrue);
});

test('Checking bbox boundaries', () {
BBox? bbox = BBox(100.0, -24.0, 110.0, -23.0);

FeatureCollection<LineString> lineString =
randomLineString(1, bbox: bbox);

lineString.features.first.geometry?.coordinates.forEach((coord) {
expect(coord[0], greaterThanOrEqualTo(bbox[0]!));
expect(coord[0], lessThanOrEqualTo(bbox[2]!));
expect(coord[1], greaterThanOrEqualTo(bbox[1]!));
expect(coord[1], lessThanOrEqualTo(bbox[3]!));
});
});

test('Testing Linestrings have vertexes = numVertices', () {
int vertices = 15;
FeatureCollection<LineString> lineString =
randomLineString(1, numVertices: vertices);

expect(lineString.features.first.geometry?.coordinates.length,
equals(vertices));
});

test('Testing maxLength and maxRotation constraints', () {
num maxLength = 0.001;
FeatureCollection<LineString> featureCollection =
randomLineString(5, maxLength: maxLength);

featureCollection.features.forEach((feature) {
final coords = feature.geometry?.coordinates;
for (int i = 1; i < coords!.length; i++) {
final dx = coords[i][0]! - coords[i - 1][0]!;
final dy = coords[i][1]! - coords[i - 1][1]!;
final distance = sqrt(dx * dx + dy * dy);

expect(distance, lessThanOrEqualTo(maxLength));
}
});
});
});
}