Opened 6 years ago

Closed 3 years ago

# Feature request: improve WKTWriter::writeNumber

Reported by: Owned by: Mike Taves strk major GEOS Fund Me Core main Feature Request

## Description

Numpy recently switched their default floating precision formatter to use a Dragon4 algorithm by Ryan Juckett to print floating point numbers with the shortest decimal representation. This feature request is to use Ryan's library (or similar) for WKTWriter, and implement it for the private `WKTWriter::writeNumber`, replacing `std::fixed` and `std::setprecision`.

There are probably a few ways that such a library could be adapted to better format coordinate data, using WKTWriter's existing setRoundingPrecision and trim options. For instance `PrintFloatFormat_Positional` can be used to always format numbers in positional notation, which I think is the preferred format for coordinates if setRoundingPrecision>-1 is specified. Also if trim=True and setRoundingPrecision=-1 are set, then the shortest representation which uniquely identifies the floating-point number can be used.

See numpy's format_float_positional see how they implemented their interface.

To see how this matters with shapely and numpy 1.14.2, see this demo (adapted from Shapely issue#586):

```import numpy as np
from shapely.wkt import dumps
from shapely.geometry import Point

p = Point(527626.93, 0.00)

# Using GEOS' WKTWriter -- takes up more space than is necessary
print(p.wkt)  # POINT (527626.9300000001 0)
# not sure what's going on here..
print(dumps(p, trim=True, rounding_precision=4))  # POINT (5.276e+005 0)

# Numpy's Dragon4 decimal formatter
pa = np.array(p)
print(np.format_float_positional(pa[0])) # 527626.93

# show that the binary representation is the same:
print(np.float64('527626.9300000001').tostring())
print(np.float64('527626.93').tostring())
# both show '\xc3\xf5(\xdc\x15\x1a A'

# getting fancy  -- this should be the default output with trim=True
print('POINT (' + ' '.join([np.format_float_positional(x, trim='-') for x in pa]) + ')')
# POINT (527626.93 0)
```

### comment:1 by Mike Taves, 6 years ago

Probably a better double -> string library is Google's double-conversion a.k.a. libdouble-conversion-dev, as it is in widespread use (e.g. V8, Firefox, etc.). Examples are in (e.g.) test/cctest/test-conversions.cc

### comment:2 by robe, 6 years ago

Milestone: GEOS Future → GEOS Fund Me

Milestone renamed

### comment:3 by Paul Ramsey <pramsey@…>, 3 years ago

Resolution: → fixed new → closed

In 2376cd6/git:

Change setTrim(true) mode to be positional, as users expect, using the ryu library to generate the shortest positionally limited string formats. For setTrim(false) continue to use C++ std::fixed format. Closes #868.

Note: See TracTickets for help on using tickets.