diff --git a/README.md b/README.md index ff6c451..4c49617 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ but might extended to include additional properties in the future. **Constructors** * `FeatureCollection.fromJson(Map json)` - Creates a [`FeatureCollection`](#Feature-Collection) from a JSON object. Automatically converts features from GeoJSON to their respective types. +* `FeatureCollection.fromWKT(String wkt)` - Creates a [`FeatureCollection`](#Feature-Collection) from a Well-Known Text string. **Methods** diff --git a/lib/src/featureTypes/feature_collection.dart b/lib/src/featureTypes/feature_collection.dart index c556bc7..9a79f9e 100644 --- a/lib/src/featureTypes/feature_collection.dart +++ b/lib/src/featureTypes/feature_collection.dart @@ -76,6 +76,45 @@ class FeatureCollection { ); } + /// Creates a FeatureCollection from a WKT string. + /// + /// Example: + /// ```dart + /// FeatureCollection.fromWKT('GEOMETRYCOLLECTION(POINT(1 2), POINT(3 4))'); // FeatureCollection([Point(Coordinate(1, 2)), Point(Coordinate(3, 4))]) + /// ``` + factory FeatureCollection.fromWKT(String wkt) { + final regexBody = RegExp(r'GEOMETRYCOLLECTION\w?\((.*)\)', multiLine: true); + final match = regexBody.firstMatch(wkt); + if (match == null) { + throw ArgumentError('Invalid WKT'); + } + + final geometryString = match.group(1); + final regexGeometry = RegExp( + r'(\),[\s|\n]{0,2})(?=(POINT|MULTIPOINT|LINESTRING|MULTILINESTRING|POLYGON|MULTIPOLYGON))'); + final geometries = geometryString?.split(regexGeometry) ?? []; + + return FeatureCollection( + geometries.map((g) { + if (g.startsWith('POINT')) { + return Point.fromWKT(g); + } else if (g.startsWith('MULTIPOINT')) { + return MultiPoint.fromWKT(g); + } else if (g.startsWith('LINESTRING')) { + return LineString.fromWKT(g); + } else if (g.startsWith('MULTILINESTRING')) { + return MultiLineString.fromWKT(g); + } else if (g.startsWith('POLYGON')) { + return Polygon.fromWKT(g); + } else if (g.startsWith('MULTIPOLYGON')) { + return MultiPolygon.fromWKT(g); + } else { + throw ArgumentError('Invalid geometry type'); + } + }).toList(), + ); + } + /// Creates a [FeatureCollection] of [Point]s from the geometries of the [Feature]s contained within. /// /// Example: diff --git a/test/featureTypes/feature_collection_test.dart b/test/featureTypes/feature_collection_test.dart index 9d8f7b7..26e245a 100644 --- a/test/featureTypes/feature_collection_test.dart +++ b/test/featureTypes/feature_collection_test.dart @@ -12,5 +12,14 @@ void main() { expect(hydroelectricLinesCanada, featureCollectionJson); }); + + test('from wkt', () { + FeatureCollection featureCollection = FeatureCollection.fromWKT( + 'GEOMETRYCOLLECTION(POINT(1 2), LINESTRING(1 2, 3 4))'); + expect(featureCollection.features.length, 2); + expect(featureCollection.features[0] is Point, true); + expect(featureCollection.features[1] is LineString, true); + expect(featureCollection.features[0], Point.fromWKT('POINT(1 2)')); + }); }); }