рдкрд╛рд░рдВрдкрд░рд┐рдХ рд╕рдВрдХреЗрддреЛрдВ рдХреЗ рд╕рд╛рде рд╣рд╛рд░реНрдб рдЪреАрдЧреЛрдВрдЧ рдпрд╛ рдЖрдкрдХреЛ рдЬреНрдпрд╛рдорд┐рддрд┐ рдЬрдирд░реЗрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ


рдХреНрдпрд╛ рдирдХреНрд╢реЗ рдкрд░ рдкреНрд░рддреАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдЧреНрд░рд╛рд╣рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рдЖрдкрдХреЗ рд▓рд┐рдП рдЕрд╡рд╛рд╕реНрддрд╡рд┐рдХ рд▓рдЧрддреА рд╣реИрдВ? рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рд╕реАрдЦреЗрдВрдЧреЗ рдХрд┐ рдЕрдкрдиреЗ рдХрдВрдбреАрд╢рдирд░ рдХреЛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреНрдпрд╛рдорд┐рддрд┐ рдЬрдирд░реЗрдЯрд░, рдХреНрдпреВрдЬреАрдЖрдИрдПрд╕ рдФрд░ рдкрд╛рдпрдерди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВред


рдкрд░рд┐рдЪрдп


! , , , , , 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], --  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 (/), тАФ . , , . , . , :


рдбрд┐рдЧреНрд░реА рдореЗрдВ рдмрдлрд░


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


рдЫреЗрдж рдмрд╣реБрднреБрдЬ


, .


, , /? , :


рд╕рдорд╛рдирд╛рдВрддрд░ рд╣реИрдЪрд┐рдВрдЧ


┬л┬╗ , ? , , .


┬л┬╗, ?


, , . , , .


рдЬрдирд░реЗрдЯрд░ рд▓рдЧрднрдЧ рдЕрд╕реАрдорд┐рдд рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рдХреЗрд╡рд▓ рдкреНрд░рджрд░реНрд╢рди рддрдХ рд╣реА рд╕реАрдорд┐рдд рд╣реЛрддреА рд╣реИрдВ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬрдЯрд┐рд▓ рдкрд╛рд░рдВрдкрд░рд┐рдХ рд╕рдВрдХреЗрдд рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдирд┐рд╡рд╛рд░реНрдп рдЙрдкрдХрд░рдг рд╣реИрдВред


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


рд╕рдВрджрд░реНрдн



All Articles