1

I have a raster layer with the day of the year on which we observe temperature above 15 degrees. There are large differences (image below):

first

I have vectorized this layer based on the Band including the information on day of the year, and now I would like to dissolve these into two different polygons.

second

The two different areas, seen in the raster image, are adjacent to each other so they will never become two different polygons with the simple dissolve tool. However, the neighbouring pixels differ by more than 5 days, so I would like to dissolve these conditionally. More specifically, I would like to dissolve the individual vectorized pixel into one polygon if the neighbouring pixel does not differ with more than 5 days.

Is this possible in QGIS or eventually Python? If so, how?

EDIT:

According to Babel's comment, I potentially have to use aggregate. My data is relatively large - with lots of these "heat islands" ranging from day of the year 65 to 345.

  1. I want to aggregate/merge/join adjacent polygons if their values of the field doy are < 5.
  2. So I cannot use specific values like "doy" > 130 AND "doy" < 136, as it would leave out the other pixels.

How can I use an expression that allows me to aggregate neighbour pixels if their ("doy" < 5)?

third

4
  • Have a look at Aggregate: docs.qgis.org/3.16/en/docs/user_manual/processing_algs/qgis/… - for further help: can you share the raster and/or polygon layer?
    – Babel
    Jun 25 '21 at 15:10
  • @Babel, seems correct. Do you have an idea with the expression to use? The field is called doy. So something like "doy" <6. Would that work?
    – Thomas
    Jun 25 '21 at 15:12
  • I don't exactly know how your data structure looks like (what kind/how many values you have), but I would try something like doy >130 and doy<=135?. You could also use select by expression and than merge the selected polygons: docs.qgis.org/3.16/en/docs/user_manual/working_with_vector/…
    – Babel
    Jun 25 '21 at 15:46
  • Does my edition help @Babel?
    – Thomas
    Jun 25 '21 at 16:00
1

You can use Aggregate, based on an expression that categorizes your values. See my example of a grid with random values (field doy) for each cell from 1 to 20. I created four groups: 1 to 5, 6 to 10, 11 to 15, 16 to 20 with this expression - you can use it in the aggregate dialog:

floor ((doy-1)/5)

Explanation: floor rounds a number downwards, thus you get integer numbers - the same for each value from 0 to 4 (as we want 1 to 5: doy-1:

  • 0/5=0
  • 1/5=0.2 - rounded downwards: 0
  • 2/5=0.4 - rounded downwards: 0

etc.

  • 5/5=1
  • 6/5=1.2 -rounded downwards:1
  • 7/5=1.4 -rounded downwards:1

etc.

Screenshot: cells grouped together/aggregated with the above expression: enter image description here

9
  • It sort of works. However, some pixels will be split irrationally because of the groups being created. E.g. pixel value 194 is in a different group than pixel value 195. That is not entirely what I wanted. I would like to aggregate adjacent pixels if their values are within a range of 5 days. How can I do that?
    – Thomas
    Jun 28 '21 at 12:15
  • Of course, you have to adapt the expression to the values you have. That's what I did with doy-1 to get "neat" categories. You first have to define your categories (like: from 151 to 195, from 196 to 200 etc.) and than adapt your expression to that.
    – Babel
    Jun 28 '21 at 12:18
  • I understand that. I have tried the following floor((doy - 65) / 26). I have done this as, the minimum value is 65, and the range from min to max is 260 days. So I create 10 groups via /26. But if I change the latter to floor((doy-65 / 52) to create 5 groups, it still splits at doy 194 and 195. How come it always splits there?
    – Thomas
    Jun 28 '21 at 12:26
  • Dividing by 26 returns you the first 26 values assigned to the first category: 65-90. The next 26 go to category 2: 91 to 116 and so on: category 7 from 247 to 272 (thus the last category will contain only values up to 260, as this is your maximum). You have totally 196 (possible) values: from 65 to 260. So now you have to divide up these values in a way that 194 (at position 130) and 195 (at position 131) go to the same category.
    – Babel
    Jun 28 '21 at 12:47
  • You want to get a pattern with a difference of 5: 1 to 5, 6 to 10, 11 to 15 etc. Thus your first value (65) belongs to another category than the second one (166). That's why you have to use this expression: floor((doy- 66) / 5). First category (for 65) will be -1, second category for 66 to 70 will be 0 etc. You can add 1 to the result to get positive values: 1+floor((doy- 66) / 5).
    – Babel
    Jun 28 '21 at 12:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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