
Os requisitos do cliente para sĂmbolos nos mapas parecem irrealistas para vocĂȘ? AlĂ©m disso, vocĂȘ aprenderĂĄ como usar o gerador de geometria, QGIS e Python para tornar seus condicionadores os melhores.
Introdução
! , , , , , 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 «» :

, .
, , /? , :

«» , ? , , .
«», ?
, , . , , .
Os geradores oferecem possibilidades quase ilimitadas, mais precisamente, as possibilidades são limitadas apenas pelo desempenho e são uma ferramenta indispensåvel para a criação de sinais convencionais verdadeiramente complexos.
Espero que o artigo seja Ăștil e que possamos considerar casos complexos no prĂłximo artigo. Obrigado pela atenção.
ReferĂȘncias