Regarding questions about values, can one declare the input / output image / table as a value so that whenever you want to switch to use a new image, you only have to change a single declaration - mostly yes: If what we are talking about is having a query with a couple of VALUE declarations followed by statements using those values, and about manually editing these VALUE declarations before rerunning the query for each new image - then sure, this is fine. You cannot do CREATE TABLE @t ... / ALTER TABLE @t ... / DROP TABLE @t - these statements require the names of components be spelled out explicitly, they cannot take them as parameters, that's why I say 'mostly yes' instead of just 'yes' above. But you can do INSERT INTO @t ..., SELECT ... FROM @t ..., etc. You can also create a query which will take components as parameters and use EXECUTE to invoke it. The attached MXB shows how - run the Range Filter query, it will create the output components and then run the Range Filter Parameterized query which will fill them. Range Filter Parameterized: --SQL9 -- accepts parameters: -- @input TABLE - input image -- @output TABLE - output image -- @radius FLOAT64 - filter radius -- @center FLOAT64 - center value in square filter FUNCTION TileFilterRange(@IN TILE, @RADIUS FLOAT64, @FILTER TILE) TILE AS TileFilterMax(@IN, @RADIUS, @FILTER) - TileFilterMin(@IN, @RADIUS, @FILTER) END; INSERT INTO @output ( [mfd_id], [X], [Y], [Tile] ) SELECT [mfd_id], [X], [Y], CASTV ((TileRemoveBorder(TileFilterRange( TileCutBorder(@input, VectorMakeX2([X], [Y]), @radius), @radius, TileFilterDefSquare(@radius, @center) ), @radius)) AS FLOAT32) FROM @input THREADS SystemCpuCount(); TABLE CALL TileUpdatePyramids(@output); Range Filter: --SQL9 -- create output image CREATE TABLE [Range Tiles] ( [mfd_id] INT64, [X] INT32, [Y] INT32, [Tile] TILE, INDEX [mfd_id_x] BTREE ([mfd_id]), INDEX [X_Y_Tile_x] RTREE ([X], [Y], [Tile] TILESIZE (128,128) TILETYPE FLOAT32), PROPERTY 'FieldCoordSystem.Tile' ComponentCoordSystem([1475 ELEVATION Raster]), PROPERTY 'FieldTileSize.Tile' '[ 128, 128 ]', PROPERTY 'FieldTileType.Tile' 'float32' ); CREATE IMAGE [Range Image] ( PROPERTY 'Table' '[Range Tiles]', PROPERTY 'FieldTile' 'Tile', PROPERTY 'FieldX' 'X', PROPERTY 'FieldY' 'Y', PROPERTY 'Rect' ComponentProperty([1475 ELEVATION Raster], 'Rect') ); -- fill output image EXECUTE WITH ( @input TABLE = [1475 ELEVATION Raster], @output TABLE = [Range Image], @radius FLOAT64 = 1, @center FLOAT64 = 1 ) [Range Filter Parameterized]; Is there a way to programmatically copy the image bounds from one image to the other - sure, see Range Filter above. It copies the coordinate system as well. You can copy any property. Regarding the last question, if I am reading it correctly you want to combine the channels of two images derived from the same original image, correct? If so, you don't have to go through conversions of pixels to points and back - you can just join one of the images to the other, creating a new channel, and then going through the result subtracting one channel from the other. The join can be performed by the Join dialog. Alternatively, since both source images are derived from the same original image, you can just join the tables on X and Y (img1 INNER JOIN img2 ON img1.x=img2.x AND img1.y=img2.y) and subtract the tile for one image from the tile for another. If the images were in different coordinate systems you could have first reprojected one of the images to the other using one of the CoordConvertTileSet functions, and then proceeded with the same join on X and Y. PS: Sorry if my post earlier felt wry, I didn't intend it that way. These queries require quite a bit of figuring out, no question. I'll help in any way I can. Attachments: 2020_0521_Range_Example-v2.mxb
|