Example: Trace Vector Areas from Raster Pixels

This example follows the Trace Vector Areas from Raster Pixels video on the Gallery page.   We use the Trace Areas template in the Transform pane for images to create a drawing with vector areas covering regions of similarly-colored pixels.  Next, we use a simple query to add classification codes from a USGS table of classes to the resulting drawing, using a simple INNER JOIN SQL statement.   


This example uses the same data set as is used in the Example: Import CTG Grid Cell File and Style topic.   Download the project used in this example from the Downloads page.

Import a Raster Image

We will first import a raster image.  We then explore the image, opening the image's table and taking a look at how it is styled, to understand what data that image shows.


Import a CTG LULC Grid Cell file containing raster data showing land use and land cover as shown in the Example: Import CTG Grid Cell File and Style topic.




There are four images created, called grid_cell Census, grid_cell Hydro, grid_cell LULC and grid_cell Political,  all created from the same grid_cell Tiles table.




Opening the table we see it has four different tile columns.   Each of the four images is created from a different tile column.   This is a typical arrangement for data imported from CTG format.




We are interested in the grid_cell LULC image, so we drag and drop that into a map, with a background layer using a Stamen Terrain data source (available in the JOSM sources project that can be downloaded from the Downloads page) and an upper layer consisting of Google's transparent street maps layer.    We can see that the grid_cell LULC image covers a region to the east and south of San Jose, California.




To simplify the presentation, we remove the other layers from the map and zoom in to the grid_cell LULC layer.  LULC stands for Land Use and Land Classification.   The image uses a limited palette of colors where each color represents a specific type of land use.   




Opening the Style pane for the image, we can see it uses a single channel and has been formatted using a palette.    The palette is used for purely visual presentation.   


A more technically accurate palette would have used unique values and not equal intervals as the tally method.  The method used does not really matter since how the image is styled for presentation does not in any way change the data in the pixels.   When we create areas, the Trace Areas template will look only at the data content of the pixels and will not care how that data is styled for presentation.




Most raster images that we work with in GIS will be based on a table where there is only one tile field.   This image is created from a table that has four tile fields, so we will need to know which tile field it uses.   To find that out, we right-click on the grid_cell LULC image and we choose Properties.




The Properties dialog tells us the image uses the Tile1 field in the table. Press OK or Cancel to close the Properties dialog.

Trace Areas

Actually tracing areas takes no time at all.     With the focus on the grid_cell LULC layer in the map we choose the Transform pane.




In the Transform pane we verify that Tile1 is the target field and we choose Trace Areas.   We leave the Similarity value at the default 1.  We leave the default Decompose to shapes option checked, which creates independent area objects for each classification of traced area.   If we like, we can click on Options to change Transform Options, such as the name of the new drawing that will be created.




Immediately, Manifold previews what the template is going to do using blue preview color.   The display above has been zoomed further into the image so we can better see details.   The Trace Areas template creates a new drawing and in that drawing creates area objects that cover each region where there is a region of similarly colored images.


We press the Add Component button to create a new drawing with the areas.




The new drawing and the new drawing's table appear in the Project pane, using the default name of grid_cell Tiles Trace Areas Drawing (whew!).  




We drag and drop the new drawing into the map.  It is, indeed, exactly what the preview predicted would be created.




We open the new drawing's table.  We see that each new area that covers a region of similarly-colored pixels has a Value attribute that provides the number of the color for the pixels in that area.   The template has created approximately 1,800 area objects, with each classed with a value corresponding to the pixel color value in the original raster.  


The Decompose to shapes option, when checked (default), will automatically decompose all areas for the same class of color into separate area objects, as seen in the table above.   Unchecking this option will result in the creation of a single, multibranched area object for each class.  This makes for a simpler results table and the ease of selecting all like areas with a single Ctrl-click, but when starting with larger raster data it can result in very large areas, consisting of millions of coordinates to cover all of the branches.




For example, had we unchecked the Decompose to shapes option, the template would have created about 30 different area objects, each of which would have had many branches.    What would still appear in the drawing to be 1,800 areas would be fewer than 30 area objects, each of which has many branches.  Each area would be multi-branched, so that all of what would appear to be independent areas with a Value of, say, 11, would all be branches of one very large and complex area.  

Styling the New Drawing

We can create a more appealing display by styling the drawing so it does not use default, gray format.




With the focus on the drawing we choose the Style pane, we click on the right-hand side of the Fill Color button, we choose Value as the field to use, unique values as the method for 100 values (there are fewer than 100 unique values but using 100 ensures we will get all of them), we choose the Color Brewer CB Paired palette and then we press Update Style.




Adding pretty colors makes the display more appealing.




We can zoom out to see how the new drawing shows many different areas, each with a Values code corresponding to the raster color from which it was created, which all together show the various land uses in the region near San Jose.


At this point we are done with the tracing task.  We have used the Trace Areas transform template to create a new drawing and to fill it with areas that each cover a region of similarly-colored pixels in the image.

Adding Classification Codes

For extra credit, we can continue on in this example by adding classification codes to the new drawing's table.   




The drawing's table lists a Value for each area.   We would like to add an additional column to the table that provides a Code field providing the text description of what each Value is intended by USGS to mean.




To do that, we will use a table of USGS codes.   We have created a table called LULC_classes (available in the project used in this example that may be downloaded from the Downloads page) that lists the classification codes defined by USGS for LULC raster data.   Each record contains a Value and a Code.     




If we open the Schema dialog for the LULC_classes table, we see that the table has a btree index called Value_x on the Value field.  This is an important detail, because the query which we will run below requires that index.


Our task is to add a text column to the grid_cell Tiles Trace Areas table called Code and to then populate that column for each record with the text descriptions for Code taken from the LULC_classes table that match the Value of the area.   


We can do that with a simple query that uses ALTER TABLE to add the column and then UPDATE and INNER JOIN to populate the column.  The example project contains the query text in a query called Update with class codes.   We can run the query by right clicking it in the Project pane and pressing the ! Run button, or we can double-click the query to open it in the Command Window to take a look at the query text.




The first part of the query adds a Code field of type nvarchar and it adds a btreedup index on the Value field that will work with the index on the Value field in the LULC_classes table:


ALTER TABLE [grid_cell Tiles Trace Areas] (

  ADD INDEX Value_x BTREEDUP (Value),




The second part of the query uses UPDATE to fill in values of the new Code field for each record, using an INNER JOIN to associate the correct Code string for each corresponding Value in the record.   





    a.Code AS a_Code,

    c.Code AS c_Code

  FROM [grid_cell Tiles Trace Areas] AS a

  INNER JOIN [LULC_classes] AS c

  ON a.Value = c.Value


SET a_Code = c_Code;


The query text uses AS to alias the longer names of the tables to single characters, aliasing grid_cell Tiles Trace Areas to the letter a, a mnemonic for "areas" and aliasing LULC_classes to c, a mnemonic for "classes".     That enables the query text to be written in much more compact form.   For example, instead of writing [grid_cell Tiles Trace Areas].Code we can simply write a.Code.   Instead of writing [LULC_classes].Code or [LULC_classes].Value we can simply write c.Code or c.Value.    Besides saving much keyboarding and avoiding typographic errors, the use of AS to alias long table names to short aliases will also help make queries more legible.  


Note that even though the use of AS to alias the longer table names to single characters happens in the FROM and INNER JOIN parts of the query, we can all the same use those alias right at the very beginning just after SELECT, with constructions like a.mfd_id.  The aliasing with AS is all part of the same SELECT so the query engine accepts it throughout.


We can also use AS to rename an aliased field in the results table, as in the constructions


  a.Code AS a_Code,

  c.Code AS c_Code


Without the renaming...







... the SELECT (shown in red since it is incorrect) would be a command to create a results table with an mfd_id field and two fields called the same name, Code, since the results table takes fields as they are named, without prefacing them with a [table name] and a dot.  We can't have two fields with the same name in a table so we rename them in the SELECT results to a_Code and c_Code.  We do not have to rename both of them, since we could have, for example, a field in the results table called Code and a second field that was renamed to be called c_Code, but it is good for clarity to be consistent and rename both.




When we run the query the grid_cell Tiles Trace Areas table acquires a new Code field that is populated for each record with the correct Code string for that record's Value, the string being taken from the corresponding Value in the LULC_classes table.




We can now use that new Code string value however we like.  For example, we can dynamically see what the meaning is of each land use area by Alt-clicking the area in the grid_cell Tiles Trace Areas Drawing.




That chooses the area as the subject for the Record pane, automatically popping open the Record pane to show the values for that record.    The area that was alt-clicked is contiguous, that is, a single area that is not branched.  The template can create very large, complex areas, with tens of millions of coordinates.




We can see that the area we Alt-clicked is coded with a Value of 42, which represents Evergreen Forest Land.  




We Alt-click another area.




This other area has a Value of 43 which is the Code for Mixed Forest Land.  


Indexes and INNER JOIN - For the INNER JOIN in the query above to work, we need an index on the Value field in one of the tables that will participate in the INNER JOIN.  The LULC_classes table has been created with an index on the Value field.  The example shows creation of a btreedup index in the grid_cell Tiles Trace Areas table.  This is not really necessary in such a small data set, but if we were working with a very large result table, the process goes faster with a btreedup index on the Value field of the trace areas results table.  With indexes in both tables on the field that participates in the INNER JOIN, the join can work much faster.  We use a btreedup (allows duplicates) index on the Value field of the in the grid_cell Tiles Trace Areas table, because if the Decompose to shapes option is checked (the default), many areas with the same Value, that is, duplicates, could be created.  


Area borders - The area borders in this topic have been styled to use a border thickness of 0.5 points, not the default 1 point.


Classification Codes - The value for each pixel in the grid_cell LULC image is a classification code that can be matched to a palette color to provide a more understandable display,.  USGS defines the following codes for LULC data like this data set:


1 Urban or Built-Up Land

11 Residential

12 Commercial Services

13 Industrial

14 Transportation, Communications

15 Industrial and Commercial

16 Mixed Urban or Built-Up Land

17 Other Urban or Built-Up Land


2 Agricultural Land

21 Cropland and Pasture

22 Orchards, Groves, Vineyards, Nurseries

23 Confined Feeding Operations

24 Other Agricultural Land


3 Rangeland

31 Herbaceous Rangeland

32 Shrub and Brush Rangeland

33 Mixed Rangeland


4 Forest Land

41 Deciduous Forest Land

42 Evergreen Forest Land

43 Mixed Forest Land


5 Water

51 Streams and Canals

52 Lakes

53 Reservoirs

54 Bays and Estuaries


6 Wetland

61 Forested Wetlands

62 Non-forested Wetlands


7 Barren Land

71 Dry Salt Flats

72 Beaches

73 Sandy Areas Other than Beaches

74 Bare Exposed Rock

75 Strip Mines, Quarries, and Gravel Pits

76 Transitional Areas

77 Mixed Barren Land


8 Tundra

81 Shrub and Brush Tundra

82 Herbaceous Tundra

83 Bare Ground

84 Wet Tundra

85 Mixed Tundra


9 Perennial Snow and Ice

91 Perennial Snowfields

92 Glaciers


Oceans may be coded with a value of 2000000102 or 0.




Trace Vector Areas from Raster Pixels


Five Minutes for Contours


Contour a 300MB DEM in Five Seconds


See Also



Record Pane


Style Pane


Transform Pane


Transform Templates






Command Window


Command Window - Query Builder


SQL Operators


JOIN Statements


Example: Tanaka Contours - Also known as illuminated contours, Tanaka contours give the appearance of three dimensionality to contour lines by brightening lines on a slope facing a presumed light source while darkening lines on a slope facing away from the light source.  Lines are also made wider when perpendicular to the light source.  This topic shows how to create the Tanaka effect in contour lines.


Example: Import CTG Grid Cell File and Style - A companion topic to the Example: Import GIRAS vector LULC File and Style topic.  We import a CTG LULC Grid Cell file containing raster data showing land use and land cover and then we use Style to provide a more understandable display.


Example: Vector to Raster using Kriging - Using the Interpolate, Kriging Transform pane template, we take a vector drawing of contour lines where each line has a Height attribute and we create a raster image that is a terrain elevation surface.   This example, uses a point and click Transform template to accomplish the same task as shown using an SQL query in the SQL Example: Kriging topic.


Example: Contour Areas and Contour Lines - In this example we use the Contour Areas transform template in the Transform pane for images to create a drawing with vector areas showing height contours at desired altitude steps.   We color the areas using the attribute fields automatically created by the template.  Next, we apply a similar procedure using the Contour Lines transform template to create a drawing with vector lines showing height contours at the desired intervals.