# QGIS: Bind polygon feature location to attributes

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

• 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

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 the`add_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)

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)

# Create p3
p3 = QgsPointXY(p1X, p1Y)

# Create polygon
poly_points_array = [p1, p2, p3]
poly_geometry = QgsGeometry.fromPolygonXY([poly_points_array])
polygon = QgsFeature()
polygon.setGeometry(poly_geometry)

``````

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):

Screenshot 2: creating any kind of polygon, defined by a ring of vertices:

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