OGR Geometry changes Floating Points

492 views Asked by At

I'm creating a Polygon in OGR and adding coordinates to it in Python. It is a must that my coordinates aren't allowed to change when adding, however they do and I don't understand why. Here is my example:

import ogr
ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(12.5433, 54.10064)
ring.AddPoint(12.5433026066, 54.1006582464)
ring.AddPoint(12.543312311, 54.1006489082)
ring.AddPoint(12.5433093954, 54.1006320625)
ring.AddPoint(12.5433, 54.10064)

poly = ogr.Geometry(ogr.wkbPolygon)
poly.AddGeometry(ring)

polygon = poly.ExportToWkt()

Now if I print the polygon, I receive:

'POLYGON ((12.5433 54.10064 0,
           12.543302606599999 54.100658246400002 0,
           12.543312311 54.1006489082 0,
           12.5433093954 54.100632062499997 0,
           12.5433 54.10064 0))'

e.g.:

Example: (12.5433026066, 54.1006582464) to (12.543302606599999 54.100658246400002)

Clearly floating points have been added and I can't understand why. Help appreciated.

How did I do it? Because I only needed the WKT Format I concatenated a String:

a = [(12.5433, 54.10064),(12.5433026066, 54.1006582464),(12.543312311, 54.1006489082),(12.5433093954, 54.1006320625),(12.5433, 54.10064)]

polygon = str('POLYGON((')

for i in range(len(a)):
    polygon+= str(a[i][0])
    polygon+= str(' ')
    polygon+= str(a[i][1])
    polygon+= str(',')
    if i==len(a)-1:
        polygon+=str(a[0][0])
        polygon+=str(a[0][1])
        polygon+=str('))')

print polygon
1

There are 1 answers

4
Ffisegydd On BEST ANSWER

The problem is that when using the float type you cannot exactly represent some numbers. e.g.

In [47]: x = 0.4

In [48]: '{:.30f}'.format(x)
Out[48]: '0.400000000000000022204460492503'

and so when you store the number 12.5433026066 it actually is 12.543302606599999293734981620219.

Your poly.ExportToWkt() method is exporting these numbers with a given number of decimal places, which is why the 9999... are appearing at the end, they are part of the internal representation of your numbers.

Unfortunately, there's probably not much you can do to avoid this. If your package works with the decimal package then you could try using those. Using Decimal objects allows you to store the numbers exactly.

This offsite resource has some details of how floating point numbers are handled internally. The Python docs also have a guide on the limitations of floating point numbers.