Hartes Qigong mit herkömmlichen Zeichen oder warum Sie einen Geometriegenerator benötigen


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:


Beispielstile für Punkt, Linie und Polygon


?


99% . ! , (, ), (, ), , .


, :



«» :


"Zähne"


. , , , ( ). 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, , , , . . .


...


, .


, ( , ), , , , , , :


Ein Objekt mit unterschiedlichen Stilen.


: , , ; , , — , . 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. , , , , :


Route


, . , 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], --  1
            @offset_lines[1], --  2
            make_line( --     1   2
                start_point(@offset_lines[0]),
                start_point(@offset_lines[1])
            ),
            make_line( --     1   2
                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( --   Python
                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? . , .



  • test_poly 100000 , 3 20.

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:


  • .
  • Python.

Python:


  • () *.py .
  • Python , .
  • Python, , ( Windows).

, QGIS . , , , , . , «» Python.



? .


: WGS84 (/), — . , , . , . , :


Puffer in Grad


: , , . , . poly3 «» :


Lochpolygon


, .


, , /? , :


Parallele Schraffur


«» , ? , , .


«», ?


, , . , , .


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



All Articles