Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#1245 closed enhancement (fixed)

[raster] ST_AddBand that can build a multi band raster from an array of raster bands

Reported by: robe Owned by: pracine
Priority: medium Milestone: PostGIS 2.0.0
Component: raster Version: master
Keywords: Cc:

Description

It's been bugging me for a while that a lot of code we have for adding multiple bands to a raster looks like this:

ST_AddBand(ST_AddBand(ST_MakeEmptyRaster(100,100,0,0,1,-1,0,0, -1), '1BB'), '4BUI') ;

There are two issues I see with this calling of multiple ST_AddBand 1) Each call I can only assume requires a memcopy of the previous raster which would be avoided if you can pass all the bands in a single call.

2) It's kinda long to type

Overloading the ST_AddBand I think will get problematic with casting of arrays etc.

But perhaps an ST_AddMultiBand or something like that

Which will 1) Have a proto to allow you to add a range of bands from one raster to another

kind of like ST_Band().. so I could do something like

ST_AddMultiBand(newrast, ST_Band(oldrast,ARRAY[1,4]) )

or

ST_AddMultiBand(newrast, ARRAY['8BUI', '8BUI'])

etc.

Change History (8)

comment:1 Changed 9 years ago by Bborie Park

Component: postgispostgis raster
Owner: changed from pramsey to pracine
Summary: ST_AddMultiBand that can add multiple bands to an existing raster[raster] ST_AddMultiBand that can add multiple bands to an existing raster

Having ST_AddMultiBand would be nice. Being able to specify the properties of each new band effectively without going off the deep end in the function parameters may be difficult. Maybe a variadic parameter of a new "band properties" type...

My only question is the following...

ST_AddMultiBand(newrast, ST_Band(oldrast,ARRAY[1,4]) )

ST_Band returns a new raster of bands 1 and 4 of oldrast so calling ST_AddMultiBand confuses me. Granted, I've been thinking that we need a function to copy a band from one existing raster to another existing raster... but that is getting off topic.

comment:2 Changed 9 years ago by robe

I was thinking along the lines of lets say I have a 2 band raster I created with same dimensions, srid etc. of an existing and I want to add 3 more bands to this raster from an existing. ST_Band works great if I want a subset of a raster but doesn't allow me to create a superset.

In current model, I'd have to do ST_AddBand(ST_AddBand(newrast,ST_Band(oldrast,1)),ST_Band(oldrast,2)) etc.

Which seems silly considering we already have an ST_Band that can take an array of band numbers and return me a multi band unless that is what this is for:

raster ST_AddBand(raster torast, raster fromrast);

But come to think of it, not sure why that one is there if it just returns band 1 of fromrast.

comment:3 Changed 9 years ago by Bborie Park

Ah. I understand what you're talking about. That would be a useful function as I know I'd use it. If I'm understanding you correctly, what you want is:

  1. A set of functions so that you can add one or more new bands to an existing raster. I'd expect that this set of functions would replace the existing one-band ST_AddBand. I think we may need to create a new type similar to reclassarg for ST_Reclass.
  1. A second set of functions to add one or more bands from an existing raster to another existing raster.

comment:4 Changed 9 years ago by robe

Yah I was actually thinking about reclassarg as a model though I feared the permutations of what you would put in may be too much. Just looking at how ST_AddBand could be rewritten to use something like a bandarg type similar to what we have with ST_Reclass.

comment:5 Changed 9 years ago by robe

Summary: [raster] ST_AddMultiBand that can add multiple bands to an existing raster[raster] ST_AddBand that can take multiple bands to an existing raster

Trying to come up with examples for the docs has forced me to think about this a bit more. Not only would it save many people from getting carpal tunnel syndrome, but like I said I think it would improve speed as fewer raster memory copy operations required and it will also improve readability. So a win, win, win in my book. here is my usecase that I am frustrated I can't use. I also changed this to ST_AddBand since I think we can fold it in -- the signature would be

ST_AddBand(raster[])

Now getting to my use case. Lets say I have a single band 32BF raster (for sake of argument lets call it solar winds). I want to convert this band to 4 8BUI bands.

So I create this user defined function to feed into my ST_MapAlgebraFnct single band version that takes pixel and a single user defined arg that will represent the band to map to. (http://www.postgis.org/documentation/manual-svn/RT_ST_MapAlgebraFct.html ).

So looks something like:

CREATE OR REPLACE FUNCTION solar_band_mapper(pixel double precision, VARIADIC args TEXT[])
    RETURNS double precision
    AS $$ BEGIN
        RETURN CASE args[1] WHEN '1' THEN pixel WHEN '2' THEN CASE WHEN pixel BETWEEN 1000 and 5000 THEN 100 ELSE 0 EMD   WHEN '3' THEN ... END;

    END; $$
    LANGUAGE 'plpgsql' IMMUTABLE COST 1000;

I have my table of solar winds and I want to be able to do this

SELECT rid, ST_AddBand(array_agg(ST_MapAlgebraFct(rast,'8BUI', 'solar_band_mapper(double precision,text[])'::regprocedure, i::text) ORDER BY i) ) As multi_band_rast
FROM solar_winds CROSS JOIN generate_series(1,3) As i
GROUP BY rid; 

comment:6 Changed 9 years ago by robe

Summary: [raster] ST_AddBand that can take multiple bands to an existing raster[raster] ST_AddBand that can build a multi band raster from an array of raster bands

comment:7 Changed 9 years ago by robe

Milestone: PostGIS Raster FuturePostGIS 2.0.0
Resolution: fixed
Status: newclosed

plpgsql version added at r8343. Would be nice to convert to C as it will be much more memory efficient.

comment:8 Changed 9 years ago by Bborie Park

Heh. Assuming the signature is stable, I have no problems converting it to C. Granted this may wait until 2.0.1. Can you add a ticket for converting this function into C.

Note: See TracTickets for help on using tickets.