3

I'm developing a QGIS plugin where users can enter some parameters (like distance, depth, area...) and by submiting the plugin interact with a PostGIS database and extract informations form vector and raster layers.

I want to classify a DEM raster by substituting the pixel values, for example:

If 200 < val < 210 Then val = 205

If 211 < val < 220 Then val = 215

This classification is based on the value entered by users using a TextBox or LineEdit

I'm using the query bellow and it's working but manually not automatically:

This query took 2 seconds for a DEM raster with (X:6000 , Y:5000) and (MIN(val):200,MAX(val):2400)

enter image description here

So each time I need to specify the gap.

Is there any way to allow to users to specify the interval they want to be applied for all values of raster?

7
  • Perhaps a little more information might help. In your example classification, you have your ranges overlapping, which may cause a problem. Do you actually need, for example: 201-210: 205; 211-220: 215, and so on? Will this be consistent in that you simply want the midpoint of each 10 digit range? If so, you may want to simplify what you are looking at, instead of caring about the entire number, you only want the tens and ones digits. If they are 1-5, then 5, if they are 6-10, then 5. A case statement may work, if this is what you are looking for. Aug 18, 2015 at 19:10
  • Okay, I immediately see a problem with my reasoning. Something even simpler is to only look at the first digit. If it is 1-9, then replace with 5. If the first digit is 0, then subtract 5 from the entire value. Operationally, the simplest way to accomplish this may be to simply round up to the nearest 10 multiple and subtract 5 regardless of the values. Aug 18, 2015 at 19:14
  • Sorry, just realized the notation that you are using for the reclass arg answered my initial question. Since you are interested in the midpoint of 0-9, then you should round down and add 5. Just need to figure out how to set that up and convert to text string for the reclass function. Aug 18, 2015 at 19:24
  • Sorry I tthink that I should give more explanation for my problem. My purpose is to reclassify a raster based on the value entered by the user (because I'm developing a QGIS plugin) for example if the user enter 10 then values will be 5,15,25... and if the user enter 20 then values will be 10,30,50...and so on
    – elmo
    Aug 18, 2015 at 19:57
  • Ah, that is a different story. It might help to update your questions with more detail about what you are actually doing, including the qgis plugin, etc. and not just the postgresql query. Also, perhaps add a tag for qgis-plugin. You may get better response. Also more detail about the types of classifications you desire is warranted. Can someone enter any number they want, or are there specific numbers they can enter that will return specific classification patterns, or for ex. numbers 1-20: pattern 1, 30: pattern 2. How variable or specific does this need to be? Aug 18, 2015 at 20:12

2 Answers 2

4
+50

if you have a constant interval, then you do not need a look up table. You can use the following formula

(int(raster@1) / interval) * interval + interval/2

of course, / must be an integer division (rounding to the integer below)

2
  • lets say that val(raster@1) = 200 and interval = 10 so the value that I want is 205 but if I apply your formula it's give 300
    – elmo
    Aug 19, 2015 at 12:57
  • 2
    (200/10) * 10 + 10/2 = 20*10 + 5 = 200 + 5 = 205 and (209/10) * 10 + 10/2 = 20*10 + 5 = 200 + 5 = 205
    – radouxju
    Aug 19, 2015 at 13:09
2

Based on the great idea of @radouxju's responce I resolve this issues.

Instead of using Reclass function I used MapAlgebra function so the query is :

SELECT ST_MapAlgebra(a.rast,b.rast, '(ceil([rast1]/10)*10)+5') AS newrast from my_raster1 a, my_raster2 b

I used 'ceil' funtion to get the smallest integer not less than argument see this link

And this is how I used it into my QGIS plugin code :

reclass_val = float(self.dlg.lineEdit.text()) 
cur.execute("create table example as SELECT ST_MapAlgebra(a.rast,b.rast, '(ceil([rast1]/%s)*%s)+(%s/2)') AS newrast from my_raster1 a, my_raster2 b",(reclass_val ,reclass_val ,reclass_val ))

I hope this will help

Your Answer

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

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