From a454f0a837ea9772a8af79c748dc979be4ff34fe Mon Sep 17 00:00:00 2001 From: Lukas Himsel Date: Mon, 6 Dec 2021 03:12:20 +0100 Subject: [PATCH] #19, #20, #21, refactor --- lib/src/geojson.dart | 138 +++++++++++++++++++++++++++++-------------- 1 file changed, 94 insertions(+), 44 deletions(-) diff --git a/lib/src/geojson.dart b/lib/src/geojson.dart index 317e180..f66379c 100644 --- a/lib/src/geojson.dart +++ b/lib/src/geojson.dart @@ -1,10 +1,6 @@ import 'package:json_annotation/json_annotation.dart'; part 'geojson.g.dart'; -//TODO assemble multipoint from points -//TODO assemble multilinestring from linestring -//TODO assemble polygon from 3 or more points - // TODO convert to enum with JsonEnum serialization class GeoJSONObjectTypes { static const String point = 'Point'; @@ -22,12 +18,16 @@ abstract class GeoJSONObject { @JsonKey(ignore: true) final String type; BBox? bbox; + GeoJSONObject.withType(this.type); + Map serialize(Map map) => { 'type': type, ...map, }; + toJson(); + GeoJSONObject clone(); } @@ -165,6 +165,7 @@ class Position extends CoordinateType { lat, if (alt != null) alt, ]); + Position.named({required num lat, required num lng, num? alt}) : super([ lng, @@ -176,6 +177,7 @@ class Position extends CoordinateType { Position.of(List list) : assert(list.length >= 2 && list.length <= 3), super(list); + factory Position.fromJson(List list) => Position.of(list); // TODO implement override operators +, -, * with vector operations @@ -244,6 +246,7 @@ class BBox extends CoordinateType { BBox.of(List list) : assert(list.length == 4 || list.length == 6), super(list); + factory BBox.fromJson(List list) => BBox.of(list); bool get _is3D => length == 6; @@ -274,6 +277,7 @@ class BBox extends CoordinateType { abstract class GeometryObject extends GeoJSONObject { GeometryObject.withType(String type) : super.withType(type); + static GeometryObject deserialize(Map json) { return json['type'] == GeoJSONObjectTypes.geometryCollection ? GeometryCollection.fromJson(json) @@ -283,6 +287,7 @@ abstract class GeometryObject extends GeoJSONObject { abstract class GeometryType extends GeometryObject { T coordinates; + GeometryType.withType(this.coordinates, String type) : super.withType(type); static GeometryType deserialize(Map json) { @@ -308,11 +313,13 @@ abstract class GeometryType extends GeometryObject { /// Point, as specified here https://tools.ietf.org/html/rfc7946#section-3.1.2 @JsonSerializable(explicitToJson: true) class Point extends GeometryType { + @override + BBox? bbox; + Point({this.bbox, required Position coordinates}) : super.withType(coordinates, GeoJSONObjectTypes.point); + factory Point.fromJson(Map json) => _$PointFromJson(json); - @override - BBox? bbox; @override bool operator ==(dynamic other) => @@ -328,12 +335,19 @@ class Point extends GeometryType { /// MultiPoint, as specified here https://tools.ietf.org/html/rfc7946#section-3.1.3 @JsonSerializable(explicitToJson: true) class MultiPoint extends GeometryType> { + @override + BBox? bbox; + MultiPoint({this.bbox, List coordinates = const []}) : super.withType(coordinates, GeoJSONObjectTypes.multiPoint); + factory MultiPoint.fromJson(Map json) => _$MultiPointFromJson(json); - @override - BBox? bbox; + + MultiPoint.fromPoints({this.bbox, List points = const []}) + : super.withType(points.map((e) => e.coordinates).toList(), + GeoJSONObjectTypes.multiPoint); + @override Map toJson() => super.serialize(_$MultiPointToJson(this)); @@ -347,12 +361,19 @@ class MultiPoint extends GeometryType> { /// LineString, as specified here https://tools.ietf.org/html/rfc7946#section-3.1.4 @JsonSerializable(explicitToJson: true) class LineString extends GeometryType> { + @override + BBox? bbox; + LineString({this.bbox, List coordinates = const []}) : super.withType(coordinates, GeoJSONObjectTypes.lineString); + factory LineString.fromJson(Map json) => _$LineStringFromJson(json); - @override - BBox? bbox; + + LineString.fromPoints({this.bbox, List points = const []}) + : super.withType(points.map((e) => e.coordinates).toList(), + GeoJSONObjectTypes.lineString); + @override Map toJson() => super.serialize(_$LineStringToJson(this)); @@ -365,12 +386,20 @@ class LineString extends GeometryType> { /// MultiLineString, as specified here https://tools.ietf.org/html/rfc7946#section-3.1.5 @JsonSerializable(explicitToJson: true) class MultiLineString extends GeometryType>> { + @override + BBox? bbox; + MultiLineString({this.bbox, List> coordinates = const []}) : super.withType(coordinates, GeoJSONObjectTypes.multiLineString); + factory MultiLineString.fromJson(Map json) => _$MultiLineStringFromJson(json); - @override - BBox? bbox; + + MultiLineString.fromLineStrings( + {this.bbox, List lineStrings = const []}) + : super.withType(lineStrings.map((e) => e.coordinates).toList(), + GeoJSONObjectTypes.multiLineString); + @override Map toJson() => super.serialize(_$MultiLineStringToJson(this)); @@ -386,12 +415,20 @@ class MultiLineString extends GeometryType>> { /// Polygon, as specified here https://tools.ietf.org/html/rfc7946#section-3.1.6 @JsonSerializable(explicitToJson: true) class Polygon extends GeometryType>> { + @override + BBox? bbox; + Polygon({this.bbox, List> coordinates = const []}) : super.withType(coordinates, GeoJSONObjectTypes.polygon); + factory Polygon.fromJson(Map json) => _$PolygonFromJson(json); - @override - BBox? bbox; + + Polygon.fromPoints({this.bbox, List> points = const []}) + : super.withType( + points.map((e) => e.map((e) => e.coordinates).toList()).toList(), + GeoJSONObjectTypes.polygon); + @override Map toJson() => super.serialize(_$PolygonToJson(this)); @@ -406,12 +443,19 @@ class Polygon extends GeometryType>> { /// MultiPolygon, as specified here https://tools.ietf.org/html/rfc7946#section-3.1.7 @JsonSerializable(explicitToJson: true) class MultiPolygon extends GeometryType>>> { + @override + BBox? bbox; + MultiPolygon({this.bbox, List>> coordinates = const []}) : super.withType(coordinates, GeoJSONObjectTypes.multiPolygon); + factory MultiPolygon.fromJson(Map json) => _$MultiPolygonFromJson(json); - @override - BBox? bbox; + + MultiPolygon.fromPolygons({this.bbox, List polygons = const []}) + : super.withType(polygons.map((e) => e.coordinates).toList(), + GeoJSONObjectTypes.multiPolygon); + @override Map toJson() => super.serialize(_$MultiPolygonToJson(this)); @@ -427,11 +471,13 @@ class MultiPolygon extends GeometryType>>> { /// GeometryCollection, as specified here https://tools.ietf.org/html/rfc7946#section-3.1.8 @JsonSerializable(explicitToJson: true, createFactory: false) class GeometryCollection extends GeometryObject { - GeometryCollection({this.bbox, this.geometries = const []}) - : super.withType(GeoJSONObjectTypes.geometryCollection); @override BBox? bbox; List geometries; + + GeometryCollection({this.bbox, this.geometries = const []}) + : super.withType(GeoJSONObjectTypes.geometryCollection); + factory GeometryCollection.fromJson(Map json) => GeometryCollection( bbox: json['bbox'] == null @@ -444,6 +490,7 @@ class GeometryCollection extends GeometryObject { .toList() ?? const [], ); + @override Map toJson() => super.serialize(_$GeometryCollectionToJson(this)); @@ -458,6 +505,13 @@ class GeometryCollection extends GeometryObject { /// Feature, as specified here https://tools.ietf.org/html/rfc7946#section-3.2 class Feature extends GeoJSONObject { + @override + BBox? bbox; + dynamic id; + Map? properties; + T? geometry; + Map fields; + Feature({ this.bbox, this.id, @@ -465,30 +519,7 @@ class Feature extends GeoJSONObject { this.geometry, this.fields = const {}, }) : super.withType(GeoJSONObjectTypes.feature); - dynamic id; - Map? properties; - T? geometry; - Map fields; - dynamic operator [](String key) { - switch (key) { - case 'id': - return id; - case 'properties': - return properties; - case 'geometry': - return geometry; - case 'type': - return type; - case 'bbox': - return bbox; - default: - return fields[key]; - } - } - - @override - BBox? bbox; factory Feature.fromJson(Map json) => Feature( id: json['id'], geometry: json['geometry'] == null @@ -509,6 +540,23 @@ class Feature extends GeoJSONObject { ), ); + dynamic operator [](String key) { + switch (key) { + case 'id': + return id; + case 'properties': + return properties; + case 'geometry': + return geometry; + case 'type': + return type; + case 'bbox': + return bbox; + default: + return fields[key]; + } + } + @override Map toJson() => super.serialize({ 'id': id, @@ -529,11 +577,13 @@ class Feature extends GeoJSONObject { /// FeatureCollection, as specified here https://tools.ietf.org/html/rfc7946#section-3.3 class FeatureCollection extends GeoJSONObject { - FeatureCollection({this.bbox, this.features = const []}) - : super.withType(GeoJSONObjectTypes.featureCollection); - List> features; @override BBox? bbox; + List> features; + + FeatureCollection({this.bbox, this.features = const []}) + : super.withType(GeoJSONObjectTypes.featureCollection); + factory FeatureCollection.fromJson(Map json) => FeatureCollection( bbox: json['bbox'] == null