Land Classification

Developer Blog

Land Classification


Published on: 2026-07-22

Tagged with: Analysis, Tactical

Land classification provides information on what kind of surface is present such as land, water, urban area, forest, etc.

In an application, it can have many uses such as:

  • Vehicle routing: allows you to avoid specific surfaces when calculating a route. Example: most vehicles cannot cross swamps or water surfaces.
  • UAS: allows you to visualize places where UAS can land. Example: swamps and water surfaces are unsuitable as landing zones.
  • Units: allows you to visualize places where units can be placed. Example: ground units cannot be placed on water surfaces, or a ship cannot be placed on land.

In this article, we will explore a scenario where land classification is used as a means to assist a user placing units on a map by removing features created on the wrong surface. A C# sample is provided to demonstrate the scenario.

Visualization of land classification

Land classification is available in raster or vector format and can be visualized using Carmenta Studio as shown below:

In the sample, we have access to TIFF data and use an ImageDataSet to read it. The data provider should provide specifications describing what each raster value represents. In our case, the provider gave another file detailing the meaning of each possible value:

NLCD Land Cover Classification System Land Cover Class Definitions
Water
11 Open Water
12 Perennial Ice/Snow

Developed
21 Low Intensity Residential
22 High Intensity Residential
23 Commercial/Industrial/Transportation

Barren
31 Bare Rock/Sand/Clay
32 Quarries/Strip Mines/Gravel Pits
33 Transitional

Forested Upland
41 Deciduous Forest
42 Evergreen Forest
43 Mixed Forest

Shrubland
51 Shrubland

Non-natural Woody
61 Orchards/Vineyards/Other

Herbaceous Upland
71 Grasslands/Herbaceous

Herbaceous Planted/Cultivated
81 Pasture/Hay
82 Row Crops
83 Small Grains
84 Fallow
85 Urban/Recreational Grasses

Wetlands
91 Woody Wetlands
92 Emergent Herbaceous Wetlands

For the visualization, each raster value can be mapped to a color:

This gives the following result:

Tip: In the sample, the visualization is accessible through the LandUse layer. There is also a LandUseSimplify layer (disabled by default) showcasing the RasterReclassificationOperator used to convert raster values to other values, with a basic visualization: green for land and blue for water.

Land classification from code

While it can be quick to visualize land cover, Carmenta Engine does not provide a built-in function to give the same information from the code. However, you can call GetFeatures or GetFloatValueAt and use the result to decide validity based on your own conditions.

A basic function could look like:

internal enum SurfaceCategoriesEnum
{
    Land = 0,
    Water = 1,
}

private SurfaceCategoriesEnum GetSurfaceCategory(Feature feature)
{
    Point loc = feature.GetGeometryAsPoint().Point;

    // Convert to match dataset crs
    if (feature.Crs != _landCoverageDataSet.Crs)
    {
        loc = feature.Crs.ProjectTo(_landCoverageDataSet.Crs, feature.GetGeometryAsPoint().Point);
    }

    // Retrieve raster value
    var rasterValue = _landCoverageDataSet.GetFloatValueAt(loc);

    if (rasterValue is 11 or 12)
    {
        return SurfaceCategoriesEnum.Water;
    }

    return SurfaceCategoriesEnum.Land;
}

In the sample, the land data is in TIFF format. To access a cell value from the raster, we use Dataset.GetFloatValueAt. We then test the result against 11 or 12, since those values match water surfaces as defined by the data provider. For vector data, you would use GetFeatures(), parse the features, and read the attribute containing the information. As before, the data provider should specify which attributes each object carries.

A detailed function would probably test all potential values and return a more appropriate state for each, but for our sample knowing if it’s land or water is enough.

The sample uses tactical symbols from MIL-STD-2525D, the US Department of Defense standard for joint military symbology. Each symbol carries a 20-character SIDC (Symbol Identification Code), and characters 5 and 6 identify which symbol set it belongs to (ground, air, sea surface, sea subsurface, space, and so on).

Once we know the type of surface, the following function can be used to test the sidc code and find the symbol set, telling us whether the symbol is a ground or sea tactical symbol. The function is used by the FeatureCreated event handler in the MapViewModel class. Each time a feature is created, it will be tested and deleted if invalid.

private void ValidateFeatureCreation(object sender, FeatureCreatedEventArgs args)
{
    if (args.Feature.GeometryType == GeometryType.Point)
    {
        var res = GetSurfaceCategory(args.Feature);

        var sidc = args.Feature.Attributes["sidc"].Value.ToString();
        var symbolSet = sidc.Substring(4, 2);

        bool invalidFeature = false;
        switch (res)
        {
            case SurfaceCategoriesEnum.Land:
                invalidFeature = (symbolSet == "30" || symbolSet == "35");
                break;
            case SurfaceCategoriesEnum.Water:
                invalidFeature = !(symbolSet == "30" || symbolSet == "35");
                break;
            default:
                break;
        }

        if (invalidFeature)
        {
            var ds = _dataSetLookup[args.Feature.Id.DataSetId];
            using var guard = new Guard(ds);

            ds.Remove(args.Feature.Id);
        }
    }
}

From the MIL-STD-2525D standard, we know the symbol set is defined by characters 5 and 6, with sea surface and subsurface symbols using values 30 and 35 respectively.

Tip: If you are not using tactical symbols, you can set an attribute on your feature to identify whether it is a ground or water feature. Update the function to read the attribute and define the condition to mark a feature as invalid.

Conclusion

Today we learned about land classification and how it can be used to assist users in their tasks. While our sample explores a solution where we create features, it is possible to use a custom tool and have live feedback.

As mentioned in the introduction, land classification has many uses in different fields, from visualization to terrain routing and landing zones for UAS. It can even be used in a vertical profile to define a custom height based on classification.

The complete C# sample project used in this article can be downloaded here: LandClassification.zip.

Carmenta Engine Linux/ARM

Previous Post

Carmenta Engine on Linux/ARM

Build and deploy Carmenta Engine applications to Linux/ARM (Raspberry Pi) in C++, .NET Core, or Java, with sample setup and run instructions.

View Post