Skip to content

Commit

Permalink
feat(geobase): content interfaces enhanced, use coordinate arrays mor…
Browse files Browse the repository at this point in the history
…e consistently #129, #136
  • Loading branch information
navispatial committed Jul 31, 2022
1 parent e3861ce commit 60a1e18
Show file tree
Hide file tree
Showing 23 changed files with 897 additions and 1,106 deletions.
111 changes: 34 additions & 77 deletions dart/geobase/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,15 @@ Tiling schemes, a sample with Web Mercator:
quad.positionToTile(Geographic(lon: -0.0014, lat: 51.4778), zoom: 2));
```

A sample to encode a `Point` geometry with a geographic position to
[GeoJSON](https://geojson.org/):
A sample to encode a `Point` geometry to [GeoJSON](https://geojson.org/):

```dart
// geometry text format encoder for GeoJSON
final encoder = GeoJSON.geometry.encoder();
// geometry encoder for GeoJSON, with number of decimals for text output set
final encoder = GeoJSON.geometry.encoder(decimals: 1);
// prints:
// {"type":"Point","coordinates":[10.123,20.25]}
encoder.content.point(const Geographic(lon: 10.123, lat: 20.25));
// {"type":"Point","coordinates":[10.1,20.3]}
encoder.writer.point([10.123, 20.25]);
print(encoder.toText());
```

Expand Down Expand Up @@ -518,38 +517,13 @@ A sample to encode a `LineString` geometry to GeoJSON:
// "bbox":[-1.1,-3.49,3.5,-1.1],
// "coordinates":[[-1.1,-1.1],[2.1,-2.5],[3.5,-3.49]]}
encoder.writer.lineString(
[
const Geographic(lon: -1.1, lat: -1.1),
const Geographic(lon: 2.1, lat: -2.5),
const Geographic(lon: 3.5, lat: -3.49),
],
[-1.1, -1.1, 2.1, -2.5, 3.5, -3.49],
type: Coords.xy,
bbox: const GeoBox(west: -1.1, south: -3.49, east: 3.5, north: -1.1),
);
print(encoder.toText());
```

The sample above can be shortened (instead of `Geographic` and `GeoBox` objects
coordinates are represented as `Iterable<num>` like `[-1.1, -1.1]` or
`[-1.1, -3.49, 3.5, -1.1]`):

```dart
final encoder = GeoJSON.geometry.encoder();
encoder.writer.lineString(
[
[-1.1, -1.1],
[2.1, -2.5],
[3.5, -3.49],
],
bbox: [-1.1, -3.49, 3.5, -1.1],
);
print(encoder.toText());
```

Shortened syntax for writing coordinates as `Iterable<num>` is available for all
content methods for writing positions, bounding boxes and other geometries, and
accepting `Position` (that is `Projected` or `Geographic`) or `Box` (that is
`ProjBox` or `GeoBox`) objects.

A sample to encode a `Feature` geometry to GeoJSON:

```dart
Expand All @@ -565,7 +539,7 @@ A sample to encode a `Feature` geometry to GeoJSON:
// {"foo":100,"bar":"this is property value","baz":true}}
encoder.writer.feature(
id: 'fid-1',
geometry: (geom) => geom.point(const Geographic(lon: 10.123, lat: 20.25)),
geometry: (geom) => geom.point([10.123, 20.25]),
properties: {
'foo': 100,
'bar': 'this is property value',
Expand All @@ -592,20 +566,12 @@ A sample to encode a `Point` geometry to WKT (with z and m coordinates too):
// prints:
// POINT ZM(10.123 20.25 -30.95 -1.999)
encoder.writer.point(
const Geographic(lon: 10.123, lat: 20.25, elev: -30.95, m: -1.999),
[10.123, 20.25, -30.95, -1.999],
type: Coords.xyzm,
);
print(encoder.toText());
```

Or shortened:

```dart
final encoder = WKT.geometry.encoder();
encoder.writer.point([10.123, 20.25, -30.95, -1.999], type: Coords.xyzm);
print(encoder.toText());
```

### WKB encoder and decoder

The `WKB` class provides encoders and decoders for
Expand Down Expand Up @@ -654,59 +620,50 @@ parameter. It implements `GeometryContent` interface and inherits following
methods from `SimpleGeometryContent`:

```dart
/// Writes a point geometry with a position from [coordinates].
///
/// The [coordinates] represents a single position of [Position] or
/// `Iterable<num>`.
///
/// Use an optional [name] to specify a name for a geometry (when applicable).
/// Writes a point geometry with [position].
///
/// Use an optional [type] to explicitely specify the type of coordinates.
///
/// Known [Position] sub classes are [Projected] (projected or cartesian
/// coordinates) and [Geographic] (geographic coordinates). Other sub classes
/// are supported too.
/// Use an optional [name] to specify a name for a geometry (when applicable).
///
/// Allowed [coordinates] value combinations for `Iterable<num>` are:
/// (x, y), (x, y, z) and (x, y, z, m).
/// Supported coordinate value combinations for `Iterable<double>` are:
/// (x, y), (x, y, z), (x, y, m) and (x, y, z, m). Use an optional [type] to
/// explicitely set the coordinate type. If not provided and an iterable has
/// 3 items, then xyz coordinates are assumed.
///
/// Examples to write a point geometry with 2D coordinates:
/// An example to write a point geometry with 2D coordinates:
/// ```dart
/// // using coordinate value list (x, y)
/// // using a coordinate value list (x, y)
/// content.point([10, 20]);
///
/// // using the type for positions with projected coordinates
/// // (same coordinates with the previous example)
/// content.point(const Projected(x: 10, y: 20));
/// ```
void point(
Object coordinates, {
String? name,
Iterable<double> position, {
Coords? type,
String? name,
});
/// Writes a line string geometry with a position array from [coordinates].
void lineString(
Iterable<Object> coordinates, {
/// Writes a line string geometry with a position array from [chain].
void lineString(
Iterable<double> chain, {
required Coords type,
String? name,
Coords? type,
Object? bbox,
Box? bbox,
});
/// Writes a polygon geometry with a position array from [coordinates].
void polygon(
Iterable<Iterable<Object>> coordinates, {
/// Writes a polygon geometry with a position array from [rings].
void polygon(
Iterable<Iterable<double>> rings, {
required Coords type,
String? name,
Coords? type,
Object? bbox,
Box? bbox,
});
/// Writes a multi point geometry with a position array from [coordinates].
void multiPoint(
Iterable<Object> coordinates, {
/// Writes a multi point geometry with a position array from [positions].
void multiPoint(
Iterable<Iterable<double>> positions, {
required Coords type,
String? name,
Coords? type,
Object? bbox,
Box? bbox,
});
// Omitted: multiLineString, multiPolygon, geometryCollection, emptyGeometry
Expand Down
69 changes: 28 additions & 41 deletions dart/geobase/example/geobase_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ void _wktPointGeometry() {

// prints:
// POINT(10.123 20.25)
encoder.writer.point(const Projected(x: 10.123, y: 20.25));
encoder.writer.point([10.123, 20.25]);
print(encoder.toText());
}

Expand All @@ -183,7 +183,7 @@ void _wktPointGeometryWithZ() {
// prints:
// POINT Z(10.123 20.25 -30.95)
encoder.writer.point(
const Projected(x: 10.123, y: 20.25, z: -30.95),
[10.123, 20.25, -30.95],
type: Coords.xyz,
);
print(encoder.toText());
Expand All @@ -196,7 +196,7 @@ void _wktPointGeometryWithM() {
// prints:
// POINT M(10.123 20.25 -1.999)
encoder.writer.point(
const Projected(x: 10.123, y: 20.25, m: -1.999),
[10.123, 20.25, -1.999],
type: Coords.xym,
);
print(encoder.toText());
Expand All @@ -209,15 +209,22 @@ void _wktPointGeometryWithZM() {
// prints:
// POINT ZM(10.123 20.25 -30.95 -1.999)
encoder.writer.point(
const Geographic(lon: 10.123, lat: 20.25, elev: -30.95, m: -1.999),
LonLatElevM(10.123, 20.25, -30.95, -1.999),
type: Coords.xyzm,
);
print(encoder.toText());
}

void _wktPointGeometryWithZMShortened() {
// geometry text format encoder for WKT
final encoder = WKT.geometry.encoder();
encoder.writer.point([10.123, 20.25, -30.95, -1.999], type: Coords.xyzm);

// prints:
// POINT ZM(10.123 20.25 -30.95 -1.999)
encoder.writer.point(
[10.123, 20.25, -30.95, -1.999],
type: Coords.xyzm,
);
print(encoder.toText());
}

Expand Down Expand Up @@ -262,7 +269,7 @@ void _geoJsonPointGeometry() {

// prints:
// {"type":"Point","coordinates":[10.123,20.25]}
encoder.writer.point(const Geographic(lon: 10.123, lat: 20.25));
encoder.writer.point([10.123, 20.25]);
print(encoder.toText());
}

Expand All @@ -272,7 +279,7 @@ void _geoJsonPointGeometryDecimals() {

// prints:
// {"type":"Point","coordinates":[10.1,20.3]}
encoder.writer.point(const Geographic(lon: 10.123, lat: 20.25));
encoder.writer.point([10.123, 20.25]);
print(encoder.toText());
}

Expand All @@ -283,7 +290,7 @@ void _geoJsonPointGeometryCustomStringBuffer() {

// write both directly to buffer and via geometry writer
buf.write('{"geometry":');
encoder.writer.point(const Geographic(lon: 10.123, lat: 20.25));
encoder.writer.point([10.123, 20.25]);
buf.write('}');

// prints:
Expand All @@ -300,11 +307,8 @@ void _geoJsonLineStringGeometryWithBbox() {
// "bbox":[-1.1,-3.49,3.5,-1.1],
// "coordinates":[[-1.1,-1.1],[2.1,-2.5],[3.5,-3.49]]}
encoder.writer.lineString(
[
const Geographic(lon: -1.1, lat: -1.1),
const Geographic(lon: 2.1, lat: -2.5),
const Geographic(lon: 3.5, lat: -3.49),
],
[-1.1, -1.1, 2.1, -2.5, 3.5, -3.49],
type: Coords.xy,
bbox: const GeoBox(west: -1.1, south: -3.49, east: 3.5, north: -1.1),
);
print(encoder.toText());
Expand All @@ -313,12 +317,9 @@ void _geoJsonLineStringGeometryWithBbox() {
void _geoJsonLineStringGeometryWithBboxShortened() {
final encoder = GeoJSON.geometry.encoder();
encoder.writer.lineString(
[
[-1.1, -1.1],
[2.1, -2.5],
[3.5, -3.49],
],
bbox: [-1.1, -3.49, 3.5, -1.1],
[-1.1, -1.1, 2.1, -2.5, 3.5, -3.49],
type: Coords.xy,
bbox: [-1.1, -3.49, 3.5, -1.1].box,
);
print(encoder.toText());
}
Expand All @@ -333,7 +334,7 @@ void _geoJsonGeometryCollection() {
// {"type":"Point",
// "coordinates":[10.123,20.25,-30.95]},
// {"type":"Polygon",
// "coordinates":[[[10.1,10.1],[5,9],[12,4],[10.1,10.1]]]}]}
// "coordinates":[[[10.1,10.1],[5.0,9.0],[12.0,4.0],[10.1,10.1]]]}]}

encoder.writer.geometryCollection(
// optional `count` argument is used to hint encoder of number of items
Expand All @@ -344,13 +345,9 @@ void _geoJsonGeometryCollection() {
..point([10.123, 20.25, -30.95], type: Coords.xyz)
..polygon(
[
[
const Geographic(lon: 10.1, lat: 10.1),
const Geographic(lon: 5, lat: 9),
const Geographic(lon: 12, lat: 4),
const Geographic(lon: 10.1, lat: 10.1)
],
[10.1, 10.1, 5, 9, 12, 4, 10.1, 10.1],
],
type: Coords.xy,
),
);
print(encoder.toText());
Expand All @@ -369,7 +366,7 @@ void _geoJsonFeature() {
// {"foo":100,"bar":"this is property value","baz":true}}
encoder.writer.feature(
id: 'fid-1',
geometry: (geom) => geom.point(const Geographic(lon: 10.123, lat: 20.25)),
geometry: (geom) => geom.point([10.123, 20.25]),
properties: {
'foo': 100,
'bar': 'this is property value',
Expand Down Expand Up @@ -408,27 +405,17 @@ void _geoJsonFeatureCollection() {
(features) => features // writing to FeatureContent
..feature(
id: 'fid-1',
geometry: (geom) => geom.point(
const Geographic(lon: 10.123, lat: 20.25),
),
geometry: (geom) => geom.point([10.123, 20.25]),
properties: {
'foo': 100,
'bar': 'this is property value',
},
)
..feature(
geometry: (geom) => geom.lineString(
[
const Geographic(lon: -1.1, lat: -1.1),
const Geographic(lon: 2.1, lat: -2.5),
const Geographic(lon: 3.5, lat: -3.49),
],
bbox: const GeoBox(
west: -1.1,
south: -3.49,
east: 3.5,
north: -1.1,
),
[-1.1, -1.1, 2.1, -2.5, 3.5, -3.49],
type: Coords.xy,
bbox: const GeoBox(west: -1.1, south: -3.49, east: 3.5, north: -1.1),
),
),
);
Expand Down
Loading

0 comments on commit 60a1e18

Please sign in to comment.