buildPosition<R extends Position> static method
R
buildPosition<R extends Position>(})
Builds a position of R
from coords
starting from offset
.
A position instance is created using the factory function to
.
Supported coordinate value combinations for coords
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 coords
has 3 items, then xyz coordinates are assumed.
If swapXY
is true, then swaps x and y for the result.
Throws FormatException if coordinates are invalid.
Implementation
static R buildPosition<R extends Position>(
Iterable<num> coords, {
required CreatePosition<R> to,
int offset = 0,
Coords? type,
bool swapXY = false,
}) {
if (coords is List<num>) {
final len = coords.length - offset;
final coordsType = type ?? Coords.fromDimension(math.min(4, len));
final mIndex = coordsType.indexForM;
if (len < 2) {
throw invalidCoordinates;
}
return to.call(
x: coords[swapXY ? offset + 1 : offset].toDouble(),
y: coords[swapXY ? offset : offset + 1].toDouble(),
z: coordsType.is3D
? (len > 2 ? coords[offset + 2] : 0.0).toDouble()
: null,
m: mIndex != null
? (len > mIndex ? coords[offset + mIndex] : 0.0).toDouble()
: null,
);
} else {
// resolve iterator for source coordinates
final Iterator<num> iter;
if (offset == 0) {
iter = coords.iterator;
} else if (coords.length >= offset + 2) {
iter = coords.skip(offset).iterator;
} else {
throw invalidCoordinates;
}
// iterate at least to x and y
final num x;
final num y;
if (swapXY) {
y = iter.moveNext() ? iter.current : throw invalidCoordinates;
x = iter.moveNext() ? iter.current : throw invalidCoordinates;
} else {
x = iter.moveNext() ? iter.current : throw invalidCoordinates;
y = iter.moveNext() ? iter.current : throw invalidCoordinates;
}
// XY was asked
if (type == Coords.xy) {
return to.call(x: x.toDouble(), y: y.toDouble());
}
// iterate optional z and m
final num? optZ;
if (type == null || type.is3D) {
if (iter.moveNext()) {
optZ = iter.current;
} else {
optZ = type?.is3D ?? false ? 0.0 : null;
}
} else {
optZ = null;
}
final num? optM;
if (type == null || type.isMeasured) {
if (iter.moveNext()) {
optM = iter.current;
} else {
optM = type?.isMeasured ?? false ? 0.0 : null;
}
} else {
optM = null;
}
// finally create a position object
return to.call(
x: x.toDouble(),
y: y.toDouble(),
z: optZ?.toDouble(),
m: optM?.toDouble(),
);
}
}