8

I have a point layer with two fields named "id" and "price", and a polygon layer with a field named "code_zone".

I need to get, for each polygon, the "id" of the point that has the highest value of "price", and this maximum value of the "price".

This is the beginning of my code:

for feature in layer_point.getFeatures():

   point_price = feature.attribute('price')
   point_geom = feature.geometry()

   for feat in layer_polygon.getFeatures():

      polygon_codeZone = feat.attribute('code_zone')
      polygon_maxValue = feat.attribute('max_value')
      polygon_geom = feat.geometry()

      if polygon_geom.contains(point_geom):
             ...

I tried with maximumValue(), but I get only the maximum value of the whole point layer and not the maximum value per polygon. What I am doing wrong?

As soon as I get these maximum values, I could fill them in my polygon layer with polygon_layer.changeAttributeValue() in the "max_value" field.

2 Answers 2

6
dpr = layer_polygon.dataProvider()
max_value_index = layer_polygon.fields().indexFromName('max_value')

for pol in layer_polygon.getFeatures():
    g = pol.geometry()
    req = QgsFeatureRequest(g.boundingBox()) # for performance
    prices = [p["price"] for p in layer_point.getFeatures(req) if g.contains(p.geometry())]
    dpr.changeAttributeValues({pol.id(): {max_value_index: max(prices)}})

enter image description here

1
  • A big thank you, it looks perfect. I will test that tomorrow.
    – Ismail
    Dec 12, 2019 at 13:24
6

The user of a SQL query is appropriate for your problem.

I created 2 tables: one with 2 polygons and another with 5 points.

enter image description here

Then I go to the database manager > Virtual layers > and open a SQL query window

I execute the following request :

--First part : For each polygon, the prices of all the points that are contained.
-- An identifier (fid) is generated for each polygon in descending order of price.

WITH all_price AS
 (SELECT row_number() over(partition by poly.id_poly  ORDER BY point.price DESC) as fid, 
 poly.id_poly, point.id, point.price
 FROM poly, point
 WHERE St_contains(poly.geometry,point.geometry)
 ORDER BY poly.id_poly, point.price)

 --When fid is equal to 1, it means that it is the highest price.
 SELECT all_price.id_poly, all_price.id, all_price.price
 FROM all_price 
 WHERE fid = 1

Result of the temporary table all_price on the left and the final result on the right. If you don't understand the request, I can give you more explanations.

enter image description here

1
  • Thank you man, I didn't try to use SQL to solve my problem. Kadir's solution looks quicker to set up and run, but I'll still do some tests with SQL tomorrow to see what happens
    – Ismail
    Dec 12, 2019 at 13:31

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.