diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..251280e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,94 @@ +# Contributiung to Turf.dart + +Welcome and thank you for deciding to contribute to the project! + +Here is how cooperation works perfectly at [Turf Dart](https://github.com/dartclub/turf_dart) +#### Table of Contents + - [Code of Conduct](#code-of-conduct) + - [Get started](#get-started) + - [Structure of modules](#structure-of-modules) + - [Implementation Process](#implementation-process) + - [Documentation](#documentation) + - [GeoJSON object model](#GeoJSON-object-model) + +## Code of conduct +By participating, you are expected to uphold international human rights and fundamental freedoms! +To put it simply, be kind to each other. + +## Get started +- Get the [Dart tools](https://dart.dev/tools) +- Clone the repository: ```git clone git@github.com:dartclub/turf_dart.git``` +- Navigate to project's folder in terminal & get its dependencies: ```dart pub get``` +- Go through [Implementation Process](#implementation-process) +- Import the library in your code and use it. For example: +```dart +import 'package:turf/helpers.dart'; +import 'package:turf/src/line_segment.dart'; + + Feature poly = Feature( + geometry: Polygon(coordinates: [ + [ + Position(0, 0), + Position(2, 2), + Position(0, 1), + Position(0, 0), + ], + [ + Position(0, 0), + Position(1, 1), + Position(0, 1), + Position(0, 0), + ], + ]), + ); + +var total = segmentReduce(poly, (previousValue, + currentSegment, + initialValue, + featureIndex, + multiFeatureIndex, + geometryIndex, + segmentIndex) { + if (previousValue != null) { + previousValue++; + } + return previousValue; + }, 0, combineNestedGeometries: false); +// total.length == 6 +``` +## Structure of modules +``` +TURF_DART/lib/.dart // public facing API, exports the implementation + │ │ + │ └───src/.dart // the implementation + │ + └───benchmark/_benchmark.dart + │ + └───test/components/_test.dart // all the related tests +``` +## Implementation process +- Check the Backlog/Issues for similar issues +- Create a new branch _feature-_ from _main_ +- Create a _draft Pull request_, mention in it the associated issues +- **Implement** + - Document everything [properly](#documentation) + - If you are importing tests, comments etc. from [Turfjs](https://github.com/Turfjs/turf), please make sure you refactor it so it conforms with Dart syntax. + - **Write [tests](https://dart.dev/guides/testing)**―Keep an eye on [Turfjs'](https://github.com/Turfjs/turf) implementation + - run the the test: ```dart test test/components/XXX.dart``` + - **Write [benchmarks](https://pub.dev/packages/benchmark)**―have a look at our [implementation](https://github.com/dartclub/turf_dart/tree/main/benchmark) + - run the benchmark: ```dart pub run benchmark``` +- Commit +- Convert to real Pull request _ready for review_ +- Code review / mention a reviewer from [contributors list](https://github.com/dartclub/turf_dart/graphs/contributors) + + +## Documentation +We follow [Effective Dart](https://dart.dev/guides/language/effective-dart/documentation) guidelines for documentation. + +After going through the [Implementation Process](#implementation-process), please mention the made changes in [README.md](https://github.com/dartclub/turf_dart/blob/main/README.md) + +In order to add to this very documentation, please develop CONTRIBUTING.md in [documentation branch](https://github.com/dartclub/turf_dart/tree/documentation) + +## GeoJSON Object Model +If you have not read our [README.md](https://github.com/dartclub/turf_dart/blob/main/README.md) this diagram will give you a lot of information. Please consider looking our [notable design decisions](https://github.com/dartclub/turf_dart/blob/main/README.md#notable-design-decisions). +![polymorphism](https://user-images.githubusercontent.com/10634693/159876354-f9da2f37-02b3-4546-b32a-c0f82c372272.png) \ No newline at end of file diff --git a/benchmark/cluster_benchmark.dart b/benchmark/cluster_benchmark.dart index e2966a5..b3d0ca5 100644 --- a/benchmark/cluster_benchmark.dart +++ b/benchmark/cluster_benchmark.dart @@ -27,10 +27,8 @@ void main() { benchmark('clusterEach', () { List clusters = []; - int total = 0; clusterEach(featureCollection, "cluster", (cluster, clusterValue, currentIndex) { - total += cluster!.features.length; clusters.add(cluster); }); }); diff --git a/lib/src/bearing.dart b/lib/src/bearing.dart index 615a260..f979375 100644 --- a/lib/src/bearing.dart +++ b/lib/src/bearing.dart @@ -3,6 +3,9 @@ import 'dart:math'; import 'geojson.dart'; import 'helpers.dart'; +// http://en.wikipedia.org/wiki/Haversine_formula +// http://www.movable-type.co.uk/scripts/latlong.html + num bearingRaw(Position start, Position end, {bool calcFinal = false}) { // Reverse calculation if (calcFinal == true) { @@ -19,6 +22,22 @@ num bearingRaw(Position start, Position end, {bool calcFinal = false}) { return radiansToDegrees(atan2(a, b)); } +/// Takes two [Point]s and finds the geographic bearing between them, +/// i.e. the angle measured in degrees from the north line (0 degrees) +/// For example: +/// +/// ```dart +/// var point1 = Point(coordinates: Position(-75.343, 39.984)); +/// var point2 = Point(coordinates: Position((-75.543, 39.123)); +/// +/// var bearing = bearing(point1, point2); +/// //addToMap +/// var addToMap = [point1, point2] +/// point1.properties['marker-color'] = '#f00' +/// point2.properties['marker-color'] = '#0f0' +/// point1.properties.bearing = bearing +/// ``` + num bearing(Point start, Point end, {bool calcFinal = false}) => bearingRaw(start.coordinates, end.coordinates, calcFinal: calcFinal); @@ -28,5 +47,6 @@ num calculateFinalBearingRaw(Position start, Position end) { return reverseBearing.remainder(360); } +/// Calculates Final Bearing num calculateFinalBearing(Point start, Point end) => calculateFinalBearingRaw(start.coordinates, end.coordinates); diff --git a/lib/src/destination.dart b/lib/src/destination.dart index 78c805c..48461b9 100644 --- a/lib/src/destination.dart +++ b/lib/src/destination.dart @@ -22,6 +22,25 @@ Position destinationRaw(Position origin, num distance, num bearing, ); } +/// Takes a [Point] and calculates the location of a destination point given a distance in +/// degrees, radians, miles, or kilometers; and bearing in degrees. +/// This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. +/// For example: +/// +/// ```dart +/// var point = Point(coordinates: Position(-75.343, 39.984)); +/// var distance = 50; +/// var bearing = 90; +/// var options = Unit.miles; +/// +/// var destination = destination(point, distance, bearing, options); +/// +/// //addToMap +/// var addToMap = [point, destination] +/// destination.properties['marker-color'] = '#f00'; +/// point.properties['marker-color'] = '#0f0'; +/// ``` + Point destination(Point origin, num distance, num bearing, [Unit unit = Unit.kilometers]) => Point( diff --git a/lib/src/distance.dart b/lib/src/distance.dart index bfe1182..f8bd526 100644 --- a/lib/src/distance.dart +++ b/lib/src/distance.dart @@ -3,6 +3,9 @@ import 'dart:math'; import 'geojson.dart'; import 'helpers.dart'; +//http://en.wikipedia.org/wiki/Haversine_formula +//http://www.movable-type.co.uk/scripts/latlong.html + num distanceRaw(Position from, Position to, [Unit unit = Unit.kilometers]) { var dLat = degreesToRadians((to.lat - from.lat)); var dLon = degreesToRadians((to.lng - from.lng)); @@ -14,5 +17,16 @@ num distanceRaw(Position from, Position to, [Unit unit = Unit.kilometers]) { return radiansToLength(2 * atan2(sqrt(a), sqrt(1 - a)), unit); } +/// Calculates the distance between two [Point]s in degrees, radians, miles, or kilometers. +/// This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature. +/// For example: +/// +/// ```dart +/// var from = Point(coordinates: Position(-75.343, 39.984)); +/// var to = Point(coordinates: Position(-75.443, 39.984)); +/// var options = Unit.miles; +/// +/// var distance = distance(from, to, options); +/// ``` num distance(Point from, Point to, [Unit unit = Unit.kilometers]) => distanceRaw(from.coordinates, to.coordinates, unit); diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index a2f6115..f83f721 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -30,8 +30,11 @@ enum Corner { centroid, } +/// Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth. const earthRadius = 6371008.8; +/// Unit of measurement factors using a spherical (non-ellipsoid) earth radius. +/// Keys are the name of the unit, values are the number of that unit in a single radian const factors = { Unit.centimeters: earthRadius * 100, Unit.degrees: earthRadius / 111325, @@ -60,6 +63,7 @@ const unitsFactors = { Unit.yards: 1 / 1.0936, }; +/// Area of measurement factors based on 1 square meter. const areaFactors = { Unit.acres: 0.000247105, Unit.centimeters: 10000, @@ -72,6 +76,7 @@ const areaFactors = { Unit.yards: 1.195990046, }; +/// Round number to precision num round(num value, [num precision = 0]) { if (!(precision >= 0)) { throw Exception("precision must be a positive number"); @@ -81,6 +86,8 @@ num round(num value, [num precision = 0]) { return result.round() / multiplier; } +/// Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit. +/// Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet num radiansToLength(num radians, [Unit unit = Unit.kilometers]) { var factor = factors[unit]; if (factor == null) { @@ -89,6 +96,8 @@ num radiansToLength(num radians, [Unit unit = Unit.kilometers]) { return radians * factor; } +/// Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians +/// Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet num lengthToRadians(num distance, [Unit unit = Unit.kilometers]) { num? factor = factors[unit]; if (factor == null) { @@ -97,10 +106,14 @@ num lengthToRadians(num distance, [Unit unit = Unit.kilometers]) { return distance / factor; } +/// Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees +/// Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet num lengthToDegrees(num distance, [Unit unit = Unit.kilometers]) { return radiansToDegrees(lengthToRadians(distance, unit)); } +/// Converts any bearing angle from the north line direction (positive clockwise) +/// and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line num bearingToAzimuth(num bearing) { num angle = bearing.remainder(360); if (angle < 0) { @@ -109,16 +122,20 @@ num bearingToAzimuth(num bearing) { return angle; } +/// Converts an angle in radians to degrees num radiansToDegrees(num radians) { num degrees = radians.remainder(2 * pi); return degrees * 180 / pi; } +/// Converts an angle in degrees to radians num degreesToRadians(num degrees) { num radians = degrees.remainder(360); return radians * pi / 180; } +/// Converts a length to the requested unit. +/// Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet num convertLength( num length, [ Unit originalUnit = Unit.kilometers, @@ -130,6 +147,8 @@ num convertLength( return radiansToLength(lengthToRadians(length, originalUnit), finalUnit); } +/// Converts a area to the requested unit. +/// Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches, hectares num convertArea(num area, [originalUnit = Unit.meters, finalUnit = Unit.kilometers]) { if (area < 0) { diff --git a/lib/src/invariant.dart b/lib/src/invariant.dart index 2cf0859..3303e25 100644 --- a/lib/src/invariant.dart +++ b/lib/src/invariant.dart @@ -26,11 +26,12 @@ Position getCoord(dynamic coord) { throw Exception("coord must be GeoJSON Point or Position"); } -/// Unwrap coordinates from a [Feature], [GeometryObject] or a [List] +/// Unwraps coordinates from a [Feature], [GeometryObject] or a [List] /// /// Gets a [List], [GeometryObject] or a [Feature] or a [List] and /// returns [List]. /// For example: +/// /// ```dart /// var polygon = Polygon(coordinates: [ /// [ diff --git a/lib/src/line_segment.dart b/lib/src/line_segment.dart index 7552323..c9db26a 100644 --- a/lib/src/line_segment.dart +++ b/lib/src/line_segment.dart @@ -3,8 +3,6 @@ import 'package:turf/src/meta/flatten.dart'; import 'geojson.dart'; -// export default lineSegment; - /// Creates a [FeatureCollection] of 2-vertex [LineString] segments from a /// [LineString] or [MultiLineString] or [Polygon] and [MultiPolygon] /// Returns [FeatureCollection] 2-vertex line segments @@ -210,7 +208,7 @@ typedef T? SegmentReduceCallback( int segmentIndex, ); -/// Reduce 2-vertex line segment in any GeoJSON object, similar to [Iterable.reduce]() +/// Reduces 2-vertex line segment in any GeoJSON object, similar to [Iterable.reduce]() /// (Multi)Point geometries do not contain segments therefore they are ignored during this operation. /// /// Takes [FeatureCollection], [Feature], [GeoJSONObject], a diff --git a/lib/src/meta/extensions.dart b/lib/src/meta/extensions.dart index 4bda278..af809c4 100644 --- a/lib/src/meta/extensions.dart +++ b/lib/src/meta/extensions.dart @@ -7,7 +7,7 @@ extension GeoJSONObjectMetaExtension on GeoJSONObject { } T? geomReduce(meta.GeomReduceCallback callback, T? initialValue) { - meta.geomReduce( + return meta.geomReduce( this, callback, initialValue, @@ -22,7 +22,7 @@ extension GeoJSONObjectMetaExtension on GeoJSONObject { meta.PropReduceCallback callback, T? initialValue, ) { - meta.propReduce( + return meta.propReduce( this, callback, initialValue, @@ -37,7 +37,7 @@ extension GeoJSONObjectMetaExtension on GeoJSONObject { meta.FeatureReduceCallback callback, T? initialValue, ) { - meta.featureReduce( + return meta.featureReduce( this, callback, initialValue, @@ -53,7 +53,7 @@ extension GeoJSONObjectMetaExtension on GeoJSONObject { T? initialValue, [ bool excludeWrapCoord = false, ]) { - meta.coordReduce( + return meta.coordReduce( this, callback, initialValue, @@ -73,7 +73,7 @@ extension GeoJSONObjectMetaExtension on GeoJSONObject { meta.FlattenReduceCallback callback, T? initialValue, ) { - meta.flattenReduce( + return meta.flattenReduce( this, callback, initialValue, @@ -89,7 +89,7 @@ extension GeoJSONObjectMetaExtension on GeoJSONObject { T? initialValue, { bool combineNestedGeometries = true, }) { - meta.segmentReduce( + return meta.segmentReduce( this, callback, initialValue, @@ -115,7 +115,7 @@ extension FeatureCollectionMetaExtension on FeatureCollection { meta.ClusterReduceCallback callback, dynamic initialValue, ) { - meta.clusterReduce( + return meta.clusterReduce( this, property, callback, diff --git a/lib/src/meta/feature.dart b/lib/src/meta/feature.dart index 46aa79b..c1b033c 100644 --- a/lib/src/meta/feature.dart +++ b/lib/src/meta/feature.dart @@ -8,7 +8,6 @@ typedef FeatureEachCallback = dynamic Function( /// Iterates over features in any [geoJSONObject], calling [callback] on each /// iteration. Similar to [Iterable.forEach]. -/// /// For example: /// /// ```dart diff --git a/lib/src/midpoint.dart b/lib/src/midpoint.dart index ec6aef1..7176457 100644 --- a/lib/src/midpoint.dart +++ b/lib/src/midpoint.dart @@ -11,6 +11,20 @@ Position midpointRaw(Position point1, Position point2) { return midpoint; } +/// Takes two [Point]s and returns a point midway between them. +/// The midpoint is calculated geodesically, meaning the curvature of the earth is taken into account. +/// For example: +/// +/// ``` +/// var point1 = Point(coordinates: Position(-75.343, 39.984)); +/// var point2 = Point(coordinates: Position((-75.543, 39.123)); +/// +/// var midpoint = midpoint(point1, point2); +/// +/// //addToMap +/// var addToMap = [point1, point2, midpoint]; +/// midpoint.properties['marker-color'] = '#f00'; +/// ``` Point midpoint(Point point1, Point point2) => Point( coordinates: midpointRaw(point1.coordinates, point2.coordinates), ); diff --git a/lib/src/nearest_point.dart b/lib/src/nearest_point.dart index 00e9428..afd1b94 100644 --- a/lib/src/nearest_point.dart +++ b/lib/src/nearest_point.dart @@ -1,6 +1,29 @@ import 'distance.dart'; import 'geojson.dart'; +/// Takes a reference [Point] and a FeatureCollection of Features +/// with Point geometries and returns the +/// point from the FeatureCollection closest to the reference. This calculation +/// is geodesic. For example: +/// +/// ```dart +/// var targetPoint = Point(coordinates: Position(-75.943, 39.984)); +/// Feature feature = +/// Feature(geometry: targetPoint, properties: {"marker-color": "#0F0"}); +/// FeatureCollection points = FeatureCollection(features: [ +/// Feature(geometry: Point(coordinates: Position(-75.343, 39.984))), +/// Feature(geometry: Point(coordinates: Position(-75.443, 39.984))), +/// Feature(geometry: Point(coordinates: Position(-75.543, 39.984))), +/// Feature(geometry: Point(coordinates: Position(-75.643, 39.984))), +/// ]); +/// +/// var nearest = nearestPoint(targetPoint, points); +/// +/// //addToMap +/// var addToMap = [targetPoint, points, nearest]; +/// nearest.properties['marker-color'] = '#F00'; +/// ``` + Feature nearestPoint( Feature targetPoint, FeatureCollection points) { Feature nearest; diff --git a/lib/turf.dart b/lib/turf.dart index 03e8c95..380b60e 100644 --- a/lib/turf.dart +++ b/lib/turf.dart @@ -1,6 +1,3 @@ -/// Support for doing something awesome. -/// -/// More dartdocs go here. library turf; export 'src/bearing.dart'; diff --git a/test/components/geojson_test.dart b/test/components/geojson_test.dart index 0485e4a..957c730 100644 --- a/test/components/geojson_test.dart +++ b/test/components/geojson_test.dart @@ -309,107 +309,111 @@ main() { expect(() => GeometryType.deserialize(geoJSON3), throwsA(isA())); }); - test('.clone()', () { - final coll = FeatureCollection( - bbox: BBox(100, 0, 101, 1), - features: [ - Feature( - bbox: BBox(100, 0, 101, 1), - geometry: GeometryCollection( + test( + '.clone()', + () { + final coll = FeatureCollection( + bbox: BBox(100, 0, 101, 1), + features: [ + Feature( bbox: BBox(100, 0, 101, 1), - geometries: [ - LineString( - bbox: BBox(100, 0, 101, 1), - coordinates: [Position(100, 0), Position(101, 1)], - ), - MultiLineString.fromLineStrings( - bbox: BBox(100, 0, 101, 1), - lineStrings: [ - LineString( - bbox: BBox(100, 0, 101, 1), - coordinates: [Position(100, 0), Position(101, 1)], - ), - LineString( - bbox: BBox(100, 0, 101, 1), - coordinates: [Position(100, 1), Position(101, 0)], - ), - ], - ), - MultiPoint.fromPoints( - bbox: BBox(100, 0, 101, 1), - points: [ - Point(coordinates: Position(100, 0)), - Point(coordinates: Position(100.5, 0.5)), - Point(coordinates: Position(101, 1)), - ], - ), - Polygon( - bbox: BBox(100, 0, 101, 1), - coordinates: [ - [ - Position(100, 0), - Position(100, 1), - Position(101, 0), - ] - ], - ), - MultiPolygon.fromPolygons( - bbox: BBox(100, 0, 101, 1), - polygons: [ - Polygon(coordinates: [ + geometry: GeometryCollection( + bbox: BBox(100, 0, 101, 1), + geometries: [ + LineString( + bbox: BBox(100, 0, 101, 1), + coordinates: [Position(100, 0), Position(101, 1)], + ), + MultiLineString.fromLineStrings( + bbox: BBox(100, 0, 101, 1), + lineStrings: [ + LineString( + bbox: BBox(100, 0, 101, 1), + coordinates: [Position(100, 0), Position(101, 1)], + ), + LineString( + bbox: BBox(100, 0, 101, 1), + coordinates: [Position(100, 1), Position(101, 0)], + ), + ], + ), + MultiPoint.fromPoints( + bbox: BBox(100, 0, 101, 1), + points: [ + Point(coordinates: Position(100, 0)), + Point(coordinates: Position(100.5, 0.5)), + Point(coordinates: Position(101, 1)), + ], + ), + Polygon( + bbox: BBox(100, 0, 101, 1), + coordinates: [ [ Position(100, 0), Position(100, 1), Position(101, 0), ] - ]), - Polygon(coordinates: [ - [ - Position(100, 0), - Position(100, 1), - Position(101, 0), - ] - ]) - ], - ), - ], - ), - id: 1, - properties: {"key": "val"}), - ], - ); - final cloned = coll.clone(); - final feat = cloned.features.first; - final bbox = BBox(100, 0, 101, 1); - expect(cloned.bbox, bbox); - expect(feat.id, 1); - expect(feat.bbox, bbox); - expect(feat.properties!.keys.first, "key"); - expect(feat.properties!.values.first, "val"); - expect(feat.geometry!, isA()); - final geomColl = feat.geometry!; - expect(geomColl.geometries.length, - coll.features.first.geometry!.geometries.length); - for (var geom in geomColl.geometries) { - expect(geom.bbox, isNotNull); - expect(geom.coordinates, isNotEmpty); - - _expandRecursively(List inner) { - if (inner is List) { - return inner; - } else { - return inner.expand((el) => el is List ? _expandRecursively(el) : el); + ], + ), + MultiPolygon.fromPolygons( + bbox: BBox(100, 0, 101, 1), + polygons: [ + Polygon(coordinates: [ + [ + Position(100, 0), + Position(100, 1), + Position(101, 0), + ] + ]), + Polygon(coordinates: [ + [ + Position(100, 0), + Position(100, 1), + Position(101, 0), + ] + ]) + ], + ), + ], + ), + id: 1, + properties: {"key": "val"}), + ], + ); + final cloned = coll.clone(); + final feat = cloned.features.first; + final bbox = BBox(100, 0, 101, 1); + expect(cloned.bbox, bbox); + expect(feat.id, 1); + expect(feat.bbox, bbox); + expect(feat.properties!.keys.first, "key"); + expect(feat.properties!.values.first, "val"); + expect(feat.geometry!, isA()); + final geomColl = feat.geometry!; + expect(geomColl.geometries.length, + coll.features.first.geometry!.geometries.length); + for (var geom in geomColl.geometries) { + expect(geom.bbox, isNotNull); + expect(geom.coordinates, isNotEmpty); + + _expandRecursively(List inner) { + if (inner is List) { + return inner; + } else { + return inner + .expand((el) => el is List ? _expandRecursively(el) : el); + } } - } - var expanded = _expandRecursively(geom.coordinates); - expect( - expanded.first, - Position(100, 0), - ); - } - // TODO refine tests - }); + var expanded = _expandRecursively(geom.coordinates); + expect( + expanded.first, + Position(100, 0), + ); + } + // TODO refine tests + }, + ); final points = [ Point(coordinates: Position(1, 2, 3)), diff --git a/test/components/meta_test.dart b/test/components/meta_test.dart index 2ad90a6..102bdba 100644 --- a/test/components/meta_test.dart +++ b/test/components/meta_test.dart @@ -7,107 +7,96 @@ import 'package:turf/src/meta/geom.dart'; import 'package:turf/src/meta/prop.dart'; Feature pt = Feature( - geometry: Point.fromJson({ - 'coordinates': [0, 0], - }), + geometry: Point(coordinates: Position(0, 0)), properties: { 'a': 1, }, ); Feature pt2 = Feature( - geometry: Point.fromJson({ - 'coordinates': [1, 1], - }), + geometry: Point(coordinates: Position(1, 1)), ); Feature line = Feature( - geometry: LineString.fromJson({ - 'coordinates': [ - [0, 0], - [1, 1], - ] - }), + geometry: LineString(coordinates: [ + Position(0, 0), + Position(1, 1), + ]), ); Feature poly = Feature( - geometry: Polygon.fromJson({ - 'coordinates': [ - [ - [0, 0], - [1, 1], - [0, 1], - [0, 0], - ], - ] - }), + geometry: Polygon(coordinates: [ + [ + Position(0, 0), + Position(1, 1), + Position(0, 1), + Position(0, 0), + ], + ]), ); Feature polyWithHole = Feature( - geometry: Polygon.fromJson({ - 'coordinates': [ - [ - [100.0, 0.0], - [101.0, 0.0], - [101.0, 1.0], - [100.0, 1.0], - [100.0, 0.0], - ], - [ - [100.2, 0.2], - [100.8, 0.2], - [100.8, 0.8], - [100.2, 0.8], - [100.2, 0.2], - ], - ] - }), + geometry: Polygon(coordinates: [ + [ + Position(100.0, 0.0), + Position(101.0, 0.0), + Position(101.0, 1.0), + Position(100.0, 1.0), + Position(100.0, 0.0), + ], + [ + Position(100.2, 0.2), + Position(100.8, 0.2), + Position(100.8, 0.8), + Position(100.2, 0.8), + Position(100.2, 0.2), + ], + ]), ); Feature multiline = Feature( - geometry: MultiLineString.fromJson({ - 'coordinates': [ + geometry: MultiLineString( + coordinates: [ [ - [0, 0], - [1, 1], + Position(0, 0), + Position(1, 1), ], [ - [3, 3], - [4, 4], + Position(3, 3), + Position(4, 4), ], ], - }), + ), ); Feature multiPoint = Feature( - geometry: MultiPoint.fromJson({ - 'coordinates': [ - [0, 0], - [1, 1], - ], -})); + geometry: MultiPoint( + coordinates: [ + Position(0, 0), + Position(1, 1), + ], + ), +); Feature multiPoly = Feature( - geometry: MultiPolygon.fromJson({ - 'coordinates': [ + geometry: MultiPolygon(coordinates: [ + [ [ - [ - [0, 0], - [1, 1], - [0, 1], - [0, 0], - ], + Position(0, 0), + Position(1, 1), + Position(0, 1), + Position(0, 0), ], + ], + [ [ - [ - [3, 3], - [2, 2], - [1, 2], - [3, 3], - ], + Position(3, 3), + Position(2, 2), + Position(1, 2), + Position(3, 3), ], - ] - }), + ], + ]), ); Feature geomCollection = Feature( @@ -120,38 +109,36 @@ Feature geomCollection = Feature( ), ); -FeatureCollection fcMixed = FeatureCollection(features: [ - Feature( - geometry: Point.fromJson( - { - 'coordinates': [0, 0], - }, +FeatureCollection fcMixed = FeatureCollection( + features: [ + Feature( + geometry: Point( + coordinates: Position(0, 0), + ), + properties: {'foo': 'bar'}, ), - properties: {'foo': 'bar'}, - ), - Feature( - geometry: LineString.fromJson({ - 'coordinates': [ - [1, 1], - [2, 2], - ] - }), - properties: {'foo': 'buz'}), - Feature( - geometry: MultiLineString.fromJson({ - 'coordinates': [ - [ - [1, 1], - [0, 0], - ], - [ - [4, 4], - [5, 5], + Feature( + geometry: LineString(coordinates: [ + Position(1, 1), + Position(2, 2), + ]), + properties: {'foo': 'buz'}), + Feature( + geometry: MultiLineString( + coordinates: [ + [ + Position(0, 0), + Position(1, 1), + ], + [ + Position(4, 4), + Position(5, 5), + ], ], - ], - }), - properties: {'foo': 'qux'}), -]); + ), + properties: {'foo': 'qux'}), + ], +); List collection(Feature feature) { FeatureCollection featureCollection = FeatureCollection( @@ -665,7 +652,6 @@ main() { // Each Iterators // meta.segmentEach has been purposely excluded from this list - // TODO fill out this list will all 'each' iterators test('geomEach', () { runBreakingIterationTest(geomEach, (geom, i, props, bbox, id) { iterationCount += 1;