1

What I would like to achieve:

A polygon feature, where the location (x,y) of one vertice ("anchor vertice") is defined by two attributes, attr_x and attr_y. The remaining vertices should be calculated relative to the "anchor vertice"

Example of a triangle: attr_x = 0 attr_y = 0

(attr_x , attr_y ) (attr_x +2 ,attr_y + 0) (attr_x + 2, attr_y +2) The location of the vertices are then (0,0) (2,0) (2,2)

If I change the attr_x and attr_y the locations of the triangle's vertices will change, relative the "anchor vertice".

Is this possible to do within QGIS?

I think my question is similar to this:

QGIS. Polygon vertices automatic bind to WFS point features

6
  • So, you want to calculate a geometry based on one point? Are the sides always the same length? Is there always the same number of sides? Will the starting point change later on? How will it be changed?
    – Erik
    Nov 22, 2021 at 9:17
  • Yes, I want to calculate a geometry based on one point. The sides always the same length. There is always the same number of sides. Starting point ("anchor point") will change later on, by change in the attribute table. Nov 22, 2021 at 9:50
  • If it is just for visualisation or do you need the polygons as an independent layer? Nov 22, 2021 at 9:52
  • I would prefer as an independent layer (for export reasons) Nov 22, 2021 at 9:58
  • Well, then it gets complicated.
    – Erik
    Nov 22, 2021 at 9:59

2 Answers 2

2

Here is a sample python code you can use. Starting scenario is that you have two layers points and polygons. After you create a new PointFeature you need to run the python script which will first drop all existing PolygonFeatures and then create a PolygonFeature at every point location using theadd_x and add_y constants. I am using EPSG:3857 so these values are meters.

# Access Point Layer
points = QgsProject.instance().mapLayersByName('points')[0]

# Access Polygon Layer and create Data Provider
polygons = QgsProject.instance().mapLayersByName('polygons')[0]
pr = polygons.dataProvider() 

# Clear all polygons first so they get recreated after point updates
# See: https://gis.stackexchange.com/questions/215530/deleting-all-features-of-a-vector-layer-in-pyqgis
with edit(polygons):
    listOfIds = [feat.id() for feat in polygons.getFeatures()]
    polygons.deleteFeatures( listOfIds )

# Loop each point feature and create polygons
# Constants in meter (EPSG:3857)
add_x = 10000
add_y = 10000

for feature in points.getFeatures():
    # Create Polygon around each anchor point
    # See: https://gis.stackexchange.com/questions/86812/how-to-draw-polygons-from-the-python-console/86901
    
    # Init polygon feature
    poly = QgsFeature()
    
    # Create p1 (anchor point)
    p1X = feature.geometry().asPoint().x()
    p1Y = feature.geometry().asPoint().y()
    p1 = QgsPointXY(p1X, p1Y)
    
    # Create p2
    p2 = QgsPointXY(p1X, p1Y)
    p2.setX(p2.x() + add_x)
    
    # Create p3
    p3 = QgsPointXY(p1X, p1Y)
    p3.setX(p3.x() + add_x)
    p3.setY(p3.y() + add_y)
    
    # Create polygon
    poly_points_array = [p1, p2, p3]
    poly_geometry = QgsGeometry.fromPolygonXY([poly_points_array])
    polygon = QgsFeature()
    polygon.setGeometry(poly_geometry)
    
    # Add polygon feature
    pr.addFeature(polygon)
    

enter image description here

2

Thin can easily be done using QGIS expressions. To get a layer with actual geometries, use Menu Processing / Toolbox / Geomtry by expression (see here for details) and an expression like this (see first screenshot):

make_triangle( 
    make_point ( "attr_x" ,  "attr_y" ),
    make_point ( "attr_x"+2,  "attr_y" ),
    make_point ( "attr_x"+2 ,  "attr_y" +2)
)

By the way: If you create the fields attr_x and attr_y as virtual fields with the expression $x and $y respectively, whenever you set a point, it's attributes will get updated to the current x-/y-coordinates.

To get any kind of polygon, use an expression like this (see second screenshot):

make_polygon( 
    make_line (
        make_point ( "attr_x" ,  "attr_y" ),
        make_point ( "attr_x"+0.8,  "attr_y"+0.4 ),
        make_point ( "attr_x"+2 ,  "attr_y" ),
        make_point ( "attr_x"+1.3 ,  "attr_y"+0.4 ),
        make_point ( "attr_x"+1.5 ,  "attr_y"+1.5 ),
        make_point ( "attr_x"+2 ,  "attr_y" +2),
        make_point ( "attr_x"+1.2 ,  "attr_y" +1.6),
        make_point ( "attr_x"+0.2 ,  "attr_y" +1.6),
        make_point ( "attr_x" ,  "attr_y" +2),
        make_point ( "attr_x"+0.3 ,  "attr_y" +1.2),
        make_point ( "attr_x"+0.3 ,  "attr_y" +0.7)
    )
)

The blue triangle is created based on the red point's attributes attr_x and attr_y using the expression from above (here with Geometry generator, for demonstration purpose):

enter image description here

Screenshot 2: creating any kind of polygon, defined by a ring of vertices: enter image description here

1
  • This solution also worked for me, thanks Nov 25, 2021 at 8:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.