diff --git a/.gitignore b/.gitignore index 81cc7ef..360fc0f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,7 @@ build/ # Directory created by dartdoc doc/api/ -coverage/ \ No newline at end of file +coverage/ + +.idea/ + diff --git a/CHANGELOG.md b/CHANGELOG.md index 37ae4ad..383fc3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ +## 0.0.7 + +- Implements `nearestPointOn(Multi)Line` [#87](https://github.com/dartclub/turf_dart/pull/87) +- Implements `explode` function [#93](https://github.com/dartclub/turf_dart/pull/93) +- Implements `bbox-polygon` and `bbox`, `center`, polyline functions [#99](https://github.com/dartclub/turf_dart/pull/99) +- Updates the `BBox`-class constructor [#100](https://github.com/dartclub/turf_dart/pull/100) +- Implements `rhumbBearing` function [#109](https://github.com/dartclub/turf_dart/pull/109) +- Implements `lineToPolygon` and `polygonToLine` functions [#104](https://github.com/dartclub/turf_dart/pull/104) +- Implements `truncate` function [#111](https://github.com/dartclub/turf_dart/pull/111) +- Implements `cleanCoord` function [#112](https://github.com/dartclub/turf_dart/pull/112) +- Some documentation & README improvements + ## 0.0.6+3 - Rename examples file + ## 0.0.6+2 - Added code examples diff --git a/README.md b/README.md index ad34295..18c4b08 100644 --- a/README.md +++ b/README.md @@ -75,32 +75,32 @@ Any new benchmarks must be named `*_benchmark.dart` and reside in the ### Measurement - [ ] along - [ ] area -- [ ] bbox -- [ ] bboxPolygon -- [x] [bearing](https://github.com/dartclub/turf_dart/blob/main/lib/bearing.dart) -- [ ] center +- [x] [bbox](https://github.com/dartclub/turf_dart/blob/main/lib/src/bbox.dart) +- [x] [bboxPolygon](https://github.com/dartclub/turf_dart/blob/main/lib/src/bbox_polygon.dart) +- [x] [bearing](https://github.com/dartclub/turf_dart/blob/main/lib/src/bearing.dart) +- [x] [center](https://github.com/Dennis-Mwea/turf_dart/blob/main/lib/src/center.dart) - [ ] centerOfMass - [ ] centroid -- [x] [destination](https://github.com/dartclub/turf_dart/blob/main/lib/destination.dart) -- [x] [distance](https://github.com/dartclub/turf_dart/blob/main/lib/distance.dart) +- [x] [destination](https://github.com/dartclub/turf_dart/blob/main/lib/src/destination.dart) +- [x] [distance](https://github.com/dartclub/turf_dart/blob/main/lib/src/distance.dart) - [ ] envelope - [ ] length -- [x] [midpoint](https://github.com/dartclub/turf_dart/blob/main/lib/midpoint.dart) +- [x] [midpoint](https://github.com/dartclub/turf_dart/blob/main/lib/src/midpoint.dart) - [ ] pointOnFeature - [ ] polygonTangents - [ ] pointToLineDistance -- [ ] rhumbBearing +- [x] [rhumbBearing](https://github.com/dartclub/turf_dart/blob/main/lib/src/rhumb_bearing.dart) - [ ] rhumbDestination - [ ] rhumbDistance - [ ] square - [ ] greatCircle ### Coordinate Mutation -- [ ] cleanCoords +- [x] [cleanCoords](https://github.com/dartclub/turf_dart/blob/main/lib/src/clean_coords.dart) - [ ] flip - [ ] rewind - [ ] round -- [ ] truncate +- [x] [truncate](https://github.com/dartclub/turf_dart/blob/main/lib/src/truncate.dart) ### Transformation - [ ] bboxClip @@ -122,14 +122,15 @@ Any new benchmarks must be named `*_benchmark.dart` and reside in the - [ ] transformScale - [ ] union - [ ] voronoi +- [x] [polyLineDecode](https://github.com/Dennis-Mwea/turf_dart/blob/main/lib/src/polyline.dart) ### Feature Conversion - [ ] combine -- [ ] explode +- [x] [explode](https://github.com/dartclub/turf_dart/blob/main/lib/src/explode.dart) - [ ] flatten -- [ ] lineToPolygon +- [x] [lineToPolygon](https://github.com/dartclub/turf_dart/blob/main/lib/src/line_to_polygon.dart) - [ ] polygonize -- [ ] polygonToLine +- [x] [polygonToLine](https://github.com/dartclub/turf_dart/blob/main/lib/src/polygon_to_line.dart) ### MISC - [ ] ellipse @@ -143,7 +144,7 @@ Any new benchmarks must be named `*_benchmark.dart` and reside in the - [ ] lineSliceAlong - [ ] lineSplit - [ ] mask -- [ ] nearestPointOnLine +- [x] [nearestPointOnLine](https://github.com/dartclub/turf_dart/blob/main/lib/src/nearest_point_on_line.dart) - [ ] sector - [ ] shortestPath - [ ] unkinkPolygon @@ -175,7 +176,7 @@ Any new benchmarks must be named `*_benchmark.dart` and reside in the - [ ] triangleGrid ### Classification -- [x] [nearestPoint](https://github.com/dartclub/turf_dart/blob/main/lib/nearest_point.dart) +- [x] [nearestPoint](https://github.com/dartclub/turf_dart/blob/main/lib/src/nearest_point.dart) ### Aggregation - [ ] collect diff --git a/benchmark/explode_benchmark.dart b/benchmark/explode_benchmark.dart new file mode 100644 index 0000000..782e0ff --- /dev/null +++ b/benchmark/explode_benchmark.dart @@ -0,0 +1,21 @@ +import 'package:benchmark/benchmark.dart'; +import 'package:turf/src/explode.dart'; +import 'package:turf/turf.dart'; + +var poly = Polygon(coordinates: [ + [ + Position.of([0, 0]), + Position.of([0, 10]), + Position.of([10, 10]), + Position.of([10, 0]), + Position.of([0, 0]), + ], +]); + +main() { + group('explode', () { + benchmark('simple', () { + explode(poly); + }); + }); +} diff --git a/lib/bbox.dart b/lib/bbox.dart new file mode 100644 index 0000000..22703d2 --- /dev/null +++ b/lib/bbox.dart @@ -0,0 +1,3 @@ +library turf_bbox; + +export "src/bbox.dart"; diff --git a/lib/bbox_polygon.dart b/lib/bbox_polygon.dart new file mode 100644 index 0000000..3c5c846 --- /dev/null +++ b/lib/bbox_polygon.dart @@ -0,0 +1,3 @@ +library turf_bbox_polygon.dart; + +export 'src/bbox_polygon.dart'; diff --git a/lib/bearing.dart b/lib/bearing.dart index 9b3eeee..64c1d49 100644 --- a/lib/bearing.dart +++ b/lib/bearing.dart @@ -1,3 +1,4 @@ library turf_bearing; export 'src/bearing.dart'; +export 'src/rhumb_bearing.dart'; diff --git a/lib/center.dart b/lib/center.dart new file mode 100644 index 0000000..898d82d --- /dev/null +++ b/lib/center.dart @@ -0,0 +1,3 @@ +library turf_center; + +export 'src/center.dart'; diff --git a/lib/clean_coords.dart b/lib/clean_coords.dart new file mode 100644 index 0000000..7c61dea --- /dev/null +++ b/lib/clean_coords.dart @@ -0,0 +1,3 @@ +library clean_coords.dart; + +export 'src/clean_coords.dart'; diff --git a/lib/explode.dart b/lib/explode.dart new file mode 100644 index 0000000..babaf58 --- /dev/null +++ b/lib/explode.dart @@ -0,0 +1,3 @@ +library explode; + +export 'src/explode.dart'; diff --git a/lib/line_to_polygon.dart b/lib/line_to_polygon.dart new file mode 100644 index 0000000..1dfc8be --- /dev/null +++ b/lib/line_to_polygon.dart @@ -0,0 +1,3 @@ +library turf_line_to_polygon.dart; + +export 'src/line_to_polygon.dart'; diff --git a/lib/nearest_point_on_line.dart b/lib/nearest_point_on_line.dart new file mode 100644 index 0000000..71d7ebc --- /dev/null +++ b/lib/nearest_point_on_line.dart @@ -0,0 +1,3 @@ +library turf_nearest_point_on_line; + +export 'src/nearest_point_on_line.dart'; diff --git a/lib/polygon_to_line.dart b/lib/polygon_to_line.dart new file mode 100644 index 0000000..0b38e83 --- /dev/null +++ b/lib/polygon_to_line.dart @@ -0,0 +1,3 @@ +library turf_polygon_to_line; + +export 'src/polygon_to_line.dart'; diff --git a/lib/polyline.dart b/lib/polyline.dart new file mode 100644 index 0000000..8ef7e96 --- /dev/null +++ b/lib/polyline.dart @@ -0,0 +1,3 @@ +library turf_polyline; + +export 'src/polyline.dart'; diff --git a/lib/src/bbox.dart b/lib/src/bbox.dart new file mode 100644 index 0000000..a7d37ab --- /dev/null +++ b/lib/src/bbox.dart @@ -0,0 +1,39 @@ +import 'package:turf/helpers.dart'; +import 'package:turf/meta.dart'; + +/// Calculates the bounding box for any [geoJson] object, including [FeatureCollection]. +/// If [recompute] is not set and the [bbox] is not null, the function uses the [bbox] of the given [GeoJSONObject]. +BBox bbox(GeoJSONObject geoJson, {bool recompute = false}) { + if (geoJson.bbox != null && !recompute) { + return geoJson.bbox!; + } + + var result = BBox.named( + lat1: double.infinity, + lng1: double.infinity, + lat2: double.negativeInfinity, + lng2: double.negativeInfinity, + ); + + coordEach( + geoJson, + (Position? currentCoord, _, __, ___, ____) { + if (currentCoord != null) { + if (result.lng1 > currentCoord.lng) { + result = result.copyWith(lng1: currentCoord.lng); + } + if (result.lat1 > currentCoord.lat) { + result = result.copyWith(lat1: currentCoord.lat); + } + if (result.lng2 < currentCoord.lng) { + result = result.copyWith(lng2: currentCoord.lng); + } + if (result.lat2 < currentCoord.lat) { + result = result.copyWith(lat2: currentCoord.lat); + } + } + }, + ); + + return result; +} diff --git a/lib/src/bbox_polygon.dart b/lib/src/bbox_polygon.dart new file mode 100644 index 0000000..70c72d7 --- /dev/null +++ b/lib/src/bbox_polygon.dart @@ -0,0 +1,42 @@ +import 'package:turf/helpers.dart'; + +/// Takes a [Bbox] and returns an equivalent [Feature]. +/// ```dart +/// var bbox = Bbox(0, 0, 10, 10); +/// var poly = bboxPolygon(bbox); +/// //addToMap +/// var addToMap = [poly] +/// ``` +Feature bboxPolygon(BBox bbox, + {Map properties = const {}, dynamic id}) { + var west = bbox[0]!; + var south = bbox[1]!; + var east = bbox[2]!; + var north = bbox[3]!; + + if (bbox.length == 6) { + throw Exception("turf/bbox-polygon does not support BBox with 6 positions"); + } + + var lowLeft = [west, south]; + var topLeft = [west, north]; + var topRight = [east, north]; + var lowRight = [east, south]; + + return Feature( + bbox: bbox.clone(), + properties: properties, + id: id, + geometry: Polygon( + coordinates: [ + [ + Position.of(lowLeft), + Position.of(lowRight), + Position.of(topRight), + Position.of(topLeft), + Position.of(lowLeft) + ] + ], + ), + ); +} diff --git a/lib/src/center.dart b/lib/src/center.dart new file mode 100644 index 0000000..4eb4cdf --- /dev/null +++ b/lib/src/center.dart @@ -0,0 +1,21 @@ +import 'package:turf/bbox.dart' as t; +import 'package:turf/helpers.dart'; + +/// Takes a [Feature] or a [FeatureCollection] and returns the absolute center point of all feature(s). +Feature center( + GeoJSONObject geoJSON, { + dynamic id, + BBox? bbox, + Map? properties, +}) { + final BBox ext = t.bbox(geoJSON); + final num x = (ext[0]! + ext[2]!) / 2; + final num y = (ext[1]! + ext[3]!) / 2; + + return Feature( + id: id, + bbox: bbox, + properties: properties, + geometry: Point(coordinates: Position.named(lat: y, lng: x)), + ); +} diff --git a/lib/src/clean_coords.dart b/lib/src/clean_coords.dart new file mode 100644 index 0000000..5ee1b37 --- /dev/null +++ b/lib/src/clean_coords.dart @@ -0,0 +1,146 @@ +import '../helpers.dart'; +import 'invariant.dart'; + +/// Removes redundant coordinates from any [GeometryType]. +/// Takes a [Feature] or [GeometryType] +/// [mutate] allows GeoJSON input to be mutated +/// Returns the cleaned input [Feature] +/// example: +/// ```dart +/// var line = LineString(coordinates:[Position.of([0, 0]), Position.of([0, 2]), Position.of([0, 5]), Position.of([0, 8]), Position.of([0, 8]), Position.of([0, 10])]); +/// var multiPoint = MultiPoint(coordinates:[Position.of([0, 0]), Position.of([0, 0]), Position.of([2, 2])]); +/// cleanCoords(line).geometry.coordinates; +/// //= [Position.of([0, 0]), Position.of([0, 10])] +/// cleanCoords(multiPoint).geometry.coordinates; +/// //= [Position.of([0, 0]), Position.of([2, 2])] +/// ``` +Feature cleanCoords( + GeoJSONObject geojson, { + bool mutate = false, +}) { + if (geojson is Feature && geojson.geometry == null) { + throw Exception("Geometry of the Feature is null"); + } + GeometryObject geom = + geojson is Feature ? geojson.geometry! : geojson as GeometryObject; + geom = mutate ? geom : geom.clone() as GeometryObject; + + if (geojson is GeometryCollection || geojson is FeatureCollection) { + throw Exception("${geojson.type} is not supported"); + } else if (geom is LineString) { + var newCoords = _cleanLine(geom.coordinates, geojson); + geom.coordinates = newCoords; + } else if (geom is MultiLineString || geom is Polygon) { + var newCoords = >[]; + for (var coord in (getCoords(geom) as List>)) { + newCoords.add(_cleanLine(coord, geom)); + } + (geom as GeometryType).coordinates = newCoords; + } else if (geom is MultiPolygon) { + var newCoords = >>[]; + for (var polyList in (getCoords(geom) as List>>)) { + var listPoly = >[]; + for (var poly in polyList) { + listPoly.add(_cleanLine(poly, geom)); + } + newCoords.add(listPoly); + } + geom.coordinates = newCoords; + } else if (geom is MultiPoint) { + var newCoords = []; + Set set = {}; + var list = getCoords(geom) as List; + for (var element in list) { + if (!set.contains([element.alt, element.lat, element.lng].join('-'))) { + newCoords.add(element); + } + set.add([element.alt, element.lat, element.lng].join('-')); + } + geom.coordinates = newCoords; + } + + if (geojson is GeometryType) { + return Feature(geometry: geom); + } else if (geojson is Feature) { + if (mutate) { + return geojson; + } else { + return Feature( + geometry: geom, + properties: Map.of(geojson.properties ?? {}), + bbox: geojson.bbox?.clone(), + id: geojson.id, + ); + } + } else { + throw Exception('${geojson.type} is not a supported type'); + } +} + +List _cleanLine(List coords, GeoJSONObject geojson) { + // handle "clean" segment + if (coords.length == 2 && coords[0] != coords[1]) { + return coords; + } + + var newPoints = []; + int secondToLast = coords.length - 1; + int newPointsLength = newPoints.length; + + newPoints.add(coords[0]); + for (int i = 1; i < secondToLast; i++) { + var prevAddedPoint = newPoints[newPoints.length - 1]; + if (coords[i] == prevAddedPoint) { + continue; + } else { + newPoints.add(coords[i]); + newPointsLength = newPoints.length; + if (newPointsLength > 2) { + if (isPointOnLineSegment(newPoints[newPointsLength - 3], + newPoints[newPointsLength - 1], newPoints[newPointsLength - 2])) { + newPoints.removeAt(newPoints.length - 2); + } + } + } + } + newPoints.add(coords[coords.length - 1]); + newPointsLength = newPoints.length; + + // (Multi)Polygons must have at least 4 points, but a closed LineString with only 3 points is acceptable + if ((geojson is Polygon || geojson is MultiPolygon) && + coords[0] == coords[coords.length - 1] && + newPointsLength < 4) { + throw Exception("invalid polygon"); + } + + if (isPointOnLineSegment(newPoints[newPointsLength - 3], + newPoints[newPointsLength - 1], newPoints[newPointsLength - 2])) { + newPoints.removeAt(newPoints.length - 2); + } + return newPoints; +} + +/// Returns if [point] is on the segment between [start] and [end]. +/// Borrowed from `booleanPointOnLine` to speed up the evaluation (instead of +/// using the module as dependency). +/// [start] is the coord pair of start of line, [end] is the coord pair of end +/// of line, and [point] is the coord pair of point to check. +bool isPointOnLineSegment(Position start, Position end, Position point) { + var x = point.lat, y = point.lng; + var startX = start.lat, startY = start.lng; + var endX = end.lat, endY = end.lng; + + var dxc = x - startX; + var dyc = y - startY; + var dxl = endX - startX; + var dyl = endY - startY; + var cross = dxc * dyl - dyc * dxl; + + if (cross != 0) { + return false; + } else if ((dxl).abs() >= (dyl).abs()) { + return dxl > 0 ? startX <= x && x <= endX : endX <= x && x <= startX; + } else { + return dyl > 0 ? startY <= y && y <= endY : endY <= y && y <= startY; + } +} diff --git a/lib/src/explode.dart b/lib/src/explode.dart new file mode 100644 index 0000000..b2e0811 --- /dev/null +++ b/lib/src/explode.dart @@ -0,0 +1,50 @@ +import 'package:turf/helpers.dart'; +import 'package:turf/meta.dart'; + +/// Takes a feature or set of features and returns all positions as [Point]s. +/// Takes [GeoJSONObhect] input. +/// Returns [FeatureCollection] representing the exploded input features +/// Throws [Exception] if it encounters an unknown geometry type +/// ```dart +/// var polygon = Polygon(coordinates: +/// [[ +/// Position.of([-81, 41]), +/// Position.of([-88, 36]), +/// Position.of([-84, 31]), +/// Position.of([-80, 33]), +/// Position.of([-77, 39]), +/// Position.of([-81, 41]), +/// ]]); +/// +/// FeatureCollection explode = explode(polygon); +/// +/// //addToMap +/// var addToMap = [polygon, explode] + +FeatureCollection explode(GeoJSONObject geojson) { + var points = >[]; + if (geojson is FeatureCollection) { + featureEach(geojson, (feature, id) { + coordEach(feature, (Position? currentCoord, int? coordIndex, + int? featureIndex, int? multiFeatureIndex, int? geometryIndex) { + points.add( + Feature( + geometry: Point(coordinates: currentCoord!), + properties: Map.of(feature.properties ?? {}), + ), + ); + }); + }); + } else if (geojson is Feature) { + coordEach(geojson, (Position? currentCoord, int? coordIndex, + int? featureIndex, int? multiFeatureIndex, int? geometryIndex) { + points.add( + Feature( + geometry: Point(coordinates: currentCoord!), + properties: Map.of(geojson.properties ?? {}), + ), + ); + }); + } + return FeatureCollection(features: points); +} diff --git a/lib/src/geojson.dart b/lib/src/geojson.dart index 6e81157..75f2e3b 100644 --- a/lib/src/geojson.dart +++ b/lib/src/geojson.dart @@ -1,4 +1,5 @@ import 'package:json_annotation/json_annotation.dart'; + part 'geojson.g.dart'; @JsonEnum(alwaysCreate: true) @@ -180,6 +181,7 @@ abstract class CoordinateType implements Iterable { CoordinateType toSigned(); bool get isSigned; + _untilSigned(val, limit) { if (val > limit) { return _untilSigned(val - 360, limit); @@ -245,7 +247,9 @@ class Position extends CoordinateType { Position operator *(Position p) => crossProduct(p); num get lng => _items[0]; + num get lat => _items[1]; + num? get alt => length == 3 ? _items[2] : null; @override @@ -274,13 +278,26 @@ class Position extends CoordinateType { /// Please make sure, you arrange your parameters like this: /// Longitude 1, Latitude 1, Altitude 1 (optional), Longitude 2, Latitude 2, Altitude 2 (optional) /// You can either specify 4 or 6 parameters +/// If you are using the default constructor with two dimensional positions (lng + lat only), please use the constructor like this: +/// `BBox(lng1, lat1, lng2, lat2);` class BBox extends CoordinateType { BBox( + /// longitude 1 num lng1, + + /// latitude 1 num lat1, + + /// longitude 2 for 2 dim. positions; altitude 1 for 3 dim. positions num alt1, + + /// latitude 2 for 2 dim. positions; longitude 2 for 3 dim. positions num lng2, [ + + /// latitude 2 for 3 dim. positions num? lat2, + + /// altitude 2 for 3 dim. positions num? alt2, ]) : super([ lng1, @@ -317,12 +334,34 @@ class BBox extends CoordinateType { bool get _is3D => length == 6; num get lng1 => _items[0]; + num get lat1 => _items[1]; + num? get alt1 => _is3D ? _items[2] : null; + num get lng2 => _items[_is3D ? 3 : 2]; + num get lat2 => _items[_is3D ? 4 : 3]; + num? get alt2 => _is3D ? _items[5] : null; + BBox copyWith({ + num? lng1, + num? lat1, + num? alt1, + num? lat2, + num? lng2, + num? alt2, + }) => + BBox.named( + lng1: lng1 ?? this.lng1, + lat1: lat1 ?? this.lat1, + alt1: alt1 ?? this.alt1, + lng2: lng2 ?? this.lng2, + lat2: lat2 ?? this.lat2, + alt2: alt2 ?? this.alt2, + ); + @override BBox clone() => BBox.of(_items); diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index f83f721..0e15b96 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -14,6 +14,7 @@ enum Unit { radians, degrees, } + enum Grid { point, square, diff --git a/lib/src/intersection.dart b/lib/src/intersection.dart new file mode 100644 index 0000000..72ecf35 --- /dev/null +++ b/lib/src/intersection.dart @@ -0,0 +1,41 @@ +import 'geojson.dart'; + +Point? intersects(LineString line1, LineString line2) { + if (line1.coordinates.length != 2) { + throw Exception('line1 must only contain 2 coordinates'); + } + + if (line2.coordinates.length != 2) { + throw Exception('line2 must only contain 2 coordinates'); + } + + final x1 = line1.coordinates[0][0]!; + final y1 = line1.coordinates[0][1]!; + final x2 = line1.coordinates[1][0]!; + final y2 = line1.coordinates[1][1]!; + final x3 = line2.coordinates[0][0]!; + final y3 = line2.coordinates[0][1]!; + final x4 = line2.coordinates[1][0]!; + final y4 = line2.coordinates[1][1]!; + + final denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); + + if (denom == 0) { + return null; + } + + final numeA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); + final numeB = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); + + final uA = numeA / denom; + final uB = numeB / denom; + + if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) { + final x = x1 + uA * (x2 - x1); + final y = y1 + uA * (y2 - y1); + + return Point(coordinates: Position.named(lng: x, lat: y)); + } + + return null; +} diff --git a/lib/src/line_to_polygon.dart b/lib/src/line_to_polygon.dart new file mode 100644 index 0000000..c26028f --- /dev/null +++ b/lib/src/line_to_polygon.dart @@ -0,0 +1,189 @@ +import 'package:turf/bbox.dart'; +import 'package:turf/helpers.dart'; +import 'package:turf/meta.dart'; +import 'package:turf/src/invariant.dart'; + +/// Converts [LineString]s & [MultiLineString](s) to [Polygon] or [MultiPolygon]. +/// Takes an optional boolean [autoComplete] that auto completes [LineString]s +/// (matches first & last coordinates). +/// Takes an optional [orderCoords] that sorts [LineString]s to place outer ring +/// at the first [Position] of the coordinates. +/// Takes an optional [mutate] that mutates the original [LineString] using +/// [autoComplete] (matches first & last coordinates. +/// Returns [Feature] or [Feature] converted to [Polygon]s. +/// example: +/// ```dart +/// var line = LineString(coordinates: [ +/// Position.of([125, -30]), +/// Position.of([145, -30]), +/// Position.of([145, -20]), +/// Position.of([125, -20]), +/// Position.of([125, -30])]); +/// var polygon = lineToPolygon(line); +/// //addToMap +/// var addToMap = [polygon]; +/// ``` +Feature lineToPolygon( + GeoJSONObject lines, { + Map? properties, + bool autoComplete = true, + bool orderCoords = true, + bool mutate = false, +}) { + Exception exc = Exception( + """allowed types are Feature, LineString, + MultiLineString, FeatureCollection"""); + if (lines is FeatureCollection) { + featureEach( + lines, + (currentFeature, index) { + if (currentFeature.geometry is! LineString && + currentFeature.geometry is! MultiLineString) { + throw exc; + } + }, + ); + List> list = []; + geomEach( + lines, + ( + GeometryType? currentGeometry, + int? featureIndex, + Map? featureProperties, + BBox? featureBBox, + dynamic featureId, + ) { + if (currentGeometry is LineString) { + list.add(currentGeometry.coordinates.map((e) => e.clone()).toList()); + } else if (currentGeometry is MultiLineString) { + list = [ + ...list, + ...currentGeometry.coordinates + .map((e) => e.map((p) => p.clone()).toList()) + .toList() + ]; + } else { + throw Exception("$currentGeometry type is not supperted"); + } + }, + ); + + lines = FeatureCollection(features: []) + ..features.add(Feature(geometry: MultiLineString(coordinates: list))); + } else if (lines is Feature) { + if (lines.geometry is LineString) { + lines = Feature( + geometry: lines.geometry as LineString, + properties: lines.properties, + id: lines.id, + ); + } else if (lines.geometry is MultiLineString) { + lines = Feature( + geometry: lines.geometry as MultiLineString, + properties: lines.properties, + id: lines.id, + ); + } else { + throw exc; + } + } else if (lines is LineString) { + lines = Feature(geometry: lines); + } else if (lines is MultiLineString) { + lines = Feature(geometry: lines); + } else { + throw exc; + } + if (!mutate) { + lines = lines.clone(); + } + + if (lines is FeatureCollection) { + List>> coords = []; + featureEach( + lines, + ((line, featureIndex) => coords.add(getCoords(lineStringToPolygon( + line, autoComplete, orderCoords, properties: {})) + as List>)), + ); + return Feature( + geometry: MultiPolygon(coordinates: coords), properties: properties); + } else { + return lineStringToPolygon(lines, autoComplete, orderCoords, + properties: properties); + } +} + +/// Converts [LineString] to [Polygon] +/// Takes a optional boolean [autoComplete] that auto completes [LineString]s +/// Takes an optional [orderCoords] that sorts [LineString]s to place outer +/// ring at the first [Position] of the coordinates. +Feature lineStringToPolygon( + GeoJSONObject line, + bool autoComplete, + bool orderCoords, { + Map? properties, +}) { + properties = properties ?? (line is Feature ? line.properties ?? {} : {}); + + if (line is Feature && line.geometry != null) { + return lineStringToPolygon(line.geometry!, autoComplete, orderCoords); + } + + if (line is GeometryType && line.coordinates.isEmpty) { + throw Exception("line must contain coordinates"); + } + + if (line is LineString) { + var coords = + autoComplete ? _autoCompleteCoords(line.coordinates) : line.coordinates; + + return Feature( + geometry: Polygon(coordinates: [coords]), properties: properties); + } else if (line is MultiLineString) { + List> multiCoords = []; + num largestArea = 0; + + line.coordinates.forEach( + (coord) { + if (autoComplete) { + coord = _autoCompleteCoords(coord); + } + + // Largest LineString to be placed in the first position of the coordinates array + if (orderCoords) { + var area = _calculateArea(bbox(LineString(coordinates: coord))); + if (area > largestArea) { + multiCoords.insert(0, coord); + largestArea = area; + } else { + multiCoords.add(coord); + } + } else { + multiCoords.add(coord); + } + }, + ); + return Feature( + geometry: Polygon(coordinates: multiCoords), properties: properties); + } else { + throw Exception("Geometry type ${line.type} is not supported"); + } +} + +/// Auto Completes Coords - matches first & last coordinates +List _autoCompleteCoords(List coords) { + var newCoords = coords.map((c) => c.clone()).toList(); + if (newCoords.first != newCoords.last) { + newCoords.add(newCoords.first.clone()); + } + return newCoords; +} + +/// Quick calculates approximate area (used to sort) +num _calculateArea(BBox bbox) { + var west = bbox[0]; + var south = bbox[1]; + var east = bbox[2]; + var north = bbox[3]; + return (west! - east!).abs() * (south! - north!).abs(); +} diff --git a/lib/src/meta/coord.dart b/lib/src/meta/coord.dart index f9712d1..9e47bc1 100644 --- a/lib/src/meta/coord.dart +++ b/lib/src/meta/coord.dart @@ -10,10 +10,8 @@ typedef CoordEachCallback = dynamic Function( int? geometryIndex, ); -/// Iterates over coordinates in any [geoJSON] object, similar to [Iterable.forEach] -/// -/// For example: -/// +/// Iterates over coordinates in any [geoJSONObject], similar to [Iterable.forEach] +/// example: /// ```dart /// var features = FeatureCollection(features: [ /// Feature(geometry: Point(coordinates: Position.of([26, 37])), properties: {'foo': 'bar'}), diff --git a/lib/src/nearest_point_on_line.dart b/lib/src/nearest_point_on_line.dart new file mode 100644 index 0000000..72e924a --- /dev/null +++ b/lib/src/nearest_point_on_line.dart @@ -0,0 +1,216 @@ +import 'dart:math'; + +import 'bearing.dart'; +import 'destination.dart'; +import 'distance.dart'; +import 'geojson.dart'; +import 'helpers.dart'; +import 'intersection.dart'; + +class _Nearest { + final Point point; + final num distance; + final int index; + final num location; + + _Nearest({ + required this.point, + required this.distance, + required this.index, + required this.location, + }); + + Feature toFeature() { + return Feature( + geometry: point, + properties: { + 'dist': distance, + 'index': index, + 'location': location, + }, + ); + } +} + +class _NearestMulti extends _Nearest { + final int line; + final int localIndex; + + _NearestMulti({ + required Point point, + required num distance, + required int index, + required this.localIndex, + required num location, + required this.line, + }) : super( + point: point, + distance: distance, + index: index, + location: location, + ); + + @override + Feature toFeature() { + return Feature( + geometry: point, + properties: { + 'dist': super.distance, + 'line': line, + 'index': super.index, + 'localIndex': localIndex, + 'location': super.location, + }, + ); + } +} + +_Nearest _nearestPointOnLine( + LineString line, + Point point, [ + Unit unit = Unit.kilometers, +]) { + _Nearest? nearest; + + num length = 0; + + for (var i = 0; i < line.coordinates.length - 1; ++i) { + final startCoordinates = line.coordinates[i]; + final stopCoordinates = line.coordinates[i + 1]; + + final startPoint = Point(coordinates: startCoordinates); + final stopPoint = Point(coordinates: stopCoordinates); + + final sectionLength = distance(startPoint, stopPoint, unit); + + final start = _Nearest( + point: startPoint, + distance: distance(point, startPoint, unit), + index: i, + location: length, + ); + + final stop = _Nearest( + point: stopPoint, + distance: distance(point, stopPoint, unit), + index: i + 1, + location: length + sectionLength, + ); + + final heightDistance = max(start.distance, stop.distance); + final direction = bearing(startPoint, stopPoint); + + final perpendicular1 = destination( + point, + heightDistance, + direction + 90, + unit, + ); + + final perpendicular2 = destination( + point, + heightDistance, + direction - 90, + unit, + ); + + final intersectionPoint = intersects( + LineString.fromPoints(points: [perpendicular1, perpendicular2]), + LineString.fromPoints(points: [startPoint, stopPoint]), + ); + + _Nearest? intersection; + + if (intersectionPoint != null) { + intersection = _Nearest( + point: intersectionPoint, + distance: distance(point, intersectionPoint, unit), + index: i, + location: length + distance(startPoint, intersectionPoint, unit), + ); + } + + if (nearest == null || start.distance < nearest.distance) { + nearest = start; + } + + if (stop.distance < nearest.distance) { + nearest = stop; + } + + if (intersection != null && intersection.distance < nearest.distance) { + nearest = intersection; + } + + length += sectionLength; + } + + /// A `LineString` is guaranteed to have at least two points and thus a + /// nearest point has to exist. + + return nearest!; +} + +_NearestMulti? _nearestPointOnMultiLine( + MultiLineString lines, + Point point, [ + Unit unit = Unit.kilometers, +]) { + _NearestMulti? nearest; + + var globalIndex = 0; + + for (var i = 0; i < lines.coordinates.length; ++i) { + final line = LineString(coordinates: lines.coordinates[i]); + + final candidate = _nearestPointOnLine(line, point); + + if (nearest == null || candidate.distance < nearest.distance) { + nearest = _NearestMulti( + point: candidate.point, + distance: candidate.distance, + index: globalIndex + candidate.index, + localIndex: candidate.index, + location: candidate.location, + line: i, + ); + } + + globalIndex += line.coordinates.length; + } + + return nearest; +} + +/// Takes a [Point] and a [LineString] and calculates the closest Point on the [LineString]. +/// ```dart +/// var line = LineString( +/// coordinates: [ +/// Position.of([-77.031669, 38.878605]), +/// Position.of([-77.029609, 38.881946]), +/// Position.of([-77.020339, 38.884084]), +/// Position.of([-77.025661, 38.885821]), +/// Position.of([-77.021884, 38.889563]), +/// Position.of([-77.019824, 38.892368)] +/// ]); +/// var pt = Point(coordinates: Position(lat: -77.037076, lng: 38.884017)); +/// +/// var snapped = nearestPointOnLine(line, pt, Unit.miles); +/// ``` +/// +Feature nearestPointOnLine( + LineString line, + Point point, [ + Unit unit = Unit.kilometers, +]) { + return _nearestPointOnLine(line, point, unit).toFeature(); +} + +/// Takes a [Point] and a [MultiLineString] and calculates the closest Point on the [MultiLineString]. +Feature? nearestPointOnMultiLine( + MultiLineString lines, + Point point, [ + Unit unit = Unit.kilometers, +]) { + return _nearestPointOnMultiLine(lines, point, unit)?.toFeature(); +} diff --git a/lib/src/polygon_to_line.dart b/lib/src/polygon_to_line.dart new file mode 100644 index 0000000..aee6257 --- /dev/null +++ b/lib/src/polygon_to_line.dart @@ -0,0 +1,65 @@ +import '../helpers.dart'; + +/// Converts a [Polygon] to [LineString] or [MultiLineString] or a [MultiPolygon] +/// to a [FeatureCollection] of [LineString] or [MultiLineString]. +/// Returns [FeatureCollection] or [Feature] or [Feature] +/// example: +/// ```dart +/// var poly = Polygon(coordinates: +/// [ +/// [ +/// Position.of([125, -30]), +/// Position.of([145, -30]), +/// Position.of([145, -20]), +/// Position.of([125, -20]), +/// Position.of([125, -30]) +/// ] +/// ]); +/// var line = polygonToLine(poly); +/// //addToMap +/// var addToMap = [line]; +/// ``` +GeoJSONObject polygonToLine(GeoJSONObject poly, + {Map? properties}) { + var geom = poly is Feature ? poly.geometry : poly; + + properties = + properties ?? ((poly is Feature) ? poly.properties : {}); + + if (geom is Polygon) { + return _polygonToLine(geom, properties: properties); + } else if (geom is MultiPolygon) { + return _multiPolygonToLine(geom, properties: properties); + } else { + throw Exception("invalid poly"); + } +} + +Feature _polygonToLine(Polygon geom, {Map? properties}) { + var coords = geom.coordinates; + properties = properties ?? {}; + + return _coordsToLine(coords, properties); +} + +FeatureCollection _multiPolygonToLine(MultiPolygon geom, + {Map? properties}) { + var coords = geom.coordinates; + properties = properties ?? {}; + + var lines = []; + coords.forEach((coord) => {lines.add(_coordsToLine(coord, properties))}); + return FeatureCollection(features: lines); +} + +Feature _coordsToLine( + List> coords, Map? properties) { + if (coords.isEmpty) { + throw RangeError("coordinates is empty"); + } else if (coords.length > 1) { + return Feature( + geometry: MultiLineString(coordinates: coords), properties: properties); + } + return Feature( + geometry: LineString(coordinates: coords[0]), properties: properties); +} diff --git a/lib/src/polyline.dart b/lib/src/polyline.dart new file mode 100644 index 0000000..861c9ad --- /dev/null +++ b/lib/src/polyline.dart @@ -0,0 +1,100 @@ +import 'dart:math' as math; + +import 'package:turf/helpers.dart'; + +/// Based off of [the offical Google document](https://developers.google.com/maps/documentation/utilities/polylinealgorithm) +/// Some parts from [this implementation](http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/PolylineEncoder.js) +/// by [Mark McClure](http://facstaff.unca.edu/mcmcclur/) +class Polyline { + static String _encode(num current, num previous, num factor) { + current = _py2Round(current * factor); + previous = _py2Round(previous * factor); + var coordinate = (current - previous).toInt(); + coordinate <<= 1; + if (current - previous < 0) { + coordinate = ~coordinate; + } + var output = ''; + while (coordinate >= 0x20) { + output += String.fromCharCode((0x20 | (coordinate & 0x1f)) + 63); + coordinate >>= 5; + } + output += String.fromCharCode(coordinate + 63); + + return output; + } + + static int _py2Round(num value) { + // Google's polyline algorithm uses the same rounding strategy as Python 2, which is different from JS for negative values + return (value.abs() + 0.5).floor() * (value >= 0 ? 1 : -1); + } + + /// Decodes a Polyline to a [List]. + /// This is adapted from the implementation in Project-OSRM. + /// See https://github.com/Project-OSRM/osrm-frontend/blob/master/WebContent/routing/OSRM.RoutingGeometry.js + static List decode(String polyline, {int precision = 5}) { + var index = 0, + lat = 0, + lng = 0, + shift = 0, + result = 0, + factor = math.pow(10, precision); + int? byte; + late int latitudeChange; + late int longitudeChange; + List coordinates = []; + + // Coordinates have variable length when encoded, so just keep + // track of whether we've hit the end of the string. In each + // loop iteration, a single coordinate is decoded. + while (index < polyline.length) { + byte = null; + shift = 0; + result = 0; + + do { + byte = polyline.codeUnitAt(index++) - 63; + result |= (byte & 0x1f) << shift; + shift += 5; + } while (byte >= 0x20); + latitudeChange = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); + shift = result = 0; + + do { + byte = polyline.codeUnitAt(index++) - 63; + result |= (byte & 0x1f) << shift; + shift += 5; + } while (byte >= 0x20); + longitudeChange = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); + + lat += latitudeChange; + lng += longitudeChange; + + coordinates.add( + Position.named( + lng: (lng / factor).toDouble(), lat: (lat / factor).toDouble()), + ); + } + + return coordinates; + } + + /// Encodes the given [List] to a polyline, a [String]. + static String encode(List coordinates, {int? precision}) { + if (coordinates.isEmpty) { + return ''; + } + + var factor = math.pow(10, precision ?? 5), + output = _encode(coordinates[0].lat, 0, factor) + + _encode(coordinates[0].lng, 0, factor); + + for (var i = 1; i < coordinates.length; i++) { + var a = coordinates[i], b = coordinates[i - 1]; + output += _encode(a.lat, b.lat, factor); + output += _encode(a.lng, b.lng, factor); + } + + return output; + } +} diff --git a/lib/src/rhumb_bearing.dart b/lib/src/rhumb_bearing.dart new file mode 100644 index 0000000..b3fc67d --- /dev/null +++ b/lib/src/rhumb_bearing.dart @@ -0,0 +1,64 @@ +// https://en.wikipedia.org/wiki/Rhumb_line +import 'package:turf/src/invariant.dart'; +import 'dart:math' as math; +import '../helpers.dart'; + +/// Takes two [Point] and finds the bearing angle between them along a Rhumb line +/// i.e. the angle measured in degrees start the north line (0 degrees) +/// [kFinal] calculates the final bearing if true. +/// Returns bearing from north in decimal degrees, between -180 and 180 degrees (positive clockwise) +/// example: +/// ```dart +/// var point1 = Feature(geometry: Point(coordinates: Position.of([-75.343, 39.984])), properties: {"marker-color": "#F00"}); +/// var point2 = Feature(geometry: Point(coordinates: Position.of([-75.534, 39.123])), properties: {"marker-color": "#00F"}); +/// var bearing = rhumbBearing(point1.geometry, point2.geometry); +/// //addToMap +/// var addToMap = [point1, point2]; +/// point1.properties['bearing'] = bearing; +/// point2.properties['bearing'] = bearing; +/// ``` +num rhumbBearing(Point start, Point end, {bool kFinal = false}) { + num bear360; + if (kFinal) { + bear360 = calculateRhumbBearing(getCoord(end), getCoord(start)); + } else { + bear360 = calculateRhumbBearing(getCoord(start), getCoord(end)); + } + + var bear180 = bear360 > 180 ? -(360 - bear360) : bear360; + + return bear180; +} + +/// Returns the bearing from ‘this’ [Point] to destination [Point] along a rhumb line. +/// Adapted from Geodesy: https://github.com/chrisveness/geodesy/blob/master/latlon-spherical.js +/// Returns Bearing in degrees from north. +/// example +/// ```dart +/// var p1 = Position.named(lng: 51.127, lat: 1.338); +/// var p2 = Position.named(lng: 50.964, lat: 1.853); +/// var d = p1.rhumbBearingTo(p2); // 116.7 m +/// ``` +num calculateRhumbBearing(Position from, Position to) { + // φ => phi + // Δλ => deltaLambda + // Δψ => deltaPsi + // θ => theta + num phi1 = degreesToRadians(from.lat); + num phi2 = degreesToRadians(to.lat); + num deltaLambda = degreesToRadians(to.lng - from.lng); + // if deltaLambda over 180° take shorter rhumb line across the anti-meridian: + if (deltaLambda > math.pi) { + deltaLambda -= 2 * math.pi; + } + if (deltaLambda < -math.pi) { + deltaLambda += 2 * math.pi; + } + + double deltaPsi = math + .log(math.tan(phi2 / 2 + math.pi / 4) / math.tan(phi1 / 2 + math.pi / 4)); + + double theta = math.atan2(deltaLambda, deltaPsi); + + return (radiansToDegrees(theta) + 360) % 360; +} diff --git a/lib/src/truncate.dart b/lib/src/truncate.dart new file mode 100644 index 0000000..1d1b6f6 --- /dev/null +++ b/lib/src/truncate.dart @@ -0,0 +1,99 @@ +import 'package:turf/helpers.dart'; +import '../meta.dart'; + +/// Takes a [Feature] or [FeatureCollection] and truncates the precision of the geometry. +/// [precision] sets the coordinate decimal precision +/// [coordinates] sets the maximum number of coordinates (primarly used to remove z coordinates) +/// [mutate] allows [GeoJSONObject] input to be mutated (significant performance increase if true) +/// Returns [GeoJSONObject] layer with truncated geometry +/// example: +/// var point = Point(coordinates: Position.of([ +/// 70.46923055566859, +/// 58.11088890802906, +/// 1508 +/// ])); +/// var truncated = truncate(point, precision: 3, coordinates: 2); +/// //=truncated.geometry.coordinates => [70.469, 58.111] +/// //addToMap +/// var addToMap = [truncated]; +GeoJSONObject truncate( + GeoJSONObject geojson, { + int precision = 6, + int coordinates = 3, + bool mutate = false, +}) { + GeoJSONObject geom = mutate ? geojson : geojson.clone(); + + // Truncate Coordinates + if (coordAll(geom).isNotEmpty) { + _replaceCoords(precision, coordinates, geom); + return geom; + } else { + return geom; + } +} + +void _replaceCoords(int precision, int coordinates, GeoJSONObject geojson) { + geomEach( + geojson, + ( + GeometryType? currentGeometry, + int? featureIndex, + Map? featureProperties, + BBox? featureBBox, + dynamic featureId, + ) { + coordEach( + currentGeometry!, + ( + Position? currentCoord, + int? coordIndex, + int? featureIndex, + int? multiFeatureIndex, + int? geometryIndex, + ) { + if (currentGeometry is Point) { + currentGeometry.coordinates = + _truncateCoords(currentCoord!, precision, coordinates); + } else if (currentGeometry is LineString) { + currentGeometry.coordinates[coordIndex!] = + _truncateCoords(currentCoord!, precision, coordinates); + } else if (currentGeometry is Polygon) { + currentGeometry.coordinates[geometryIndex!][coordIndex!] = + _truncateCoords(currentCoord!, precision, coordinates); + } else if (currentGeometry is MultiLineString) { + currentGeometry.coordinates[multiFeatureIndex!][coordIndex!] = + _truncateCoords(currentCoord!, precision, coordinates); + } else if (currentGeometry is MultiPolygon) { + currentGeometry.coordinates[multiFeatureIndex!][geometryIndex!] + [coordIndex!] = + _truncateCoords(currentCoord!, precision, coordinates); + } + }, + ); + }, + ); +} + +/// Truncate Coordinates - Mutates coordinates in place +/// [factor] is the rounding factor for coordinate decimal precision +/// [coordinates] sets maximum number of coordinates (primarly used to remove z coordinates) +/// Returns mutated coordinates +Position _truncateCoords(Position coord, num factor, int coordinates) { + // Remove extra coordinates (usually elevation coordinates and more) + List list = []; + list.addAll([coord.lng, coord.lat]); + if (coord.alt != null) { + list.add(coord.alt!); + } + + if (list.length > coordinates) { + list = list.sublist(0, coordinates); + } + + // Truncate coordinate decimals + for (var i = 0; i < list.length; i++) { + list[i] = round(list[i], factor); + } + return Position.of(list); +} diff --git a/lib/truncate.dart b/lib/truncate.dart new file mode 100644 index 0000000..d50cd33 --- /dev/null +++ b/lib/truncate.dart @@ -0,0 +1,3 @@ +library truncate.dart; + +export 'src/truncate.dart'; diff --git a/lib/turf.dart b/lib/turf.dart index 380b60e..bccc157 100644 --- a/lib/turf.dart +++ b/lib/turf.dart @@ -1,9 +1,13 @@ library turf; +export 'src/bbox.dart'; export 'src/bearing.dart'; +export 'src/center.dart'; export 'src/destination.dart'; export 'src/distance.dart'; export 'src/geojson.dart'; -export 'src/midpoint.dart'; export 'src/helpers.dart'; +export 'src/midpoint.dart'; export 'src/nearest_point.dart'; +export 'src/polyline.dart'; +export 'src/nearest_point_on_line.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 3809d44..7fe1231 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: turf description: A turf.js-like geospatial analysis library working with GeoJSON, written in pure Dart. -version: 0.0.6+3 +version: 0.0.7 environment: sdk: '>=2.12.0 <3.0.0' homepage: https://github.com/dartclub/turf_dart @@ -8,6 +8,7 @@ repository: https://github.com/dartclub/turf_dart dependencies: json_annotation: ^4.4.0 + turf_equality: ^0.0.1 dev_dependencies: dartclub_lint: ^0.4.2 diff --git a/test/components/bbox_polygon_test.dart b/test/components/bbox_polygon_test.dart new file mode 100644 index 0000000..199341d --- /dev/null +++ b/test/components/bbox_polygon_test.dart @@ -0,0 +1,58 @@ +import 'package:test/test.dart'; +import 'package:turf/helpers.dart'; +import 'package:turf/src/bbox_polygon.dart'; + +main() { + test( + "bbox-polygon", + () { + var poly = bboxPolygon(BBox(0, 0, 10, 10)); + expect(poly.geometry is Polygon, true); + }, + ); + + test( + "bbox-polygon -- valid geojson", + () { + var poly = bboxPolygon(BBox(0, 0, 10, 10)); + var coordinates = poly.geometry!.coordinates; + + expect(coordinates[0].length == 5, true); + expect(coordinates[0][0][0] == coordinates[0][coordinates.length - 1][0], + true); + expect(coordinates[0][0][1] == coordinates[0][coordinates.length - 1][1], + true); + }, + ); + + test( + "bbox-polygon -- Error handling", + () { + expect(() => bboxPolygon(BBox(-110, 70, 5000, 50, 60, 3000)), + throwsA(isA())); + }, + ); + + test( + "bbox-polygon -- Translate BBox (Issue #1179)", + () { + var id = 123; + var properties = {"foo": "bar"}; + var bbox = BBox(0, 0, 10, 10); + var poly = bboxPolygon(bbox, properties: properties, id: id); + + expect(poly.properties, equals(properties)); + expect(poly.bbox, equals(bbox)); + expect(poly.id, equals(id)); + }, + ); + + test( + "bbox-polygon -- assert bbox", + () { + var bbox = BBox(0, 0, 10, 10); + var poly = bboxPolygon(bbox); + expect(poly.bbox, equals(bbox)); + }, + ); +} diff --git a/test/components/bbox_test.dart b/test/components/bbox_test.dart new file mode 100644 index 0000000..75740b7 --- /dev/null +++ b/test/components/bbox_test.dart @@ -0,0 +1,102 @@ +import 'package:test/test.dart'; +import 'package:turf/bbox.dart'; +import 'package:turf/helpers.dart'; + +main() { + final pt = Feature( + geometry: Point(coordinates: Position.named(lat: 102.0, lng: 0.5))); + final line = Feature( + geometry: LineString(coordinates: [ + Position.named(lat: 102.0, lng: -10.0), + Position.named(lat: 103.0, lng: 1.0), + Position.named(lat: 104.0, lng: 0.0), + Position.named(lat: 130.0, lng: 4.0), + ])); + final poly = Feature( + geometry: Polygon(coordinates: [ + [ + Position.named(lat: 101.0, lng: 0.0), + Position.named(lat: 101.0, lng: 1.0), + Position.named(lat: 100.0, lng: 1.0), + Position.named(lat: 100.0, lng: 0.0), + Position.named(lat: 101.0, lng: 0.0), + ], + ])); + final multiLine = Feature( + geometry: MultiLineString(coordinates: [ + [ + Position.named(lat: 100.0, lng: 0.0), + Position.named(lat: 101.0, lng: 1.0), + ], + [ + Position.named(lat: 102.0, lng: 2.0), + Position.named(lat: 103.0, lng: 3.0), + ], + ])); + final multiPoly = Feature( + geometry: MultiPolygon(coordinates: [ + [ + [ + Position.named(lat: 102.0, lng: 2.0), + Position.named(lat: 103.0, lng: 2.0), + Position.named(lat: 103.0, lng: 3.0), + Position.named(lat: 102.0, lng: 3.0), + Position.named(lat: 102.0, lng: 2.0), + ], + ], + [ + [ + Position.named(lat: 100.0, lng: 0.0), + Position.named(lat: 101.0, lng: 0.0), + Position.named(lat: 101.0, lng: 1.0), + Position.named(lat: 100.0, lng: 1.0), + Position.named(lat: 100.0, lng: 0.0), + ], + [ + Position.named(lat: 100.2, lng: 0.2), + Position.named(lat: 100.8, lng: 0.2), + Position.named(lat: 100.8, lng: 0.8), + Position.named(lat: 100.2, lng: 0.8), + Position.named(lat: 100.2, lng: 0.2), + ], + ], + ])); + final fc = + FeatureCollection(features: [pt, line, poly, multiLine, multiPoly]); + + test("bbox", () { + // FeatureCollection + final fcBBox = bbox(fc); + expect(fcBBox, equals([-10, 100, 4, 130]), reason: "featureCollection"); + + // Point + final ptBBox = bbox(pt); + expect(ptBBox, equals([0.5, 102, 0.5, 102]), reason: "point"); + + // // Line + final lineBBox = bbox(line); + expect(lineBBox, equals([-10, 102, 4, 130]), reason: "lineString"); + + // // Polygon + final polyExtent = bbox(poly); + expect(polyExtent, equals([0, 100, 1, 101]), reason: "polygon"); + + // // MultiLineString + final multiLineBBox = bbox(multiLine); + expect(multiLineBBox, equals([0, 100, 3, 103]), reason: "multiLineString"); + + // // MultiPolygon + final multiPolyBBox = bbox(multiPoly); + expect(multiPolyBBox, equals([0, 100, 3, 103]), reason: "multiPolygon"); + + final pt2 = Feature( + geometry: Point(coordinates: Position.named(lat: 102.0, lng: 0.5)), + bbox: bbox(Feature( + geometry: Point(coordinates: Position.named(lat: 0, lng: 0)))), + ); + expect(bbox(pt2), equals([0, 0, 0, 0]), + reason: "uses built-in bbox by default"); + expect(bbox(pt2, recompute: true), [0.5, 102, 0.5, 102], + reason: "recomputes bbox with recompute option"); + }); +} diff --git a/test/components/center_test.dart b/test/components/center_test.dart new file mode 100644 index 0000000..2ad5fac --- /dev/null +++ b/test/components/center_test.dart @@ -0,0 +1,83 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/test.dart'; +import 'package:turf/meta.dart'; +import 'package:turf/src/bbox_polygon.dart'; +import 'package:turf/turf.dart'; + +main() { + group( + 'center in == out', + () { + var inDir = Directory('./test/examples/center/in'); + for (var file in inDir.listSync(recursive: true)) { + if (file is File && file.path.endsWith('.geojson')) { + test( + file.path, + () { + var inSource = file.readAsStringSync(); + var inGeom = GeoJSONObject.fromJson(jsonDecode(inSource)); + Map properties = { + "marker-symbol": "star", + "marker-color": "#F00" + }; + Feature inCenter = center(inGeom, properties: properties); + FeatureCollection featureCollection = + FeatureCollection(features: [])..features.add(inCenter); + featureEach(inGeom, (feature, index) { + featureCollection.features.add(feature); + }); + var extent = bboxPolygon(bbox(inGeom)); + extent.properties = { + "stroke": "#00F", + "stroke-width": 1, + "fill-opacity": 0, + }; + coordEach( + extent, + ( + currentCoord, + coordIndex, + featureIndex, + multiFeatureIndex, + geometryIndex, + ) => + featureCollection.features.add( + Feature( + geometry: LineString(coordinates: [ + currentCoord!, + inCenter.geometry!.coordinates + ]), + properties: { + 'stroke': "#00F", + "stroke-width": 1, + }, + ), + ), + ); + featureCollection.features.add(extent); + + var outPath = './' + + file.uri.pathSegments + .sublist(0, file.uri.pathSegments.length - 2) + .join('/') + + '/out/${file.uri.pathSegments.last}'; + + var outSource = File(outPath).readAsStringSync(); + + var outGeom = FeatureCollection.fromJson(jsonDecode(outSource)); + for (var i = 0; i < featureCollection.features.length; i++) { + var input = featureCollection.features[i]; + var output = outGeom.features[i]; + expect(input.id, output.id); + expect(input.properties, equals(output.properties)); + expect(input.geometry!.type, output.geometry!.type); + } + }, + ); + } + } + }, + ); +} diff --git a/test/components/clean_coords_test.dart b/test/components/clean_coords_test.dart new file mode 100644 index 0000000..f631059 --- /dev/null +++ b/test/components/clean_coords_test.dart @@ -0,0 +1,156 @@ +import 'dart:convert'; +import 'dart:io'; +import 'package:test/test.dart'; +import 'package:turf/helpers.dart'; +import 'package:turf/src/clean_coords.dart'; +import 'package:turf/src/truncate.dart'; +import 'package:turf_equality/turf_equality.dart'; + +main() { + group( + 'cleanCoords', + () { + var inDir = Directory('./test/examples/cleanCoords/in'); + for (var file in inDir.listSync(recursive: true)) { + if (file is File && file.path.endsWith('.geojson')) { + test( + file.path, + () { + var inSource = file.readAsStringSync(); + var inGeom = GeoJSONObject.fromJson(jsonDecode(inSource)); + Feature results = cleanCoords(inGeom); + var outPath = './' + + file.uri.pathSegments + .sublist(0, file.uri.pathSegments.length - 2) + .join('/') + + '/out/${file.uri.pathSegments.last}'; + + var outSource = File(outPath).readAsStringSync(); + var outGeom = GeoJSONObject.fromJson(jsonDecode(outSource)); + Equality eq = Equality(); + expect(eq.compare(results, outGeom), true); + }, + ); + } + } + + test( + "turf-clean-coords -- extras", + () { + expect( + ((cleanCoords(Point(coordinates: Position.of([0, 0])))).geometry! + as GeometryType) + .coordinates + .length, + 2); + expect( + (cleanCoords(LineString( + coordinates: [ + Position.of([0, 0]), + Position.of([1, 1]), + Position.of([2, 2]), + ], + )).geometry! as GeometryType) + .coordinates + .length, + 2); + expect( + ((cleanCoords(Polygon( + coordinates: [ + [ + Position.of([0, 0]), + Position.of([1, 1]), + Position.of([2, 2]), + Position.of([0, 2]), + Position.of([0, 0]), + ], + ], + ))).geometry! as GeometryType) + .coordinates[0] + .length, + 4); + expect( + ((cleanCoords(MultiPoint( + coordinates: [ + Position.of([0, 0]), + Position.of([0, 0]), + Position.of([2, 2]), + ], + ))).geometry! as GeometryType) + .coordinates + .length, + 2, + ); + }, + ); + + test( + "turf-clean-coords -- truncate", + () { + expect( + (cleanCoords(truncate( + LineString( + coordinates: [ + Position.of([0, 0]), + Position.of([1.1, 1.123]), + Position.of([2.12, 2.32]), + Position.of([3, 3]), + ], + ), + precision: 0)) + .geometry! as GeometryType) + .coordinates + .length, + 2, + ); + }, + ); + + test( + "turf-clean-coords -- prevent input mutation", + () { + var line = LineString( + coordinates: [ + Position.of([0, 0]), + Position.of([1, 1]), + Position.of([2, 2]), + ], + ); + var lineBefore = line.clone(); + cleanCoords(line); + Equality eq = Equality(); + expect(eq.compare(line, lineBefore), true); + + var multiPoly = MultiPolygon( + coordinates: [ + [ + [ + Position.of([0, 0]), + Position.of([1, 1]), + Position.of([2, 2]), + Position.of([2, 0]), + Position.of([0, 0]), + ], + ], + [ + [ + Position.of([0, 0]), + Position.of([0, 5]), + Position.of([5, 5]), + Position.of([5, 5]), + Position.of([5, 0]), + Position.of([0, 0]), + ], + ], + ], + ); + var multiPolyBefore = multiPoly.clone(); + cleanCoords(multiPoly); + Equality eq1 = Equality(); + + expect(eq1.compare(multiPolyBefore, multiPoly), true); + }, + ); + }, + ); +} diff --git a/test/components/explode_test.dart b/test/components/explode_test.dart new file mode 100644 index 0000000..a068ad4 --- /dev/null +++ b/test/components/explode_test.dart @@ -0,0 +1,45 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/test.dart'; +import 'package:turf/src/explode.dart'; +import 'package:turf/turf.dart'; + +main() { + group( + 'explode in == out', + () { + var inDir = Directory('./test/examples/explode/in'); + for (var file in inDir.listSync(recursive: true)) { + if (file is File && file.path.endsWith('.geojson')) { + test( + file.path, + () { + var inSource = file.readAsStringSync(); + var inGeom = GeoJSONObject.fromJson(jsonDecode(inSource)); + var inExploded = explode(inGeom); + + var outPath = './' + + file.uri.pathSegments + .sublist(0, file.uri.pathSegments.length - 2) + .join('/') + + '/out/${file.uri.pathSegments.last}'; + + var outSource = File(outPath).readAsStringSync(); + var outGeom = + FeatureCollection.fromJson(jsonDecode(outSource)); + + for (var i = 0; i < inExploded.features.length; i++) { + var input = inExploded.features[i]; + var output = outGeom.features[i]; + expect(input.id, output.id); + expect(input.properties, equals(output.properties)); + expect(input.geometry, output.geometry); + } + }, + ); + } + } + }, + ); +} diff --git a/test/components/intersection_test.dart b/test/components/intersection_test.dart new file mode 100644 index 0000000..13bc630 --- /dev/null +++ b/test/components/intersection_test.dart @@ -0,0 +1,31 @@ +import 'package:test/test.dart'; +import 'package:turf/helpers.dart'; +import 'package:turf/src/intersection.dart'; + +final l1 = LineString(coordinates: [ + Position(0, 0), + Position(2, 2), +]); + +final l2 = LineString(coordinates: [ + Position(2, 0), + Position(0, 2), +]); + +final l3 = LineString(coordinates: [ + Position(2, 2), + Position(2, 0), +]); + +final l4 = LineString(coordinates: [ + Position(0, 0), + Position(0, 2), +]); + +main() { + test('test intersects()', () { + expect(intersects(l1, l2)?.coordinates, Position(1, 1)); + expect(intersects(l1, l3)?.coordinates, Position(2, 2)); + expect(intersects(l3, l4), null); + }); +} diff --git a/test/components/line_to_polygon_test.dart b/test/components/line_to_polygon_test.dart new file mode 100644 index 0000000..05ee437 --- /dev/null +++ b/test/components/line_to_polygon_test.dart @@ -0,0 +1,72 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/test.dart'; +import 'package:turf/helpers.dart'; +import 'package:turf/src/line_to_polygon.dart'; + +void main() { + group( + 'lineToPolygon:', + () { + var inDir = Directory('./test/examples/lineToPolygon/in'); + for (var file in inDir.listSync(recursive: true)) { + if (file is File && file.path.endsWith('.geojson')) { + test( + file.path, + () { + var inSource = file.readAsStringSync(); + var inGeom = GeoJSONObject.fromJson(jsonDecode(inSource)); + var properties = (inGeom is Feature) + ? inGeom.properties ?? {"stroke": "#F0F", "stroke-width": 6} + : {"stroke": "#F0F", "stroke-width": 6}; + var results = lineToPolygon( + inGeom, + properties: properties, + ); + + var outPath = './' + + file.uri.pathSegments + .sublist(0, file.uri.pathSegments.length - 2) + .join('/') + + '/out/${file.uri.pathSegments.last}'; + + var outSource = File(outPath).readAsStringSync(); + var outGeom = GeoJSONObject.fromJson(jsonDecode(outSource)); + + if (outGeom is Feature) { + if (outGeom.geometry is Polygon) { + outGeom = + Feature(geometry: outGeom.geometry as Polygon); + } else { + outGeom = Feature( + geometry: outGeom.geometry as MultiPolygon); + } + } + expect(results, equals(outGeom)); + }, + ); + } + test( + 'Handles Errors', + () { + expect( + () => lineToPolygon(Point(coordinates: Position.of([10, 5]))), + throwsA(isA())); + expect(() => lineToPolygon(LineString(coordinates: [])), + throwsA(isA())); + expect( + lineToPolygon( + LineString(coordinates: [ + Position.of([10, 5]), + Position.of([20, 10]), + Position.of([30, 20]), + ]), + autoComplete: false) is Feature, + true); + }, + ); + } + }, + ); +} diff --git a/test/components/nearest_point_on_line_test.dart b/test/components/nearest_point_on_line_test.dart new file mode 100644 index 0000000..84079e2 --- /dev/null +++ b/test/components/nearest_point_on_line_test.dart @@ -0,0 +1,302 @@ +import 'package:test/test.dart'; +import 'package:turf/distance.dart'; +import 'package:turf/helpers.dart'; +import 'package:turf/nearest_point_on_line.dart'; + +main() { + test('nearest_point_on_line -- start point', () { + final start = Point(coordinates: Position.of([-122.457175, 37.720033])); + final end = Point(coordinates: Position.of([-122.457175, 37.718242])); + + final line = LineString.fromPoints(points: [start, end]); + + final snapped = nearestPointOnLine(line, start); + + expect(snapped.geometry, start); + expect(snapped.properties!['dist'], 0); + }); + + test('nearest_point_on_line -- end point', () { + final start = Point(coordinates: Position.of([-122.457175, 37.720033])); + final end = Point(coordinates: Position.of([-122.457175, 37.718242])); + + final line = LineString.fromPoints(points: [start, end]); + + final snapped = nearestPointOnLine(line, end); + + expect(snapped.geometry, end); + expect(snapped.properties!['dist'], 0); + }); + + test('nearest_point_on_line -- behind start point', () { + final start = Point(coordinates: Position.of([-122.457175, 37.720033])); + final end = Point(coordinates: Position.of([-122.457175, 37.718242])); + + final line = LineString.fromPoints(points: [start, end]); + + final points = [ + Point(coordinates: Position.of([-122.457175, 37.720093])), + Point(coordinates: Position.of([-122.457175, 37.820093])), + Point(coordinates: Position.of([-122.457165, 37.720093])), + Point(coordinates: Position.of([-122.455165, 37.720093])), + ]; + + for (final point in points) { + expect(nearestPointOnLine(line, point).geometry, start); + } + }); + + test('nearest_point_on_line -- in front of last point', () { + final start = Point(coordinates: Position.of([-122.456161, 37.721259])); + final middle = Point(coordinates: Position.of([-122.457175, 37.720033])); + final end = Point(coordinates: Position.of([-122.457175, 37.718242])); + + final line = LineString.fromPoints(points: [start, middle, end]); + + final points = [ + Point(coordinates: Position.of([-122.45696, 37.71814])), + Point(coordinates: Position.of([-122.457363, 37.718132])), + Point(coordinates: Position.of([-122.457309, 37.717979])), + Point(coordinates: Position.of([-122.45718, 37.717045])), + ]; + + for (final point in points) { + expect(nearestPointOnLine(line, point).geometry, end); + } + }); + + test('nearest_point_on_line -- on joints', () { + final lines = [ + LineString.fromPoints( + points: [ + Point(coordinates: Position.of([-122.456161, 37.721259])), + Point(coordinates: Position.of([-122.457175, 37.720033])), + Point(coordinates: Position.of([-122.457175, 37.718242])), + ], + ), + LineString.fromPoints( + points: [ + Point(coordinates: Position.of([26.279296, 31.728167])), + Point(coordinates: Position.of([21.796875, 32.694865])), + Point(coordinates: Position.of([18.808593, 29.993002])), + Point(coordinates: Position.of([12.919921, 33.137551])), + Point(coordinates: Position.of([10.195312, 35.603718])), + Point(coordinates: Position.of([4.921875, 36.527294])), + Point(coordinates: Position.of([-1.669921, 36.527294])), + Point(coordinates: Position.of([-5.449218, 34.741612])), + Point(coordinates: Position.of([-8.789062, 32.990235])), + ], + ), + LineString.fromPoints( + points: [ + Point(coordinates: Position.of([-0.109198, 51.522042])), + Point(coordinates: Position.of([-0.10923, 51.521942])), + Point(coordinates: Position.of([-0.109165, 51.521862])), + Point(coordinates: Position.of([-0.109047, 51.521775])), + Point(coordinates: Position.of([-0.108865, 51.521601])), + Point(coordinates: Position.of([-0.108747, 51.521381])), + Point(coordinates: Position.of([-0.108554, 51.520687])), + Point(coordinates: Position.of([-0.108436, 51.520279])), + Point(coordinates: Position.of([-0.108393, 51.519952])), + Point(coordinates: Position.of([-0.108178, 51.519578])), + Point(coordinates: Position.of([-0.108146, 51.519285])), + Point(coordinates: Position.of([-0.107899, 51.518624])), + Point(coordinates: Position.of([-0.107599, 51.517782])), + ], + ), + ]; + + for (final line in lines) { + for (final position in line.coordinates) { + final point = Point(coordinates: position); + + expect(nearestPointOnLine(line, point).geometry, point); + } + } + }); + + test('nearest_point_on_line -- along the line', () { + final line = LineString.fromPoints( + points: [ + Point(coordinates: Position.of([-0.109198, 51.522042])), + Point(coordinates: Position.of([-0.10923, 51.521942])), + Point(coordinates: Position.of([-0.109165, 51.521862])), + Point(coordinates: Position.of([-0.109047, 51.521775])), + Point(coordinates: Position.of([-0.108865, 51.521601])), + Point(coordinates: Position.of([-0.108747, 51.521381])), + Point(coordinates: Position.of([-0.108554, 51.520687])), + Point(coordinates: Position.of([-0.108436, 51.520279])), + Point(coordinates: Position.of([-0.108393, 51.519952])), + Point(coordinates: Position.of([-0.108178, 51.519578])), + Point(coordinates: Position.of([-0.108146, 51.519285])), + Point(coordinates: Position.of([-0.107899, 51.518624])), + Point(coordinates: Position.of([-0.107599, 51.517782])), + ], + ); + + final points = [ + Point( + coordinates: Position.of([-0.109198, 51.522042]), + ), + Point( + coordinates: Position.of([-0.10892694586958439, 51.52166022315509]), + ), + Point( + coordinates: Position.of([-0.10870869056086806, 51.52124324652249]), + ), + Point( + coordinates: Position.of([-0.10858746428471407, 51.520807334251415]), + ), + Point( + coordinates: Position.of([-0.10846283773612979, 51.52037179553692]), + ), + Point( + coordinates: Position.of([-0.10838216818271691, 51.51993315783233]), + ), + Point( + coordinates: Position.of([-0.1081708961571415, 51.51951295576514]), + ), + Point( + coordinates: Position.of([-0.10806814357223703, 51.5190766495002]), + ), + Point( + coordinates: Position.of([-0.10790712893372725, 51.51864575426176]), + ), + Point( + coordinates: Position.of([-0.10775288313545159, 51.518213902651325]), + ), + ]; + + for (final point in points) { + final snapped = nearestPointOnLine(line, point); + final shift = distance(point, snapped.geometry!, Unit.centimeters); + + expect(shift < 1, isTrue); + } + }); + + test('nearest_point_on_line -- on sides of line', () { + final start = Point(coordinates: Position.of([-122.456161, 37.721259])); + final end = Point(coordinates: Position.of([-122.457175, 37.718242])); + + final line = LineString.fromPoints(points: [start, end]); + + final points = [ + Point(coordinates: Position.of([-122.457025, 37.71881])), + Point(coordinates: Position.of([-122.457336, 37.719235])), + Point(coordinates: Position.of([-122.456864, 37.72027])), + Point(coordinates: Position.of([-122.45652, 37.720635])), + ]; + + for (final point in points) { + final snapped = nearestPointOnLine(line, point); + + expect(snapped.geometry, isNot(start)); + expect(snapped.geometry, isNot(end)); + } + }); + + test('nearest_point_on_line -- distance and index', () { + final line = LineString.fromPoints( + points: [ + Point(coordinates: Position.of([-92.090492, 41.102897])), + Point(coordinates: Position.of([-92.191085, 41.079868])), + Point(coordinates: Position.of([-92.228507, 41.056055])), + Point(coordinates: Position.of([-92.237091, 41.008143])), + Point(coordinates: Position.of([-92.225761, 40.966937])), + Point(coordinates: Position.of([-92.15023, 40.936858])), + Point(coordinates: Position.of([-92.112464, 40.977565])), + Point(coordinates: Position.of([-92.062683, 41.034564])), + Point(coordinates: Position.of([-92.100791, 41.040002])), + ], + ); + + final point = Point(coordinates: Position.of([-92.110576, 41.040649])); + final target = Point(coordinates: Position.of([-92.100791, 41.040002])); + + final snapped = nearestPointOnLine(line, point); + + expect(snapped.geometry, target); + + final index = snapped.properties!['index'] as int; + final distance = snapped.properties!['dist'] as num; + + expect(index, 8); + expect(distance.toStringAsFixed(6), '0.823802'); + }); + + test('nearest_point_on_line -- empty multi-line', () { + final multiLine = MultiLineString(coordinates: []); + + final point = Point(coordinates: Position.of([-92.110576, 41.040649])); + + final snapped = nearestPointOnMultiLine(multiLine, point); + + expect(snapped, isNull); + }); + + test('nearest_point_on_line -- distance, line, and index', () { + final multiLine = MultiLineString.fromLineStrings( + lineStrings: [ + LineString.fromPoints( + points: [ + Point(coordinates: Position.of([-92.090492, 41.102897])), + Point(coordinates: Position.of([-92.191085, 41.079868])), + Point(coordinates: Position.of([-92.228507, 41.056055])), + Point(coordinates: Position.of([-92.237091, 41.008143])), + Point(coordinates: Position.of([-92.225761, 40.966937])), + Point(coordinates: Position.of([-92.15023, 40.936858])), + Point(coordinates: Position.of([-92.112464, 40.977565])), + Point(coordinates: Position.of([-92.062683, 41.034564])), + Point(coordinates: Position.of([-92.100791, 41.040002])), + ], + ), + LineString.fromPoints( + points: [ + Point(coordinates: Position.of([-92.141304, 41.124107])), + Point(coordinates: Position.of([-92.020797, 41.108329])), + Point(coordinates: Position.of([-91.973762, 41.019023])), + Point(coordinates: Position.of([-92.041740, 40.944120])), + Point(coordinates: Position.of([-92.151260, 40.928299])), + Point(coordinates: Position.of([-92.198295, 40.941008])), + Point(coordinates: Position.of([-92.199668, 41.012547])), + Point(coordinates: Position.of([-92.115413, 41.041633])), + Point(coordinates: Position.of([-92.143020, 41.076504])), + ], + ), + LineString.fromPoints( + points: [ + Point(coordinates: Position.of([-92.066116, 41.079092])), + Point(coordinates: Position.of([-92.028007, 41.045957])), + Point(coordinates: Position.of([-92.040023, 40.981453])), + Point(coordinates: Position.of([-92.114181, 40.951640])), + Point(coordinates: Position.of([-92.176666, 40.968752])), + Point(coordinates: Position.of([-92.210655, 40.997002])), + Point(coordinates: Position.of([-92.209968, 41.048547])), + Point(coordinates: Position.of([-92.158126, 41.071327])), + Point(coordinates: Position.of([-92.102508, 41.082197])), + ], + ), + ], + ); + + final point = Point(coordinates: Position.of([-92.110576, 41.040649])); + final target = Point(coordinates: Position.of([-92.115413, 41.041633])); + + final snapped = nearestPointOnMultiLine(multiLine, point); + + expect(snapped, isNotNull); + + expect(snapped!.geometry, target); + + final line = snapped.properties!['line'] as int; + final localIndex = snapped.properties!['localIndex'] as int; + final globalIndex = snapped.properties!['index'] as int; + final distance = snapped.properties!['dist'] as num; + + expect(line, 1); + expect(localIndex, 7); + expect(globalIndex, 16); + expect(distance.toStringAsFixed(6), '0.420164'); + }); +} diff --git a/test/components/polygon_to_line_test.dart b/test/components/polygon_to_line_test.dart new file mode 100644 index 0000000..8084653 --- /dev/null +++ b/test/components/polygon_to_line_test.dart @@ -0,0 +1,72 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/expect.dart'; +import 'package:test/scaffolding.dart'; +import 'package:turf/polygon_to_line.dart'; +import 'package:turf/turf.dart'; + +main() { + group( + 'polygonToLine', + () { + var inDir = Directory('./test/examples/polygonToLine/in'); + for (var file in inDir.listSync(recursive: true)) { + if (file is File && file.path.endsWith('.geojson')) { + test( + file.path, + () { + var inSource = file.readAsStringSync(); + var inGeom = GeoJSONObject.fromJson(jsonDecode(inSource)); + var results = polygonToLine(inGeom); + + var outPath = './' + + file.uri.pathSegments + .sublist(0, file.uri.pathSegments.length - 2) + .join('/') + + '/out/${file.uri.pathSegments.last}'; + + var outSource = File(outPath).readAsStringSync(); + var outGeom = GeoJSONObject.fromJson(jsonDecode(outSource)); + if (results is FeatureCollection) { + expect(outGeom is FeatureCollection, true); + for (var i = 0; i < results.features.length; i++) { + expect(results.features[i], + equals((outGeom as FeatureCollection).features[i])); + expect( + (results.features[i].geometry as GeometryType).coordinates, + equals((outGeom.features[i].geometry as GeometryType) + .coordinates), + ); + expect( + results.features[i].properties, + equals(outGeom.features[i].properties), + ); + } + } else if (results is Feature) { + expect(outGeom is Feature, true); + expect((outGeom as Feature).properties, + equals(results.properties)); + expect((results.geometry as GeometryType).type, + equals((outGeom.geometry)?.type)); + expect((results.geometry as GeometryType).coordinates, + equals((outGeom.geometry as GeometryType).coordinates)); + } + }, + ); + test( + "handles error", + () { + // Handle Errors + expect( + () => polygonToLine(Point(coordinates: Position.of([10, 5]))), + throwsA(isA())); + expect(() => polygonToLine(Polygon(coordinates: [])), + throwsA(isA())); + }, + ); + } + } + }, + ); +} diff --git a/test/components/polyline.dart b/test/components/polyline.dart new file mode 100644 index 0000000..6f9b030 --- /dev/null +++ b/test/components/polyline.dart @@ -0,0 +1,116 @@ +import 'package:test/test.dart'; +import 'package:turf/helpers.dart'; +import 'package:turf/polyline.dart'; + +main() { + group('Polyline:', () { + var example = [ + Position.named(lat: 38.5, lng: -120.2), + Position.named(lat: 40.7, lng: -120.95), + Position.named(lat: 43.252, lng: -126.453), + ], + exampleWithZ = [ + Position.named(lat: 38.5, lng: -120.2, alt: 0), + Position.named(lat: 40.7, lng: -120.95, alt: 0), + Position.named(lat: 43.252, lng: -126.453, alt: 0) + ], + exampleZero = [ + Position.named(lat: 39, lng: -120), + Position.named(lat: 41, lng: -121), + Position.named(lat: 43, lng: -126), + ], + exampleSlashes = [ + Position.named(lat: 35.6, lng: -82.55), + Position.named(lat: 35.59985, lng: -82.55015), + Position.named(lat: 35.6, lng: -82.55) + ], + exampleRounding = [ + Position.named(lat: 0, lng: 0.000006), + Position.named(lat: 0, lng: 0.000002) + ], + exampleRoundingNegative = [ + Position.named(lat: 36.05322, lng: -112.084004), + Position.named(lat: 36.053573, lng: -112.083914), + Position.named(lat: 36.053845, lng: -112.083965) + ]; + + group('#decode():', () { + test('decodes an empty Array', () { + expect(Polyline.decode(''), equals([])); + }); + test('decodes a String into an Array of lat/lon pairs', () { + expect(Polyline.decode('_p~iF~ps|U_ulLnnqC_mqNvxq`@'), equals(example)); + }); + test('decodes with a custom precision', () { + expect( + Polyline.decode('_izlhA~rlgdF_{geC~ywl@_kwzCn`{nI', precision: 6), + equals(example)); + }); + test('decodes with precision 0', () { + expect(Polyline.decode('mAnFC@CH', precision: 0), equals(exampleZero)); + }); + }); + + group('#identity', () { + test( + 'feed encode into decode and check if the result is the same as the input', + () { + expect( + Polyline.decode(Polyline.encode(exampleSlashes)), exampleSlashes); + }); + + test( + 'feed decode into encode and check if the result is the same as the input', + () { + expect(Polyline.encode(Polyline.decode('_chxEn`zvN\\\\]]')), + equals('_chxEn`zvN\\\\]]')); + // t.end(); + }); + }); + + group('#encode()', () { + test('encodes an empty Array', () { + expect(Polyline.encode([]), equals('')); + }); + + test('encodes an Array of lat/lon pairs into a String', () { + expect(Polyline.encode(example), equals('_p~iF~ps|U_ulLnnqC_mqNvxq`@')); + }); + + test('encodes an Array of lat/lon/z into the same string as lat/lon', () { + expect(Polyline.encode(exampleWithZ), + equals('_p~iF~ps|U_ulLnnqC_mqNvxq`@')); + }); + + test('encodes with proper rounding', () { + expect(Polyline.encode(exampleRounding), equals('?A?@')); + }); + + test('encodes with proper negative rounding', () { + expect(Polyline.encode(exampleRoundingNegative), + equals('ss`{E~kbkTeAQw@J')); + }); + + test('encodes with a custom precision', () { + expect(Polyline.encode(example, precision: 6), + equals('_izlhA~rlgdF_{geC~ywl@_kwzCn`{nI')); + }); + + test('encodes with precision 0', () { + expect(Polyline.encode(example, precision: 0), equals('mAnFC@CH')); + }); + + test('encodes negative values correctly', () { + expect( + Polyline.decode( + Polyline.encode( + [Position.named(lat: -107.3741825, lng: 0)], + precision: 7), + precision: 7)[0] + .lat < + 0, + isTrue); + }); + }); + }); +} diff --git a/test/components/rhumb_bearing_test.dart b/test/components/rhumb_bearing_test.dart new file mode 100644 index 0000000..61893e1 --- /dev/null +++ b/test/components/rhumb_bearing_test.dart @@ -0,0 +1,46 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/test.dart'; +import 'package:turf/helpers.dart'; +import 'package:turf/src/rhumb_bearing.dart'; + +main() { + group( + '', + () { + Directory inDir = Directory('./test/examples/rhumb_bearing/in'); + for (var file in inDir.listSync(recursive: true)) { + if (file is File && file.path.endsWith('.geojson')) { + test( + file.path, + () { + var inSource = file.readAsStringSync(); + var inGeom = GeoJSONObject.fromJson(jsonDecode(inSource)); + + var start = (inGeom as FeatureCollection).features[0]; + var end = inGeom.features[1]; + var initialBearing = + rhumbBearing(start.geometry as Point, end.geometry as Point); + var finalBearing = rhumbBearing( + start.geometry as Point, end.geometry as Point, + kFinal: true); + var result = { + 'initialBearing': initialBearing, + 'finalBearing': finalBearing, + }; + + Directory outDir = Directory('./test/examples/rhumb_bearing/out'); + for (var file in outDir.listSync(recursive: true)) { + if (file is File && file.path.endsWith('.json')) { + var outSource = jsonDecode(file.readAsStringSync()); + expect(result, outSource); + } + } + }, + ); + } + } + }, + ); +} diff --git a/test/components/truncate_test.dart b/test/components/truncate_test.dart new file mode 100644 index 0000000..10d2958 --- /dev/null +++ b/test/components/truncate_test.dart @@ -0,0 +1,108 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/test.dart'; +import 'package:turf/helpers.dart'; +import 'package:turf/truncate.dart'; +import 'package:turf_equality/turf_equality.dart'; + +main() { + group( + 'truncate', + () { + var inDir = Directory('./test/examples/truncate/in'); + for (var file in inDir.listSync(recursive: true)) { + if (file is File && file.path.endsWith('.geojson')) { + var inSource = file.readAsStringSync(); + var inGeom = GeoJSONObject.fromJson(jsonDecode(inSource)); + Map json = jsonDecode(inSource); + var coordinates = json['properties']?['coordinates']; + var precision = json['properties']?['precision']; + + var outDir = Directory('./test/examples/truncate/out'); + for (var file2 in outDir.listSync(recursive: true)) { + if (file2 is File && + file2.path.endsWith('.geojson') && + file2.uri.pathSegments.last == file.uri.pathSegments.last) { + test( + file2.path, + () { + var outSource = file2.readAsStringSync(); + var outGeom = GeoJSONObject.fromJson(jsonDecode(outSource)); + Equality eq = Equality(); + expect( + eq.compare( + truncate(inGeom, + coordinates: coordinates ?? 3, + precision: precision ?? 6), + outGeom), + true); + }, + ); + } + } + } + } + + test( + "turf-truncate - precision & coordinates", + () { + Equality eq = Equality(); + // "precision 3" + expect( + eq.compare( + truncate( + Point(coordinates: Position.of([50.1234567, 40.1234567])), + precision: 3), + Point(coordinates: Position.of([50.123, 40.123])), + ), + true); + // "precision 0" + expect( + eq.compare( + truncate( + Point(coordinates: Position.of([50.1234567, 40.1234567])), + precision: 0), + Point(coordinates: Position.of([50, 40]))), + true); + // "coordinates default to 3" + expect( + eq.compare( + truncate(Point(coordinates: Position.of([50, 40, 1100])), + precision: 6), + Point(coordinates: Position.of([50, 40, 1100]))), + true); + // "coordinates 2" + expect( + eq.compare( + truncate(Point(coordinates: Position.of([50, 40, 1100])), + precision: 6, coordinates: 2), + Point(coordinates: Position.of([50, 40])), + ), + true); + }, + ); + + test( + "turf-truncate - prevent input mutation", + () { + var pt = Point(coordinates: Position.of([120.123, 40.123, 3000])); + Point ptBefore = pt.clone(); + Point afterPoint = truncate(pt, precision: 0) as Point; + // "does not mutate input" + expect( + (ptBefore.coordinates.lat == afterPoint.coordinates.lat && + ptBefore.coordinates.lng == afterPoint.coordinates.lng && + ptBefore.coordinates.alt == afterPoint.coordinates.alt), + false); + + // "does mutate input" + truncate(pt, precision: 0, coordinates: 2, mutate: true); + Equality eq = Equality(); + expect( + eq.compare(pt, Point(coordinates: Position.of([120, 40]))), true); + }, + ); + }, + ); +} diff --git a/test/examples/.DS_Store b/test/examples/.DS_Store new file mode 100644 index 0000000..0c63b13 Binary files /dev/null and b/test/examples/.DS_Store differ diff --git a/test/examples/center/in/feature-collection.geojson b/test/examples/center/in/feature-collection.geojson new file mode 100644 index 0000000..79fa4a7 --- /dev/null +++ b/test/examples/center/in/feature-collection.geojson @@ -0,0 +1,37 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.833351373672485, 45.760809294695534] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.8331475257873535, 45.760296567821456] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.833984374999999, 45.76073818687033] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.834005832672119, 45.76022171678877] + } + } + ] +} diff --git a/test/examples/center/in/imbalanced-polygon.geojson b/test/examples/center/in/imbalanced-polygon.geojson new file mode 100644 index 0000000..27ddbfd --- /dev/null +++ b/test/examples/center/in/imbalanced-polygon.geojson @@ -0,0 +1,31 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [4.854240417480469, 45.77258200374433], + [4.8445844650268555, 45.777431068484894], + [4.845442771911621, 45.778658234059755], + [4.845914840698242, 45.779376562352425], + [4.846644401550292, 45.78021460033108], + [4.847245216369629, 45.78078326178593], + [4.848060607910156, 45.78138184652523], + [4.8487043380737305, 45.78186070968964], + [4.849562644958495, 45.78248921135124], + [4.850893020629883, 45.78302792142197], + [4.852008819580077, 45.78374619341895], + [4.852995872497559, 45.784075398324866], + [4.853854179382324, 45.78443452873236], + [4.8549699783325195, 45.78470387501975], + [4.85569953918457, 45.784793656826345], + [4.857330322265624, 45.784853511283764], + [4.858231544494629, 45.78494329284938], + [4.859304428100585, 45.784883438488365], + [4.858360290527344, 45.77294120818474], + [4.854240417480469, 45.77258200374433] + ] + ] + } +} diff --git a/test/examples/center/in/linestring.geojson b/test/examples/center/in/linestring.geojson new file mode 100644 index 0000000..6b885f5 --- /dev/null +++ b/test/examples/center/in/linestring.geojson @@ -0,0 +1,11 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.86020565032959, 45.76884015325622], + [4.85994815826416, 45.749558161214516] + ] + } +} diff --git a/test/examples/center/in/point.geojson b/test/examples/center/in/point.geojson new file mode 100644 index 0000000..e49e07d --- /dev/null +++ b/test/examples/center/in/point.geojson @@ -0,0 +1,8 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.831961989402771, 45.75764678012361] + } +} diff --git a/test/examples/center/in/points-with-weights.geojson b/test/examples/center/in/points-with-weights.geojson new file mode 100644 index 0000000..df330d8 --- /dev/null +++ b/test/examples/center/in/points-with-weights.geojson @@ -0,0 +1,48 @@ +{ + "type": "FeatureCollection", + "options": { + "weight": "weight" + }, + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [0, 0] + }, + "properties": { + "weight": 10 + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [0, 5] + }, + "properties": { + "weight": 1 + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [5, 5] + }, + "properties": { + "weight": 2 + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [5, 0] + }, + "properties": { + "weight": 3 + } + } + ] +} diff --git a/test/examples/center/in/polygon-without-weights.geojson b/test/examples/center/in/polygon-without-weights.geojson new file mode 100644 index 0000000..9802b04 --- /dev/null +++ b/test/examples/center/in/polygon-without-weights.geojson @@ -0,0 +1,37 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [122.51953124999999, -22.024545601240337], + [126.91406249999999, -22.024545601240337], + [126.91406249999999, -18.312810846425442], + [122.51953124999999, -18.312810846425442], + [122.51953124999999, -22.024545601240337] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [140.888671875, -36.10237644873643], + [145.283203125, -36.10237644873643], + [145.283203125, -32.76880048488168], + [140.888671875, -32.76880048488168], + [140.888671875, -36.10237644873643] + ] + ] + } + } + ] +} diff --git a/test/examples/center/in/polygon.geojson b/test/examples/center/in/polygon.geojson new file mode 100644 index 0000000..5ef4bca --- /dev/null +++ b/test/examples/center/in/polygon.geojson @@ -0,0 +1,19 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [4.8250579833984375, 45.79398056386735], + [4.882392883300781, 45.79254427435898], + [4.910373687744141, 45.76081677972451], + [4.894924163818359, 45.7271539426975], + [4.824199676513671, 45.71337148333104], + [4.773387908935547, 45.74021417890731], + [4.778022766113281, 45.778418789239055], + [4.8250579833984375, 45.79398056386735] + ] + ] + } +} diff --git a/test/examples/center/out/feature-collection.geojson b/test/examples/center/out/feature-collection.geojson new file mode 100644 index 0000000..aef084c --- /dev/null +++ b/test/examples/center/out/feature-collection.geojson @@ -0,0 +1,144 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-symbol": "star", + "marker-color": "#F00" + }, + "geometry": { + "type": "Point", + "coordinates": [4.833576679229736, 45.76051550574215] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.833351373672485, 45.760809294695534] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.8331475257873535, 45.760296567821456] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.833984374999999, 45.76073818687033] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.834005832672119, 45.76022171678877] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.8331475257873535, 45.76022171678877], + [4.833576679229736, 45.76051550574215] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.834005832672119, 45.76022171678877], + [4.833576679229736, 45.76051550574215] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.834005832672119, 45.760809294695534], + [4.833576679229736, 45.76051550574215] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.8331475257873535, 45.760809294695534], + [4.833576679229736, 45.76051550574215] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.8331475257873535, 45.76022171678877], + [4.833576679229736, 45.76051550574215] + ] + } + }, + { + "type": "Feature", + "bbox": [ + 4.8331475257873535, + 45.76022171678877, + 4.834005832672119, + 45.760809294695534 + ], + "properties": { + "stroke": "#00F", + "stroke-width": 1, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [4.8331475257873535, 45.76022171678877], + [4.834005832672119, 45.76022171678877], + [4.834005832672119, 45.760809294695534], + [4.8331475257873535, 45.760809294695534], + [4.8331475257873535, 45.76022171678877] + ] + ] + } + } + ] +} diff --git a/test/examples/center/out/imbalanced-polygon.geojson b/test/examples/center/out/imbalanced-polygon.geojson new file mode 100644 index 0000000..4436749 --- /dev/null +++ b/test/examples/center/out/imbalanced-polygon.geojson @@ -0,0 +1,143 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-symbol": "star", + "marker-color": "#F00" + }, + "geometry": { + "type": "Point", + "coordinates": [4.851944446563721, 45.778762648296855] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [4.854240417480469, 45.77258200374433], + [4.8445844650268555, 45.777431068484894], + [4.845442771911621, 45.778658234059755], + [4.845914840698242, 45.779376562352425], + [4.846644401550292, 45.78021460033108], + [4.847245216369629, 45.78078326178593], + [4.848060607910156, 45.78138184652523], + [4.8487043380737305, 45.78186070968964], + [4.849562644958495, 45.78248921135124], + [4.850893020629883, 45.78302792142197], + [4.852008819580077, 45.78374619341895], + [4.852995872497559, 45.784075398324866], + [4.853854179382324, 45.78443452873236], + [4.8549699783325195, 45.78470387501975], + [4.85569953918457, 45.784793656826345], + [4.857330322265624, 45.784853511283764], + [4.858231544494629, 45.78494329284938], + [4.859304428100585, 45.784883438488365], + [4.858360290527344, 45.77294120818474], + [4.854240417480469, 45.77258200374433] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.8445844650268555, 45.77258200374433], + [4.851944446563721, 45.778762648296855] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.859304428100585, 45.77258200374433], + [4.851944446563721, 45.778762648296855] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.859304428100585, 45.78494329284938], + [4.851944446563721, 45.778762648296855] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.8445844650268555, 45.78494329284938], + [4.851944446563721, 45.778762648296855] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.8445844650268555, 45.77258200374433], + [4.851944446563721, 45.778762648296855] + ] + } + }, + { + "type": "Feature", + "bbox": [ + 4.8445844650268555, + 45.77258200374433, + 4.859304428100585, + 45.78494329284938 + ], + "properties": { + "stroke": "#00F", + "stroke-width": 1, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [4.8445844650268555, 45.77258200374433], + [4.859304428100585, 45.77258200374433], + [4.859304428100585, 45.78494329284938], + [4.8445844650268555, 45.78494329284938], + [4.8445844650268555, 45.77258200374433] + ] + ] + } + } + ] +} diff --git a/test/examples/center/out/linestring.geojson b/test/examples/center/out/linestring.geojson new file mode 100644 index 0000000..3f345e0 --- /dev/null +++ b/test/examples/center/out/linestring.geojson @@ -0,0 +1,123 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-symbol": "star", + "marker-color": "#F00" + }, + "geometry": { + "type": "Point", + "coordinates": [4.860076904296875, 45.75919915723537] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.86020565032959, 45.76884015325622], + [4.85994815826416, 45.749558161214516] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.85994815826416, 45.749558161214516], + [4.860076904296875, 45.75919915723537] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.86020565032959, 45.749558161214516], + [4.860076904296875, 45.75919915723537] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.86020565032959, 45.76884015325622], + [4.860076904296875, 45.75919915723537] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.85994815826416, 45.76884015325622], + [4.860076904296875, 45.75919915723537] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.85994815826416, 45.749558161214516], + [4.860076904296875, 45.75919915723537] + ] + } + }, + { + "type": "Feature", + "bbox": [ + 4.85994815826416, + 45.749558161214516, + 4.86020565032959, + 45.76884015325622 + ], + "properties": { + "stroke": "#00F", + "stroke-width": 1, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [4.85994815826416, 45.749558161214516], + [4.86020565032959, 45.749558161214516], + [4.86020565032959, 45.76884015325622], + [4.85994815826416, 45.76884015325622], + [4.85994815826416, 45.749558161214516] + ] + ] + } + } + ] +} diff --git a/test/examples/center/out/point.geojson b/test/examples/center/out/point.geojson new file mode 100644 index 0000000..6d08095 --- /dev/null +++ b/test/examples/center/out/point.geojson @@ -0,0 +1,120 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-symbol": "star", + "marker-color": "#F00" + }, + "geometry": { + "type": "Point", + "coordinates": [4.831961989402771, 45.75764678012361] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [4.831961989402771, 45.75764678012361] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.831961989402771, 45.75764678012361], + [4.831961989402771, 45.75764678012361] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.831961989402771, 45.75764678012361], + [4.831961989402771, 45.75764678012361] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.831961989402771, 45.75764678012361], + [4.831961989402771, 45.75764678012361] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.831961989402771, 45.75764678012361], + [4.831961989402771, 45.75764678012361] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.831961989402771, 45.75764678012361], + [4.831961989402771, 45.75764678012361] + ] + } + }, + { + "type": "Feature", + "bbox": [ + 4.831961989402771, + 45.75764678012361, + 4.831961989402771, + 45.75764678012361 + ], + "properties": { + "stroke": "#00F", + "stroke-width": 1, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [4.831961989402771, 45.75764678012361], + [4.831961989402771, 45.75764678012361], + [4.831961989402771, 45.75764678012361], + [4.831961989402771, 45.75764678012361], + [4.831961989402771, 45.75764678012361] + ] + ] + } + } + ] +} diff --git a/test/examples/center/out/points-with-weights.geojson b/test/examples/center/out/points-with-weights.geojson new file mode 100644 index 0000000..ec912ff --- /dev/null +++ b/test/examples/center/out/points-with-weights.geojson @@ -0,0 +1,147 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-symbol": "star", + "marker-color": "#F00" + }, + "geometry": { + "type": "Point", + "coordinates": [2.5, 2.5] + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [0, 0] + }, + "properties": { + "weight": 10 + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [0, 5] + }, + "properties": { + "weight": 1 + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [5, 5] + }, + "properties": { + "weight": 2 + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [5, 0] + }, + "properties": { + "weight": 3 + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [2.5, 2.5] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [5, 0], + [2.5, 2.5] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [5, 5], + [2.5, 2.5] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 5], + [2.5, 2.5] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [2.5, 2.5] + ] + } + }, + { + "type": "Feature", + "bbox": [0, 0, 5, 5], + "properties": { + "stroke": "#00F", + "stroke-width": 1, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [0, 0], + [5, 0], + [5, 5], + [0, 5], + [0, 0] + ] + ] + } + } + ] +} diff --git a/test/examples/center/out/polygon-without-weights.geojson b/test/examples/center/out/polygon-without-weights.geojson new file mode 100644 index 0000000..013b04d --- /dev/null +++ b/test/examples/center/out/polygon-without-weights.geojson @@ -0,0 +1,144 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-symbol": "star", + "marker-color": "#F00" + }, + "geometry": { + "type": "Point", + "coordinates": [133.9013671875, -27.207593647580936] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [122.51953124999999, -22.024545601240337], + [126.91406249999999, -22.024545601240337], + [126.91406249999999, -18.312810846425442], + [122.51953124999999, -18.312810846425442], + [122.51953124999999, -22.024545601240337] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [140.888671875, -36.10237644873643], + [145.283203125, -36.10237644873643], + [145.283203125, -32.76880048488168], + [140.888671875, -32.76880048488168], + [140.888671875, -36.10237644873643] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [122.51953124999999, -36.10237644873643], + [133.9013671875, -27.207593647580936] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [145.283203125, -36.10237644873643], + [133.9013671875, -27.207593647580936] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [145.283203125, -18.312810846425442], + [133.9013671875, -27.207593647580936] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [122.51953124999999, -18.312810846425442], + [133.9013671875, -27.207593647580936] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [122.51953124999999, -36.10237644873643], + [133.9013671875, -27.207593647580936] + ] + } + }, + { + "type": "Feature", + "bbox": [ + 122.51953124999999, + -36.10237644873643, + 145.283203125, + -18.312810846425442 + ], + "properties": { + "stroke": "#00F", + "stroke-width": 1, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [122.51953124999999, -36.10237644873643], + [145.283203125, -36.10237644873643], + [145.283203125, -18.312810846425442], + [122.51953124999999, -18.312810846425442], + [122.51953124999999, -36.10237644873643] + ] + ] + } + } + ] +} diff --git a/test/examples/center/out/polygon.geojson b/test/examples/center/out/polygon.geojson new file mode 100644 index 0000000..6409a8c --- /dev/null +++ b/test/examples/center/out/polygon.geojson @@ -0,0 +1,131 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-symbol": "star", + "marker-color": "#F00" + }, + "geometry": { + "type": "Point", + "coordinates": [4.841880798339844, 45.7536760235992] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [4.8250579833984375, 45.79398056386735], + [4.882392883300781, 45.79254427435898], + [4.910373687744141, 45.76081677972451], + [4.894924163818359, 45.7271539426975], + [4.824199676513671, 45.71337148333104], + [4.773387908935547, 45.74021417890731], + [4.778022766113281, 45.778418789239055], + [4.8250579833984375, 45.79398056386735] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.773387908935547, 45.71337148333104], + [4.841880798339844, 45.7536760235992] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.910373687744141, 45.71337148333104], + [4.841880798339844, 45.7536760235992] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.910373687744141, 45.79398056386735], + [4.841880798339844, 45.7536760235992] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.773387908935547, 45.79398056386735], + [4.841880798339844, 45.7536760235992] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [4.773387908935547, 45.71337148333104], + [4.841880798339844, 45.7536760235992] + ] + } + }, + { + "type": "Feature", + "bbox": [ + 4.773387908935547, + 45.71337148333104, + 4.910373687744141, + 45.79398056386735 + ], + "properties": { + "stroke": "#00F", + "stroke-width": 1, + "fill-opacity": 0 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [4.773387908935547, 45.71337148333104], + [4.910373687744141, 45.71337148333104], + [4.910373687744141, 45.79398056386735], + [4.773387908935547, 45.79398056386735], + [4.773387908935547, 45.71337148333104] + ] + ] + } + } + ] +} diff --git a/test/examples/cleanCoords/in/clean-segment.geojson b/test/examples/cleanCoords/in/clean-segment.geojson new file mode 100644 index 0000000..f378c39 --- /dev/null +++ b/test/examples/cleanCoords/in/clean-segment.geojson @@ -0,0 +1,11 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [2, 2] + ] + } +} diff --git a/test/examples/cleanCoords/in/closed-linestring.geojson b/test/examples/cleanCoords/in/closed-linestring.geojson new file mode 100644 index 0000000..0a53c3d --- /dev/null +++ b/test/examples/cleanCoords/in/closed-linestring.geojson @@ -0,0 +1,12 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [1, 1], + [0, 0] + ] + } +} diff --git a/test/examples/cleanCoords/in/geometry.geojson b/test/examples/cleanCoords/in/geometry.geojson new file mode 100644 index 0000000..72820b5 --- /dev/null +++ b/test/examples/cleanCoords/in/geometry.geojson @@ -0,0 +1,24 @@ +{ + "type": "Polygon", + "coordinates": [ + [ + [0, 0], + [0, 5], + [0, 10], + [10, 10], + [10, 0], + [5, 0], + [5, 0], + [0, 0] + ], + [ + [1, 5], + [4.5, 5], + [4.5, 7], + [4.5, 8.5], + [1, 8.5], + [1, 7], + [1, 5] + ] + ] +} diff --git a/test/examples/cleanCoords/in/multiline.geojson b/test/examples/cleanCoords/in/multiline.geojson new file mode 100644 index 0000000..ed8221b --- /dev/null +++ b/test/examples/cleanCoords/in/multiline.geojson @@ -0,0 +1,25 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [0, 0], + [0, 2], + [0, 5], + [0, 8], + [0, 10], + [0, 10] + ], + [ + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [5, 5], + [6, 6] + ] + ] + } +} diff --git a/test/examples/cleanCoords/in/multipoint.geojson b/test/examples/cleanCoords/in/multipoint.geojson new file mode 100644 index 0000000..3457c47 --- /dev/null +++ b/test/examples/cleanCoords/in/multipoint.geojson @@ -0,0 +1,12 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPoint", + "coordinates": [ + [14.765625, 26.194876675795218], + [8.61328125, 23.483400654325642], + [17.75390625, 24.926294766395593] + ] + } +} diff --git a/test/examples/cleanCoords/in/multipolygon.geojson b/test/examples/cleanCoords/in/multipolygon.geojson new file mode 100644 index 0000000..dd1fce7 --- /dev/null +++ b/test/examples/cleanCoords/in/multipolygon.geojson @@ -0,0 +1,41 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [0, 0], + [5, 0], + [5, 0], + [10, 0], + [10, 10], + [0, 10], + [0, 5], + [0, 0] + ], + [ + [1, 5], + [1, 7], + [1, 8.5], + [4.5, 8.5], + [4.5, 7], + [4.5, 5], + [1, 5] + ] + ], + [ + [ + [11, 11], + [11.5, 11.5], + [12, 12], + [12, 11], + [11.5, 11], + [11, 11], + [11, 11] + ] + ] + ] + } +} diff --git a/test/examples/cleanCoords/in/point.geojson b/test/examples/cleanCoords/in/point.geojson new file mode 100644 index 0000000..c86f49a --- /dev/null +++ b/test/examples/cleanCoords/in/point.geojson @@ -0,0 +1,8 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [14.765625, 26.194876675795218] + } +} diff --git a/test/examples/cleanCoords/in/polygon-with-hole.geojson b/test/examples/cleanCoords/in/polygon-with-hole.geojson new file mode 100644 index 0000000..d632ad6 --- /dev/null +++ b/test/examples/cleanCoords/in/polygon-with-hole.geojson @@ -0,0 +1,28 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [0, 0], + [0, 5], + [0, 10], + [10, 10], + [10, 0], + [5, 0], + [5, 0], + [0, 0] + ], + [ + [1, 5], + [4.5, 5], + [4.5, 7], + [4.5, 8.5], + [1, 8.5], + [1, 7], + [1, 5] + ] + ] + } +} diff --git a/test/examples/cleanCoords/in/polygon.geojson b/test/examples/cleanCoords/in/polygon.geojson new file mode 100644 index 0000000..5a4634f --- /dev/null +++ b/test/examples/cleanCoords/in/polygon.geojson @@ -0,0 +1,19 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [0, 0], + [0, 5], + [0, 10], + [10, 10], + [10, 0], + [5, 0], + [0, 0], + [0, 0] + ] + ] + } +} diff --git a/test/examples/cleanCoords/in/segment.geojson b/test/examples/cleanCoords/in/segment.geojson new file mode 100644 index 0000000..b106c0d --- /dev/null +++ b/test/examples/cleanCoords/in/segment.geojson @@ -0,0 +1,12 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [1, 1], + [2, 2] + ] + } +} diff --git a/test/examples/cleanCoords/in/simple-line.geojson b/test/examples/cleanCoords/in/simple-line.geojson new file mode 100644 index 0000000..4baea9a --- /dev/null +++ b/test/examples/cleanCoords/in/simple-line.geojson @@ -0,0 +1,15 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [0, 2], + [0, 5], + [0, 8], + [0, 10], + [0, 10] + ] + } +} diff --git a/test/examples/cleanCoords/in/triangle.geojson b/test/examples/cleanCoords/in/triangle.geojson new file mode 100644 index 0000000..afcd715 --- /dev/null +++ b/test/examples/cleanCoords/in/triangle.geojson @@ -0,0 +1,22 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [0, 0], + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [4, 3], + [4, 0], + [3, 0], + [1, 0], + [0, 0], + [0, 0] + ] + ] + } +} diff --git a/test/examples/cleanCoords/in/triplicate-issue1255.geojson b/test/examples/cleanCoords/in/triplicate-issue1255.geojson new file mode 100644 index 0000000..8c6e26d --- /dev/null +++ b/test/examples/cleanCoords/in/triplicate-issue1255.geojson @@ -0,0 +1,14 @@ +{ + "type": "Polygon", + "coordinates": [ + [ + [0, 0], + [2, 2], + [3, 30], + [3, 30], + [3, 30], + [4, 4], + [0, 0] + ] + ] +} diff --git a/test/examples/cleanCoords/out/clean-segment.geojson b/test/examples/cleanCoords/out/clean-segment.geojson new file mode 100644 index 0000000..f378c39 --- /dev/null +++ b/test/examples/cleanCoords/out/clean-segment.geojson @@ -0,0 +1,11 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [2, 2] + ] + } +} diff --git a/test/examples/cleanCoords/out/closed-linestring.geojson b/test/examples/cleanCoords/out/closed-linestring.geojson new file mode 100644 index 0000000..0a53c3d --- /dev/null +++ b/test/examples/cleanCoords/out/closed-linestring.geojson @@ -0,0 +1,12 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [1, 1], + [0, 0] + ] + } +} diff --git a/test/examples/cleanCoords/out/geometry.geojson b/test/examples/cleanCoords/out/geometry.geojson new file mode 100644 index 0000000..7a18c2d --- /dev/null +++ b/test/examples/cleanCoords/out/geometry.geojson @@ -0,0 +1,52 @@ +{ + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 0 + ], + [ + 0, + 10 + ], + [ + 10, + 10 + ], + [ + 10, + 0 + ], + [ + 0, + 0 + ] + ], + [ + [ + 1, + 5 + ], + [ + 4.5, + 5 + ], + [ + 4.5, + 8.5 + ], + [ + 1, + 8.5 + ], + [ + 1, + 5 + ] + ] + ] + } +} \ No newline at end of file diff --git a/test/examples/cleanCoords/out/multiline.geojson b/test/examples/cleanCoords/out/multiline.geojson new file mode 100644 index 0000000..dc36aa3 --- /dev/null +++ b/test/examples/cleanCoords/out/multiline.geojson @@ -0,0 +1,17 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [0, 0], + [0, 10] + ], + [ + [1, 1], + [6, 6] + ] + ] + } +} diff --git a/test/examples/cleanCoords/out/multipoint.geojson b/test/examples/cleanCoords/out/multipoint.geojson new file mode 100644 index 0000000..3457c47 --- /dev/null +++ b/test/examples/cleanCoords/out/multipoint.geojson @@ -0,0 +1,12 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPoint", + "coordinates": [ + [14.765625, 26.194876675795218], + [8.61328125, 23.483400654325642], + [17.75390625, 24.926294766395593] + ] + } +} diff --git a/test/examples/cleanCoords/out/multipolygon.geojson b/test/examples/cleanCoords/out/multipolygon.geojson new file mode 100644 index 0000000..fc5c50b --- /dev/null +++ b/test/examples/cleanCoords/out/multipolygon.geojson @@ -0,0 +1,33 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [0, 0], + [10, 0], + [10, 10], + [0, 10], + [0, 0] + ], + [ + [1, 5], + [1, 8.5], + [4.5, 8.5], + [4.5, 5], + [1, 5] + ] + ], + [ + [ + [11, 11], + [12, 12], + [12, 11], + [11, 11] + ] + ] + ] + } +} diff --git a/test/examples/cleanCoords/out/point.geojson b/test/examples/cleanCoords/out/point.geojson new file mode 100644 index 0000000..c86f49a --- /dev/null +++ b/test/examples/cleanCoords/out/point.geojson @@ -0,0 +1,8 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [14.765625, 26.194876675795218] + } +} diff --git a/test/examples/cleanCoords/out/polygon-with-hole.geojson b/test/examples/cleanCoords/out/polygon-with-hole.geojson new file mode 100644 index 0000000..1dba45f --- /dev/null +++ b/test/examples/cleanCoords/out/polygon-with-hole.geojson @@ -0,0 +1,23 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [0, 0], + [0, 10], + [10, 10], + [10, 0], + [0, 0] + ], + [ + [1, 5], + [4.5, 5], + [4.5, 8.5], + [1, 8.5], + [1, 5] + ] + ] + } +} diff --git a/test/examples/cleanCoords/out/polygon.geojson b/test/examples/cleanCoords/out/polygon.geojson new file mode 100644 index 0000000..96aee62 --- /dev/null +++ b/test/examples/cleanCoords/out/polygon.geojson @@ -0,0 +1,16 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [0, 0], + [0, 10], + [10, 10], + [10, 0], + [0, 0] + ] + ] + } +} diff --git a/test/examples/cleanCoords/out/segment.geojson b/test/examples/cleanCoords/out/segment.geojson new file mode 100644 index 0000000..f378c39 --- /dev/null +++ b/test/examples/cleanCoords/out/segment.geojson @@ -0,0 +1,11 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [2, 2] + ] + } +} diff --git a/test/examples/cleanCoords/out/simple-line.geojson b/test/examples/cleanCoords/out/simple-line.geojson new file mode 100644 index 0000000..cea55b5 --- /dev/null +++ b/test/examples/cleanCoords/out/simple-line.geojson @@ -0,0 +1,11 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [0, 0], + [0, 10] + ] + } +} diff --git a/test/examples/cleanCoords/out/triangle.geojson b/test/examples/cleanCoords/out/triangle.geojson new file mode 100644 index 0000000..a4add84 --- /dev/null +++ b/test/examples/cleanCoords/out/triangle.geojson @@ -0,0 +1,15 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [0, 0], + [4, 4], + [4, 0], + [0, 0] + ] + ] + } +} diff --git a/test/examples/cleanCoords/out/triplicate-issue1255.geojson b/test/examples/cleanCoords/out/triplicate-issue1255.geojson new file mode 100644 index 0000000..8c0ce0e --- /dev/null +++ b/test/examples/cleanCoords/out/triplicate-issue1255.geojson @@ -0,0 +1,30 @@ +{ + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 0 + ], + [ + 2, + 2 + ], + [ + 3, + 30 + ], + [ + 4, + 4 + ], + [ + 0, + 0 + ] + ] + ] + } +} \ No newline at end of file diff --git a/test/examples/explode/in/geometrycollection-0-0.geojson b/test/examples/explode/in/geometrycollection-0-0.geojson new file mode 100644 index 0000000..9b0d3a4 --- /dev/null +++ b/test/examples/explode/in/geometrycollection-0-0.geojson @@ -0,0 +1,16 @@ +{ + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [100, 0] + }, + { + "type": "LineString", + "coordinates": [ + [101, 0], + [102, 1] + ] + } + ] +} diff --git a/test/examples/explode/in/geometrycollection-xyz-0-6.geojson b/test/examples/explode/in/geometrycollection-xyz-0-6.geojson new file mode 100644 index 0000000..3380236 --- /dev/null +++ b/test/examples/explode/in/geometrycollection-xyz-0-6.geojson @@ -0,0 +1,16 @@ +{ + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [100, 0, 3] + }, + { + "type": "LineString", + "coordinates": [ + [101, 0, 5], + [102, 1, 8] + ] + } + ] +} diff --git a/test/examples/explode/in/multilinestring-0-5.geojson b/test/examples/explode/in/multilinestring-0-5.geojson new file mode 100644 index 0000000..bb09e17 --- /dev/null +++ b/test/examples/explode/in/multilinestring-0-5.geojson @@ -0,0 +1,13 @@ +{ + "type": "MultiLineString", + "coordinates": [ + [ + [100, 0], + [101, 1] + ], + [ + [102, 2], + [103, 3] + ] + ] +} diff --git a/test/examples/explode/in/multilinestring-xyz-0-11.geojson b/test/examples/explode/in/multilinestring-xyz-0-11.geojson new file mode 100644 index 0000000..54778fb --- /dev/null +++ b/test/examples/explode/in/multilinestring-xyz-0-11.geojson @@ -0,0 +1,13 @@ +{ + "type": "MultiLineString", + "coordinates": [ + [ + [100, 0, 5.2], + [101, 1, 8.1] + ], + [ + [102, 2, 2.3], + [103, 3, 7.4] + ] + ] +} diff --git a/test/examples/explode/in/multipoint-0-3.geojson b/test/examples/explode/in/multipoint-0-3.geojson new file mode 100644 index 0000000..965fec4 --- /dev/null +++ b/test/examples/explode/in/multipoint-0-3.geojson @@ -0,0 +1,7 @@ +{ + "type": "MultiPoint", + "coordinates": [ + [100, 0], + [101, 1] + ] +} diff --git a/test/examples/explode/in/multipoint-xyz-0-9.geojson b/test/examples/explode/in/multipoint-xyz-0-9.geojson new file mode 100644 index 0000000..3561370 --- /dev/null +++ b/test/examples/explode/in/multipoint-xyz-0-9.geojson @@ -0,0 +1,7 @@ +{ + "type": "MultiPoint", + "coordinates": [ + [100, 0, 1], + [101, 1, 2] + ] +} diff --git a/test/examples/explode/in/multipolygon-0-4.geojson b/test/examples/explode/in/multipolygon-0-4.geojson new file mode 100644 index 0000000..ced6b8e --- /dev/null +++ b/test/examples/explode/in/multipolygon-0-4.geojson @@ -0,0 +1,30 @@ +{ + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [102, 2], + [103, 2], + [103, 3], + [102, 3], + [102, 2] + ] + ], + [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ], + [ + [100.2, 0.2], + [100.8, 0.2], + [100.8, 0.8], + [100.2, 0.8], + [100.2, 0.2] + ] + ] + ] +} diff --git a/test/examples/explode/in/multipolygon-xyz-0-10.geojson b/test/examples/explode/in/multipolygon-xyz-0-10.geojson new file mode 100644 index 0000000..f6c58aa --- /dev/null +++ b/test/examples/explode/in/multipolygon-xyz-0-10.geojson @@ -0,0 +1,30 @@ +{ + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [102, 2, 1], + [103, 2, 1], + [103, 3, 1], + [102, 3, 1], + [102, 2, 1] + ] + ], + [ + [ + [100, 0, 2], + [101, 0, 2], + [101, 1, 2], + [100, 1, 2], + [100, 0, 2] + ], + [ + [100.2, 0.2, 3], + [100.8, 0.2, 3], + [100.8, 0.8, 3], + [100.2, 0.8, 3], + [100.2, 0.2, 3] + ] + ] + ] +} diff --git a/test/examples/explode/in/one-1-0.geojson b/test/examples/explode/in/one-1-0.geojson new file mode 100644 index 0000000..8eb9204 --- /dev/null +++ b/test/examples/explode/in/one-1-0.geojson @@ -0,0 +1,52 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [102, 0.5] + }, + "properties": { + "prop0": "value0" + } + }, + { + "type": "Feature", + "geometry": { + "type": "LineString", + "coordinates": [ + [102, 0], + [103, 1], + [104, 0], + [105, 1] + ] + }, + "properties": { + "prop0": "value0", + "prop1": 0 + } + }, + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ] + ] + }, + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + } + } + ] + } \ No newline at end of file diff --git a/test/examples/explode/in/one-2-0.geojson b/test/examples/explode/in/one-2-0.geojson new file mode 100644 index 0000000..46b6609 --- /dev/null +++ b/test/examples/explode/in/one-2-0.geojson @@ -0,0 +1,21 @@ +{ + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ] + ] + }, + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + } +} diff --git a/test/examples/explode/in/point-0-2.geojson b/test/examples/explode/in/point-0-2.geojson new file mode 100644 index 0000000..e84975a --- /dev/null +++ b/test/examples/explode/in/point-0-2.geojson @@ -0,0 +1,4 @@ +{ + "type": "Point", + "coordinates": [100, 0] +} diff --git a/test/examples/explode/in/point-xyz-0-8.geojson b/test/examples/explode/in/point-xyz-0-8.geojson new file mode 100644 index 0000000..114f479 --- /dev/null +++ b/test/examples/explode/in/point-xyz-0-8.geojson @@ -0,0 +1,4 @@ +{ + "type": "Point", + "coordinates": [100, 0, 1] +} diff --git a/test/examples/explode/in/polygon-0-1.geojson b/test/examples/explode/in/polygon-0-1.geojson new file mode 100644 index 0000000..f90b241 --- /dev/null +++ b/test/examples/explode/in/polygon-0-1.geojson @@ -0,0 +1,12 @@ +{ + "type": "Polygon", + "coordinates": [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ] + ] +} diff --git a/test/examples/explode/in/polygon-with-properties.geojson b/test/examples/explode/in/polygon-with-properties.geojson new file mode 100644 index 0000000..fd910b3 --- /dev/null +++ b/test/examples/explode/in/polygon-with-properties.geojson @@ -0,0 +1,23 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "foo": "bar" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-88.24218749999999, 37.996162679728116], + [-88.24218749999999, 53.330872983017066], + [-64.3359375, 53.330872983017066], + [-64.3359375, 37.996162679728116], + [-88.24218749999999, 37.996162679728116] + ] + ] + } + } + ] +} diff --git a/test/examples/explode/in/polygon-xyz-0-7.geojson b/test/examples/explode/in/polygon-xyz-0-7.geojson new file mode 100644 index 0000000..0a368db --- /dev/null +++ b/test/examples/explode/in/polygon-xyz-0-7.geojson @@ -0,0 +1,12 @@ +{ + "type": "Polygon", + "coordinates": [ + [ + [100, 0, 1], + [101, 0], + [101, 1, 1], + [100, 1, 1], + [100, 0, 1] + ] + ] +} diff --git a/test/examples/explode/out/geometrycollection-0-0.geojson b/test/examples/explode/out/geometrycollection-0-0.geojson new file mode 100644 index 0000000..95fb8f3 --- /dev/null +++ b/test/examples/explode/out/geometrycollection-0-0.geojson @@ -0,0 +1,29 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 1] + } + } + ] +} diff --git a/test/examples/explode/out/geometrycollection-xyz-0-6.geojson b/test/examples/explode/out/geometrycollection-xyz-0-6.geojson new file mode 100644 index 0000000..25ead20 --- /dev/null +++ b/test/examples/explode/out/geometrycollection-xyz-0-6.geojson @@ -0,0 +1,29 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0, 3] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 0, 5] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 1, 8] + } + } + ] +} diff --git a/test/examples/explode/out/multilinestring-0-5.geojson b/test/examples/explode/out/multilinestring-0-5.geojson new file mode 100644 index 0000000..9afd547 --- /dev/null +++ b/test/examples/explode/out/multilinestring-0-5.geojson @@ -0,0 +1,37 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [103, 3] + } + } + ] +} diff --git a/test/examples/explode/out/multilinestring-xyz-0-11.geojson b/test/examples/explode/out/multilinestring-xyz-0-11.geojson new file mode 100644 index 0000000..848b674 --- /dev/null +++ b/test/examples/explode/out/multilinestring-xyz-0-11.geojson @@ -0,0 +1,37 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0, 5.2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 1, 8.1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 2, 2.3] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [103, 3, 7.4] + } + } + ] +} diff --git a/test/examples/explode/out/multipoint-0-3.geojson b/test/examples/explode/out/multipoint-0-3.geojson new file mode 100644 index 0000000..a51ad03 --- /dev/null +++ b/test/examples/explode/out/multipoint-0-3.geojson @@ -0,0 +1,21 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 1] + } + } + ] +} diff --git a/test/examples/explode/out/multipoint-xyz-0-9.geojson b/test/examples/explode/out/multipoint-xyz-0-9.geojson new file mode 100644 index 0000000..5430ccc --- /dev/null +++ b/test/examples/explode/out/multipoint-xyz-0-9.geojson @@ -0,0 +1,21 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 1, 2] + } + } + ] +} diff --git a/test/examples/explode/out/multipolygon-0-4.geojson b/test/examples/explode/out/multipolygon-0-4.geojson new file mode 100644 index 0000000..eb00007 --- /dev/null +++ b/test/examples/explode/out/multipolygon-0-4.geojson @@ -0,0 +1,125 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [103, 2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [103, 3] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 3] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.2, 0.2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.8, 0.2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.8, 0.8] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.2, 0.8] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.2, 0.2] + } + } + ] +} diff --git a/test/examples/explode/out/multipolygon-xyz-0-10.geojson b/test/examples/explode/out/multipolygon-xyz-0-10.geojson new file mode 100644 index 0000000..09ee470 --- /dev/null +++ b/test/examples/explode/out/multipolygon-xyz-0-10.geojson @@ -0,0 +1,125 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 2, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [103, 2, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [103, 3, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 3, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [102, 2, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0, 2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 0, 2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 1, 2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 1, 2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0, 2] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.2, 0.2, 3] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.8, 0.2, 3] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.8, 0.8, 3] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.2, 0.8, 3] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100.2, 0.2, 3] + } + } + ] +} diff --git a/test/examples/explode/out/one-1-0.geojson b/test/examples/explode/out/one-1-0.geojson new file mode 100644 index 0000000..03e4911 --- /dev/null +++ b/test/examples/explode/out/one-1-0.geojson @@ -0,0 +1,124 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "prop0": "value0" + }, + "geometry": { + "type": "Point", + "coordinates": [102, 0.5] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": 0 + }, + "geometry": { + "type": "Point", + "coordinates": [102, 0] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": 0 + }, + "geometry": { + "type": "Point", + "coordinates": [103, 1] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": 0 + }, + "geometry": { + "type": "Point", + "coordinates": [104, 0] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": 0 + }, + "geometry": { + "type": "Point", + "coordinates": [105, 1] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [101, 0] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [101, 1] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [100, 1] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + } + ] + } \ No newline at end of file diff --git a/test/examples/explode/out/one-2-0.geojson b/test/examples/explode/out/one-2-0.geojson new file mode 100644 index 0000000..cb44d2d --- /dev/null +++ b/test/examples/explode/out/one-2-0.geojson @@ -0,0 +1,70 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [101, 0] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [101, 1] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [100, 1] + } + }, + { + "type": "Feature", + "properties": { + "prop0": "value0", + "prop1": { + "this": "that" + } + }, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + } + ] +} diff --git a/test/examples/explode/out/point-0-2.geojson b/test/examples/explode/out/point-0-2.geojson new file mode 100644 index 0000000..e02ae61 --- /dev/null +++ b/test/examples/explode/out/point-0-2.geojson @@ -0,0 +1,13 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + } + ] +} diff --git a/test/examples/explode/out/point-xyz-0-8.geojson b/test/examples/explode/out/point-xyz-0-8.geojson new file mode 100644 index 0000000..368d5e7 --- /dev/null +++ b/test/examples/explode/out/point-xyz-0-8.geojson @@ -0,0 +1,13 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0, 1] + } + } + ] +} diff --git a/test/examples/explode/out/polygon-0-1.geojson b/test/examples/explode/out/polygon-0-1.geojson new file mode 100644 index 0000000..d963633 --- /dev/null +++ b/test/examples/explode/out/polygon-0-1.geojson @@ -0,0 +1,45 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0] + } + } + ] +} diff --git a/test/examples/explode/out/polygon-with-properties.geojson b/test/examples/explode/out/polygon-with-properties.geojson new file mode 100644 index 0000000..7591a53 --- /dev/null +++ b/test/examples/explode/out/polygon-with-properties.geojson @@ -0,0 +1,55 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "foo": "bar" + }, + "geometry": { + "type": "Point", + "coordinates": [-88.24218749999999, 37.996162679728116] + } + }, + { + "type": "Feature", + "properties": { + "foo": "bar" + }, + "geometry": { + "type": "Point", + "coordinates": [-88.24218749999999, 53.330872983017066] + } + }, + { + "type": "Feature", + "properties": { + "foo": "bar" + }, + "geometry": { + "type": "Point", + "coordinates": [-64.3359375, 53.330872983017066] + } + }, + { + "type": "Feature", + "properties": { + "foo": "bar" + }, + "geometry": { + "type": "Point", + "coordinates": [-64.3359375, 37.996162679728116] + } + }, + { + "type": "Feature", + "properties": { + "foo": "bar" + }, + "geometry": { + "type": "Point", + "coordinates": [-88.24218749999999, 37.996162679728116] + } + } + ] +} diff --git a/test/examples/explode/out/polygon-xyz-0-7.geojson b/test/examples/explode/out/polygon-xyz-0-7.geojson new file mode 100644 index 0000000..ac01076 --- /dev/null +++ b/test/examples/explode/out/polygon-xyz-0-7.geojson @@ -0,0 +1,45 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 0] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [101, 1, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 1, 1] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [100, 0, 1] + } + } + ] +} diff --git a/test/examples/lineToPolygon/in/collection_linestring.geojson b/test/examples/lineToPolygon/in/collection_linestring.geojson new file mode 100644 index 0000000..40586ab --- /dev/null +++ b/test/examples/lineToPolygon/in/collection_linestring.geojson @@ -0,0 +1,39 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [102, 2], + [103, 2], + [103, 3], + [102, 3], + [102, 2] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ] + } + } + ] +} diff --git a/test/examples/lineToPolygon/in/geometry_linestring.geojson b/test/examples/lineToPolygon/in/geometry_linestring.geojson new file mode 100644 index 0000000..61e6ffa --- /dev/null +++ b/test/examples/lineToPolygon/in/geometry_linestring.geojson @@ -0,0 +1,10 @@ +{ + "type": "LineString", + "coordinates": [ + [-2.275543, 53.464547], + [-2.275543, 53.489271], + [-2.215118, 53.489271], + [-2.215118, 53.464547], + [-2.275543, 53.464547] + ] +} diff --git a/test/examples/lineToPolygon/in/linestring.geojson b/test/examples/lineToPolygon/in/linestring.geojson new file mode 100644 index 0000000..b453fed --- /dev/null +++ b/test/examples/lineToPolygon/in/linestring.geojson @@ -0,0 +1,17 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [-2.275543, 53.464547], + [-2.275543, 53.489271], + [-2.215118, 53.489271], + [-2.215118, 53.464547], + [-2.275543, 53.464547] + ] + } +} diff --git a/test/examples/lineToPolygon/in/linestring_incomplete.geojson b/test/examples/lineToPolygon/in/linestring_incomplete.geojson new file mode 100644 index 0000000..4f045fb --- /dev/null +++ b/test/examples/lineToPolygon/in/linestring_incomplete.geojson @@ -0,0 +1,20 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [131.0009765625, -30.939924331023455], + [125.46386718749999, -29.878755346037963], + [121.77246093750001, -26.07652055985696], + [121.5087890625, -21.902277966668624], + [127.79296875, -16.1724728083975], + [133.154296875, -14.944784875088372], + [137.4169921875, -20.097206227083888], + [138.515625, -26.82407078047018] + ] + } +} diff --git a/test/examples/lineToPolygon/in/linestrings_to_multipolygons.geojson b/test/examples/lineToPolygon/in/linestrings_to_multipolygons.geojson new file mode 100644 index 0000000..82df227 --- /dev/null +++ b/test/examples/lineToPolygon/in/linestrings_to_multipolygons.geojson @@ -0,0 +1,113 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#008000", + "stroke-width": 6, + "stroke-opacity": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [33.4149169921875, 48.28684818710906], + [32.816162109375, 48.42191010942875], + [32.783203125, 48.09642606004488], + [33.3270263671875, 47.931066347509784], + [33.4149169921875, 48.28684818710906] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#ff8000", + "stroke-width": 6, + "stroke-opacity": 1 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [35.244140625, 47.15984001304432], + [35.17822265625, 46.37725420510028], + [36.40869140625, 46.240651955001695], + [37.02392578125, 46.9502622421856], + [35.244140625, 47.15984001304432] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#ff0000", + "stroke-width": 6, + "stroke-opacity": 1 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [33.398, 46.867], + [34.057, 46.867], + [34.057, 47.197], + [33.398, 47.197], + [33.398, 46.867] + ], + [ + [33.42041015625, 46.164614496897094], + [34.12353515625, 46.58906908309182], + [34.73876953125, 46.73233101286786], + [35.013427734375, 47.34626718205302], + [34.07958984374999, 47.73193447949174], + [32.947998046875, 47.338822694822], + [32.354736328125, 46.73986059969267], + [32.54150390625, 46.240651955001695], + [33.42041015625, 46.164614496897094] + ], + [ + [32.969, 46.46], + [33.321, 46.46], + [33.321, 46.672], + [32.969, 46.672], + [32.969, 46.46] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#0080ff", + "stroke-width": 6, + "stroke-opacity": 1 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [34.178466796875, 48.436489955944154], + [35.101318359375, 47.57652571374621], + [37.3974609375, 47.48008846346322], + [38.133544921875, 48.777912755501845], + [35.92529296875, 49.930008124606886], + [34.178466796875, 48.436489955944154] + ], + [ + [34.80468749999999, 48.29050321714062], + [35.04638671874999, 47.938426929481054], + [35.760498046875, 47.95314495015594], + [35.343017578125, 48.32703913063476], + [34.80468749999999, 48.29050321714062] + ], + [ + [35.99395751953125, 47.83528342275264], + [35.93902587890624, 47.73193447949174], + [36.15325927734375, 47.65428791076272], + [35.99395751953125, 47.83528342275264] + ] + ] + } + } + ] +} diff --git a/test/examples/lineToPolygon/in/multi_linestring_incomplete.geojson b/test/examples/lineToPolygon/in/multi_linestring_incomplete.geojson new file mode 100644 index 0000000..30b9ea4 --- /dev/null +++ b/test/examples/lineToPolygon/in/multi_linestring_incomplete.geojson @@ -0,0 +1,29 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [129.28710937499997, -31.57853542647337], + [120.05859375, -26.35249785815401], + [120.05859375, -19.72534224805787], + [124.62890625, -17.056784609942543], + [131.572265625, -17.224758206624628], + [133.330078125, -23.644524198573677] + ], + [ + [126.2548828125, -20.427012814257385], + [123.662109375, -22.512556954051437], + [124.1455078125, -25.36388227274024], + [126.9580078125, -25.799891182088306], + [128.5400390625, -24.166802085303225], + [127.83691406249999, -21.207458730482642], + [127.265625, -20.756113874762068] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/in/multi_linestring_nested.geojson b/test/examples/lineToPolygon/in/multi_linestring_nested.geojson new file mode 100644 index 0000000..3bc2751 --- /dev/null +++ b/test/examples/lineToPolygon/in/multi_linestring_nested.geojson @@ -0,0 +1,49 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [102.359619140625, 33.916013113401696], + [103.65600585937499, 33.916013113401696], + [103.65600585937499, 34.97600151317588], + [102.359619140625, 34.97600151317588], + [102.359619140625, 33.916013113401696] + ], + [ + [101.18408203124999, 32.95336814579932], + [101.18408203124999, 35.93354064249312], + [104.952392578125, 35.93354064249312], + [104.952392578125, 32.95336814579932], + [101.18408203124999, 32.95336814579932] + ], + [ + [101.612548828125, 33.330528249028085], + [104.556884765625, 33.330528249028085], + [104.556884765625, 35.46961797120201], + [101.612548828125, 35.46961797120201], + [101.612548828125, 33.330528249028085] + ], + [ + [106.4794921875, 32.7872745269555], + [110.687255859375, 32.7872745269555], + [110.687255859375, 36.83566824724438], + [106.4794921875, 36.83566824724438], + [106.4794921875, 32.7872745269555] + ], + [ + [106.06201171875, 32.47269502206151], + [111.86279296875, 32.47269502206151], + [111.86279296875, 37.33522435930639], + [106.06201171875, 37.33522435930639], + [106.06201171875, 32.47269502206151] + ] + ] + } + } + ] +} diff --git a/test/examples/lineToPolygon/in/multi_linestring_nested2.geojson b/test/examples/lineToPolygon/in/multi_linestring_nested2.geojson new file mode 100644 index 0000000..1958996 --- /dev/null +++ b/test/examples/lineToPolygon/in/multi_linestring_nested2.geojson @@ -0,0 +1,71 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [115.927734375, -34.016241889667015], + [134.560546875, -34.016241889667015], + [134.560546875, -16.8886597873816], + [115.927734375, -16.8886597873816], + [115.927734375, -34.016241889667015] + ], + [ + [118.65234374999999, -30.90222470517144], + [131.484375, -30.90222470517144], + [131.484375, -19.808054128088575], + [118.65234374999999, -19.808054128088575], + [118.65234374999999, -30.90222470517144] + ], + [ + [120.9375, -28.998531814051795], + [129.7265625, -28.998531814051795], + [129.7265625, -22.105998799750566], + [120.9375, -22.105998799750566], + [120.9375, -28.998531814051795] + ], + [ + [123.48632812499999, -27.137368359795584], + [127.44140625, -27.137368359795584], + [127.44140625, -24.126701958681668], + [123.48632812499999, -24.126701958681668], + [123.48632812499999, -27.137368359795584] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [139.21874999999997, -36.10237644873643], + [158.73046875, -36.10237644873643], + [158.73046875, -17.476432197195518], + [139.21874999999997, -17.476432197195518], + [139.21874999999997, -36.10237644873643] + ], + [ + [142.3828125, -34.016241889667015], + [155.91796874999997, -34.016241889667015], + [155.91796874999997, -20.13847031245114], + [142.3828125, -20.13847031245114], + [142.3828125, -34.016241889667015] + ] + ] + } + } + ] +} diff --git a/test/examples/lineToPolygon/in/multi_linestring_outer_ring_middle_position.geojson b/test/examples/lineToPolygon/in/multi_linestring_outer_ring_middle_position.geojson new file mode 100644 index 0000000..a6f77a8 --- /dev/null +++ b/test/examples/lineToPolygon/in/multi_linestring_outer_ring_middle_position.geojson @@ -0,0 +1,34 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [33.398, 46.867], + [34.057, 46.867], + [34.057, 47.197], + [33.398, 47.197], + [33.398, 46.867] + ], + [ + [33.42041015625, 46.164614496897094], + [34.12353515625, 46.58906908309182], + [34.73876953125, 46.73233101286786], + [35.013427734375, 47.34626718205302], + [34.07958984374999, 47.73193447949174], + [32.947998046875, 47.338822694822], + [32.354736328125, 46.73986059969267], + [32.54150390625, 46.240651955001695], + [33.42041015625, 46.164614496897094] + ], + [ + [32.969, 46.46], + [33.321, 46.46], + [33.321, 46.672], + [32.969, 46.672], + [32.969, 46.46] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/in/multi_linestring_with_hole.geojson b/test/examples/lineToPolygon/in/multi_linestring_with_hole.geojson new file mode 100644 index 0000000..660dcbd --- /dev/null +++ b/test/examples/lineToPolygon/in/multi_linestring_with_hole.geojson @@ -0,0 +1,26 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ], + [ + [100.2, 0.2], + [100.8, 0.2], + [100.8, 0.8], + [100.2, 0.8], + [100.2, 0.2] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/in/multi_linestrings_nested.geojson b/test/examples/lineToPolygon/in/multi_linestrings_nested.geojson new file mode 100644 index 0000000..1958996 --- /dev/null +++ b/test/examples/lineToPolygon/in/multi_linestrings_nested.geojson @@ -0,0 +1,71 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [115.927734375, -34.016241889667015], + [134.560546875, -34.016241889667015], + [134.560546875, -16.8886597873816], + [115.927734375, -16.8886597873816], + [115.927734375, -34.016241889667015] + ], + [ + [118.65234374999999, -30.90222470517144], + [131.484375, -30.90222470517144], + [131.484375, -19.808054128088575], + [118.65234374999999, -19.808054128088575], + [118.65234374999999, -30.90222470517144] + ], + [ + [120.9375, -28.998531814051795], + [129.7265625, -28.998531814051795], + [129.7265625, -22.105998799750566], + [120.9375, -22.105998799750566], + [120.9375, -28.998531814051795] + ], + [ + [123.48632812499999, -27.137368359795584], + [127.44140625, -27.137368359795584], + [127.44140625, -24.126701958681668], + [123.48632812499999, -24.126701958681668], + [123.48632812499999, -27.137368359795584] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [139.21874999999997, -36.10237644873643], + [158.73046875, -36.10237644873643], + [158.73046875, -17.476432197195518], + [139.21874999999997, -17.476432197195518], + [139.21874999999997, -36.10237644873643] + ], + [ + [142.3828125, -34.016241889667015], + [155.91796874999997, -34.016241889667015], + [155.91796874999997, -20.13847031245114], + [142.3828125, -20.13847031245114], + [142.3828125, -34.016241889667015] + ] + ] + } + } + ] +} diff --git a/test/examples/lineToPolygon/in/multi_linestrings_outer_doughnut.geojson b/test/examples/lineToPolygon/in/multi_linestrings_outer_doughnut.geojson new file mode 100644 index 0000000..3d3d994 --- /dev/null +++ b/test/examples/lineToPolygon/in/multi_linestrings_outer_doughnut.geojson @@ -0,0 +1,57 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [115.927734375, -34.016241889667015], + [134.560546875, -34.016241889667015], + [134.560546875, -16.8886597873816], + [115.927734375, -16.8886597873816], + [115.927734375, -34.016241889667015] + ], + [ + [118.65234374999999, -30.90222470517144], + [131.484375, -30.90222470517144], + [131.484375, -19.808054128088575], + [118.65234374999999, -19.808054128088575], + [118.65234374999999, -30.90222470517144] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [120.9375, -28.998531814051795], + [129.7265625, -28.998531814051795], + [129.7265625, -22.105998799750566], + [120.9375, -22.105998799750566], + [120.9375, -28.998531814051795] + ], + [ + [123.48632812499999, -27.137368359795584], + [127.44140625, -27.137368359795584], + [127.44140625, -24.126701958681668], + [123.48632812499999, -24.126701958681668], + [123.48632812499999, -27.137368359795584] + ] + ] + } + } + ] +} diff --git a/test/examples/lineToPolygon/in/multi_linestrings_with_holes.geojson b/test/examples/lineToPolygon/in/multi_linestrings_with_holes.geojson new file mode 100644 index 0000000..804a27c --- /dev/null +++ b/test/examples/lineToPolygon/in/multi_linestrings_with_holes.geojson @@ -0,0 +1,74 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [102, 2], + [103, 2], + [103, 3], + [102, 3], + [102, 2] + ], + [ + [102.227783203125, 2.191238104506552], + [102.227783203125, 2.8223442468940902], + [102.843017578125, 2.8223442468940902], + [102.843017578125, 2.191238104506552], + [102.227783203125, 2.191238104506552] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F80", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ], + [ + [100.206298828125, 0.2526847277643438], + [100.206298828125, 0.7909904981540058], + [100.8050537109375, 0.7909904981540058], + [100.8050537109375, 0.2526847277643438], + [100.206298828125, 0.2526847277643438] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#080", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [101.700439453125, 0.5273363048115169], + [102.645263671875, 0.5273363048115169], + [102.645263671875, 1.3511930983018892], + [101.700439453125, 1.3511930983018892], + [101.700439453125, 0.5273363048115169] + ] + } + } + ] +} diff --git a/test/examples/lineToPolygon/out/collection_linestring.geojson b/test/examples/lineToPolygon/out/collection_linestring.geojson new file mode 100644 index 0000000..bc0a389 --- /dev/null +++ b/test/examples/lineToPolygon/out/collection_linestring.geojson @@ -0,0 +1,30 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [102, 2], + [103, 2], + [103, 3], + [102, 3], + [102, 2] + ] + ], + [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/geometry_linestring.geojson b/test/examples/lineToPolygon/out/geometry_linestring.geojson new file mode 100644 index 0000000..5043748 --- /dev/null +++ b/test/examples/lineToPolygon/out/geometry_linestring.geojson @@ -0,0 +1,19 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-2.275543, 53.464547], + [-2.275543, 53.489271], + [-2.215118, 53.489271], + [-2.215118, 53.464547], + [-2.275543, 53.464547] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/linestring.geojson b/test/examples/lineToPolygon/out/linestring.geojson new file mode 100644 index 0000000..5043748 --- /dev/null +++ b/test/examples/lineToPolygon/out/linestring.geojson @@ -0,0 +1,19 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-2.275543, 53.464547], + [-2.275543, 53.489271], + [-2.215118, 53.489271], + [-2.215118, 53.464547], + [-2.275543, 53.464547] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/linestring_incomplete.geojson b/test/examples/lineToPolygon/out/linestring_incomplete.geojson new file mode 100644 index 0000000..19d6558 --- /dev/null +++ b/test/examples/lineToPolygon/out/linestring_incomplete.geojson @@ -0,0 +1,23 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [131.0009765625, -30.939924331023455], + [125.46386718749999, -29.878755346037963], + [121.77246093750001, -26.07652055985696], + [121.5087890625, -21.902277966668624], + [127.79296875, -16.1724728083975], + [133.154296875, -14.944784875088372], + [137.4169921875, -20.097206227083888], + [138.515625, -26.82407078047018], + [131.0009765625, -30.939924331023455] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/linestrings_to_multipolygons.geojson b/test/examples/lineToPolygon/out/linestrings_to_multipolygons.geojson new file mode 100644 index 0000000..3c8f176 --- /dev/null +++ b/test/examples/lineToPolygon/out/linestrings_to_multipolygons.geojson @@ -0,0 +1,80 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [33.4149169921875, 48.28684818710906], + [32.816162109375, 48.42191010942875], + [32.783203125, 48.09642606004488], + [33.3270263671875, 47.931066347509784], + [33.4149169921875, 48.28684818710906] + ] + ], + [ + [ + [35.244140625, 47.15984001304432], + [35.17822265625, 46.37725420510028], + [36.40869140625, 46.240651955001695], + [37.02392578125, 46.9502622421856], + [35.244140625, 47.15984001304432] + ] + ], + [ + [ + [33.42041015625, 46.164614496897094], + [34.12353515625, 46.58906908309182], + [34.73876953125, 46.73233101286786], + [35.013427734375, 47.34626718205302], + [34.07958984374999, 47.73193447949174], + [32.947998046875, 47.338822694822], + [32.354736328125, 46.73986059969267], + [32.54150390625, 46.240651955001695], + [33.42041015625, 46.164614496897094] + ], + [ + [33.398, 46.867], + [34.057, 46.867], + [34.057, 47.197], + [33.398, 47.197], + [33.398, 46.867] + ], + [ + [32.969, 46.46], + [33.321, 46.46], + [33.321, 46.672], + [32.969, 46.672], + [32.969, 46.46] + ] + ], + [ + [ + [34.178466796875, 48.436489955944154], + [35.101318359375, 47.57652571374621], + [37.3974609375, 47.48008846346322], + [38.133544921875, 48.777912755501845], + [35.92529296875, 49.930008124606886], + [34.178466796875, 48.436489955944154] + ], + [ + [34.80468749999999, 48.29050321714062], + [35.04638671874999, 47.938426929481054], + [35.760498046875, 47.95314495015594], + [35.343017578125, 48.32703913063476], + [34.80468749999999, 48.29050321714062] + ], + [ + [35.99395751953125, 47.83528342275264], + [35.93902587890624, 47.73193447949174], + [36.15325927734375, 47.65428791076272], + [35.99395751953125, 47.83528342275264] + ] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/multi_linestring_incomplete.geojson b/test/examples/lineToPolygon/out/multi_linestring_incomplete.geojson new file mode 100644 index 0000000..16dfc89 --- /dev/null +++ b/test/examples/lineToPolygon/out/multi_linestring_incomplete.geojson @@ -0,0 +1,31 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [129.28710937499997, -31.57853542647337], + [120.05859375, -26.35249785815401], + [120.05859375, -19.72534224805787], + [124.62890625, -17.056784609942543], + [131.572265625, -17.224758206624628], + [133.330078125, -23.644524198573677], + [129.28710937499997, -31.57853542647337] + ], + [ + [126.2548828125, -20.427012814257385], + [123.662109375, -22.512556954051437], + [124.1455078125, -25.36388227274024], + [126.9580078125, -25.799891182088306], + [128.5400390625, -24.166802085303225], + [127.83691406249999, -21.207458730482642], + [127.265625, -20.756113874762068], + [126.2548828125, -20.427012814257385] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/multi_linestring_nested.geojson b/test/examples/lineToPolygon/out/multi_linestring_nested.geojson new file mode 100644 index 0000000..fce548b --- /dev/null +++ b/test/examples/lineToPolygon/out/multi_linestring_nested.geojson @@ -0,0 +1,49 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [106.06201171875, 32.47269502206151], + [111.86279296875, 32.47269502206151], + [111.86279296875, 37.33522435930639], + [106.06201171875, 37.33522435930639], + [106.06201171875, 32.47269502206151] + ], + [ + [106.4794921875, 32.7872745269555], + [110.687255859375, 32.7872745269555], + [110.687255859375, 36.83566824724438], + [106.4794921875, 36.83566824724438], + [106.4794921875, 32.7872745269555] + ], + [ + [101.18408203124999, 32.95336814579932], + [101.18408203124999, 35.93354064249312], + [104.952392578125, 35.93354064249312], + [104.952392578125, 32.95336814579932], + [101.18408203124999, 32.95336814579932] + ], + [ + [102.359619140625, 33.916013113401696], + [103.65600585937499, 33.916013113401696], + [103.65600585937499, 34.97600151317588], + [102.359619140625, 34.97600151317588], + [102.359619140625, 33.916013113401696] + ], + [ + [101.612548828125, 33.330528249028085], + [104.556884765625, 33.330528249028085], + [104.556884765625, 35.46961797120201], + [101.612548828125, 35.46961797120201], + [101.612548828125, 33.330528249028085] + ] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/multi_linestring_nested2.geojson b/test/examples/lineToPolygon/out/multi_linestring_nested2.geojson new file mode 100644 index 0000000..4a3384c --- /dev/null +++ b/test/examples/lineToPolygon/out/multi_linestring_nested2.geojson @@ -0,0 +1,58 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [115.927734375, -34.016241889667015], + [134.560546875, -34.016241889667015], + [134.560546875, -16.8886597873816], + [115.927734375, -16.8886597873816], + [115.927734375, -34.016241889667015] + ], + [ + [118.65234374999999, -30.90222470517144], + [131.484375, -30.90222470517144], + [131.484375, -19.808054128088575], + [118.65234374999999, -19.808054128088575], + [118.65234374999999, -30.90222470517144] + ], + [ + [120.9375, -28.998531814051795], + [129.7265625, -28.998531814051795], + [129.7265625, -22.105998799750566], + [120.9375, -22.105998799750566], + [120.9375, -28.998531814051795] + ], + [ + [123.48632812499999, -27.137368359795584], + [127.44140625, -27.137368359795584], + [127.44140625, -24.126701958681668], + [123.48632812499999, -24.126701958681668], + [123.48632812499999, -27.137368359795584] + ] + ], + [ + [ + [139.21874999999997, -36.10237644873643], + [158.73046875, -36.10237644873643], + [158.73046875, -17.476432197195518], + [139.21874999999997, -17.476432197195518], + [139.21874999999997, -36.10237644873643] + ], + [ + [142.3828125, -34.016241889667015], + [155.91796874999997, -34.016241889667015], + [155.91796874999997, -20.13847031245114], + [142.3828125, -20.13847031245114], + [142.3828125, -34.016241889667015] + ] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/multi_linestring_outer_ring_middle_position.geojson b/test/examples/lineToPolygon/out/multi_linestring_outer_ring_middle_position.geojson new file mode 100644 index 0000000..98e5458 --- /dev/null +++ b/test/examples/lineToPolygon/out/multi_linestring_outer_ring_middle_position.geojson @@ -0,0 +1,37 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [33.42041015625, 46.164614496897094], + [34.12353515625, 46.58906908309182], + [34.73876953125, 46.73233101286786], + [35.013427734375, 47.34626718205302], + [34.07958984374999, 47.73193447949174], + [32.947998046875, 47.338822694822], + [32.354736328125, 46.73986059969267], + [32.54150390625, 46.240651955001695], + [33.42041015625, 46.164614496897094] + ], + [ + [33.398, 46.867], + [34.057, 46.867], + [34.057, 47.197], + [33.398, 47.197], + [33.398, 46.867] + ], + [ + [32.969, 46.46], + [33.321, 46.46], + [33.321, 46.672], + [32.969, 46.672], + [32.969, 46.46] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/multi_linestring_with_hole.geojson b/test/examples/lineToPolygon/out/multi_linestring_with_hole.geojson new file mode 100644 index 0000000..342f08f --- /dev/null +++ b/test/examples/lineToPolygon/out/multi_linestring_with_hole.geojson @@ -0,0 +1,26 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ], + [ + [100.2, 0.2], + [100.8, 0.2], + [100.8, 0.8], + [100.2, 0.8], + [100.2, 0.2] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/multi_linestrings_nested.geojson b/test/examples/lineToPolygon/out/multi_linestrings_nested.geojson new file mode 100644 index 0000000..4a3384c --- /dev/null +++ b/test/examples/lineToPolygon/out/multi_linestrings_nested.geojson @@ -0,0 +1,58 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [115.927734375, -34.016241889667015], + [134.560546875, -34.016241889667015], + [134.560546875, -16.8886597873816], + [115.927734375, -16.8886597873816], + [115.927734375, -34.016241889667015] + ], + [ + [118.65234374999999, -30.90222470517144], + [131.484375, -30.90222470517144], + [131.484375, -19.808054128088575], + [118.65234374999999, -19.808054128088575], + [118.65234374999999, -30.90222470517144] + ], + [ + [120.9375, -28.998531814051795], + [129.7265625, -28.998531814051795], + [129.7265625, -22.105998799750566], + [120.9375, -22.105998799750566], + [120.9375, -28.998531814051795] + ], + [ + [123.48632812499999, -27.137368359795584], + [127.44140625, -27.137368359795584], + [127.44140625, -24.126701958681668], + [123.48632812499999, -24.126701958681668], + [123.48632812499999, -27.137368359795584] + ] + ], + [ + [ + [139.21874999999997, -36.10237644873643], + [158.73046875, -36.10237644873643], + [158.73046875, -17.476432197195518], + [139.21874999999997, -17.476432197195518], + [139.21874999999997, -36.10237644873643] + ], + [ + [142.3828125, -34.016241889667015], + [155.91796874999997, -34.016241889667015], + [155.91796874999997, -20.13847031245114], + [142.3828125, -20.13847031245114], + [142.3828125, -34.016241889667015] + ] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/multi_linestrings_outer_doughnut.geojson b/test/examples/lineToPolygon/out/multi_linestrings_outer_doughnut.geojson new file mode 100644 index 0000000..037a064 --- /dev/null +++ b/test/examples/lineToPolygon/out/multi_linestrings_outer_doughnut.geojson @@ -0,0 +1,44 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [115.927734375, -34.016241889667015], + [134.560546875, -34.016241889667015], + [134.560546875, -16.8886597873816], + [115.927734375, -16.8886597873816], + [115.927734375, -34.016241889667015] + ], + [ + [118.65234374999999, -30.90222470517144], + [131.484375, -30.90222470517144], + [131.484375, -19.808054128088575], + [118.65234374999999, -19.808054128088575], + [118.65234374999999, -30.90222470517144] + ] + ], + [ + [ + [120.9375, -28.998531814051795], + [129.7265625, -28.998531814051795], + [129.7265625, -22.105998799750566], + [120.9375, -22.105998799750566], + [120.9375, -28.998531814051795] + ], + [ + [123.48632812499999, -27.137368359795584], + [127.44140625, -27.137368359795584], + [127.44140625, -24.126701958681668], + [123.48632812499999, -24.126701958681668], + [123.48632812499999, -27.137368359795584] + ] + ] + ] + } +} diff --git a/test/examples/lineToPolygon/out/multi_linestrings_with_holes.geojson b/test/examples/lineToPolygon/out/multi_linestrings_with_holes.geojson new file mode 100644 index 0000000..11bc7f7 --- /dev/null +++ b/test/examples/lineToPolygon/out/multi_linestrings_with_holes.geojson @@ -0,0 +1,53 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [102, 2], + [103, 2], + [103, 3], + [102, 3], + [102, 2] + ], + [ + [102.227783203125, 2.191238104506552], + [102.227783203125, 2.8223442468940902], + [102.843017578125, 2.8223442468940902], + [102.843017578125, 2.191238104506552], + [102.227783203125, 2.191238104506552] + ] + ], + [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ], + [ + [100.206298828125, 0.2526847277643438], + [100.206298828125, 0.7909904981540058], + [100.8050537109375, 0.7909904981540058], + [100.8050537109375, 0.2526847277643438], + [100.206298828125, 0.2526847277643438] + ] + ], + [ + [ + [101.700439453125, 0.5273363048115169], + [102.645263671875, 0.5273363048115169], + [102.645263671875, 1.3511930983018892], + [101.700439453125, 1.3511930983018892], + [101.700439453125, 0.5273363048115169] + ] + ] + ] + } +} diff --git a/test/examples/polygonToLine/in/geometry_polygon.geojson b/test/examples/polygonToLine/in/geometry_polygon.geojson new file mode 100644 index 0000000..401ebe2 --- /dev/null +++ b/test/examples/polygonToLine/in/geometry_polygon.geojson @@ -0,0 +1,12 @@ +{ + "type": "Polygon", + "coordinates": [ + [ + [-2.275543, 53.464547], + [-2.275543, 53.489271], + [-2.215118, 53.489271], + [-2.215118, 53.464547], + [-2.275543, 53.464547] + ] + ] +} diff --git a/test/examples/polygonToLine/in/multi_polygon.geojson b/test/examples/polygonToLine/in/multi_polygon.geojson new file mode 100644 index 0000000..d8731f8 --- /dev/null +++ b/test/examples/polygonToLine/in/multi_polygon.geojson @@ -0,0 +1,30 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [102, 2], + [103, 2], + [103, 3], + [102, 3], + [102, 2] + ] + ], + [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ] + ] + ] + } +} diff --git a/test/examples/polygonToLine/in/multi_polygon_outer_doughnut.geojson b/test/examples/polygonToLine/in/multi_polygon_outer_doughnut.geojson new file mode 100644 index 0000000..037a064 --- /dev/null +++ b/test/examples/polygonToLine/in/multi_polygon_outer_doughnut.geojson @@ -0,0 +1,44 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [115.927734375, -34.016241889667015], + [134.560546875, -34.016241889667015], + [134.560546875, -16.8886597873816], + [115.927734375, -16.8886597873816], + [115.927734375, -34.016241889667015] + ], + [ + [118.65234374999999, -30.90222470517144], + [131.484375, -30.90222470517144], + [131.484375, -19.808054128088575], + [118.65234374999999, -19.808054128088575], + [118.65234374999999, -30.90222470517144] + ] + ], + [ + [ + [120.9375, -28.998531814051795], + [129.7265625, -28.998531814051795], + [129.7265625, -22.105998799750566], + [120.9375, -22.105998799750566], + [120.9375, -28.998531814051795] + ], + [ + [123.48632812499999, -27.137368359795584], + [127.44140625, -27.137368359795584], + [127.44140625, -24.126701958681668], + [123.48632812499999, -24.126701958681668], + [123.48632812499999, -27.137368359795584] + ] + ] + ] + } +} diff --git a/test/examples/polygonToLine/in/multi_polygon_with_holes.geojson b/test/examples/polygonToLine/in/multi_polygon_with_holes.geojson new file mode 100644 index 0000000..dd14d7c --- /dev/null +++ b/test/examples/polygonToLine/in/multi_polygon_with_holes.geojson @@ -0,0 +1,53 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [102, 2], + [103, 2], + [103, 3], + [102, 3], + [102, 2] + ], + [ + [102.227783203125, 2.191238104506552], + [102.227783203125, 2.8223442468940902], + [102.843017578125, 2.8223442468940902], + [102.843017578125, 2.191238104506552], + [102.227783203125, 2.191238104506552] + ] + ], + [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ], + [ + [100.206298828125, 0.2526847277643438], + [100.206298828125, 0.7909904981540058], + [100.8050537109375, 0.7909904981540058], + [100.8050537109375, 0.2526847277643438], + [100.206298828125, 0.2526847277643438] + ] + ], + [ + [ + [101.700439453125, 0.5273363048115169], + [102.645263671875, 0.5273363048115169], + [102.645263671875, 1.3511930983018892], + [101.700439453125, 1.3511930983018892], + [101.700439453125, 0.5273363048115169] + ] + ] + ] + } +} diff --git a/test/examples/polygonToLine/in/polygon.geojson b/test/examples/polygonToLine/in/polygon.geojson new file mode 100644 index 0000000..a518e3d --- /dev/null +++ b/test/examples/polygonToLine/in/polygon.geojson @@ -0,0 +1,19 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-2.275543, 53.464547], + [-2.275543, 53.489271], + [-2.215118, 53.489271], + [-2.215118, 53.464547], + [-2.275543, 53.464547] + ] + ] + } +} diff --git a/test/examples/polygonToLine/in/polygon_with_hole.geojson b/test/examples/polygonToLine/in/polygon_with_hole.geojson new file mode 100644 index 0000000..20bb898 --- /dev/null +++ b/test/examples/polygonToLine/in/polygon_with_hole.geojson @@ -0,0 +1,26 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-2.275543, 53.464547], + [-2.215118, 53.464547], + [-2.215118, 53.489271], + [-2.275543, 53.489271], + [-2.275543, 53.464547] + ], + [ + [-2.261037826538086, 53.47062762161877], + [-2.2293663024902344, 53.47062762161877], + [-2.2293663024902344, 53.48196795587917], + [-2.261037826538086, 53.48196795587917], + [-2.261037826538086, 53.47062762161877] + ] + ] + } +} diff --git a/test/examples/polygonToLine/out/geometry_polygon.geojson b/test/examples/polygonToLine/out/geometry_polygon.geojson new file mode 100644 index 0000000..c8c6b04 --- /dev/null +++ b/test/examples/polygonToLine/out/geometry_polygon.geojson @@ -0,0 +1,14 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "LineString", + "coordinates": [ + [-2.275543, 53.464547], + [-2.275543, 53.489271], + [-2.215118, 53.489271], + [-2.215118, 53.464547], + [-2.275543, 53.464547] + ] + } +} diff --git a/test/examples/polygonToLine/out/multi_polygon.geojson b/test/examples/polygonToLine/out/multi_polygon.geojson new file mode 100644 index 0000000..fa82c4d --- /dev/null +++ b/test/examples/polygonToLine/out/multi_polygon.geojson @@ -0,0 +1,39 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [102, 2], + [103, 2], + [103, 3], + [102, 3], + [102, 2] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ] + } + } + ] +} diff --git a/test/examples/polygonToLine/out/multi_polygon_outer_doughnut.geojson b/test/examples/polygonToLine/out/multi_polygon_outer_doughnut.geojson new file mode 100644 index 0000000..3d3d994 --- /dev/null +++ b/test/examples/polygonToLine/out/multi_polygon_outer_doughnut.geojson @@ -0,0 +1,57 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [115.927734375, -34.016241889667015], + [134.560546875, -34.016241889667015], + [134.560546875, -16.8886597873816], + [115.927734375, -16.8886597873816], + [115.927734375, -34.016241889667015] + ], + [ + [118.65234374999999, -30.90222470517144], + [131.484375, -30.90222470517144], + [131.484375, -19.808054128088575], + [118.65234374999999, -19.808054128088575], + [118.65234374999999, -30.90222470517144] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F0F", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [120.9375, -28.998531814051795], + [129.7265625, -28.998531814051795], + [129.7265625, -22.105998799750566], + [120.9375, -22.105998799750566], + [120.9375, -28.998531814051795] + ], + [ + [123.48632812499999, -27.137368359795584], + [127.44140625, -27.137368359795584], + [127.44140625, -24.126701958681668], + [123.48632812499999, -24.126701958681668], + [123.48632812499999, -27.137368359795584] + ] + ] + } + } + ] +} diff --git a/test/examples/polygonToLine/out/multi_polygon_with_holes.geojson b/test/examples/polygonToLine/out/multi_polygon_with_holes.geojson new file mode 100644 index 0000000..4af234d --- /dev/null +++ b/test/examples/polygonToLine/out/multi_polygon_with_holes.geojson @@ -0,0 +1,74 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [102, 2], + [103, 2], + [103, 3], + [102, 3], + [102, 2] + ], + [ + [102.227783203125, 2.191238104506552], + [102.227783203125, 2.8223442468940902], + [102.843017578125, 2.8223442468940902], + [102.843017578125, 2.191238104506552], + [102.227783203125, 2.191238104506552] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [100, 0], + [101, 0], + [101, 1], + [100, 1], + [100, 0] + ], + [ + [100.206298828125, 0.2526847277643438], + [100.206298828125, 0.7909904981540058], + [100.8050537109375, 0.7909904981540058], + [100.8050537109375, 0.2526847277643438], + [100.206298828125, 0.2526847277643438] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [101.700439453125, 0.5273363048115169], + [102.645263671875, 0.5273363048115169], + [102.645263671875, 1.3511930983018892], + [101.700439453125, 1.3511930983018892], + [101.700439453125, 0.5273363048115169] + ] + } + } + ] +} diff --git a/test/examples/polygonToLine/out/polygon.geojson b/test/examples/polygonToLine/out/polygon.geojson new file mode 100644 index 0000000..b453fed --- /dev/null +++ b/test/examples/polygonToLine/out/polygon.geojson @@ -0,0 +1,17 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [-2.275543, 53.464547], + [-2.275543, 53.489271], + [-2.215118, 53.489271], + [-2.215118, 53.464547], + [-2.275543, 53.464547] + ] + } +} diff --git a/test/examples/polygonToLine/out/polygon_with_hole.geojson b/test/examples/polygonToLine/out/polygon_with_hole.geojson new file mode 100644 index 0000000..a5dea97 --- /dev/null +++ b/test/examples/polygonToLine/out/polygon_with_hole.geojson @@ -0,0 +1,26 @@ +{ + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "MultiLineString", + "coordinates": [ + [ + [-2.275543, 53.464547], + [-2.215118, 53.464547], + [-2.215118, 53.489271], + [-2.275543, 53.489271], + [-2.275543, 53.464547] + ], + [ + [-2.261037826538086, 53.47062762161877], + [-2.2293663024902344, 53.47062762161877], + [-2.2293663024902344, 53.48196795587917], + [-2.261037826538086, 53.48196795587917], + [-2.261037826538086, 53.47062762161877] + ] + ] + } +} diff --git a/test/examples/rhumb_bearing/in/pair1.geojson b/test/examples/rhumb_bearing/in/pair1.geojson new file mode 100644 index 0000000..b48344e --- /dev/null +++ b/test/examples/rhumb_bearing/in/pair1.geojson @@ -0,0 +1,31 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-color": "#F00" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -75, + 45 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 20, + 60 + ] + } + } + ] +} \ No newline at end of file diff --git a/test/examples/rhumb_bearing/out/pair1.geojson b/test/examples/rhumb_bearing/out/pair1.geojson new file mode 100644 index 0000000..b5ab5e2 --- /dev/null +++ b/test/examples/rhumb_bearing/out/pair1.geojson @@ -0,0 +1,71 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "marker-color": "#F00" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -75, + 45 + ] + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "#00F" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 20, + 60 + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#F00", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -75, + 45 + ], + [ + -66.10068737769872, + 51.79325008492101 + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "stroke": "#00F", + "stroke-width": 6 + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 20, + 60 + ], + [ + 2.3844816279733956, + 63.440396381483744 + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/test/examples/rhumb_bearing/out/pair1.json b/test/examples/rhumb_bearing/out/pair1.json new file mode 100644 index 0000000..171e525 --- /dev/null +++ b/test/examples/rhumb_bearing/out/pair1.json @@ -0,0 +1,4 @@ +{ + "initialBearing": 75.28061364784332, + "finalBearing": -104.7193863521567 +} \ No newline at end of file diff --git a/test/examples/truncate/in/geometry-collection-in-feature.geojson b/test/examples/truncate/in/geometry-collection-in-feature.geojson new file mode 100644 index 0000000..8122718 --- /dev/null +++ b/test/examples/truncate/in/geometry-collection-in-feature.geojson @@ -0,0 +1,24 @@ +{ + "type": "Feature", + "properties": {}, + "id": 123, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [ + -75.69992065429688, + 45.42509718349142 + ] + }, + { + "type": "Point", + "coordinates": [ + -75.6917667388916, + 45.42226585577467 + ] + } + ] + } +} \ No newline at end of file diff --git a/test/examples/truncate/in/geometry-collection.geojson b/test/examples/truncate/in/geometry-collection.geojson new file mode 100644 index 0000000..537edea --- /dev/null +++ b/test/examples/truncate/in/geometry-collection.geojson @@ -0,0 +1,13 @@ +{ + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [-75.69992065429688, 45.42509718349142] + }, + { + "type": "Point", + "coordinates": [-75.6917667388916, 45.42226585577467] + } + ] +} diff --git a/test/examples/truncate/in/linestring-geometry.geojson b/test/examples/truncate/in/linestring-geometry.geojson new file mode 100644 index 0000000..4853a97 --- /dev/null +++ b/test/examples/truncate/in/linestring-geometry.geojson @@ -0,0 +1,8 @@ +{ + "type": "LineString", + "coordinates": [ + [33.046875, 12.554563528593656], + [31.9921875, 20.632784250388028], + [43.2421875, 27.371767300523047] + ] +} diff --git a/test/examples/truncate/in/point-elevation.geojson b/test/examples/truncate/in/point-elevation.geojson new file mode 100644 index 0000000..30c908e --- /dev/null +++ b/test/examples/truncate/in/point-elevation.geojson @@ -0,0 +1,11 @@ +{ + "type": "Feature", + "properties": { + "precision": 4, + "coordinates": 2 + }, + "geometry": { + "type": "Point", + "coordinates": [-75.69992065429688, 45.42509718349142, 2312.132] + } +} diff --git a/test/examples/truncate/in/point-geometry.geojson b/test/examples/truncate/in/point-geometry.geojson new file mode 100644 index 0000000..3fc00b6 --- /dev/null +++ b/test/examples/truncate/in/point-geometry.geojson @@ -0,0 +1,4 @@ +{ + "type": "Point", + "coordinates": [-75.69992065429688, 45.42509718349142] +} diff --git a/test/examples/truncate/in/point.geojson b/test/examples/truncate/in/point.geojson new file mode 100644 index 0000000..5edee00 --- /dev/null +++ b/test/examples/truncate/in/point.geojson @@ -0,0 +1,12 @@ +{ + "type": "Feature", + "properties": { + "precision": 3 + }, + "id": 12345, + "bbox": [1, 2, 3, 4], + "geometry": { + "type": "Point", + "coordinates": [-75.69992065429688, 45.42509718349142] + } +} diff --git a/test/examples/truncate/in/points.geojson b/test/examples/truncate/in/points.geojson new file mode 100644 index 0000000..232b1a3 --- /dev/null +++ b/test/examples/truncate/in/points.geojson @@ -0,0 +1,22 @@ +{ + "type": "FeatureCollection", + "id": 12345, + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [-75.69992065429688, 45.42509718349142] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [-75.6917667388916, 45.42226585577467] + } + } + ] +} diff --git a/test/examples/truncate/in/polygon.geojson b/test/examples/truncate/in/polygon.geojson new file mode 100644 index 0000000..a04ef68 --- /dev/null +++ b/test/examples/truncate/in/polygon.geojson @@ -0,0 +1,16 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-75.74506759643555, 45.383622119671905], + [-75.74506759643555, 45.437128742131435], + [-75.6547737121582, 45.437128742131435], + [-75.6547737121582, 45.383622119671905], + [-75.74506759643555, 45.383622119671905] + ] + ] + } +} diff --git a/test/examples/truncate/in/polygons.geojson b/test/examples/truncate/in/polygons.geojson new file mode 100644 index 0000000..d284d66 --- /dev/null +++ b/test/examples/truncate/in/polygons.geojson @@ -0,0 +1,37 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-75.74506759643555, 45.383622119671905], + [-75.74506759643555, 45.437128742131435], + [-75.6547737121582, 45.437128742131435], + [-75.6547737121582, 45.383622119671905], + [-75.74506759643555, 45.383622119671905] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-75.76927185058594, 45.441826226418996], + [-75.76927185058594, 45.48059563971866], + [-75.68000793457031, 45.48059563971866], + [-75.68000793457031, 45.441826226418996], + [-75.76927185058594, 45.441826226418996] + ] + ] + } + } + ] +} diff --git a/test/examples/truncate/out/geometry-collection-in-feature.geojson b/test/examples/truncate/out/geometry-collection-in-feature.geojson new file mode 100644 index 0000000..43d0874 --- /dev/null +++ b/test/examples/truncate/out/geometry-collection-in-feature.geojson @@ -0,0 +1,24 @@ +{ + "type": "Feature", + "properties": {}, + "id": 123, + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [ + -75.699921, + 45.425097 + ] + }, + { + "type": "Point", + "coordinates": [ + -75.691767, + 45.422266 + ] + } + ] + } +} \ No newline at end of file diff --git a/test/examples/truncate/out/geometry-collection.geojson b/test/examples/truncate/out/geometry-collection.geojson new file mode 100644 index 0000000..1772773 --- /dev/null +++ b/test/examples/truncate/out/geometry-collection.geojson @@ -0,0 +1,13 @@ +{ + "type": "GeometryCollection", + "geometries": [ + { + "type": "Point", + "coordinates": [-75.699921, 45.425097] + }, + { + "type": "Point", + "coordinates": [-75.691767, 45.422266] + } + ] +} diff --git a/test/examples/truncate/out/linestring-geometry.geojson b/test/examples/truncate/out/linestring-geometry.geojson new file mode 100644 index 0000000..f983934 --- /dev/null +++ b/test/examples/truncate/out/linestring-geometry.geojson @@ -0,0 +1,8 @@ +{ + "type": "LineString", + "coordinates": [ + [33.046875, 12.554564], + [31.992188, 20.632784], + [43.242188, 27.371767] + ] +} diff --git a/test/examples/truncate/out/point-elevation.geojson b/test/examples/truncate/out/point-elevation.geojson new file mode 100644 index 0000000..17dbb41 --- /dev/null +++ b/test/examples/truncate/out/point-elevation.geojson @@ -0,0 +1,11 @@ +{ + "type": "Feature", + "properties": { + "precision": 4, + "coordinates": 2 + }, + "geometry": { + "type": "Point", + "coordinates": [-75.6999, 45.4251] + } +} diff --git a/test/examples/truncate/out/point-geometry.geojson b/test/examples/truncate/out/point-geometry.geojson new file mode 100644 index 0000000..539a61a --- /dev/null +++ b/test/examples/truncate/out/point-geometry.geojson @@ -0,0 +1,4 @@ +{ + "type": "Point", + "coordinates": [-75.699921, 45.425097] +} diff --git a/test/examples/truncate/out/point.geojson b/test/examples/truncate/out/point.geojson new file mode 100644 index 0000000..951413a --- /dev/null +++ b/test/examples/truncate/out/point.geojson @@ -0,0 +1,12 @@ +{ + "type": "Feature", + "properties": { + "precision": 3 + }, + "id": 12345, + "bbox": [1, 2, 3, 4], + "geometry": { + "type": "Point", + "coordinates": [-75.7, 45.425] + } +} diff --git a/test/examples/truncate/out/points.geojson b/test/examples/truncate/out/points.geojson new file mode 100644 index 0000000..5b918e3 --- /dev/null +++ b/test/examples/truncate/out/points.geojson @@ -0,0 +1,22 @@ +{ + "type": "FeatureCollection", + "id": 12345, + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [-75.699921, 45.425097] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Point", + "coordinates": [-75.691767, 45.422266] + } + } + ] +} diff --git a/test/examples/truncate/out/polygon.geojson b/test/examples/truncate/out/polygon.geojson new file mode 100644 index 0000000..0ac226e --- /dev/null +++ b/test/examples/truncate/out/polygon.geojson @@ -0,0 +1,16 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-75.745068, 45.383622], + [-75.745068, 45.437129], + [-75.654774, 45.437129], + [-75.654774, 45.383622], + [-75.745068, 45.383622] + ] + ] + } +} diff --git a/test/examples/truncate/out/polygons.geojson b/test/examples/truncate/out/polygons.geojson new file mode 100644 index 0000000..c0f44cc --- /dev/null +++ b/test/examples/truncate/out/polygons.geojson @@ -0,0 +1,37 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-75.745068, 45.383622], + [-75.745068, 45.437129], + [-75.654774, 45.437129], + [-75.654774, 45.383622], + [-75.745068, 45.383622] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [-75.769272, 45.441826], + [-75.769272, 45.480596], + [-75.680008, 45.480596], + [-75.680008, 45.441826], + [-75.769272, 45.441826] + ] + ] + } + } + ] +}