Simple geometries
The geometry model implemented by the geobase
package is based on
Simple Feature Access - Part 1: Common Architecture
published by the
Open Geospatial Consortium (OGC).
The basic primitives are point, line string (or a polyline) and polygon, and their multi-part representations. A geometry collection may contain any type of other geometry objects.
𧩠Geometry types
Geometry primitive types supported by this package (with samples adapted from the samples of the Wikipedia page about WKT, and compatible also with GeoJSON):
Also multipart geometry classes are supported:
π§ Building geometry objects
Samples above expect 2D coordinates (x and y coordinates - or longitude and latitude).
When data contains more coordinates, like also z in 3D data, then the type
parameter in build methods (for geometries other than Point
) must always be
used explicitely to define the coordinate type.
A line string with 3 points (2D coordinates with x and y) from the table above:
LineString.build([30, 10, 10, 30, 40, 40]);
In this call there was no need to specify the coordinate type, but the same
example adjusted to contain 3D coordinates (x, y and z) requires explicitely
also the type
parameter (here each point has the z
value of 5.5):
LineString.build([30, 10, 5.5, 10, 30, 5.5, 40, 40, 5.5], type: Coords.xyz);
This sample even extended, a line string with 3D and measured coordinates (x, y,
z and m) is created below (here the m
value grows from 3.1 to 3.3):
LineString.build( [30, 10, 5.5, 3.1, 10, 30, 5.5, 3.2, 40, 40, 5.5, 3.3], type: Coords.xyzm,);
Geometry objects can be created also from iterables of Position
objects
(instances of Position
itself, or subtypes Projected
and Geographic
):
// A line string with 3 points (2D coordinates with x and y). LineString.from([ [30.0, 10.0].xy, // xy => Position.view() [10.0, 30.0].xy, [40.0, 40.0].xy, ]);
// A line string with 3 points (3D coordinates with x, y and z). LineString.from([ Geographic(lon: 30, lat: 10, elev: 5.5), // x = lon, y = lat, z = elev Geographic(lon: 10, lat: 30, elev: 5.5), Geographic(lon: 40, lat: 40, elev: 5.5), ]);
// A line string with 3 points (3D and measured coordinates: x, y, z and m). LineString.from([ Projected(x: 30, y: 10, z: 5.5, m: 3.1), Projected(x: 10, y: 30, z: 5.5, m: 3.2), Projected(x: 40, y: 40, z: 5.5, m: 3.3), ]);
In all geometry classes there are also some other ways to create objects:
- default constructors: creates a geometry object using coordinate arrays
parse
: parses a geometry object from text conforming to some text format like GeoJSON or WKTdecode
: decodes a geometry object from bytes conforming to some binary format like WKB
Alternative ways to construct geometries are shown for 3D lines strings.
// a line string from a PositionSeries created from coordinate values (3D)LineString( [ 10.0, 20.0, 30.0, // (x, y, z) for position 0 12.5, 22.5, 32.5, // (x, y, z) for position 1 15.0, 25.0, 35.0, // (x, y, z) for position 2 ].positions(Coords.xyz), // `.positions()` on a double list creates a `PositionSeries` instance.);
// a line string from 3D position objectsLineString.from([ [10.0, 20.0, 30.0].xyz, // `.xyz` creates a `Position` instance [12.5, 22.5, 32.5].xyz, [15.0, 25.0, 35.0].xyz,]);
// a line string from 3D positions encoded as GeoJSON textLineString.parse( format: GeoJSON.geometry, ''' { "type": "LineString", "coordinates": [ [10.0,20.0,30.0], [12.5,22.5,32.5], [15.0,25.0,35.0] ] } ''',);
// a line string from 3D positions encoded as WKT textLineString.parse( format: WKT.geometry, 'LINESTRING Z (10.0 20.0 30.0,12.5 22.5 32.5,15.0 25.0 35.0)',);
// a line string from 3D positions encoded as a comma delimited stringLineString.parseCoords( // values for three (x, y, z) positions '10.0,20.0,30.0,12.5,22.5,32.5,15.0,25.0,35.0', type: Coords.xyz,);
All other geometry objects have similar factories too.
π¦ Calculating bounding boxes
Geometry objects also know how to calculate their minimum bounding boxes.
// a line string from 2D positions (without a bounding box stored)final line = LineString.build( [ 10.0, 20.0, // (x, y) for position 0 12.5, 22.5, // (x, y) for position 1 15.0, 25.0, // (x, y) for position 2 ], type: Coords.xy,);
// calculate the bounding box when neededfinal bounds = line.calculateBounds();
// `bounds` would be equal with this one:Box.create(minX: 10.0, minY: 20.0, maxX: 15.0, maxY: 25.0);
If bounding boxes are needed frequently it might be more efficient to populate bounding boxes on geometry objects.
// a line string from 2D positions (with bounding box populated and stored)final line = LineString.build( [ 10.0, 20.0, // (x, y) for position 0 12.5, 22.5, // (x, y) for position 1 15.0, 25.0, // (x, y) for position 2 ], type: Coords.xy,).populated(onBounds: true);
// as the line string already contains it's bounds, you can just access itfinal bounds = line.bounds;
When reading external data, itβs possible that a minimum bounding box is included in data already. The last example shows how to use external data for bounding box.
// a line string from 2D positions (with a bounding box given explicitly)final line = LineString.build( [ 10.0, 20.0, // (x, y) for position 0 12.5, 22.5, // (x, y) for position 1 15.0, 25.0, // (x, y) for position 2 ], type: Coords.xy,
// a bounding box (minX, minY, maxX, maxY) bounds: Box.build(10.0, 20.0, 15.0, 25.0),)
ποΈ Geometry data model
The following class diagram describes key members of Point
, LineString
and Polygon
geometry classes:
Primitive geometry classes described by the diagram:
Point
with a single position represented byPosition
LineString
with a chain of positions (at least two positions) represented byPositionSeries
Polygon
with an array of linear rings- exactly one
exterior
ring represented byPositionSeries
- 0 to N
interior
rings (holes) with each represented byPositionSeries
- exactly one
The PositionSeries
class is described in the appendix
about coordinate arrays and
the SimpleGeometryContent
interface visible in the diagram in
content interfaces.
The usage of project()
method is described in the chapter about
projections.
See also the class diagram about multi and collection geometries below:
For example MultiLineString
stores chains
of positions for all line strings
as a list of PositionSeries
. Itβs also possible to get a mapped iterable of
LineString
objects using the lineStrings
getter.