Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
224 changes: 222 additions & 2 deletions docs/user_manual/processing_algs/qgis/vectorgeometry.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3849,12 +3849,232 @@ Python code

Lines to polygons
-----------------
Generates a polygon layer using as polygon rings the lines from an
input line layer.
Generates a polygon layer from line layer, considering LineString geometry with three
or more vertices as polygon rings. Input LineString geometry doesn't need to close a loop,
algorithm will automatically connect last to first point when forming a polygon.
Result is always promoted to MultiPolygon.
LineString geometry that have less than three vertices will produce
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(concerns the examples in the table also) Should we count in number of vertices or number of segments?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would count number of vertices - because when we use Identify tool on feature we get number of vertices, not number of segments.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @phidrho , "vertices" is also a term used in the log message - "One or more line ignored due to geometry not having a minimum of three vertices."

new polygon features with **EMPTY** MultiPolygon geometry, attributes are kept.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
new polygon features with **EMPTY** MultiPolygon geometry, attributes are kept.
new polygon features with **EMPTY** geometry.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know if this is just QGIS representation, or there is actually some information that generated geometry is indeed MultiPolygon:
image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code show us a MultiPolygon, but there is no need to repeat that information twice in the same description?

Copy link
Contributor Author

@phidrho phidrho May 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Selma, this two sentences describe different things. Let me try to explain:

Row 3855 explains that you will never get Polygon geometry as a result - it will always be MultiPolygon even when not needed - this is a decision made by developer and should be documented. Many results could be simple Polygons, but result is always promoted to MultiPolygon because then we would need two layers on output - Polygon layer and MultiPolygon layer for specific cases (see table below for difference between Polygon and MultiPolygon for the same geometry shape - they are pretty different in WKB (in database or on hard disk, while on screen they are identical). Although to casual QGIS user doesn't mean much - it is still different geometry type, just like Point and Polygon are different just on a different level. This sentence is very important because if user wants Polygons in final output he must additionally run native:multiparttosingleparts algorithm (rough estimation from AI - multipolygons are 5% larger in storage size compared to same geometry stored as polygons).

Row 3857 explains that result is EMPTY geometry - but technically there is no such thing as "EMPTY geometry", you can only have data-types (literally Point EMPTY, LineString EMPTY, Polygon EMPTY etc.) that are defined by standard, and if you want to parse them you need to know what to expect - Point EMPTY is very different from MultiPolygon EMPTY, see table:

Geometry Type WKT WKB (Hexadecimal)
POINT POINT EMPTY 01 01000000 000000000000F87F 000000000000F87F
POINT (1 2) 01 01000000 000000000000F03F 0000000000000040
MULTIPOINT MULTIPOINT EMPTY 01 04000000 00000000
MULTIPOINT ((1 2), (3 4)) 01 04000000 02000000 0101000000000000000000F03F0000000000000040 010100000000000000000008400000000000001040
LINESTRING LINESTRING EMPTY 01 02000000 00000000
LINESTRING (1 2, 3 4) 01 02000000 02000000 000000000000F03F 0000000000000040 0000000000000840 0000000000001040
MULTILINESTRING MULTILINESTRING EMPTY 01 05000000 00000000
MULTILINESTRING ((1 2, 3 4)) 01 05000000 01000000 010200000002000000000000000000F03F000000000000004000000000000008400000000000001040
POLYGON POLYGON EMPTY 01 03000000 00000000
POLYGON ((1 2, 3 4, 5 6, 1 2)) 01 03000000 01000000 04000000 000000000000F03F 0000000000000040 0000000000000840 0000000000001040 0000000000001440 0000000000001840 000000000000F03F 0000000000000040
MULTIPOLYGON MULTIPOLYGON EMPTY 01 06000000 00000000
MULTIPOLYGON (((1 2, 3 4, 5 6, 1 2))) 01 06000000 01000000 01030000000100000004000000000000000000F03F00000000000000400000000000000840000000000000104000000000000014400000000000001840000000000000F03F0000000000000040

So, because of technical reasons I would like to keep name MultiPolygon EMPTY whenever we are explaining output. That's at least how I would write documentation - so that it is technically correct and exact, if this is not practice in QGIS User Guide, or if you consider this overkill we can remove this and keep only "EMPTY" geometry, I'm not against it by any mean. Please let me know your final decision.

P.S. I've been personally through these problems before - trying to parsing binary geometry in PHP (I didn't have any good library to parse this for me) - so - in this type of cases it is very useful to know whether should you expect MULTIPOLYGON (((0 0, 0 0, 0 0, 0 0))) or MULTIPOLYGON EMPTY data-type, or possibly even more problematic POINT EMPTY.


The attribute table of the output layer is the same as the one of
the input layer.
Comment on lines 3859 to 3860
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The attribute table of the output layer is the same as the one of
the input layer.
Attributes of the input line feature are ALWAYS kept in the output polygon geometry.

And then I wonder if we need to repeat it for every example below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add this new sentence to new PR, but I would like to keep it repeated for every example.
Why? Because of users who do not read documentation thoroughly but are more of a "visual persons" and want to see examples immediately. Me personally is one of these persons - I would jump straight to examples - probably without reading entire description properly. But I also agree with you that's not needed redundancy - please make a decision and I'll fix it the way it should be.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t have a strong opinion on this, but I’m concerned that if we adopt this kind of repetition for every example in every algorithm (we will probably add more examples in the future) it could lead to a lot of unnecessary text in the documentation?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, once we get a final description. I think this should be suggested to code repo...


Examples
........

Lines to polygons on linestrings
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note: I think the titles “Lines to polygons on lines” vs “...on linestrings” could be a bit confusing, especially for users who aren’t deeply familiar with GIS geometry types (as you mentioned someone with a CAD background). Since both examples use LineString inputs, maybe we could rephrase the titles to reflect the real difference, like “with two points” vs “with three or more points” or “simple vs complex LineStrings”?
Might also be worth adding a short intro sentence before each table to explain the behavior upfront (e.g. that lines with only two points will result in empty polygons)...

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Features with 3 or more vertices are expected on input: **start point - vertex/vertices - end point**
Comment on lines +3866 to +3869
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first example contradicts this statement. And as I suggest later, I'd just merge concept of single and multiline segments together

Suggested change
Lines to polygons on linestrings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Features with 3 or more vertices are expected on input: **start point - vertex/vertices - end point**

Copy link
Contributor Author

@phidrho phidrho May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I am aware that first example is opposite of description, but as noted in previous comment it's for people who will immediately jump to examples. My logic is to prove the opposite - just like in math - this is an example how algorithm works - and it is only example that show that in this case algorithm will have an output visible in attribute table only, with EMPTY geometry so it does fit in this table since output does exist it is not rejected.

I didn't merge examples from single segment lines and multi segment lines because the first table explains how algorithm works and it's much more important, and second table is like an appendix for users that are coming from CAD background and finding name of algorithm - "lines to polygons" confusing. The second table could be dismissed at all, but I would like to keep it separate because I find it important for understanding how algorithm works in these cases.

Copy link
Contributor Author

@phidrho phidrho May 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ADDITIONAL NOTES:

  1. first example from second table with examples (appendix - as I call it) is also to avoid possible bug reports for this case, where a user might be confused why the algorithm doesn't work - it is not obvious in normal conditions (see image below) - and if not documented with example image could possibly be hard to determine cause of behavior (imagine thousands of features on input):
  • same layer, lines look exactly the same

image

image

  1. second example from second table is overkill, I agree, but it is very important for connection with description of Polygonize algorithm - user then can see clearly that this algorithm is not what he/she needs - and we have a "see also" note where he/she can jump to Polygonize algorithm and then user can see there an example that on the same input - algorithm produces polygon for this case
  • same case, example that will be in Polygonize algorithm documentation:

image


So both of these examples are intended for better user experience and not directly for describing algorithm so I moved them to another table/section.


.. list-table::
:header-rows: 1
:widths: 30 30 40

* - INPUT
- OUTPUT
- NOTE

* - **Feature a**: Single line LineString

.. figure:: img/lines_to_polygons_from_linestr_input_1.png
:width: 25 em
:align: center

LineString with two vertices

- **Feature a**: MultiPolygon EMPTY

.. figure:: img/lines_to_polygons_from_linestr_output_1.png
:width: 25 em
:align: center

Output doesn't contain geometry

- | Algorithm creates one new feature with empty geometry, but with all attributes from source feature.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does the | character stand for?

Copy link
Contributor Author

@phidrho phidrho May 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used these to force empty newline/paragraph on rendering - some kind of codeblock, no affect on rows with text, see images:
image

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this it's converted to single newline.

image
image

|
| **Output has a valid (empty) geometry.**

* - **Feature b**: LineString with three vertices
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the number of vertice/segments matters? It is more the situation of a not closed linestring with more than one segment, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linestring doesn't need to be closed. Algorithm always assume vertices are closing a loop - that's why I included example as open linestring with three vertices. I have also tried some other examples when all three vertices lie on same line but these are special cases, and I think that I decided to discard these examples.


.. figure:: img/lines_to_polygons_from_linestr_input_2.png
:width: 25 em
:align: center

Open LineString with three vertices

- **Feature b**: MultiPolygon

.. figure:: img/lines_to_polygons_from_linestr_output_2.png
:width: 25 em
:align: center

Output is a triangle shaped MultiPolygon

- | Algorithm creates one new feature as MultiPolygon with one part, with all attributes from source feature.
|
| **Output has a valid geometry.**

* - **Feature c**: LineString with four vertices

.. figure:: img/lines_to_polygons_from_linestr_input_3.png
:width: 25 em
:align: center

Closed loop LineString with four vertices
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these 4 or 5 vertices? Anyway, maybe the number doesn't matter, just the fact that it is a closed linestring?

Suggested change
Closed loop LineString with four vertices
Closed loop LineString

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, thanks, I have set your version for new PR.


- **Feature c**: MultiPolygon

.. figure:: img/lines_to_polygons_from_linestr_output_3.png
:width: 25 em
:align: center

Output is a quadrilateral shaped MultiPolygon
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it would not necessarily be quadrilateral then

Suggested change
Output is a quadrilateral shaped MultiPolygon
Output is a shaped MultiPolygon

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I have set your version for new PR.


- | Algorithm creates one new feature as MultiPolygon with one part, with all attributes from source feature.
|
| **Output has a valid geometry.**

* - **Feature d**: MultiLineString with two parts

.. figure:: img/lines_to_polygons_from_linestr_input_4.png
:width: 25 em
:align: center

Valid MultiLineString with two parts

- **Feature d**: MultiPolygon with two parts

.. figure:: img/lines_to_polygons_from_linestr_output_4.png
:width: 25 em
:align: center

Two parts MultiPolygon with invalid geometry

- | Algorithm creates one new feature as MultiPolygon with two parts, all attributes from source feature are kept.

.. warning:: **Output geometry is invalid!**

MultiPolygon parts should not intersect.
Comment on lines +3958 to +3960
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.. warning:: **Output geometry is invalid!**
MultiPolygon parts should not intersect.
.. warning:: Output geometry is invalid, as MultiPolygon parts should not intersect.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I split these two to render them as header and a description, but I can make it all header as you proposed, please confirm what version do you like better (on image it is my version):
image


.. tip:: **Options for fixing intersecting parts of MultiPolygon invalid geometry**

This can be fixed by using :ref:`qgisfixgeometries` algorithm with two possible scenarios:

1. *Fixing by structure repair method* - two parts will dissolve into MultiPolygon geometry with one part
2. *Fixing by linework repair method* - equal to symmetrical difference of two parts which results MultiPolygon geometry with one part (doughnut shape in this case)

* - | **Feature e**: LineString
| **Feature f**: LineString

.. figure:: img/lines_to_polygons_from_linestr_input_5.png
:width: 25 em
:align: center

Two distinct LineStrings, one geometrically contained inside another
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(here and below) Are LineString and MultiPolygon (written with that casing) pluralizable? How about

Suggested change
Two distinct LineStrings, one geometrically contained inside another
Two distinct line features, one geometrically contained inside another


- | **Feature e**: MultiPolygon
| **Feature f**: MultiPolygon
Comment on lines +3978 to +3979
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this render in HTML?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems that this forces a paragraph in rendering, without it, it would all be in same line:
image

and by adding new line they these two rows are too close in my opinion, see images:
image
image

I would like to keep my version if you agree.


.. figure:: img/lines_to_polygons_from_linestr_output_5.png
:width: 25 em
:align: center

Output are two single part MultiPolygons

- | Algorithm creates two new features as MultiPolygons, each having one part, each of them kept all attributes from source features.
|
| **Output has a valid geometry.**

* - **Feature g**: LineString

.. figure:: img/lines_to_polygons_from_linestr_input_6.png
:width: 25 em
:align: center

LineString in wave form

- **Feature g**: MultiPolygon

.. figure:: img/lines_to_polygons_from_linestr_output_6.png
:width: 25 em
:align: center

Single part MultiPolygon with invalid geometry

- | Algorithm creates one new feature as MultiPolygon with one self-intersecting part, all attributes from source feature are kept.

.. warning:: **Output geometry is invalid!**

MultiPolygon part should not self-intersect.

.. tip:: **Options for fixing self-intersection parts of MultiPolygon invalid geometry**

This can be fixed by using :ref:`qgisfixgeometries` algorithm:

1. *Fixing by structure repair method* or
2. *Fixing by linework repair method*

In both cases, self-intersecting part will be splitted into two individual parts

Lines to polygons on lines
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO this subsection is unnecessary. It repeats the example a. We just need to clearly state that the alg processes line by line, one feature at a time.
Or we could reuse the first example (next to a) to show that connected single segment features behave same as one segment feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my comment on first example.

^^^^^^^^^^^^^^^^^^^^^^^^^^

Features with less than 3 vertices: **start point - end point**

.. list-table::
:header-rows: 1
:widths: 30 30 40

* - INPUT
- OUTPUT
- NOTE

* - | **Feature b**: LineString with two vertices
| **Feature c**: LineString with two vertices

.. figure:: img/lines_to_polygons_from_lines_input_1.png
:width: 25 em
:align: center

Two geometrically connected line features.

- | **Feature b**: MultiPolygon EMPTY
| **Feature c**: MultiPolygon EMPTY

.. figure:: img/lines_to_polygons_from_lines_output_1.png
:width: 25 em
:align: center

Output features do not contain geometry.

- | Algorithm creates two new features with empty geometry, each containing all attributes from their source features.
|
| **Output has a valid (empty) geometry.**

* - | **Features d, e, f, g**: LineStrings with two vertices

.. figure:: img/lines_to_polygons_from_lines_input_2.png
:width: 25 em
:align: center

Four geometrically connected line features forming a closed loop.

- | **Feature d**: MultiPolygon EMPTY
| **Feature e**: MultiPolygon EMPTY
| **Feature f**: MultiPolygon EMPTY
| **Feature g**: MultiPolygon EMPTY

.. figure:: img/lines_to_polygons_from_lines_output_2.png
:width: 25 em
:align: center

Output features do not contain geometry.

- | Algorithm creates four new features with empty geometry, each containing all attributes from their source features.
|
| **Output has a valid (empty) geometry.**

**Default menu**: :menuselection:`Vector --> Geometry Tools`

.. seealso:: :ref:`qgispolygonstolines`, :ref:`qgispolygonize`, :ref:`qgisconvertgeometrytype`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines are part of the alg description and should be kept out of the example section. To move above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my comment on first example.

Expand Down
Loading