# Tile SQL Functions

This topic covers functions built into the Manifold query engine, called SQL functions or query functions,  that begin with Tile.   Functions that begin with Tile manipulate tiles and pixels within tiles, as used within raster images.  Tile functions provide a huge range of functions for working with raster data.  Tile functions do mathematics on tiles, provide comparisons, or create vector objects from tiles, for example, TileContourLines, or rasters from vectors, for example, TileInterpolateKriging.

The Manifold query engine also supports declaring and calling functions, including script functions, functions in external files and compiled functions as .NET assemblies.

• For information on functions in queries, please see the Queries topic.

• For information on declaring and calling functions, please see the Functions topic.

Manifold has so many SQL functions they have been grouped into several topics:

• SQL Functions - Introduction and list of topics by function category.

• Geom SQL Functions - Functions that begin with Geom and manipulate geometry, as used within drawings.

• String SQL Functions - Functions that begin with String and manipulate strings (text) within tables, including attributes of drawings and labels.

• Tile SQL Functions - This topic:  Functions that begin with Tile and manipulate tiles and pixels within tiles, as used within images (rasters).

• Other SQL Functions - Non-aggregate functions that do not begin with Coord, Geom, String or Tile.

The list of functions below uses the same nomenclature as the function templates in the Query Builder.  SQL functions take arguments as specified in angle < > brackets.  The data type or value type the function returns is given after the : colon.    For example, Chr(<value>) : <string> takes a numeric <value> and returns a text <string>, as noted in the description a string that is a single character.   CoordSystems() : <table> takes no arguments and returns a table.

Examples in the list below which use an ? expression evaluation command are intended to be run in a Command Window.   Do not add a semicolon ; character when using the ? command in a Command window.  When using the ? command we use CALL when the function returns more than just a value, for example, when it returns a table.

Indexes are always zero based: for example, in an object consisting of three branches the first branch is branch 0, the second is branch 1 and the third is branch 2.

This is a long list, so to find a function it is best when viewing this topic in a browser to do a Ctrl-F to open a Find box and to enter the function name of interest to be able to jump to that function.  The list in this topic is comprehensive but new items are often added with updates to Manifold and may appear in the product before they appear in this documentation.   See the list in the query builder tab of the Command Window for an authoritative list of operators, commands and functions.

## Constants

See the Identifiers, Constants and Literals topic for some useful constants.   For information on functions that use a <filter> argument or which produce a filter definition matrix, see the How Matrix Filters Work topic.

## Functions Numeric functions on tiles operate on the first channel in the tile, ignoring all other channels, in the case of images that have more than one channel.

 TileAbs() : Given a tile value returns a tile with pixel values set to the absolute value of the input tile pixel values.   Absolute value leaves positive numbers unchanged and converts negative numbers into their positive equivalents. TileAcos() : Given a tile value returns a tile with pixel values set to the arc cosine (inverse cosine) of the input tile pixel values. TileAcosh() : Given a tile value returns a tile with pixel values set to the hyperbolic arc cosine of the input tile pixel values. TileAsin() : Given a tile value returns a tile with pixel values set to the arc sine (inverse sine) ofthe input tile pixel values. TileAsinh() : Given a tile value returns a tile with pixel values set to the hyperbolic arc sine of the input tile pixel values. TileAspect(, , ) : Given a tile value, a radius, and XYZ scales, returns a tile with pixel values set to the aspect in degrees of the surface implied by treating input tile pixel values as heights.  GPU parallelism switches to CPU parallelism at a radius of 9 or greater. TileAtan() : Given a tile value returns a tile with pixel values set to the arc tangent (inverse tangent) of the input tile pixel values. TileAtan2(, ) : Given a tile value returns a tile with pixel values set to the arc tangent (inverse tangent) of the ratio between the DY field and the DX field specified. TileAtanh() : Given a tile value returns a tile with pixel values set to the hyperbolic arc tangent of  the input tile pixel values. TileBgrHcy() : Given a tile value with pixels in BGR color space returns a tile with pixel values in HCY (Hue, Chroma, Luminance) color space. "Luminance" is often referred to as "Y".    This color space is often known as HCL (Hue, Chroma, Luminance). TileBgrHsi() : Given a tile value with pixels in BGR color space returns a tile with pixel values in HSI (Hue, Saturation, Intensity) color space. TileBgrHsl() : Given a tile value with pixels in BGR color space returns a tile with pixel values in HSL (Hue, Saturation, Lightness) color space. TileBgrHsv() : Given a tile value with pixels in BGR color space returns a tile with pixel values in HSV (Hue, Saturation, Value) color space.  Often referred to as HSB (Hue, Saturation, Brightness) color space. TileCbrt() : Given a tile value returns a tile with pixel values set to cubic root of the input tile pixel values. TileCeil() : Given a tile value returns a tile with pixel values set to the rounded up integer value of the input tile pixel values. TileCeilDecs(, ) : Given a tile value and the desired number of decimals returns a tile with pixel values set to the integer value rounded up to the specified number of decimals of the input tile pixel values. TileChannel(, ) : Given a tile value returns a tile with pixel values set to the values in the designated channel of the input tile. TileChannelCopy(, , , ): Given a source tile and source channel, and a destination tile and destination channel, copies pixel values from the source channel in the source tile into the destination channel in the destination tile.   Source and destination tiles must be the same dimension.  Source and destination pixel data types can be different, with conversion automatically being done on the fly. TileChannelCount() : Given a tile value returns the number of channels in the tile.  For example, a tile containing uint8x3 pixel values will have three channels. TileChannels(, ) : Rearrange the component parts of a pixel value vector within a tile as directed by an index vector, similar to how the VectorValues function rearranges component parts of a vector value.  The VectorValues function rearranges the component parts of a single vector value.   The TileChannels function rearranges the component parts of all pixel value vectors in the tile.     For example, if a tile is composed of uint8x3 vector values for each pixel where the three parts of the uint8x3 vector represent B, G and R channel values, applying TileChannels function to that tile using an index vector set of {2,1,0} will reshuffle the values so the uint8x3 vector will contain R, G and B channel values.   See the discussion for the VectorValues function.   Passing a single value makes TileChannels work like TileChannel, extracting a single channel from potentially multi-channel data. The number of channels in the tile returned by TileChannels does not have to be the same as the  number of channels in the original tile.   For example, executing an expression in the Command Window using TileMake to construct an example tile from which we will take a channel:   ? TileJson(TileChannels(TileMake(3, 3, VectorMakeX3(160, 192, 255)), 1)) nvarchar: [  192, 192, 192,  192, 192, 192,  192, 192, 192 ]   The above extracts the second channel (Channel 1 in zero-based counting) from a three channel tile.   For example, we can add an extra channel not in the original tile:   ? TileJson(TileChannels(TileMake(3, 3, 255), VectorMakeX4(0, 0, 0, -1))) nvarchar: [  255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,  255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,  255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0 ]   The above fills the first three channels with the original first channel (Channel 0 in zero-based counting) and then adds an extra channel filled with zeros.   See the Example: Rearrange Channels using an Expression topic for an example using TileChannels to change BGR channel order to RGB channel order. TileChannelsConcat(, ) :   TileChannelsConcatFill(, ) : Given a tile and a second tile of the same dimensions, concatenates the second tile's channels onto the first tile, returning a tile with concatenated channels up to a total of four channels.     Using the TileChannelsConcat  function, pixels will be visible if they are visible in both of the concatenated tiles.  Using the TileChannelsConcatFill function, pixels will be visible if they are visible in either of the concatenated tiles, and any missing channel values will be filled with zeros.   For example, if the first tile called [BG Tile] has uint8x2 values, that is, a vector value with two parts, that represent B and G values for an image, and a second tile called [R Tile] has a single uint8 value for each pixel that represents R values, then:   TileChannelsConcat([BG Tile], [R Tile])   Returns a tile with pixel values as uint8x3 three part vectors that represent  B, G and R values. TileClear(): Given a tile, returns a tile with all pixels set to invisible. With the focus on the image shown above, in the Transform pane we choose the Expression tab. We enter the expression:   TileClear([Tile]) The image disappears.  If in the Layers pane we turn off the background layer, we can see the default checkerboard pattern, since all pixels in the image are now transparent. TileCompare(, ) : This function has been removed, since the Compare SQL function does everything it did and more. TileContourArea(, , , ) : Takes a raster image with terrain heights in the specified channel, minimum contour height, maximum contour height and returns a single contour area for the specified height range. If none of the image pixels is in the specified height range, the function returns a NULL value.   Example: create a single contour area:   VALUES (TileContourArea([german_alps], 0, 1000, 2000)); TileContourAreaPar(, , , , ): A parallel form of the TileContourArea function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileContourArea function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileContourAreas(, , , ): Takes a raster image with terrain heights in the specified channel, and a set of desired contour heights specified as a table, and returns a table of contour areas with fields for: Geom, ValueMin, and ValueMax.   The set of heights does not have to be sorted and may contain duplicates, which will be ignored. For N unique heights, the returned table contains N+1 records: the area below the smallest height, N-1 areas between subsequent heights, and the  area above the biggest height.   Some of the geoms in the returned table might be NULL values. The returned areas cover the entire image.  The argument is true or false: when true, the result is decomposed into multiple objects when a single object would exceed 64 million coordinates. TileContourAreasPar(, , , , ) A parallel form of the TileContourAreas function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileContourAreas function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads.   Example: create a set of contours for the given heights using all available threads:   TABLE CALL TileContourAreasPar([german_alps], 0,   (VALUES (500), (1000), (1500), (3500)), -- heights   true, ThreadConfig(SystemCpuCount()));   Example: create a set of contours for the given heights using four threads:   TABLE CALL TileContourAreasPar([german_alps], 0,   (VALUES (500), (1000), (1500), (3500)), -- heights   true, ThreadConfig(4)); TileContourLine(, , Takes a raster image with terrain heights in the specified channel, and a desired contour line height, and returns a single contour line for the specified height. If the specified height is lower or higher than any of the image pixels, the function returns a NULL value. TileContourLinePar(, , , ): A parallel form of the TileContourLine function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileContourLine function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileContourLines(, , , ): Takes a raster image with terrain heights in the specified channel, and a set of desired contour heights specified as a table, and returns a table of contour lines with fields for:  Geom, and Value (height).   The set of heights does not have to be sorted and may contain duplicates, which will be ignored. The returned table contains a record for each unique height.   Some of the geoms in the returned table might be NULL values.  The argument is true or false: when true, the result is decomposed into multiple objects when a single object would exceed 64 million coordinates. TileContourLinesPar(, , , , ): A parallel form of the TileContourLines function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileContourLines function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileContrast(,
, ) : Given a tile with single channel values, a center value and an exponent value adjust the contrast of the image.  Tones below the center value will be darkened exponentially and those above will be lightened exponentially using the power argument, to produce values for the returned tile that will give it altered contrast. TileCos() : Given a tile value returns a tile with pixel values set to  the input tile pixel values. TileCosh() : Given a tile value returns a tile with pixel values set to  the input tile pixel values. TileCurvGaussian(, , ) : Given a tile value, a radius, and XYZ scales, computes Gaussian curvature.  Gaussian curvature indicates the overall curvature of a surface, if the surfce is positively curved like a dome, negatively curved like a cup, saddle-shaped or not curved. Gaussian curvature at any pixel is the geometric mean of the maximum and minimum curvatures that can be found in any given direction from that pixel. High values indicate more curvature along both maximum and minimum curvature directions. GPU parallelism switches to CPU parallelism at a radius of 9 or greater.  See the Wolfram articles on Gaussian curvature and Curvature in general for mathematical details. TileCurvMean(, , ) : Given a tile value, a radius, and XYZ scales, computes mean curvature.  The mean curvature at any pixel is the arithmetic mean of the maximum and minimum curvatures that can be found in any given direction from that pixel.  High values indicate more curvature along at least one of the maximum and minimum curvature directions.  GPU parallelism switches to CPU parallelism at a radius of 9 or greater.   See the Wolfram articles on mean curvature and Curvature in general for mathematical details. TileCurvPlan(, , ) : Given a tile value, a radius, and XYZ scales, computes planform curvature. Plan curvature is the curvature of a surface perpendicular to the direction of maximum slope. GPU parallelism switches to CPU parallelism at a radius of 9 or greater.  See the ESRI article. TileCurvProfile(, , ) : Given a tile value, a radius, and XYZ scales, computes profile curvature. Profile curvature is the curvature of a surface parallel to the direction of maximum slope.   GPU parallelism switches to CPU parallelism at a radius of 9 or greater.  See the ESRI article. TileCut(, ) : Given an image and X and Y values as an x2 vector, returns the tile at the specified X and Y location in the image. TileCutBorder(, , ) : Given an image,  X and Y values as an x2 vector, and a border size, returns the tile at the specified X and Y location in the image with the specified border.  The border size can be negative.  GPU parallelism switches to CPU parallelism at a border size of 9 pixels or more.  Calls to tile functions which use borders of 9 or more pixels automatically dispatch to CPU parallelism, and can freely intermix with calls dispatched to GPU parallelism. TileCutRect(, ) : Given an image and the two X,Y corners of a rectangle (Xmin, Ymin and Xmax, Ymax) in the image as an x4 vector, returns the tile at the specified rectangle in the image. TileDistanceMake(, , ): Given a raster image, a channel to use in that image, and a boolean flag to use or not use  NULL pixels as barriers, returns a distance buffer computed using shortest Euclidean (straight line) distance that can be used in further calls. TileDistanceMakePar(, , , ): A parallel form of the TileDistanceMake function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileDistanceMake function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileDistanceMakeSlope(, , , , , , , ): Given a raster where each pixel value is a slope, a channel to use in that image, and using specified parameters, returns a distance buffer that can be used in further calls. Computed using path distances where pixel costs are generated from slope values based on slope values and the specified parameters, thus allowing paths going downhill to have lower costs.   , -  Minimum and maximum values for the allowed slopes.  Pixels with slopes equal to or lower than minimum, or equal to or higher than maximum are considered to not be traversable and will be avoided by paths.  Transform templates using this function use -90 and 90 as defaults for minimum and maximum slope values allowed.   , , - Costs for minimum slope, zero or flat slope, and maximum slope.  Transform templates using this function use 0, 1, and 2 as defaults for costs for minimum slope, zero slope, and maximum slope respectively.  The default values weight paths going downhill as having lower costs.   - A boolean flag to reverse path direction to reckon paths from points specified in a drawing used in subsequent steps, instead of toward drawing points. TileDistanceMakeSlopePar(, , , , , , , , ): A parallel form of the TileDistanceMakeSlope function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileDistanceMakeSlope function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileDistanceMakeWeighted(, , ): Given a raster image, a channel to use in that image, and a boolean flag to use equal costs (weights), returns a distance buffer computed using shortest or lowest cost path distance that can be used in further calls.  An flag of TRUE uses equal costs for all pixels, computing shortest paths that avoid missing pixels.  An flag of FALSE uses values in valid pixels as distance / travel costs, computing lowest cost paths that avoid missing pixels. TileDistanceMakeWeightedPar(, , , ): A parallel form of the TileDistanceMakeWeighted function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileDistanceMakeWeighted function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileDistanceTilesClosest(, , ): Given a distance buffer, a drawing with points, and a numeric field in that drawing to use for identification of each point,  returns a raster with the value of each pixel set to the identification field value of the closest point. If the name of the source field is a blank string, sequential numbers will be used to identify each point, starting from zero.   The table returned is an indexed table, to allow use in joins. TileDistanceTilesClosestPar(, , , ): A parallel form of the TileDistanceTilesClosest function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileDistanceTilesClosest function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileDistanceTilesDirection(, , ): Given a distance buffer, a drawing with points, and a direction type, returns a raster with the value of each pixel set to the direction of the shortest path from the pixel to the closest point. Direction types:   0 - Direction to the closest point, in degrees between 0 and 360, Euclidean distances only, the default. 1 - Direction to the next pixel on the shortest path to the closest point, in degrees The direction from each pixel to an adjacent pixel can be only one of eight possible directions, 45, 90, 135, 180, 225, 270, or 315, or 360 degrees,  since adjacent pixels can only be to the left or right, above or below, or at one of four diagonal directions in between.  Direction values will be restricted to those eight values, plus 0 for the pixel coincident with the nearest point. Path distances only. 2 - Direction to the next pixel on the shortest path to the closest point, a quadrant value between 0 and 7, and using -1 when the pixel is coincident with the closest point, path distances only. 3 - Direction to the next pixel on the shortest path to the closest point, a quadrant value between 1 and 8, and using 0 when the pixel is coincident with the closest point, path distances only. TileDistanceTilesDirectionPar(, , , ): A parallel form of the TileDistanceTilesDirection function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileDistanceTilesDirection function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileDistanceTilesLength(, ): Given a distance buffer, and a drawing with points, returns a raster with the value of each pixel set to the distance from the pixel to the closest point. TileDistanceTilesLengthPar(, , ): A parallel form of the TileDistanceTilesLength function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileDistanceTilesLength function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileErf() : Given a tile value returns a tile with pixel values set to the error function (also called erf(z) ) of the input tile pixel values. TileErfc() : Given a tile value returns a tile with pixel values set to the complementary error function (also called erfc(z) ) of the input tile pixel values. TileExp() : The exponential function: Given a tile value returns a tile with pixel values set to e to the power of the input tile pixel values. TileExp10() : Given a tile value returns a tile with pixel values set to 10 to the power of the input tile pixel values. TileExp2() : Given a tile value returns a tile with pixel values set to 2 to the power of the input tile pixel values. TileExpm1() : Given a tile value with pixel values of x, returns a tile with pixel values set to e^x-1. TileFill(, ) : Given a tile value and a pixel value returns a tile with all pixel values set to the specified pixel value.  The function can accept xN values. TileFill keeps the original tile data type. TileFillBaseLevel(): Given an image, returns a table (filling the image's table) with tiles for all image tiles within the image rect (rectangular extent), and adding NULL tiles for any missing records (tiles) in the image. Consider an example using the small image above. The table for the image has only four records, each record containing a tile. We select two of the records and delete them. The table now has only two records, and is missing two records that are required to fill in the image's rect (rectangular extent). The image window updates with regions of the image where tiles are missing not being rendered.   The message warns us intermediate levels are now out of date.   We run the following SQL in the Command Window:   TABLE CALL TileFillBaseLevel([Bronze]); Immediately two new records are added to the table, providing NULL values for the missing tiles.  The image is not complete, of course, but the table has records for all X,Y tile positions that are required to fill in the image's rect. TileFillMissing(, ): Given a tile value and a pixel value returns a tile with all missing pixel values set to the specified pixel value and makes them visible. The function can accept xN values. Keeps the original tile data type. TileFillMissingCopy(, ): Given a tile and a background tile with the same tile sizes, returns a tile with pixels from the first tile where invisible pixels in the first tile have been replaced by corresponding pixels from the background tile.  Keeps the original tile data type. Does nothing if the tile sizes are not the same. TileFillMissingNearest(, ): Given a tile value and a pixel value returns a tile with all missing pixel values set to the first found visible pixel value within the specified radius. The function can accept xN values. Keeps the original tile data type. TileFillSinks(, , , ): Given an image, a specified channel, a minimum difference in height (the fill height value), and a minimum flow (the fill flow value), returns an image with filled sinks, as follows:    If both deltaMin and flowMin are negative or zero, the image is left unchanged. If deltaMin is positive and flowMin is negative or zero, sinks are filled based solely on height, equivalent to the depth of the sink. If deltaMin is negative or zero and flowMin is positive, sinks are filled based solely on flow, equivalent to the area of the sink.   If both deltaMin and flowMin are positive, sinks are filled based on both height and flow.   The table returned is an indexed table, to allow use in joins.   See illustrations and examples in the Watershed Prepare: Filling Sinks  topic. TileFillSinksPar(, , , , ): A parallel form of the TileFillSinks function that takes a parameter for the suggested number of threads as encoded in the JSON string as "threads".  If the number of threads is less than or equal to 1 the TileFillSinks function will be executed.  Use ThreadConfig to generate a JSON string with the desired number of threads. TileFilter(, , ): Takes an input tile, a radius and a tile with filter coefficients, and performs a linear filter. This is a generalization of TileFilterDefGaussian and similar functions, which imply specific ways to create the filter tile.  The function produces missing pixels if the filter shape covers no valid pixels.  GPU parallelism switches to CPU parallelism at a radius of 9 or greater. TileFilterCount(, , ): Given an  input tile, a radius and a tile with filter coefficients, counts the number of non-NULL pixel values with non-zero weights in the filter.   The number of non-zero coefficients must be 32 or less.  The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array.   GPU parallelism switches to CPU parallelism at a radius of 9 or greater. TileFilterDefCircle(,
): Given a radius and center, produce a filter definition matrix to pass to TileFilter.    Applies a circle-shaped linear filter of specified radius.  The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array. The
argument is the weight to give the center pixel: a weight of 1 means not to emphasize it.  A weight of 5 means to give the center pixel's value five times the value compared to other pixels in the array. TileFilterDefCross(,
) : Given a radius and center, produce a filter definition matrix to pass to TileFilter.    Applies a cross-shaped linear filter of specified radius.  The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array. The
argument is the weight to give the center pixel: a weight of 1 means not to emphasize it.  A weight of 5 means to give the center pixel's value five times the value compared to other pixels in the array. TileFilterDefDiamond(,
: Given a radius and center, produce a filter definition matrix to pass to TileFilter.    Applies a diamond-shaped (mid-way between cross and circle) linear filter of specified radius.  The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array. The
argument is the weight to give the center pixel: a weight of 1 means not to emphasize it.  A weight of 5 means to give the center pixel's value five times the value compared to other pixels in the array. TileFilterDefDirection(,
, ) : Given a radius, center and angle in radians, produce a filter definition matrix to pass to TileFilter.  Produces a blur effect in the direction specified.  The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array. The
argument is the weight to give the center pixel: a weight of 1 means not to emphasize it.  A weight of 5 means to give the center pixel's value five times the value in averaging compared to other pixels in the array. TileFilterDefEdges(,
) : Given a radius and center, produce a filter definition matrix to pass to TileFilter.    Detects edges in an image using a Laplacian of Gaussian filter shape, normed to the center value.   The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array. The
argument is the weight to give the center pixel: a weight of 1 means not to emphasize it.  A weight of 5 means to give the center pixel's value five times the value compared to other pixels in the array. TileFilterDefEdgesDirection(,
, ) : Given a radius and center, produce a filter definition matrix to pass to TileFilter.   Detects edges in an image using a Laplacian of Gaussian filter shape, normed to the center value.   The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array. The
argument is the weight to give the center pixel: a weight of 1 means not to emphasize it.  A weight of 5 means to give the center pixel's value five times the value compared to other pixels in the array. TileFilterDefGaussian(,
) : Given a radius and center, produce a filter definition matrix to pass to TileFilter.   Produces a blur effect using an algorithm that corrects for circular radius and using a decaying exponent in the filter shape.   The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array. The
argument is the weight to give the center pixel: a weight of 1 means not to emphasize it.  A weight of 5 means to give the center pixel's value five times the value in averaging compared to other pixels in the array. TileFilterDefSharpen(,
) : Given a radius and center, produce a filter definition matrix to pass to TileFilter.  Sharpens an image by convolution with a moving, square matrix to detect changes in pixel values that indicate transitions in visual appearance,  returning a tile where transitions have been enhanced with greater contrast.   The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array. The
argument is the weight to give the center pixel: a weight of 1 means not to emphasize it.  A weight of 5 means to give the center pixel's value five times the value compared to other pixels in the array. TileFilterDefSquare(,
) : Given the radius and center, produce a filter definition matrix to pass to TileFilter.  Produces a blur effect.  The argument sets the number of pixels from the center pixel to the edge:  A radius of 1 results in a 3x3 pixel array. The

, ) : Takes a tile and a value and returns the greater (maximum) value of the two for each pixel position.     For example,  TileMax([Tile], -10) compares the value in the tile for each pixel to -10 and chooses which is the greater.  Used in a Transform pane Expression that would have the effect of setting all pixel values less than -10 to -10.     For example, if a tile consists of a single channel with values from 0 to 255 in each pixel, then TileMax([Tile], 150) will return a tile where each pixel has the value of the corresponding pixel in [Tile] except that if that value is less than 150 then the pixel will have a value of 150.   The value could be another tile, so that TileMax([Tile1], [Tile2]) for each pixel returns whichever is the greater value of Tile1 or Tile2. TileMin(

## Notes

New functions - The list in this topic is intended to be comprehensive but might be not up to date.  New items are often added with updates to Manifold and may appear in the product before they appear in this documentation.   See the list in the query builder tab of the Command Window for an authoritative list of operators, commands and functions.

Operators - Many SQL Operators also work with tiles.   For example, the NOT, AND, OR, and XOR Boolean operators work with numeric tiles, where the tile contains values of 0 or any other number.  0 is interpreted as FALSE and any other value is TRUE.   The result is a numeric tile with 0 values for FALSE and 1 values for TRUE.  Comparison operators (<>, =, >=, >, <=, and <) also work with tiles, and with tiles and a number, producing a numeric tile with values of 0 or 1.  The BETWEEN operator also works with tiles and produces a numeric tile with values of 0 or 1.  See the SQL Operators  topic.

TileGeom functions in Release 9 compared to Release 8 -   Release 9 provides an upgrade for geometry (vector) to raster operations compared to Release 8.  Most of the considerations that follow involve fine details down to the level of individual pixels, to cover cases where very precise vector objects touch only part of a pixel:

• Each pixel overlaid by a vector object is only counted once, even for multipoints which fall onto the same pixel.  This is consistent with not counting pixels multiple times for lines and areas even if they have multiple coordinates which fall onto the same pixel.  This is the same as in 8 (save for multipoints which 8 does not support).

• As with 8, pixels overlaid by lines do not necessarily include pixels for line ends if point were placed at the line end.  Sometimes a neighboring pixel is a better match.

• As with 8, pixels overlaid by areas do not necessarily include pixels for the area boundary, if it would be converted to a line.  Horizontal shapes thinner than 1 pixel might be ignored.

• Pixels for areas are computed more accurately than in 8.

• Ultimately, as with 8, pixel shapes covered by a geom in 9 are an approximation that aims to be reasonably good without being slow.

• 9 runs faster than 8.  Quick performance numbers for TileGeomAvg in 8 and 9:

• Transferring heights from 10k x 10k pixels to 8142 small areas: 8 = 37.800 sec, 9 forced to use single thread = 7.835 sec, 9 with 8 threads = 1.769 sec, max difference in the result between 8 and 9: 9.3e-11 with a height range of 100-1500 (9 counts slightly more accurately).

• Transferring heights from 10k x 10k pixels to 1050 big areas: 8 = 74.050 sec, 9 forced to use single thread = 7.256 sec, 9 with 8 threads = 1.680 sec, max difference in the result between 8 and 9: 4.7e-11 with a height range of 100-1500.

TileFillMissingNearest in Release 9 compared to Interpolation functions in Release 8 - The TileFillMissingNearest function is similar to surface interpolation functions in 8, but there are two important differences:

• First, 9 uses a limited radius, not an unlimited radius as could be done with 8.  For example, Release 8 allowed unlimited radius only because surfaces in 8 were far smaller than the much bigger images 9 can handle.  9 also takes a more precise view of data and seeks to avoid questionable results:  if we want to fill in a missing data pixel in New York, but the nearest pixel exists in Africa, can we just use the value of a pixel in Africa because that happens to be the closest? Usually, searching for a closest known value has some common sense limits beyond which it is better to give up and take a different approach, such as perhaps using a constant or some average value if we absolutely must have missing pixel data filled in with something.

• Second, when there are multiple pixels at the same distance to the missing pixel, TileFillMissingNearest does not attempt to average them like 8 did and instead simply uses the first found value. This has the benefit of not introducing new values in cases where pixels stores some sort of unique codes, unlike heights, that cannot be averaged, or in cases where pixels store xN values where channels are connected to each other and per-channel averaging is undesirable.  Medians are an alternative, but computing a median is significantly more expensive  than computing an average or picking a random value, so a median is not provided by default.   If the community desires a median, that could be added, as could other options, such as returning all pixels closest to a user-defined function, or allowing specification of a metric that controls what is "closest," or other options.   For tips on recommending such options, see the Suggestions page.

Functions retaining the original tile type - Functions such as TileFill and several other functions retain the original tile type. What does this mean? Consider a simple example:

? TileJson(TileFill(TileMake(3, 3, CAST(1 AS UINT8)), 5))

The above creates a 3x3 tile of type UINT8 filled with the value 1 in each pixel.  It then refills the tile with the value 5 in each pixel.  Finally, it outputs the result as a JSON string. The result is what we would expect: [ 5, 5, 5, ... ]

Consider a variation:

? TileJson(TileFill(TileMake(3, 3, CAST(1 AS UINT8)), -1))

This creates the same tile as before but then tries to refill it with a value of -1 in each pixel.  The result is: [ 255, 255, 255 ... ].

What happened? Because TileFill keeps the original tile type, in this case an unsigned eight bit number, the value of -1 was converted to UINT8 and this produced the value 255, the unsigned eight bit equivalent of the number -1.

Other frequent conversions to keep in mind are from doubles to ints, where values are cut, and from numbers to xN values or vice versa, where values get padded or are cut.

Filters - For information on functions that use a <filter> argument or which produce a filter definition matrix, see the How Matrix Filters Work topic.

What are the built-in filters? -  Functions that are named beginning with TileFilterDef define a filter tile definition for subsequent use by TileFilter.  To see the filter matrix those functions generate we can use TileJson.  For example, to see what TileFilterDefSquare(1,1) generates using arguments that specify a radius of 1 to get a 3x3 matrix, and a center of 1, we can launch the Command Window and enter:

? TileJson(TileFilterDefSquare(1, 1))

Press the ! Run button and the Log pane of the Command Window reports:

> ? TileJson(TileFilterDefSquare(1, 1))

nvarchar: [

1, 1, 1,

1, 1, 1,

1, 1, 1

]

Some of the built-in filter definition functions generate much more complex filter matrix definitions than we would want to keyboard manually.  For example:

? TileJson(TileFilterDefEdges(1, 1))

Reports:

> ? TileJson(TileFilterDefEdges(1, 1))

nvarchar: [

-0.0009872784326934365, -0.03888148788384807, -0.0009872784326934365,

-0.03888148788384807, 1, -0.03888148788384807,

-0.0009872784326934365, -0.03888148788384807, -0.0009872784326934365

]

Most filter matrices published on various web sites use simpler forms, or provide fractions in the matrix filter cells instead of long decimal fractions.

GPGPU - Manifold automatically uses GPU parallelism (see the GPGPU topic) in functions where it makes sense to do so and when workflow is such that it is worth it to dispatch to GPU instead of simply using CPU parallelism.  In many cases both CPU parallelism and GPU parallelism will be used.  For example, all Kriging implementations (standard, median polish, and regression Kriging) use GPU, if available, to compute model parameters together with CPU parallelism in other parts of the function's operation.  GPU cards are so cheap that it doesn't make sense to try to guess when it pays to use GPGPU: simply install a GPU card, at least a cheapo GPU card.  Always.  Do not overthink it.  Just install an NVIDIA GPU card.

Why a GPU parallelism limit to radius/border of 8 or less? - Filter functions using a <radius> argument to set the size of the filter matrix applied typically are limited to a radius of 8 or less for GPGPU parallelism, switching to CPU parallelism at a radius of 9 or greater.   Calls to tile functions which use borders of 9 or more pixels likewise automatically dispatch to CPU parallelism.  In both cases, calls dispatched to CPU parallelism can freely intermix with calls dispatched to GPU parallelism.

Those limitations allows more flexible use of a greater range of GPU cards.  Some cards, perhaps older cards or lower cost cards, may have limited memory or earlier generation GPU chips, but they nonetheless can provide very many cores for GPGPU parallel computation.  Manifold makes it possible to use such cards effectively for GPGPU parallelism.

A radius of 8 implies a 17x17, 289-cell matrix, an absurdly huge and almost always an excessively large choice for matrix size.  A radius of 9 or above may indicate a conceptual error or workflow error.   At the same time, use of a radius of 9 or above requires so much GPU-accessible memory that such tasks fit into fewer and fewer cards, even if performance-reducing methods are adopted.   Given a choice between assuring a wide range of GPU cards will always work well, or restricting GPU choice to allow practices that are probably wrong in any event, Manifold chooses to support a wider range of GPU cards, placing the current switch to CPU parallelism at a radius or border of 9.  That may change as CUDA editions evolve.

Invisible pixels and filters - A difference in handling invisible pixels between Release 8 and Release 9 emerges when using functions such as TileFilterMax,  TileFilterMajor and similar matrix filter functions:  The surface evaluator tool in 8 was produces a visible pixel if at least one pixel in the vicinity is visible, which could make some invisible pixels visible.  In Release 9 invisible pixels stay invisible and visible pixels generally stay visible.  Visible pixels only turn invisible if non-zero filter coefficients all fall onto invisible pixels.  If the center value for a filter is non-zero, then visible pixels will always stay visible.

TileTrace functions - TileTrace functions track the number of different pixel values they encounter, and thus the number of different "bins" for which areas should be created, and stop if that number gets too big.  Currently, the limit is 20,000. Having too many different pixel values usually means that the image has to be preprocessed or that the function has to be called with a higher quantization factor to make the results usable.

Division by zero - returns NULL.

All types of values - Operators and functions generally  support all types of values so that, for example, we can use comparison or boolean operators on tiles and not just on scalar values.

Everything Math - For a handy reference to anything in mathematics, see the Wolfram MathWorld site.   Thank you, Wolfram!

Tables

Add an Index to a Table

Functions

Queries

Regular Expressions

How Matrix Filters Work

Command Window

Command Window - Query Builder

Identifiers, Constants and Literals

SQL Statements

SQL Operators

SQL Functions

Aggregate SQL Functions

Coord SQL Functions

Geom SQL Functions

String SQL Functions

Other SQL Functions

Temporary Databases

EXECUTE

Example: Create and Run a Query -  See how the different parts of a command window operate when creating and running SQL queries.   Includes use of the Log tab as well as the ?expression and !fullfetch commands.

Example: Transfer DEM Terrain Heights to Areas in a Drawing - Given a map with an image layer that shows terrain heights taken from a DEM, and a drawing layer that contains areas, using a small SQL query we transfer the average terrain height within each area to that area as a Height attribute for the area. Easy!

SQL Example: Process Images with 3x3 Filters -  Shows a step-by-step example of developing an SQL query that takes a query written by the Edit Query button and then modifies that query into a general purpose query that can apply any 3x3 filter.   This makes it easy to use matrix filters we find on the web for custom image processing.   We extend the query by using parameters and adding a function, and then show how it can be adapted to use a 5x5 filter.

SQL Example: Process Images using Dual 3x3 Filters  - A continuation of the above topic, extending the example query to utilize two filters for processing, as commonly done with Sobel and Prewitt two filter processing.

SQL Example: Process RGB Images using Matrix Filters - A continuation of the above two topics, extending the example query to process three channel, RGB images.

SQL Example: Miscellaneous SQL Functions - A variety of small examples using SQL functions.

SQL Example: GeomOverlayAdjacent Function - Using the GeomOverlayAdjacent function, an example that shows how this function and similar functions such as GeomOverlayContained, GeomOverlayContaining, GeomOverlayIntersecting and GeomOverlayTouching operate.

SQL Example: GeomOverlayTopologyUnion Function - A continuation of the SQL Example: GeomOverlayAdjacent Function example, using the GeomOverlayTopologyUnion function, an example that shows how this function and similar functions such as GeomOverlayTopologyIdentity, GeomOverlayTopologyIntersect and GeomOverlayTopologyUpdate operate.

Example: Merge : areas (dissolve) - In this example we combine multiple area objects into a single area object by using the Merge template in the Transform pane, using the areas (dissolve) option.  A drawing of French regions shows some regions as more than one area.  We would like each region to be one area so the table of regions has one record per region.

SQL Example: Learn SQL from Edit Query - Merging Areas - We learn how to write an SQL query that does a Merge : area (dissolve) operation by cutting and pasting from what the Edit Query button automatically generates.

Example: Use a Transform Expression to Create Buffers in a Drawing - Use the Expression tab of the Transform pane to create three different sizes of buffers for different lines in a drawing and then automatically create a query which does the same thing.  Includes examples of using the Add Component button and also the Edit Query button.

Example: Clip Areas with a Transform Expression - Use the Expression tab of the Transform pane to clip areas in a drawing to fit within horizontal bounds.   Includes examples of using the Add Component button and also the Edit Query button.

Example: Transform Templates, Expressions and Queries - We learn to use a function by clicking on a template in the Transform pane, seeing what it does in a preview, looking at the query Manifold creates and then trying out the function in the Expression tab.

SQL Example: List Transformation Grids - In this example we use a few snippets of easy SQL to list NTv2 and NADCON transformation grids that are available within the grids.dat compressed collection of transformation grid files.   Grid transformation files can be used when creating custom base coordinate systems, for NADCON / HARN / HPGN and NTv2 high accuracy transformations that use grid files.