
рдХреНрдпрд╛ рдирдХреНрд╢реЗ рдкрд░ рдкреНрд░рддреАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдЧреНрд░рд╛рд╣рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрд╡рд╛рд╕реНрддрд╡рд┐рдХ рд▓рдЧрддреА рд╣реИрдВ? рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рд╕реАрдЦреЗрдВрдЧреЗ рдХрд┐ рдЕрдкрдиреЗ рдХрдВрдбреАрд╢рдирд░ рдХреЛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреНрдпрд╛рдорд┐рддрд┐ рдЬрдирд░реЗрдЯрд░, рдХреНрдпреВрдЬреАрдЖрдИрдПрд╕ рдФрд░ рдкрд╛рдпрдерди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВред
рдкрд░рд┐рдЪрдп
! , , , , , QGIS Python PyQt. , , () . QGIS , geometry generator тАФ . . , .
┬л┬╗ ?
QGIS MVC . , .. , Model-Based PyQt . , . , .
QGIS:

?
99% . ! , (, ), (, ), , .
, :

┬л┬╗ :

. , , , ( ). QGIS Python.
, , -, , , , (!) , , ! , .
- QGIS 3.10.6 Ubuntu 18.04.
- ┬л┬╗ UTM 37N, .
- GitHub .
- ┬л┬╗ , .
- , , , .
geometry generator
тАФ .
, : /, /, /. , , , , . : , , .
┬л┬╗?
, , (expression), . Expressions, Python Expressions, Filtering and Calculating Values.
, , . тАФ , . Python, . QGIS. , a .
: . - , .
, , QGIS, , , , . . .
...
, .
, ( , ), , , , , , :

: , , ; , , тАФ , . points.
geometry_n()
, :
geometry_n($geometry, 1)
$geometry
тАФ , .
, :
if(
@geometry_part_num > 1,
geometry_n($geometry, @geometry_part_num ),
NULL
)
, if()
тАФ . 2 @geometry_part_num
, , ( @
). NULL
. , , , .
тАФ , :
if(
@geometry_part_num > 1,
with_variable(
'inputs',
array(
10000,
length(
make_line(
start_point($geometry),
geometry_n($geometry, @geometry_part_num)
)
),
azimuth(
geometry_n($geometry, @geometry_part_num),
start_point($geometry)
)
),
if(
@inputs[0] < @inputs[1],
make_line(
geometry_n($geometry, @geometry_part_num),
project(
geometry_n($geometry, @geometry_part_num),
@inputs[1] - @inputs[0],
@inputs[2]
)
),
NULL
)
),
NULL
)
. , , , NULL
.
тАФ . , . , . , .
with_variable()
, : , , . , - , with_variable
, . .
тАФ inputs
array()
тАФ 0. тАФ , . тАФ , :
...
length(
make_line(
start_point($geometry),
geometry_n($geometry, @geometry_part_num)
)
),
azimuth(
geometry_n($geometry, @geometry_part_num),
start_point($geometry)
)
...
length()
, , make_line()
тАФ start_point($geometry)
, ( ). azimuth()
, !
, . if()
, , . @inputs
, , ┬л┬╗ NULL
.
:
...
make_line(
geometry_n($geometry, @geometry_part_num),
project(
geometry_n($geometry, @geometry_part_num),
@inputs[1] - @inputs[0],
@inputs[2]
)
)
...
project()
, , . , .
, Klas Karlsson, QGIS. , , , , :

, . , WKT , , ┬л||┬╗, . , , . :
( lines1). , :
:
collect_geometries(
array_foreach(
generate_series(1, num_points($geometry)),
point_n($geometry, @element)
)
)
┬л┬╗ . . generate_series()
, () 1 num_points($geometry)
, . . . array_foreach()
. array_foreach
, point_n($geometry, @element)
, . . (point_n()
тАФ ), @element
тАФ . , . тАФ , collect_geometries()
. ( ).
. ┬л/┬╗. :
with_variable(
'minimal_length',
7000.0,
collect_geometries(
array_foreach(
generate_series(1, num_points($geometry) - 1),
with_variable(
'inputs',
array(
azimuth(
point_n($geometry, @element),
point_n($geometry, @element + 1)
),
length(
make_line(
point_n($geometry, @element),
point_n($geometry, @element + 1)
)
)
),
if(
@inputs[1] - @minimal_length * 2 > 0,
line_substring(
make_line(
point_n($geometry, @element),
point_n($geometry, @element+1)
),
@minimal_length, @inputs[1] - @minimal_length
),
geom_from_wkt('LINESTRING EMPTY')
)
)
)
)
)
, . @minimal_length
. collect_geometries
, array_foreach
, . , , @inputs
: .
. , @minimal_length
( ). , , :
geom_from_wkt('LINESTRING EMPTY')
, , NULL
, . , . WKT ┬лLINESTRING EMPTY┬╗, WKT QGIS geom_from_wkt()
.
. line_subtring()
, . , .
? , , . (. lines2).
, buffer()
, : , 1. .. :

, .

, , , . , . , . :
with_variable(
'distance',
4000,
with_variable(
'offset_lines',
array(
extend(
offset_curve($geometry, @distance, join:=2),
@distance, @distance
),
extend(
offset_curve($geometry, -@distance, join:=2),
@distance, @distance
)
),
collect_geometries(
@offset_lines[0],
@offset_lines[1],
make_line(
start_point(@offset_lines[0]),
start_point(@offset_lines[1])
),
make_line(
end_point(@offset_lines[0]),
end_point(@offset_lines[1])
)
)
)
)
, with_variable
, , , . . @offset_lines
, , ( offset_curve()
), extend()
. , тАФ start_point()
тАФ end_point()
.
тАФ , тАФ
, , . (. lines3). , :
with_variable(
'lines',
segments_to_lines($geometry),
collect_geometries(
array_foreach(
generate_series(2, num_geometries(@lines), 2),
geometry_n(@lines, @element)
)
)
)
segments_to_lines()
, тАФ , . , generate_series
. :

. , ( poly2).

┬л/┬╗ :
with_variable(
'points_num',
num_points($geometry) - 1,
collect_geometries(
array_foreach(
generate_series(1, round(@points_num / 2.0)),
make_line(
point_n(
$geometry,
@element
),
point_n(
$geometry,
@element + floor(@points_num / 2.0)
)
)
)
)
)
┬л┬╗ , generate_series()
. .
, ( poly3):

:
collect_geometries(
array_foreach(
generate_series(1, num_points($geometry) - 1),
make_line(
centroid($geometry),
point_n($geometry, @element)
)
)
)
, centroid()
, , , .
тАФ poly4. , , ┬л┬╗, . ┬л┬╗ тАФ , , , . :

, , . . . , :
with_variable(
'lines',
segments_to_lines($geometry),
collect_geometries(
array_foreach(
segments_between_sides_nums(
array_foreach(
generate_series(1, num_geometries(@lines)),
array(
@element,
length(
geometry_n(@lines, @element)
)
)
)
),
geometry_n(@lines, @element)
)
)
)
, . , , .
segments_between_sides_num()
. QGIS Python ( custom.py ~/.local/share/QGIS/QGIS3/profiles/default/python/expressions):
@qgsfunction(args="auto", group="")
def segments_between_sides_nums(sides, feature, parent):
"""
.
sides - ( , )
"""
sorted_sides = sorted(sides, key=lambda x: x[1])
return list(range(int(sorted_sides[0][0]) + 1, int(sorted_sides[1][0])))
Python , .. ( ), .
. , Python?
, : QGIS Python? . , .
create_poly_lyr.py, ( ).
Python, QGIS, Python. expression_benchmarking.py:
EXPRESSION = """
collect_geometries(
array_foreach(
generate_series(1, num_points($geometry)),
make_line(
centroid($geometry),
point_n($geometry, @element)
)
)
)
"""
тАж
for counter, poly in enumerate(lyr_polys.getFeatures()):
exp = QgsExpression(EXPRESSION)
context = QgsExpressionContext()
context.setFeature(poly)
star = exp.evaluate(context)
python_benchmarking.py:
for counter, poly in enumerate(lyr_polys.getFeatures()):
centroid = QgsPoint(poly.geometry().centroid().asPoint())
star = QgsMultiLineString()
for vertex in poly.geometry().vertices():
line = QgsLineString(centroid, vertex)
star.addGeometry(line)

Python 5,3 , 23,16 . Python 4,5 . , , , .
:
- . ┬л┬╗ , , ┬л- 1┬╗ , Python, .
- QGIS, . . , .
:
Python:
Python:
- () *.py .
- Python , .
- Python, , ( Windows).
, QGIS . , , , , . , ┬л┬╗ Python.
? .
: WGS84 (/), тАФ . , , . , . , :

: , , . , . poly3 ┬л┬╗ :

, .
, , /? , :

┬л┬╗ , ? , , .
┬л┬╗, ?
, , . , , .
рдЬрдирд░реЗрдЯрд░ рд▓рдЧрднрдЧ рдЕрд╕реАрдорд┐рдд рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рдХреЗрд╡рд▓ рдкреНрд░рджрд░реНрд╢рди рддрдХ рд╣реА рд╕реАрдорд┐рдд рд╣реЛрддреА рд╣реИрдВ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬрдЯрд┐рд▓ рдкрд╛рд░рдВрдкрд░рд┐рдХ рд╕рдВрдХреЗрдд рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдирд┐рд╡рд╛рд░реНрдп рдЙрдкрдХрд░рдг рд╣реИрдВред
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд▓реЗрдЦ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛, рдФрд░ рд╣рдо рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдЬрдЯрд┐рд▓ рдорд╛рдорд▓реЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдзрдиреНрдпрд╡рд╛рджред
рд╕рдВрджрд░реНрдн