
Scheinen Ihnen Kundenanforderungen an Symbole auf Karten unrealistisch? Außerdem erfahren Sie, wie Sie Geometriegenerator, QGIS und Python verwenden, um Ihre Conditioner optimal zu nutzen.
Einführung
! , , , , , 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 «» :

, .
, , /? , :

«» , ? , , .
«», ?
, , . , , .
Generatoren bieten nahezu unbegrenzte Möglichkeiten, genauer gesagt, die Möglichkeiten sind nur durch die Leistung begrenzt und ein unverzichtbares Werkzeug für die Erstellung wirklich komplexer herkömmlicher Zeichen.
Ich hoffe, dass der Artikel nützlich sein wird, und wir können im nächsten Artikel komplexe Fälle betrachten. Vielen Dank für Ihre Aufmerksamkeit.
Verweise