From 200c36c4fa8d94d008aa8df5c11952cd998edad4 Mon Sep 17 00:00:00 2001 From: tiinsy Date: Wed, 14 May 2025 12:46:52 +1000 Subject: [PATCH 1/2] partial linestring implementation --- lib/src/random_linestring.dart | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 lib/src/random_linestring.dart diff --git a/lib/src/random_linestring.dart b/lib/src/random_linestring.dart new file mode 100644 index 00000000..c3d8fb84 --- /dev/null +++ b/lib/src/random_linestring.dart @@ -0,0 +1,33 @@ +import 'dart:math'; +import 'package:turf/src/random_position.dart'; +import 'package:turf/turf.dart'; + +// Returns a random linestring + +Feature randomLineString( + count, { + BBox? bbox, + numVertices, + maxLength, + maxRotation}) { + + void checkBBox(BBox? bbox) { + if (bbox == null) { + return; + } + } + + checkBBox(bbox); + + numVertices = 10; + maxLength = 0.0001; + maxRotation = pi / 8; + + if (count <= 0) { + throw ArgumentError('Count must be set to a positive integer to return a LineString.'); + } + + for (i= 0) + + +} \ No newline at end of file From 5945e7aed9a8546c53066d6139dd31a683d99aa4 Mon Sep 17 00:00:00 2001 From: tiinsy Date: Mon, 2 Jun 2025 01:36:47 +1000 Subject: [PATCH 2/2] final implementation of randomLineString + tests --- lib/random_linestring.dart | 4 ++ lib/src/random_linestring.dart | 69 +++++++++++++++------ test/components/random_linestring_test.dart | 57 +++++++++++++++++ 3 files changed, 110 insertions(+), 20 deletions(-) create mode 100644 lib/random_linestring.dart create mode 100644 test/components/random_linestring_test.dart diff --git a/lib/random_linestring.dart b/lib/random_linestring.dart new file mode 100644 index 00000000..f6a6800d --- /dev/null +++ b/lib/random_linestring.dart @@ -0,0 +1,4 @@ +library turf_random_linestring; + +export 'src/random_linestring.dart'; +export 'package:geotypes/geotypes.dart'; \ No newline at end of file diff --git a/lib/src/random_linestring.dart b/lib/src/random_linestring.dart index c3d8fb84..a3984fda 100644 --- a/lib/src/random_linestring.dart +++ b/lib/src/random_linestring.dart @@ -1,33 +1,62 @@ import 'dart:math'; -import 'package:turf/src/random_position.dart'; 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 -Feature randomLineString( - count, { - BBox? bbox, - numVertices, - maxLength, - maxRotation}) { +FeatureCollection randomLineString(int? count, + {BBox? bbox, numVertices, maxLength, maxRotation}) { + numVertices ??= 10; + maxLength ??= 0.0001; + maxRotation ??= pi / 8; - void checkBBox(BBox? bbox) { - if (bbox == null) { - return; + // 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); } - checkBBox(bbox); + // Generate list for all features, and loops through to generate all linestrings + List> features = []; - numVertices = 10; - maxLength = 0.0001; - maxRotation = pi / 8; + for (int i = 0; i < count; i++) { + Position startingPos = randomPositionUnchecked(bbox); - if (count <= 0) { - throw ArgumentError('Count must be set to a positive integer to return a LineString.'); - } + List vertices = [startingPos]; - for (i= 0) - + 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]!)); -} \ No newline at end of file + 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); +} diff --git a/test/components/random_linestring_test.dart b/test/components/random_linestring_test.dart new file mode 100644 index 00000000..1eda342f --- /dev/null +++ b/test/components/random_linestring_test.dart @@ -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 featureCollection = randomLineString(3); + + expect(featureCollection, isA>()); + 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 = + 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 = + randomLineString(1, numVertices: vertices); + + expect(lineString.features.first.geometry?.coordinates.length, + equals(vertices)); + }); + + test('Testing maxLength and maxRotation constraints', () { + num maxLength = 0.001; + FeatureCollection 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)); + } + }); + }); + }); +}