8

I have a gpkg file and I am changing the geometry to wkt format by using expression geom_to_wkt( $geometry ) in the Field Calculator.

The output looks like this in the image. The geometry type is not written in capital letters and the polygon is not closed as WKT format is defined here http://giswiki.org/wiki/Datei:Geometrietypen_im_WKT-Format.jpg.

Am I doing something wrong?

enter image description here

  • You could try importing that into QGIS as WKT and see if it works? – TeddyTedTed Jan 13 at 15:56
  • 3
    The geometry type does not need to be written in capital letters. But of course, the wkt string should have closing coordinates. I just tested myself in 3.16.1 on win10 64bit version and geom_to_wkt($geometry) adds these coordinates. Which version do you use? Possibly a bug. – MrXsquared Jan 13 at 16:04
  • I am in 3.10.13 – Nil Jan 13 at 16:07
  • I tested it 3.12. and the same problem occurs there as well. – Nil Jan 13 at 16:13
  • Works fine for me on 3.10.12 as well. Are you on windows 10 64bit? If you have a chance, try the latest non-ltr. If the issue still remains, I'd open a bug report. Meanwhile you could use some fancy expressions to rebuild the correct WKT-String... – MrXsquared Jan 13 at 16:16
7

The geometry type does not need to be written in capital letters. But of course, the wkt string should have closing coordinates. Seems like a bug to me as on Windows 64bit version of 3.16.2 and 3.10.12 I get closing coordinates when using geom_to_wkt($geometry).

However, as stated by Kadir Şahbaz, QGIS should be able to work without. However, just to complete this in case you need the closing coordinate, here is a fancy workaround:

'Polygon((' || -- start wkt string
array_to_string(
array_foreach( -- Go throuth every element of the following array
    string_to_array(geom_to_wkt(nodes_to_points($geometry)),','), -- Create the array of WKT information splitted by comma [ 'MultiPoint ((0.2974026 51.8987013)', '(0.00909091 51.50… ]
        x(make_point( -- Create a point geometry for every array content
            to_real(if(
                length(regexp_substr( -- Only create X coordinate if
                    regexp_substr(@element,'\\d.*\\d.[0-9]'),'([^ ]+)'))>0, -- everything between the Brackets of 'MultiPoint ((0.2974026 51.8987013)' before the whitespace '0.2974026' is not empty like ''
                    to_real(regexp_substr(regexp_substr(@element,'\\d.*\\d.[0-9]'),'([^ ]+)')), -- Extract the X coordinate of 'MultiPoint ((0.2974026 51.8987013)' --> 0.2974026
                    NULL -- If invalid coordinate use NULL, maybe replace with 0
            )),
            to_real(if(
                length(regexp_substr( -- Only create Y coordinate if
                    regexp_substr(@element,'\\d.*\\d.[0-9]'),'(?<=\\s).*'))>0, --  everything between the Brackets of 'MultiPoint ((0.2974026 51.8987013)' after the whitespace '51.8987013' is not empty like ''
                    to_real(regexp_substr(regexp_substr(@element,'\\d.*\\d.[0-9]'),'(?<=\\s).*')), -- Extract the Y coordinate of 'MultiPoint ((0.2974026 51.8987013)' --> 51.8987013
                    NULL -- If invalid coordinate use NULL, maybe replace with 0
            ))
        ))
|| ' ' || -- separator between x and y coordinates
        y(make_point( -- Create a point geometry for every array content
            to_real(if(
                length(regexp_substr( -- Only create X coordinate if
                    regexp_substr(@element,'\\d.*\\d.[0-9]'),'([^ ]+)'))>0, -- everything between the Brackets of 'MultiPoint ((0.2974026 51.8987013)' before the whitespace '0.2974026' is not empty like ''
                    to_real(regexp_substr(regexp_substr(@element,'\\d.*\\d.[0-9]'),'([^ ]+)')), -- Extract the X coordinate of 'MultiPoint ((0.2974026 51.8987013)' --> 0.2974026
                    NULL -- If invalid coordinate use NULL, maybe replace with 0
            )),
            to_real(if(
                length(regexp_substr( -- Only create Y coordinate if
                    regexp_substr(@element,'\\d.*\\d.[0-9]'),'(?<=\\s).*'))>0, --  everything between the Brackets of 'MultiPoint ((0.2974026 51.8987013)' after the whitespace '51.8987013' is not empty like ''
                    to_real(regexp_substr(regexp_substr(@element,'\\d.*\\d.[0-9]'),'(?<=\\s).*')), -- Extract the Y coordinate of 'MultiPoint ((0.2974026 51.8987013)' --> 51.8987013
                    NULL -- If invalid coordinate use NULL, maybe replace with 0
            ))
        ))
)
,', ') -- Split node coordinates from the array to a string separated by comma and whitespace
|| ', ' || x(point_n($geometry,1)) || ' ' || y(point_n($geometry,1)) -- re-add the first vertex-coordinates and add it as closing-coordinates
|| '))' -- Add closing brackets
  • 2
    You are right. Considering QGIS must provide a proper WKT string to other programs/libraries, it must be a bug. – Kadir Şahbaz Jan 13 at 18:08
7

WKT is case-insensitive for definition of geometry (Reference) and QGIS accepts the WKT string without the first and last point being the same.

For example:

geom_from_wkt( 'Polygon ((27 52, 31 37, 18 21))' )

and

geomWkt = QgsGeometry.fromWkt('Polygon ((27 52, 31 37, 18 21))')

work.

From documentation:

Note that unlike some programs, QGIS will close the ring for you so there is no need to duplicate the first point as the last.

  • 1
    I don't think that applies to WKT which is a standard – Ian Turton Jan 13 at 18:30
  • @IanTurton It also applies to WKT which is a standard. Please review the reference in the answer. – Kadir Şahbaz Jan 18 at 23:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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