2

I have a PostGIS database with an geom-accurancy of 9 decimal places for X and 8 decimal places for Y.

Reading out the coordinates of an PostGIS-Polygon in PyQGIS shows:

import psycopg2
conn = psycopg2.connect('spb', 'postgres', 'postgres', 'localhost', 5433)
cur = conn.cursor()
sql = f"""SELECT ST_AsText(geom)
          FROM geom
          WHERE id = 19695"""
cur.execute(sql)
cur.fetchone()

# Output:
('MULTIPOLYGON(((349749.532007553 5575769.14298604,349777.370999882 5575792.32299964,349792.406197559 5575794.8902163,...)',)

But when I import the polygon from PostGIS as a layer in QGIS, and read out its coordinates afterwards, I see that QGIS "invents" new decimal places, 17 for X and Y.

uri = QgsDataSourceUri()
uri.setConnection("localhost", "5433", "spb", "postgres", "postgres")
uri.setDataSource ("public", "geom", "geom", "id = 19695")
vlayer = QgsVectorLayer(uri .uri(False), "geom", "postgres")
QgsProject.instance().addMapLayer(vlayer)

lyr = iface.activeLayer()
features = lyr.getFeatures()
for f in features:
    f.geometry()

# Output
<QgsGeometry: MultiPolygon (((349749.53200755297439173 5575769.14298603963106871, 349777.37099988199770451 5575792.32299964036792517, 349792.40619755897205323 5575794.89021630026400089,...>

So what QGIS is doing here? How can I prevent that QGIS "invents" non existing decimal places?

2
  • 3
    It is not possible to express a decimal number 349749.532007553 as a floating point number. You can test that for example with exploringbinary.com/floating-point-converter.
    – user30184
    Commented Feb 19, 2021 at 11:51
  • So f.geometry() returns a floating point number? How I can return a decimal number representation of the coordinates?
    – Vaiaro
    Commented Feb 19, 2021 at 15:16

1 Answer 1

2

In a PostGIS database, I create a new table and add as layer the sample in QGIS

CREATE TABLE to_delete AS
SELECT 1, ST_SetSrid(ST_GeomFromText('MULTIPOLYGON(((349749.532007553 5575769.14298604,349777.370999882 5575792.32299964,349792.406197559 5575794.8902163, 349749.532007553 5575769.14298604)))'), 3857) AS geom;

Due to comment feedback by @user30184

It is not possible to express a decimal number 349749.532007553 as a floating point number.

You can check it's fine also in QGIS, it's just the representation when printing the QGsGeometry returned by your f.geometry() that mislead you.

You will see it's fine when inspecting points coordinates from your polygons in below sample

# Explore coordinates infos precision
layer = iface.activeLayer()
for f in layer.getFeatures():
    geom = f.geometry()
    # print with the "wrong" precision
    print(geom)
    # if geom.type() == QgsWkbTypes.PolygonGeometry and geom.isMultipart():
    # below if is a shorter equivalent of above test
    if geom.wkbType() == QgsWkbTypes.MultiPolygon:
        vertices_iterators_parts = [i.vertices() for i in geom.parts()]
        for vertices_iterator in vertices_iterators_parts:
            for point in vertices_iterator:
                x = point.x()
                y = point.y()
                # print with the "right" precision
                print(x, y)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.