# Coordinates

Geographic and projected coordinates can be represented as single positions, series of positions and bounding boxes (with minimum and maximum positions).

This chapter discusses using and creating such objects.

Geometric objects commonly used in geospatial applications like like *points*,
*line strings* (or polylines) and *polygons* are introduced in the separate
chapter about simple geometries.

## 📍 Position data

The basic building blocks to represent position data in this package are:

Class | Description |
---|---|

`Position` | A position with 2 to 4 coordinate values (x and y are required, z and m are optional) representing an exact location in some coordinate reference system. |

`PositionSeries` | A series of 0 to N positions built from a coordinate value array or a list of position objects. |

`Box` | A bounding box with 4 to 8 coordinate values (minX, minY, maxX and maxY are required, minZ, minM, maxZ and maxM are optional). |

These classes are used by simple geometry classes too as internal data structures to store single positions and boxes, and series of positions.

Some basic samples to create position objects:

When a position contains geographic coordinates, then `x`

represents
`longitude`

, `y`

represents `latitude`

, and `z`

represents `elevation`

(or
height or altitude) when manipulating data with classes introduced here
(external data formats may use different
axis orders).

Bounding boxes have similar factory methods too:

## 🪣 Series of positions

`PositionSeries`

is a fixed-length (and random-access) view to a series of
positions. There are two main structures to store coordinate values of positions
contained in a series:

- A list of
`Position`

objects (each object contains x and y coordinates, and optionally z and m too). - A list of
`double`

values as a flat structure. For example a double list could contain coordinates like`[x0, y0, z0, x1, y1, z1, x2, y2, z2]`

that represents three positions each with x, y and z coordinates.

These two structures are demonstrated by code:

When manipulating positions in code it may be easier to handle lists or
iterables of `Position`

objects. However coordinate value arrays in a flat
structure is used by default when decoding position data from geospatial data
formats.

Coordinate value arrays represented as `List<double>`

also provides more
memory-efficient structure than `List<Position>`

. This is further enhanced by
using optimized `Float64List`

(a list of double-precision floating-point numbers)
or `Float32List`

(a list of single-precision floating-point numbers, takes even
less space but sacrifices accuracy a bit) data structures defined by the
standard `dart:typed_data`

package.

Building `PositionSeries`

objects from coordinate value arrays can be also
shortened. This can be handy when specifying position data in Dart code.

See also the advanced topic about coordinate arrays for more information about handling coordinate value arrays for a single position, series of positions and a single bounding box.

Classes described above can be used to represented position data in various
coordinate reference systems, including *geographic*, *projected* and local
systems.

There are also very specific subtypes of `Position`

and `Box`

classes.

`Projected`

(extending `Position`

) and `ProjBox`

(extending `Box`

) can be used
to represent *projected* or cartesian (XYZ) coordinates. Similarily `Geographic`

and `GeoBox`

can be used to represent *geographic* coordinates.

These special purpose subtypes for positions and boxes are discussed in next few sections.

## 🌐 Geographic coordinates

*Geographic* coordinates are based on a spherical or ellipsoidal coordinate
system representing positions on the Earth as longitude (`lon`

) and latitude
(`lat`

).

Elevation (`elev`

) in meters and measure (`m`

) coordinates are optional.

Geographic *positions*:

Geographic *bounding boxes*:

## 🔢 Geographic string representations (DMS)

A geographic position can also be parsed from sexagesimal degrees (latitude and longitude subdivided to degrees, minutes and seconds):

Format geographic coordinates as string representations (DD, DM, DMS):

Parsing and formatting is supported also for geographic bounding boxes:

In the previous example `dm`

, `dm0`

, `dms`

and `dmsTextual`

are instances of the
`Dms`

class that implements `DmsFormat`

. This defines multiple methods for
parsing and formatting decimal degrees and sexagesimal degrees
(degrees/minutes/seconds) on latitude, longitude and bearing values.

The default format used by `Geographic`

and `GeoBox`

classes formats values as
decimal degrees with cardinal direction symbols. To use other formats
(degrees/minutes or degrees/minutes/seconds), or to set other parameters (like
separators, symbol characters, the number of decimals, zero padding or value
signing) you should create a custom `Dms`

instance.

See the API documentation and DMS test cases for more samples.

## 🗺️ Projected coordinates

*Projected* coordinates represent projected or cartesian (XYZ) coordinates with
an optional measure (m) coordinate. For projected map positions `x`

often
represents *easting* (E) and `y`

represents *northing* (N), however a coordinate
reference system might specify something else too.

The `m`

(measure) coordinate represents a measurement or a value on a linear
referencing system (like time). It could be associated with a 2D position
(x, y, m) or a 3D position (x, y, z, m).

Projected *positions*:

Projected *bounding boxes*:

## 🗄️ Scalable coordinates

*Scalable* coordinates are coordinates associated with a *level of detail* (LOD)
or a `zoom`

level. They are used for example by
tiling schemes to represent *pixels* or
*tiles* in tile matrices.

The `Scalable2i`

class represents projected `x`

, `y`

coordinates at `zoom`

level, with all values as integers.

## ⌖ Coordinates summary

Classes representing *position*, *bounding box* and *scalable* coordinates:

Coordinate values in *position* classes (*projected* and *geographic*):

Class | Required coordinates | Optional coordinates | Values |
---|---|---|---|

`Position` | x, y | z, m | double |

`Projected` | x, y | z, m | double |

`Geographic` | lon, lat | elev, m | double |

Coordinate values in *bounding box* classes (*projected* and *geographic*):

Class | Required coordinates | Optional coordinates | Values |
---|---|---|---|

`Box` | minX, minY, maxX, maxY | minZ, minM, maxZ, maxM | double |

`ProjBox` | minX, minY, maxX, maxY | minZ, minM, maxZ, maxM | double |

`GeoBox` | west, south, east, north | minElev, minM, maxElev, maxM | double |

Coordinate values in *scalable* classes:

Class | Required coordinates | Optional coordinates | Values |
---|---|---|---|

`Scalable2i` | zoom, x, y | int |

Coordinates are stored as `double`

values in all position and bounding box
classes but `Scalable2i`

uses `int`

coordinate values.

The `Position`

class is a super type for `Projected`

and `Geographic`

, and
the `Box`

class is a super type for `ProjBox`

and `GeoBox`

. Please see more
information about them in the API reference.

## 📡 Coordinate reference systems

According to Wikipedia a
Coordinate reference system
is *a coordinate-based local, regional or global system used to locate
geographical entities*.

Coordinate reference systems are identified by `String`

identifiers. Such ids
are specified by registries like The EPSG dataset and
OGC CRS registry. Also W3C has a
good introduction
about coordinate reference systems.

The package also contains `CoordRefSys`

class that has constant instaces for:

Constant | Description |
---|---|

`CRS84` | WGS 84 geographic coordinates (order: longitude, latitude). |

`CRS84h` | WGS 84 geographic coordinates (order: longitude, latitude) with ellipsoidal height (elevation). |

`EPSG_4326` | WGS 84 geographic coordinates (order: latitude, longitude). |

`EPSG_4258` | ETRS89 geographic coordinates (order: latitude, longitude). |

`EPSG_3857` | WGS 84 projected (Web Mercator) metric coordinates based on “spherical development of ellipsoidal coordinates”. |

`EPSG_3395` | WGS 84 projected (World Mercator) metric coordinates based on “ellipsoidal coordinates”. |

These constants can be used to check `id`

, `axisOrder`

and whether to `swapXY`

when dealing with external data sources like GeoJSON data. However currently
geodetic datum and projection parameters are not available.

Other identifiers can be added by creating a custom class implementing
`CoordRefSysResolver`

and by registering it’s global instance using
`CoordRefSysResolver.register()`

on startup routines of your app.

Please note that `CRS84`

and `EPSG_4326`

(or “EPSG:4326”) constants both refer
to the WGS 84 geographic coordinate system, but in external data representations
their axis order differs.

## 📅 Temporal coordinate reference systems

There is also a type `TemporalRefSys`

for specifying a temporal coordinate
reference system. A custom logic can be registered using
`TemporalRefSysResolver.register()`

.

Currently there is only one constant identifier defined by `TemporalRefSys`

:

Constant | Description |
---|---|

`gregorian` | References temporal coordinates, dates or timestamps, that are in the Gregorian calendar and conform to RFC 3339. |