// https://trac.osgeo.org/geos/ticket/1005
// https://github.com/OSGeo/gdal/issues/2472
_testEncodeToBytesBase64(
Endian.little,
'AQEAAAAAAAAAAAD4fwAAAAAAAPh/',
// hex: 0101000000000000000000F87F000000000000F87F
// IEEE specifies NaN in float64 as (big endian) 7ff80000 00000000
// in Dart it seems that (using ByteData) need to write `-double.nan`
// this is handled by wkb encoder / byte writer util....
'POINT EMPTY',
[
(writer) => writer.emptyGeometry(Geom.point),
(writer) => writer.point([double.nan, double.nan].xy),
(writer) => writer.point([-double.nan, -double.nan].xy),
],
);
This has succeed on geobase 1.0.0 tests in previous Dart SDKs but with latest Dart 3.3 SDK it seems that double.nan is written using dart:typed_data in different way.
Utility class ByteWriter had special cases (nanEncodedAsNegative):
/// Writes [value] as four bytes (IEEE 754 single-precision floating-point).
///
/// Uses the parameter [endian] if non-null, otherwise uses `this.endian`.
///
/// See `ByteData.setFloat32` from `dart:typed_data` for reference.
///
/// See also configuration parameter [nanEncodedAsNegative].
void writeFloat32(double value, [Endian? endian]) {
_reserve(4);
_chunk.setFloat32(
_offset,
value.isNaN ? -double.nan : value,
nanEncodedAsNegative && value.isNaN ? -double.nan : value,
endian ?? this.endian,
);
_offset += 4;
}
/// Writes [value] as eight bytes (IEEE 754 double-precision floating-point).
///
/// Uses the parameter [endian] if non-null, otherwise uses `this.endian`.
///
/// See `ByteData.setFloat64` from `dart:typed_data` for reference.
///
/// See also configuration parameter [nanEncodedAsNegative].
void writeFloat64(double value, [Endian? endian]) {
_reserve(8);
_chunk.setFloat64(
_offset,
nanEncodedAsNegative && value.isNaN ? -double.nan : value,
endian ?? this.endian,
);
_offset += 8;
}
That were used on WKBEncoder:
@override
void emptyGeometry(Geom type, {String? name}) {
// type for coordinates
const coordType = Coords.xy;
switch (type) {
case Geom.point:
// this is a special case => https://trac.osgeo.org/geos/ticket/1005
// https://trac.osgeo.org/postgis/ticket/3181
// https://github.com/OSGeo/gdal/issues/2472
// write only x and y as double.nan
// that is POINT(NaN NaN) is considered POINT EMPTY, or something..
// Note: negative NaN (whatever it is) is needed to get same output in
// bytes as those OSGEO related (reliable?) sources
// (thats why buffer is create with nanEncodedAsNegative: true)
_writeGeometryHeader(type, Coords.xy);
_buffer
..writeFloat64(double.nan)
..writeFloat64(double.nan);
break;
case Geom.lineString:
case Geom.polygon:
case Geom.multiPoint:
case Geom.multiLineString:
case Geom.multiPolygon:
case Geom.geometryCollection:
// write geometry with 0 elements (points, rings, geometries, etc.)
_writeGeometryHeader(type, coordType);
_buffer.writeUint32(0);
break;
}
}
Removing special case for negative NaN and just writing a positive NaN whenever a NaN value (negative or positive) seems to fix...
There is a special case test:
This has succeed on geobase 1.0.0 tests in previous Dart SDKs but with latest Dart 3.3 SDK it seems that
double.nan
is written usingdart:typed_data
in different way.Utility class
ByteWriter
had special cases (nanEncodedAsNegative
):That were used on
WKBEncoder
:Removing special case for negative NaN and just writing a positive NaN whenever a NaN value (negative or positive) seems to fix...