GeoJson
The geojson
module contains an implementation of the GeoJson standard.
See below for constructing GeoJson objects using the DSL.
Installation
GeoJson Objects
The GeoJson
interface represents all GeoJson objects. All GeoJson objects can have a bbox
property specified on them
which is a BoundingBox
that represents the bounds of that object's geometry.
Geometry
Geometry objects are a sealed hierarchy of classes that inherit from the Geometry
class. This allows for exhaustive
type checks in Kotlin using a when
block.
All seven types of GeoJSON geometries are implemented and summarized below. Full documentation can be found in the API pages.
Position
Positions are implemented as a DoubleArray
-backed class. Each component (longitude
, latitude
, altitude
) can be accessed by its propery.
The class also supports destructuring.
Positions are implemented as an interface where the longitude, latitude, and optionally an altitude are accessible as
properties. The basic implementation of the Position
interface is the LngLat
class.
Point
A Point is a single Position.
MultiPoint
A MultiPoint
is an array of Positions.
LineString
A LineString
is a sequence of two or more Positions.
MultiLineString
A MultiLineString
is an array of LineStrings.
Polygon
A Polygon
is an array of rings. Each ring is a sequence of points with the last point matching the first point to indicate a closed area.
The first ring defines the outer shape of the polygon, while all the following rings define "holes" inside the polygon.
MultiPolygon
A MultiPolygon
is an array of Polygons.
val polygon = listOf(
Position(-79.87, 43.42),
Position(-78.89, 43.49),
Position(-79.07, 44.02),
Position(-79.95, 43.87),
Position(-79.87, 43.42)
),
listOf(
Position(-79.75, 43.81),
Position(-79.56, 43.85),
Position(-79.7, 43.88),
Position(-79.75, 43.81)
)
val multiPolygon = MultiPolygon(polygon, polygon)
{
"type": "MultiPolygon",
"coordinates": [
[
[[-79.87, 43.42], [-78.89, 43.49], [-79.07, 44.02], [-79.95, 43.87], [-79.87, 43.42]],
[[-79.75, 43.81], [-79.56, 43.85], [-79.7, 43.88], [-79.75, 43.81]]
],
[
[[-79.87, 43.42], [-78.89, 43.49], [-79.07, 44.02], [-79.95, 43.87], [-79.87, 43.42]],
[[-79.75, 43.81], [-79.56, 43.85], [-79.7, 43.88], [-79.75, 43.81]]
]
]
}
GeometryCollection
A GeometryCollection
is a collection of different types of Geometry. It implements the Collection
interface and can be used in any place that a collection can be used.
Feature
A Feature
can contain a Geometry
object, as well as a set of data properties, and optionally a commonly used identifier (id
).
A feature's properties are stored as a map of JsonElement
objects from kotlinx.serialization
.
A set of helper methods to get and set properties with the appropriate types directly.
FeatureCollection
A FeatureCollection
is a collection of multiple features. FeatureCollection
implements the Collection
interface and can be used in any place that a collection can be used.
BoundingBox
The BoundingBox
class is used to represent the bounding boxes that can be set for any GeoJson
object.
Like the Position
class, bounding boxes are backed by a DoubleArray
with each component accessible by its propery (southwest
and northeast
).
Bounding boxes also support destructuring.
Serialization
To Json
Any GeoJson
object can be serialized to a JSON string using the json()
function.
This function converts the object to JSON using string concatenation and is therefore very fast.
Spatial-K is also fully compatible with kotlinx.serialization
to allow for integration into more complex models, however
this is much slower. For encoding directly to JSON strings, prefer to use the json()
function.
From Json
The fromJson
and fromJsonOrNull
companion (or static) functions are available on each GeoJson
class to decode each
type of object from a JSON string.
Like with encoding, Spatial-K objects can also be decoded using kotlinx.serialization
.
GeoJson DSL
It's recommended to construct GeoJson objects in-code using the GeoJson DSL.
Positions
Convenience functions to construct latitude/longitude Position instances is included.
These functions will check for valid latitude and longitude values and will throw an IllegalArgumentException
otherwise.
Geometry
Each geometry type has a corresponding DSL.
A GeoJson object's bbox
value can be assigned in any of the DSLs.
Point
MultiPoint
The MultiPoint
DSL creates a MultiPoint
from many Point
s, or by using the unary plus operator to add Position
instances as positions in the geometry.
Point
geometries can also be added to the multi point using the unary plus operator.
LineString
A LineString
contains main points. Like with MultiPoint
, a LineString
can also be built using the unary plus operator to add positions as part of the line.
The order in which positions are added to the LineString
is the order that the LineString
will follow.
MultiLineString
The MultiLineString
DSL uses the unary plus operator to add multiple line strings. The LineString
DSL can be used to
create LineString
objects to add.
Polygon
The Polygon
DSL is used by specifying linear rings that make up the polygon's shape and holes.
The first ring
is the exterior ring with four or more positions. The last position must be the same as the first position.
All ring
s that follow will represent interior rings (i.e. holes) in the polygon.
For convenience, the complete()
function can be used to "complete" a ring.
It adds the last position in the ring by copying the first position that was added.
MultiPolygon
Like with previous "Multi" geometries, the unary plus operator is used to add multiple Polygon
objects.
The Polygon
DSL can also be used here.
Geometry Collection
The unary plus operator can be used to add any geometry instance to a GeometryCollection
.
{
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [-75.0, 45.0, 100.0]
},
{
"type": "LineString",
"coordinates": [[45.0, 45.0], [0.0, 0.0]]
},
{
"type": "Polygon",
"coordinates": [
[[45.0, 45.0], [0.0, 0.0], [12.0, 12.0], [45.0, 45.0]],
[[4.0, 4.0], [2.0, 2.0], [3.0, 3.0], [4.0, 4.0]]
]
}
]
}
Feature
The Feature
DSL can construct a Feature
object with a geometry, a bounding box, and an id. Properties can be specified
in the PropertiesBuilder
block by calling put(key, value)
to add properties.
Feature Collection
A FeatureCollection
is constructed by adding multiple Feature
objects using the unary plus operator.