
マップ上のシンボルに対する顧客の要求は、あなたにとって現実的ではないように見えますか?さらに、ジオメトリジェネレーター、QGIS、Pythonを使用してコンディショナーを最高にする方法を学びます。
前書き
! , , , , , 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 «» :

, .
, , /? , :

«» , ? , , .
«», ?
, , . , , .
ジェネレーターはほとんど無限の可能性を提供します。より正確には、可能性はパフォーマンスによってのみ制限され、本当に複雑な従来の標識を作成するための不可欠なツールです。
この記事がお役に立てば幸いです。次の記事で複雑なケースを検討する場合があります。ご清聴ありがとうございました。
参考文献