Opened 11 years ago

Closed 9 years ago

#2603 closed task (fixed)

[raster] Add docs for ST_MapAlgebra with mask parameter

Reported by: dustymugs Owned by: dustymugs
Priority: critical Milestone: PostGIS 2.2.0
Component: raster Version: master
Keywords: Cc:

Description

Need to add docs for mask parameter containing variant of ST_MapAlgebra.

Change History (13)

comment:1 by dustymugs, 9 years ago

Priority: mediumcritical

comment:2 by robe, 9 years ago

dustymugs if you are around, I'm working on adding this to docs. I presume this is new in 2.2.0 (so flagging it as such). Can you explain what the mask does? From example in rt_mapalgebra_mast.sql — looks like the mask is a matrix of some sort which I am guessing only gets applied to the neighborhood of pixels to set pixels as nodata.

So I'm guessing it does similar to :

http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=selectmask

(I apologize now for linking to competitor documentation :) )

If I don't hear back from you before Paul pulls the switch, I'll just document the protos and be very vague about what it does not to embarrass myself.

comment:3 by dustymugs, 9 years ago

Thanks for the reminder. I'll take a look. Need to refresh my memory.

comment:4 by robe, 9 years ago

I'm guessing it does similar to ST_Clip except instead of passing in a geometry you pass in a matrix?

Anway committed first attempt at r14178. I'm not sure what weighted arg does either. I'll try to come up with a visual example before Paul pulls the trigger.

comment:5 by dustymugs, 9 years ago

I don't believe it does what that ESRI link does…

Instead, the mask is used to pull the neighborhood that you want for the pixel of interest…

comment:6 by robe, 9 years ago

I guess I'll have a better idea once I do a visual picture example :).

So what does the weighted param do? does it add the mask to the otherwise neighborhood? instead of just replacing it?

comment:7 by robe, 9 years ago

dustymugs: seems you have hard-coded somewhere a neighborhood of 1 for mask as I can't input distance x and y. Yet I can't find where that is. So if I understand correctly, then the mask should always be a 3x3 matrix as it stands. I'm also not sure what you mean by pull the neighborhood.

comment:8 by dustymugs, 9 years ago

Just looked through the code and I see no hard-coding of any neighborhood… I'll see about sending you an example…

comment:9 by dustymugs, 9 years ago

Probably not the best example…

The idea is that instead of distancex and distancey, the mask (an odd numbered array in X and Y) can provide a means to selectively filter pixels.

In the example below, I provide a mask of

1 0 0
0 1 0
0 0 1

which drives the neighborhood fetch to only pass those pixels in the neighborhood where the mask element is 1 (true) to the MapAlgebra Callback function.

DROP FUNCTION sample_callbackfunc(double precision[],integer[],text[]);
CREATE OR REPLACE FUNCTION sample_callbackfunc(v double precision[][][], pos int[][], VARIADIC userargs text[])
RETURNS double precision
AS $$
BEGIN
	RAISE NOTICE 'v = %', v;
	RAISE NOTICE 'pos = %', pos;
	RAISE NOTICE 'userargs = %', userargs;
	RETURN v[1][1][1];
END;
$$ LANGUAGE 'plpgsql';

WITH foo AS (
	SELECT 1 AS rid, ST_AddBand(ST_MakeEmptyRaster(4, 4, 0, 0, 1, -1, 0, 0, 0), 1, '16BUI', 1, 0) AS rast
)
SELECT
	ST_DumpValues(
		ST_MapAlgebra(
			rast, 1, 
			'sample_callbackfunc(double precision[], int[], text[])'::regprocedure,
			ARRAY[[1, 0, 0],[0, 1, 0],[0, 0, 1]]::double precision[], False
		)
	)
FROM foo

comment:10 by robe, 9 years ago

Ah okay I think I'm getting it now. I kept on thinking it was being applied after the mapalgebra call. So should the mask always be 0s and 1s? I'm not sure that behavior works right because when I gave it a 5x5 matrix it complained dimension was not the same as neighbor (that's why I augmented the error message to see what it thought was wrong). That's what I had thought that the distance was inferred from the matrix.

Here is an example:

DROP TABLE IF EXISTS shapes;
CREATE TABLE shapes(rid integer, rast raster);  

INSERT INTO shapes(rid,rast)
VALUES ( 1, ST_AsRaster(
		ST_Buffer(
			ST_GeomFromText('LINESTRING(50 50,150 150,150 50)'), 10,'join=bevel'), 
			200,200,ARRAY['8BUI'], ARRAY[118], ARRAY[0]) );

 SELECT st_mapalgebra(rast,1,'st_mean4ma(double precision[], int[], text[])'::regprocedure,'{{1,0,1,1,1}, {1,0,1,1,1}, {1,0,1,1,1}, {1,0,1,1,1}, {1,0,1,1,1}}'::double precision[],false)
FROM shapes;

Gives me:

ERROR:  rt_pixel_set_array: mask dimensions 5 x 5 do not match given dims 3 x 3

Why doesn't the distancex/y become 2,2?

Version 0, edited 9 years ago by robe (next)

comment:11 by dustymugs, 9 years ago

Distance is two pixels left, right, up, down from the pixel of interest…

2 2 2 2 2
2 1 1 1 2
2 1 0 1 2
2 1 1 1 2
2 2 2 2 2

So the distance x/y are correct. As for that error message, I'll need to dig.

comment:12 by robe, 9 years ago

I updated the doco at r14198. I'm still coming up with examples, but uncortable at the fact that my examples don't seem to display what I expect them to.

comment:13 by robe, 9 years ago

Resolution: fixed
Status: newclosed

put in pictures at r14199. done enough for release

Note: See TracTickets for help on using tickets.