Opened 11 years ago

Closed 9 years ago

#2603 closed task (fixed)

[raster] Add docs for ST_MapAlgebra with mask parameter

Reported by: Bborie Park Owned by: Bborie Park
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 Bborie Park, 10 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 Bborie Park, 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 Bborie Park, 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 Bborie Park, 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 Bborie Park, 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 the behavior of using the matrix to infer the neighborhood works right or I'm missing something 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 include what dimensions it thought were mismatched and assumed 3x3 was hardcoded somewhere). 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?

Last edited 9 years ago by robe (previous) (diff)

comment:11 by Bborie Park, 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.