diff --git a/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml
new file mode 100644
index 0000000000..55f5cb3920
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml.cs b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml.cs
new file mode 100644
index 0000000000..fb49b9b74f
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml.cs
@@ -0,0 +1,214 @@
+// Copyright 2026 Esri.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+// language governing permissions and limitations under the License.
+
+using ArcGIS.Samples.Managers;
+using Esri.ArcGISRuntime.Analysis;
+using Esri.ArcGISRuntime.Mapping;
+using Esri.ArcGISRuntime.Rasters;
+using System;
+using System.Drawing;
+using System.IO;
+using System.Threading.Tasks;
+
+namespace ArcGIS.Samples.ApplyMapAlgebra
+{
+ [ArcGIS.Samples.Shared.Attributes.Sample(
+ name: "Apply map algebra",
+ category: "Analysis",
+ description: "Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.",
+ instructions: "When the sample opens, it displays the source elevation raster. Select the **Categorize** button to generate a raster with three distinct ice age related geomorphological categories (raised shore line areas in blue, ice free high ground in brown and areas covered by ice in teal). After processing completes, use the radio buttons to switch between the map algebra results raster and the original elevation raster.",
+ tags: new[] { "elevation", "map algebra", "raster", "spatial analysis", "terrain" })]
+ [ArcGIS.Samples.Shared.Attributes.OfflineData("aa97788593e34a32bcaae33947fdc271")]
+ public partial class ApplyMapAlgebra : ContentPage
+ {
+ private RasterLayer _elevationRasterLayer;
+ private RasterLayer _geomorphicRasterLayer;
+ private ContinuousField _elevationField;
+ private DiscreteField _geomorphicCategoryField;
+
+ public ApplyMapAlgebra()
+ {
+ InitializeComponent();
+ _ = Initialize();
+ }
+
+ private async Task Initialize()
+ {
+ // Create a map with a dark hillshade basemap and set the initial viewpoint to the Isle of Arran, Scotland.
+ MyMapView.Map = new Map(BasemapStyle.ArcGISHillshadeDark)
+ {
+ InitialViewpoint = new Viewpoint(55.584612, -5.234218, 300000)
+ };
+
+ try
+ {
+ // Get the path to the locally stored elevation raster file.
+ string rasterPath = DataManager.GetDataFolder("aa97788593e34a32bcaae33947fdc271", "arran.tif");
+
+ // Create a continuous field from the elevation raster file.
+ _elevationField = await ContinuousField.CreateAsync(new[] { rasterPath }, 0);
+
+ // Display the source elevation raster on the map.
+ DisplayElevationRaster(rasterPath);
+
+ // Enable the categorize button once the data is loaded.
+ CategorizeButton.IsEnabled = true;
+ }
+ catch (Exception ex)
+ {
+ await Application.Current.Windows[0].Page.DisplayAlert("Error", ex.Message, "OK");
+ }
+ }
+
+ private void DisplayElevationRaster(string rasterPath)
+ {
+ // Create a raster layer from the elevation raster file.
+ _elevationRasterLayer = new RasterLayer(new Raster(rasterPath));
+
+ // Create a stretch renderer to visualize the elevation raster layer using the surface preset color ramp.
+ _elevationRasterLayer.Renderer = new StretchRenderer(
+ new MinMaxStretchParameters(new[] { 0.0 }, new[] { 874.0 }),
+ gammas: new[] { 1.0 },
+ estimateStatistics: false,
+ colorRamp: ColorRamp.Create(PresetColorRampType.Surface, 256));
+
+ // Set opacity to allow the basemap hillshade to show through.
+ _elevationRasterLayer.Opacity = 0.5;
+
+ // Add the elevation raster layer to the map.
+ MyMapView.Map.OperationalLayers.Add(_elevationRasterLayer);
+ }
+
+ private async Task CreateGeomorphicCategoryField()
+ {
+ // Create a continuous field function from the elevation field.
+ var continuousFieldFunction = ContinuousFieldFunction.Create(_elevationField);
+
+ // Mask out values below sea level to categorize only land.
+ var elevationFieldFunction = continuousFieldFunction.Mask(
+ continuousFieldFunction.IsGreaterThanOrEqualTo(0));
+
+ // Round elevation values down to the lower 10 m interval, then convert to a discrete field function.
+ var tenMeterBinField = ((elevationFieldFunction / 10).Floor() * 10).ToDiscreteFieldFunction();
+
+ // Create boolean fields for each geomorphic category based on the nearest 10 m interval field.
+ var isRaisedShoreline = tenMeterBinField.IsGreaterThanOrEqualTo(0)
+ .LogicalAnd(tenMeterBinField.IsLessThan(10));
+
+ // Operator overloads (>=, <, &) can be used in place of IsGreaterThanOrEqualTo, IsLessThan, and LogicalAnd.
+ var isIceCovered = (tenMeterBinField >= 10) & (tenMeterBinField < 600);
+
+ var isIceFreeHighGround = tenMeterBinField.IsGreaterThanOrEqualTo(600);
+
+ // Assign geomorphic categories based on the boolean fields:
+ // raised shoreline = 1, ice covered = 2, ice-free high ground = 3.
+ _geomorphicCategoryField = await tenMeterBinField
+ .ReplaceIf(isRaisedShoreline, 1)
+ .ReplaceIf(isIceCovered, 2)
+ .ReplaceIf(isIceFreeHighGround, 3)
+ .EvaluateAsync();
+ }
+
+ private async void OnCategorizeClicked(object sender, EventArgs e)
+ {
+ CategorizeButton.IsEnabled = false;
+ CategorizeButton.Text = "Map algebra computing...";
+
+ try
+ {
+ // Build and evaluate the map algebra expression to generate the geomorphic category field.
+ await CreateGeomorphicCategoryField();
+ }
+ catch (Exception ex)
+ {
+ await Application.Current.Windows[0].Page.DisplayAlert("Error creating geomorphic category field", ex.Message, "OK");
+ CategorizeButton.IsEnabled = true;
+ CategorizeButton.Text = "Categorize";
+ return;
+ }
+
+ try
+ {
+ // Export the discrete field to a temporary folder.
+ string tempDir = Path.Combine(Path.GetTempPath(), "geomorphic_temp_files");
+ Directory.CreateDirectory(tempDir);
+
+ // Clean up any previously exported files.
+ const string filenamesPrefix = "geomorphicCategorization";
+ foreach (string file in Directory.GetFiles(tempDir, $"{filenamesPrefix}*"))
+ File.Delete(file);
+
+ // Export the discrete field result to a raster file.
+ var exportedFiles = await _geomorphicCategoryField.ExportToFilesAsync(tempDir, filenamesPrefix);
+
+ if (exportedFiles.Count == 0 || !File.Exists(exportedFiles[0]))
+ {
+ await Application.Current.Windows[0].Page.DisplayAlert("Export Error", "Exported geomorphic categorization file does not exist.", "OK");
+ CategorizeButton.IsEnabled = true;
+ CategorizeButton.Text = "Categorize";
+ return;
+ }
+
+ // Display the geomorphic categories on the map.
+ DisplayGeomorphicCategories(exportedFiles[0]);
+
+ // Show the layer toggle controls and hide the categorize button.
+ CategorizeButton.IsVisible = false;
+ LayerTogglePanel.IsVisible = true;
+ GeomorphicRadioButton.IsChecked = true;
+ UpdateVisibleRasterLayer();
+ }
+ catch (Exception ex)
+ {
+ await Application.Current.Windows[0].Page.DisplayAlert("Error exporting geomorphic categorization", ex.Message, "OK");
+ CategorizeButton.IsEnabled = true;
+ CategorizeButton.Text = "Categorize";
+ }
+ }
+
+ private void DisplayGeomorphicCategories(string rasterFilePath)
+ {
+ // Create a raster layer from the exported geomorphic categorization file.
+ _geomorphicRasterLayer = new RasterLayer(new Raster(rasterFilePath));
+
+ // Create an array of colors for the geomorphic categories.
+ // The array index maps directly to the pixel value in the raster.
+ var colors = new System.Drawing.Color[]
+ {
+ System.Drawing.Color.Transparent, // 0 = no category (NoData pixels are hidden)
+ System.Drawing.Color.FromArgb(25, 118, 210), // 1 = raised shoreline - blue
+ System.Drawing.Color.FromArgb(128, 203, 196), // 2 = ice covered - teal
+ System.Drawing.Color.FromArgb(121, 85, 72), // 3 = ice-free high ground - brown
+ };
+
+ // Create a colormap renderer to assign colors to pixel values and apply it to the raster layer.
+ _geomorphicRasterLayer.Renderer = new ColormapRenderer(colors);
+
+ // Set opacity to allow the basemap hillshade to show through.
+ _geomorphicRasterLayer.Opacity = 0.5;
+
+ // Add the geomorphic categorization raster layer to the map.
+ MyMapView.Map.OperationalLayers.Add(_geomorphicRasterLayer);
+ }
+
+ private void OnRasterLayerSelectionChanged(object sender, CheckedChangedEventArgs e)
+ {
+ UpdateVisibleRasterLayer();
+ }
+
+ private void UpdateVisibleRasterLayer()
+ {
+ if (_elevationRasterLayer == null) return;
+ bool showGeomorphic = GeomorphicRadioButton.IsChecked;
+ _elevationRasterLayer.IsVisible = !showGeomorphic;
+ if (_geomorphicRasterLayer != null)
+ _geomorphicRasterLayer.IsVisible = showGeomorphic;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/applymapalgebra.jpg b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/applymapalgebra.jpg
new file mode 100644
index 0000000000..a76903c85c
Binary files /dev/null and b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/applymapalgebra.jpg differ
diff --git a/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/readme.md b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/readme.md
new file mode 100644
index 0000000000..69862f4806
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/readme.md
@@ -0,0 +1,57 @@
+# Apply map algebra
+
+Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.
+
+
+
+## Use case
+
+Categorizing raster data, such as elevation values, into distinct categories is a common spatial analysis workflow. This often involves applying threshold‑based logic or algebraic expressions to transform continuous numeric fields into discrete, integer‑based categories suitable for downstream analytical or computational operations. These operations can be specified and applied using map algebra.
+
+## How to use the sample
+
+When the sample opens, it displays the source elevation raster. Select the **Categorize** button to generate a raster with three distinct ice age related geomorphological categories (raised shore line areas in blue, ice free high ground in brown and areas covered by ice in teal). After processing completes, use the radio buttons to switch between the map algebra results raster and the original elevation raster.
+
+## How it works
+
+1. Create a `ContinuousField` from a raster file using `ContinuousField.CreateAsync`.
+2. Create a `ContinuousFieldFunction` from the continuous field and mask values below sea level using `IsGreaterThanOrEqualTo`.
+3. Round elevation values down to the lowest 10-meter interval with map algebra operators
+ `((continuousFieldFunction / 10).Floor() * 10)`, and then convert the result to a `DiscreteFieldFunction` with
+ `ToDiscreteFieldFunction`.
+4. Create `BooleanFieldFunction`s for each category by defining a range with map algebra operators such as
+ `IsGreaterThanOrEqualTo`, `LogicalAnd`, and `IsLessThan`.
+5. Create a new `DiscreteField` by chaining `ReplaceIf` operations into discrete category values and evaluating the
+ result with `EvaluateAsync`.
+6. Export the discrete field to files with `ExportToFilesAsync` and create a `Raster` with the result. Use it to create
+ a `RasterLayer`.
+7. Apply a `ColormapRenderer` to the raster and display it in the map view.
+
+## Relevant API
+
+* BooleanFieldFunction
+* ColormapRenderer
+* ColorRamp
+* ContinuousField
+* ContinuousFieldFunction
+* DiscreteField
+* DiscreteFieldFunction
+* MinMaxStretchParameters
+* Raster
+* RasterLayer
+* StretchRenderer
+
+## Offline data
+
+This sample downloads the following items from ArcGIS Online automatically:
+
+* [Isle of Arran 10m resolution digital terrain elevation raster](https://www.arcgis.com/home/item.html?id=aa97788593e34a32bcaae33947fdc271)
+
+## About the data
+
+The elevation raster of the Isle of Arran, Scotland is a 10m resolution digital terrain model.
+(Data Copyright Scottish Government and SEPA (2014)).
+
+## Tags
+
+elevation, map algebra, raster, spatial analysis, terrain
diff --git a/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/readme.metadata.json b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/readme.metadata.json
new file mode 100644
index 0000000000..2fd9d2cf68
--- /dev/null
+++ b/src/MAUI/Maui.Samples/Samples/Analysis/ApplyMapAlgebra/readme.metadata.json
@@ -0,0 +1,38 @@
+{
+ "category": "Analysis",
+ "description": "Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.",
+ "formal_name": "ApplyMapAlgebra",
+ "ignore": false,
+ "images": [
+ "applymapalgebra.jpg"
+ ],
+ "keywords": [
+ "elevation",
+ "map algebra",
+ "raster",
+ "spatial analysis",
+ "terrain"
+ ],
+ "offline_data": [
+ "aa97788593e34a32bcaae33947fdc271"
+ ],
+ "redirect_from": [],
+ "relevant_apis": [
+ "BooleanFieldFunction",
+ "ColorRamp",
+ "ColormapRenderer",
+ "ContinuousField",
+ "ContinuousFieldFunction",
+ "DiscreteField",
+ "DiscreteFieldFunction",
+ "MinMaxStretchParameters",
+ "Raster",
+ "RasterLayer",
+ "StretchRenderer"
+ ],
+ "snippets": [
+ "ApplyMapAlgebra.xaml.cs",
+ "ApplyMapAlgebra.xaml"
+ ],
+ "title": "Apply map algebra"
+}
\ No newline at end of file
diff --git a/src/MAUI/readme.md b/src/MAUI/readme.md
index 8700136329..855fcf0dec 100644
--- a/src/MAUI/readme.md
+++ b/src/MAUI/readme.md
@@ -2,6 +2,7 @@
## Analysis
+* [Apply map algebra](Maui.Samples/Samples/Analysis/ApplyMapAlgebra) - Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.
* [Distance measurement analysis](Maui.Samples/Samples/Analysis/DistanceMeasurement) - Measure distances between two points in 3D.
* [Line of sight (geoelement)](Maui.Samples/Samples/Analysis/LineOfSightGeoElement) - Show a line of sight between two moving objects.
* [Line of sight (location)](Maui.Samples/Samples/Analysis/LineOfSightLocation) - Perform a line of sight analysis between two points in real time.
diff --git a/src/Samples.Shared/Resources/FeaturedSamples.xml b/src/Samples.Shared/Resources/FeaturedSamples.xml
index ed7287b035..15d646d3ca 100644
--- a/src/Samples.Shared/Resources/FeaturedSamples.xml
+++ b/src/Samples.Shared/Resources/FeaturedSamples.xml
@@ -2,6 +2,7 @@
+ ApplyMapAlgebraDistanceMeasurement
diff --git a/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.jpg b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.jpg
new file mode 100644
index 0000000000..b9cea7cb2f
Binary files /dev/null and b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.jpg differ
diff --git a/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml
new file mode 100644
index 0000000000..4e25680f4d
--- /dev/null
+++ b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml.cs b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml.cs
new file mode 100644
index 0000000000..07e29f5250
--- /dev/null
+++ b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml.cs
@@ -0,0 +1,215 @@
+// Copyright 2026 Esri.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+// language governing permissions and limitations under the License.
+
+using ArcGIS.Samples.Managers;
+using Esri.ArcGISRuntime.Analysis;
+using Esri.ArcGISRuntime.Mapping;
+using Esri.ArcGISRuntime.Rasters;
+using System;
+using System.Drawing;
+using System.IO;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace ArcGIS.WPF.Samples.ApplyMapAlgebra
+{
+ [ArcGIS.Samples.Shared.Attributes.Sample(
+ name: "Apply map algebra",
+ category: "Analysis",
+ description: "Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.",
+ instructions: "When the sample opens, it displays the source elevation raster. Select the **Categorize** button to generate a raster with three distinct ice age related geomorphological categories (raised shore line areas in blue, ice free high ground in brown and areas covered by ice in teal). After processing completes, use the radio buttons to switch between the map algebra results raster and the original elevation raster.",
+ tags: new[] { "elevation", "map algebra", "raster", "spatial analysis", "terrain" })]
+ [ArcGIS.Samples.Shared.Attributes.OfflineData("aa97788593e34a32bcaae33947fdc271")]
+ public partial class ApplyMapAlgebra
+ {
+ private RasterLayer _elevationRasterLayer;
+ private RasterLayer _geomorphicRasterLayer;
+ private ContinuousField _elevationField;
+ private DiscreteField _geomorphicCategoryField;
+
+ public ApplyMapAlgebra()
+ {
+ InitializeComponent();
+ _ = Initialize();
+ }
+
+ private async Task Initialize()
+ {
+ // Create a map with a dark hillshade basemap and set the initial viewpoint to the Isle of Arran, Scotland.
+ MyMapView.Map = new Map(BasemapStyle.ArcGISHillshadeDark)
+ {
+ InitialViewpoint = new Viewpoint(55.584612, -5.234218, 300000)
+ };
+
+ try
+ {
+ // Get the path to the locally stored elevation raster file.
+ string rasterPath = DataManager.GetDataFolder("aa97788593e34a32bcaae33947fdc271", "arran.tif");
+
+ // Create a continuous field from the elevation raster file.
+ _elevationField = await ContinuousField.CreateAsync(new[] { rasterPath }, 0);
+
+ // Display the source elevation raster on the map.
+ DisplayElevationRaster(rasterPath);
+
+ // Enable the categorize button once the data is loaded.
+ CategorizeButton.IsEnabled = true;
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Error");
+ }
+ }
+
+ private void DisplayElevationRaster(string rasterPath)
+ {
+ // Create a raster layer from the elevation raster file.
+ _elevationRasterLayer = new RasterLayer(new Raster(rasterPath));
+
+ // Create a stretch renderer to visualize the elevation raster layer using the surface preset color ramp.
+ _elevationRasterLayer.Renderer = new StretchRenderer(
+ new MinMaxStretchParameters(new[] { 0.0 }, new[] { 874.0 }),
+ gammas: new[] { 1.0 },
+ estimateStatistics: false,
+ colorRamp: ColorRamp.Create(PresetColorRampType.Surface, 256));
+
+ // Set opacity to allow the basemap hillshade to show through.
+ _elevationRasterLayer.Opacity = 0.5;
+
+ // Add the elevation raster layer to the map.
+ MyMapView.Map.OperationalLayers.Add(_elevationRasterLayer);
+ }
+
+ private async Task CreateGeomorphicCategoryField()
+ {
+ // Create a continuous field function from the elevation field.
+ var continuousFieldFunction = ContinuousFieldFunction.Create(_elevationField);
+
+ // Mask out values below sea level to categorize only land.
+ var elevationFieldFunction = continuousFieldFunction.Mask(
+ continuousFieldFunction.IsGreaterThanOrEqualTo(0));
+
+ // Round elevation values down to the lower 10 m interval, then convert to a discrete field function.
+ var tenMeterBinField = ((elevationFieldFunction / 10).Floor() * 10).ToDiscreteFieldFunction();
+
+ // Create boolean fields for each geomorphic category based on the nearest 10 m interval field.
+ var isRaisedShoreline = tenMeterBinField.IsGreaterThanOrEqualTo(0)
+ .LogicalAnd(tenMeterBinField.IsLessThan(10));
+
+ // Operator overloads (>=, <, &) can be used in place of IsGreaterThanOrEqualTo, IsLessThan, and LogicalAnd.
+ var isIceCovered = (tenMeterBinField >= 10) & (tenMeterBinField < 600);
+
+ var isIceFreeHighGround = tenMeterBinField.IsGreaterThanOrEqualTo(600);
+
+ // Assign geomorphic categories based on the boolean fields:
+ // raised shoreline = 1, ice covered = 2, ice-free high ground = 3.
+ _geomorphicCategoryField = await tenMeterBinField
+ .ReplaceIf(isRaisedShoreline, 1)
+ .ReplaceIf(isIceCovered, 2)
+ .ReplaceIf(isIceFreeHighGround, 3)
+ .EvaluateAsync();
+ }
+
+ private async void OnCategorizeClicked(object sender, RoutedEventArgs e)
+ {
+ CategorizeButton.IsEnabled = false;
+ CategorizeButton.Content = "Map algebra computing...";
+
+ try
+ {
+ // Build and evaluate the map algebra expression to generate the geomorphic category field.
+ await CreateGeomorphicCategoryField();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Error creating geomorphic category field");
+ CategorizeButton.IsEnabled = true;
+ CategorizeButton.Content = "Categorize";
+ return;
+ }
+
+ try
+ {
+ // Export the discrete field to a temporary folder.
+ string tempDir = Path.Combine(Path.GetTempPath(), "geomorphic_temp_files");
+ Directory.CreateDirectory(tempDir);
+
+ // Clean up any previously exported files.
+ const string filenamesPrefix = "geomorphicCategorization";
+ foreach (string file in Directory.GetFiles(tempDir, $"{filenamesPrefix}*"))
+ File.Delete(file);
+
+ // Export the discrete field result to a raster file.
+ var exportedFiles = await _geomorphicCategoryField.ExportToFilesAsync(tempDir, filenamesPrefix);
+
+ if (exportedFiles.Count == 0 || !File.Exists(exportedFiles[0]))
+ {
+ MessageBox.Show("Exported geomorphic categorization file does not exist.", "Export Error");
+ CategorizeButton.IsEnabled = true;
+ CategorizeButton.Content = "Categorize";
+ return;
+ }
+
+ // Display the geomorphic categories on the map.
+ DisplayGeomorphicCategories(exportedFiles[0]);
+
+ // Show the layer toggle controls and hide the categorize button.
+ CategorizePanel.Visibility = Visibility.Collapsed;
+ LayerTogglePanel.Visibility = Visibility.Visible;
+ GeomorphicRadioButton.IsChecked = true;
+ UpdateVisibleRasterLayer();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Error exporting geomorphic categorization");
+ CategorizeButton.IsEnabled = true;
+ CategorizeButton.Content = "Categorize";
+ }
+ }
+
+ private void DisplayGeomorphicCategories(string rasterFilePath)
+ {
+ // Create a raster layer from the exported geomorphic categorization file.
+ _geomorphicRasterLayer = new RasterLayer(new Raster(rasterFilePath));
+
+ // Create an array of colors for the geomorphic categories.
+ // The array index maps directly to the pixel value in the raster.
+ var colors = new Color[]
+ {
+ Color.Transparent, // 0 = no category (NoData pixels are hidden)
+ Color.FromArgb(25, 118, 210), // 1 = raised shoreline - blue
+ Color.FromArgb(128, 203, 196), // 2 = ice covered - teal
+ Color.FromArgb(121, 85, 72), // 3 = ice-free high ground - brown
+ };
+
+ // Create a colormap renderer to assign colors to pixel values and apply it to the raster layer.
+ _geomorphicRasterLayer.Renderer = new ColormapRenderer(colors);
+
+ // Set opacity to allow the basemap hillshade to show through.
+ _geomorphicRasterLayer.Opacity = 0.5;
+
+ // Add the geomorphic categorization raster layer to the map.
+ MyMapView.Map.OperationalLayers.Add(_geomorphicRasterLayer);
+ }
+
+ private void OnRasterLayerSelectionChanged(object sender, RoutedEventArgs e)
+ {
+ UpdateVisibleRasterLayer();
+ }
+
+ private void UpdateVisibleRasterLayer()
+ {
+ if (_elevationRasterLayer == null) return;
+ bool showGeomorphic = GeomorphicRadioButton.IsChecked == true;
+ _elevationRasterLayer.IsVisible = !showGeomorphic;
+ if (_geomorphicRasterLayer != null)
+ _geomorphicRasterLayer.IsVisible = showGeomorphic;
+ }
+ }
+}
diff --git a/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.md b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.md
new file mode 100644
index 0000000000..337f08b9c0
--- /dev/null
+++ b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.md
@@ -0,0 +1,57 @@
+# Apply map algebra
+
+Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.
+
+
+
+## Use case
+
+Categorizing raster data, such as elevation values, into distinct categories is a common spatial analysis workflow. This often involves applying threshold‑based logic or algebraic expressions to transform continuous numeric fields into discrete, integer‑based categories suitable for downstream analytical or computational operations. These operations can be specified and applied using map algebra.
+
+## How to use the sample
+
+When the sample opens, it displays the source elevation raster. Select the **Categorize** button to generate a raster with three distinct ice age related geomorphological categories (raised shore line areas in blue, ice free high ground in brown and areas covered by ice in teal). After processing completes, use the radio buttons to switch between the map algebra results raster and the original elevation raster.
+
+## How it works
+
+1. Create a `ContinuousField` from a raster file using `ContinuousField.CreateAsync`.
+2. Create a `ContinuousFieldFunction` from the continuous field and mask values below sea level using `IsGreaterThanOrEqualTo`.
+3. Round elevation values down to the lowest 10-meter interval with map algebra operators
+ `((continuousFieldFunction / 10).Floor() * 10)`, and then convert the result to a `DiscreteFieldFunction` with
+ `ToDiscreteFieldFunction`.
+4. Create `BooleanFieldFunction`s for each category by defining a range with map algebra operators such as
+ `IsGreaterThanOrEqualTo`, `LogicalAnd`, and `IsLessThan`.
+5. Create a new `DiscreteField` by chaining `ReplaceIf` operations into discrete category values and evaluating the
+ result with `EvaluateAsync`.
+6. Export the discrete field to files with `ExportToFilesAsync` and create a `Raster` with the result. Use it to create
+ a `RasterLayer`.
+7. Apply a `ColormapRenderer` to the raster and display it in the map view.
+
+## Relevant API
+
+* BooleanFieldFunction
+* ColormapRenderer
+* ColorRamp
+* ContinuousField
+* ContinuousFieldFunction
+* DiscreteField
+* DiscreteFieldFunction
+* MinMaxStretchParameters
+* Raster
+* RasterLayer
+* StretchRenderer
+
+## Offline data
+
+This sample downloads the following items from ArcGIS Online automatically:
+
+* [Isle of Arran 10m resolution digital terrain elevation raster](https://www.arcgis.com/home/item.html?id=aa97788593e34a32bcaae33947fdc271)
+
+## About the data
+
+The elevation raster of the Isle of Arran, Scotland is a 10m resolution digital terrain model.
+(Data Copyright Scottish Government and SEPA (2014)).
+
+## Tags
+
+elevation, map algebra, raster, spatial analysis, terrain
diff --git a/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.metadata.json b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.metadata.json
new file mode 100644
index 0000000000..b0e4a95cfb
--- /dev/null
+++ b/src/WPF/WPF.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.metadata.json
@@ -0,0 +1,38 @@
+{
+ "category": "Analysis",
+ "description": "Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.",
+ "formal_name": "ApplyMapAlgebra",
+ "ignore": false,
+ "images": [
+ "ApplyMapAlgebra.jpg"
+ ],
+ "keywords": [
+ "elevation",
+ "map algebra",
+ "raster",
+ "spatial analysis",
+ "terrain"
+ ],
+ "offline_data": [
+ "aa97788593e34a32bcaae33947fdc271"
+ ],
+ "redirect_from": [],
+ "relevant_apis": [
+ "BooleanFieldFunction",
+ "ColorRamp",
+ "ColormapRenderer",
+ "ContinuousField",
+ "ContinuousFieldFunction",
+ "DiscreteField",
+ "DiscreteFieldFunction",
+ "MinMaxStretchParameters",
+ "Raster",
+ "RasterLayer",
+ "StretchRenderer"
+ ],
+ "snippets": [
+ "ApplyMapAlgebra.xaml.cs",
+ "ApplyMapAlgebra.xaml"
+ ],
+ "title": "Apply map algebra"
+}
\ No newline at end of file
diff --git a/src/WPF/readme.md b/src/WPF/readme.md
index 2585af23a2..637ff0e7ce 100644
--- a/src/WPF/readme.md
+++ b/src/WPF/readme.md
@@ -2,6 +2,7 @@
## Analysis
+* [Apply map algebra](WPF.Viewer/Samples/Analysis/ApplyMapAlgebra) - Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.
* [Distance measurement analysis](WPF.Viewer/Samples/Analysis/DistanceMeasurement) - Measure distances between two points in 3D.
* [Line of sight (geoelement)](WPF.Viewer/Samples/Analysis/LineOfSightGeoElement) - Show a line of sight between two moving objects.
* [Line of sight (location)](WPF.Viewer/Samples/Analysis/LineOfSightLocation) - Perform a line of sight analysis between two points in real time.
diff --git a/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.jpg b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.jpg
new file mode 100644
index 0000000000..b375949780
Binary files /dev/null and b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.jpg differ
diff --git a/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml
new file mode 100644
index 0000000000..97f15fca75
--- /dev/null
+++ b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml.cs b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml.cs
new file mode 100644
index 0000000000..cf8e07f852
--- /dev/null
+++ b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/ApplyMapAlgebra.xaml.cs
@@ -0,0 +1,215 @@
+// Copyright 2026 Esri.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
+// language governing permissions and limitations under the License.
+
+using ArcGIS.Samples.Managers;
+using Esri.ArcGISRuntime.Analysis;
+using Esri.ArcGISRuntime.Mapping;
+using Esri.ArcGISRuntime.Rasters;
+using Microsoft.UI.Xaml;
+using System;
+using System.Drawing;
+using System.IO;
+using System.Threading.Tasks;
+
+namespace ArcGIS.WinUI.Samples.ApplyMapAlgebra
+{
+ [ArcGIS.Samples.Shared.Attributes.Sample(
+ name: "Apply map algebra",
+ category: "Analysis",
+ description: "Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.",
+ instructions: "When the sample opens, it displays the source elevation raster. Select the **Categorize** button to generate a raster with three distinct ice age related geomorphological categories (raised shore line areas in blue, ice free high ground in brown and areas covered by ice in teal). After processing completes, use the radio buttons to switch between the map algebra results raster and the original elevation raster.",
+ tags: new[] { "elevation", "map algebra", "raster", "spatial analysis", "terrain" })]
+ [ArcGIS.Samples.Shared.Attributes.OfflineData("aa97788593e34a32bcaae33947fdc271")]
+ public partial class ApplyMapAlgebra
+ {
+ private RasterLayer _elevationRasterLayer;
+ private RasterLayer _geomorphicRasterLayer;
+ private ContinuousField _elevationField;
+ private DiscreteField _geomorphicCategoryField;
+
+ public ApplyMapAlgebra()
+ {
+ InitializeComponent();
+ _ = Initialize();
+ }
+
+ private async Task Initialize()
+ {
+ // Create a map with a dark hillshade basemap and set the initial viewpoint to the Isle of Arran, Scotland.
+ MyMapView.Map = new Map(BasemapStyle.ArcGISHillshadeDark)
+ {
+ InitialViewpoint = new Viewpoint(55.584612, -5.234218, 300000)
+ };
+
+ try
+ {
+ // Get the path to the locally stored elevation raster file.
+ string rasterPath = DataManager.GetDataFolder("aa97788593e34a32bcaae33947fdc271", "arran.tif");
+
+ // Create a continuous field from the elevation raster file.
+ _elevationField = await ContinuousField.CreateAsync(new[] { rasterPath }, 0);
+
+ // Display the source elevation raster on the map.
+ DisplayElevationRaster(rasterPath);
+
+ // Enable the categorize button once the data is loaded.
+ CategorizeButton.IsEnabled = true;
+ }
+ catch (Exception ex)
+ {
+ await new MessageDialog2(ex.Message, "Error").ShowAsync();
+ }
+ }
+
+ private void DisplayElevationRaster(string rasterPath)
+ {
+ // Create a raster layer from the elevation raster file.
+ _elevationRasterLayer = new RasterLayer(new Raster(rasterPath));
+
+ // Create a stretch renderer to visualize the elevation raster layer using the surface preset color ramp.
+ _elevationRasterLayer.Renderer = new StretchRenderer(
+ new MinMaxStretchParameters(new[] { 0.0 }, new[] { 874.0 }),
+ gammas: new[] { 1.0 },
+ estimateStatistics: false,
+ colorRamp: ColorRamp.Create(PresetColorRampType.Surface, 256));
+
+ // Set opacity to allow the basemap hillshade to show through.
+ _elevationRasterLayer.Opacity = 0.5;
+
+ // Add the elevation raster layer to the map.
+ MyMapView.Map.OperationalLayers.Add(_elevationRasterLayer);
+ }
+
+ private async Task CreateGeomorphicCategoryField()
+ {
+ // Create a continuous field function from the elevation field.
+ var continuousFieldFunction = ContinuousFieldFunction.Create(_elevationField);
+
+ // Mask out values below sea level to categorize only land.
+ var elevationFieldFunction = continuousFieldFunction.Mask(
+ continuousFieldFunction.IsGreaterThanOrEqualTo(0));
+
+ // Round elevation values down to the lower 10 m interval, then convert to a discrete field function.
+ var tenMeterBinField = ((elevationFieldFunction / 10).Floor() * 10).ToDiscreteFieldFunction();
+
+ // Create boolean fields for each geomorphic category based on the nearest 10 m interval field.
+ var isRaisedShoreline = tenMeterBinField.IsGreaterThanOrEqualTo(0)
+ .LogicalAnd(tenMeterBinField.IsLessThan(10));
+
+ // Operator overloads (>=, <, &) can be used in place of IsGreaterThanOrEqualTo, IsLessThan, and LogicalAnd.
+ var isIceCovered = (tenMeterBinField >= 10) & (tenMeterBinField < 600);
+
+ var isIceFreeHighGround = tenMeterBinField.IsGreaterThanOrEqualTo(600);
+
+ // Assign geomorphic categories based on the boolean fields:
+ // raised shoreline = 1, ice covered = 2, ice-free high ground = 3.
+ _geomorphicCategoryField = await tenMeterBinField
+ .ReplaceIf(isRaisedShoreline, 1)
+ .ReplaceIf(isIceCovered, 2)
+ .ReplaceIf(isIceFreeHighGround, 3)
+ .EvaluateAsync();
+ }
+
+ private async void OnCategorizeClicked(object sender, RoutedEventArgs e)
+ {
+ CategorizeButton.IsEnabled = false;
+ CategorizeButton.Content = "Map algebra computing...";
+
+ try
+ {
+ // Build and evaluate the map algebra expression to generate the geomorphic category field.
+ await CreateGeomorphicCategoryField();
+ }
+ catch (Exception ex)
+ {
+ await new MessageDialog2(ex.Message, "Error creating geomorphic category field").ShowAsync();
+ CategorizeButton.IsEnabled = true;
+ CategorizeButton.Content = "Categorize";
+ return;
+ }
+
+ try
+ {
+ // Export the discrete field to a temporary folder.
+ string tempDir = Path.Combine(Path.GetTempPath(), "geomorphic_temp_files");
+ Directory.CreateDirectory(tempDir);
+
+ // Clean up any previously exported files.
+ const string filenamesPrefix = "geomorphicCategorization";
+ foreach (string file in Directory.GetFiles(tempDir, $"{filenamesPrefix}*"))
+ File.Delete(file);
+
+ // Export the discrete field result to a raster file.
+ var exportedFiles = await _geomorphicCategoryField.ExportToFilesAsync(tempDir, filenamesPrefix);
+
+ if (exportedFiles.Count == 0 || !File.Exists(exportedFiles[0]))
+ {
+ await new MessageDialog2("Exported geomorphic categorization file does not exist.", "Export Error").ShowAsync();
+ CategorizeButton.IsEnabled = true;
+ CategorizeButton.Content = "Categorize";
+ return;
+ }
+
+ // Display the geomorphic categories on the map.
+ DisplayGeomorphicCategories(exportedFiles[0]);
+
+ // Show the layer toggle controls and hide the categorize button.
+ CategorizePanel.Visibility = Visibility.Collapsed;
+ LayerTogglePanel.Visibility = Visibility.Visible;
+ GeomorphicRadioButton.IsChecked = true;
+ UpdateVisibleRasterLayer();
+ }
+ catch (Exception ex)
+ {
+ await new MessageDialog2(ex.Message, "Error exporting geomorphic categorization").ShowAsync();
+ CategorizeButton.IsEnabled = true;
+ CategorizeButton.Content = "Categorize";
+ }
+ }
+
+ private void DisplayGeomorphicCategories(string rasterFilePath)
+ {
+ // Create a raster layer from the exported geomorphic categorization file.
+ _geomorphicRasterLayer = new RasterLayer(new Raster(rasterFilePath));
+
+ // Create an array of colors for the geomorphic categories.
+ // The array index maps directly to the pixel value in the raster.
+ var colors = new Color[]
+ {
+ Color.Transparent, // 0 = no category (NoData pixels are hidden)
+ Color.FromArgb(25, 118, 210), // 1 = raised shoreline - blue
+ Color.FromArgb(128, 203, 196), // 2 = ice covered - teal
+ Color.FromArgb(121, 85, 72), // 3 = ice-free high ground - brown
+ };
+
+ // Create a colormap renderer to assign colors to pixel values and apply it to the raster layer.
+ _geomorphicRasterLayer.Renderer = new ColormapRenderer(colors);
+
+ // Set opacity to allow the basemap hillshade to show through.
+ _geomorphicRasterLayer.Opacity = 0.5;
+
+ // Add the geomorphic categorization raster layer to the map.
+ MyMapView.Map.OperationalLayers.Add(_geomorphicRasterLayer);
+ }
+
+ private void OnRasterLayerSelectionChanged(object sender, RoutedEventArgs e)
+ {
+ UpdateVisibleRasterLayer();
+ }
+
+ private void UpdateVisibleRasterLayer()
+ {
+ if (_elevationRasterLayer == null) return;
+ bool showGeomorphic = GeomorphicRadioButton.IsChecked == true;
+ _elevationRasterLayer.IsVisible = !showGeomorphic;
+ if (_geomorphicRasterLayer != null)
+ _geomorphicRasterLayer.IsVisible = showGeomorphic;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.md b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.md
new file mode 100644
index 0000000000..337f08b9c0
--- /dev/null
+++ b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.md
@@ -0,0 +1,57 @@
+# Apply map algebra
+
+Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.
+
+
+
+## Use case
+
+Categorizing raster data, such as elevation values, into distinct categories is a common spatial analysis workflow. This often involves applying threshold‑based logic or algebraic expressions to transform continuous numeric fields into discrete, integer‑based categories suitable for downstream analytical or computational operations. These operations can be specified and applied using map algebra.
+
+## How to use the sample
+
+When the sample opens, it displays the source elevation raster. Select the **Categorize** button to generate a raster with three distinct ice age related geomorphological categories (raised shore line areas in blue, ice free high ground in brown and areas covered by ice in teal). After processing completes, use the radio buttons to switch between the map algebra results raster and the original elevation raster.
+
+## How it works
+
+1. Create a `ContinuousField` from a raster file using `ContinuousField.CreateAsync`.
+2. Create a `ContinuousFieldFunction` from the continuous field and mask values below sea level using `IsGreaterThanOrEqualTo`.
+3. Round elevation values down to the lowest 10-meter interval with map algebra operators
+ `((continuousFieldFunction / 10).Floor() * 10)`, and then convert the result to a `DiscreteFieldFunction` with
+ `ToDiscreteFieldFunction`.
+4. Create `BooleanFieldFunction`s for each category by defining a range with map algebra operators such as
+ `IsGreaterThanOrEqualTo`, `LogicalAnd`, and `IsLessThan`.
+5. Create a new `DiscreteField` by chaining `ReplaceIf` operations into discrete category values and evaluating the
+ result with `EvaluateAsync`.
+6. Export the discrete field to files with `ExportToFilesAsync` and create a `Raster` with the result. Use it to create
+ a `RasterLayer`.
+7. Apply a `ColormapRenderer` to the raster and display it in the map view.
+
+## Relevant API
+
+* BooleanFieldFunction
+* ColormapRenderer
+* ColorRamp
+* ContinuousField
+* ContinuousFieldFunction
+* DiscreteField
+* DiscreteFieldFunction
+* MinMaxStretchParameters
+* Raster
+* RasterLayer
+* StretchRenderer
+
+## Offline data
+
+This sample downloads the following items from ArcGIS Online automatically:
+
+* [Isle of Arran 10m resolution digital terrain elevation raster](https://www.arcgis.com/home/item.html?id=aa97788593e34a32bcaae33947fdc271)
+
+## About the data
+
+The elevation raster of the Isle of Arran, Scotland is a 10m resolution digital terrain model.
+(Data Copyright Scottish Government and SEPA (2014)).
+
+## Tags
+
+elevation, map algebra, raster, spatial analysis, terrain
diff --git a/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.metadata.json b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.metadata.json
new file mode 100644
index 0000000000..b0e4a95cfb
--- /dev/null
+++ b/src/WinUI/ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra/readme.metadata.json
@@ -0,0 +1,38 @@
+{
+ "category": "Analysis",
+ "description": "Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.",
+ "formal_name": "ApplyMapAlgebra",
+ "ignore": false,
+ "images": [
+ "ApplyMapAlgebra.jpg"
+ ],
+ "keywords": [
+ "elevation",
+ "map algebra",
+ "raster",
+ "spatial analysis",
+ "terrain"
+ ],
+ "offline_data": [
+ "aa97788593e34a32bcaae33947fdc271"
+ ],
+ "redirect_from": [],
+ "relevant_apis": [
+ "BooleanFieldFunction",
+ "ColorRamp",
+ "ColormapRenderer",
+ "ContinuousField",
+ "ContinuousFieldFunction",
+ "DiscreteField",
+ "DiscreteFieldFunction",
+ "MinMaxStretchParameters",
+ "Raster",
+ "RasterLayer",
+ "StretchRenderer"
+ ],
+ "snippets": [
+ "ApplyMapAlgebra.xaml.cs",
+ "ApplyMapAlgebra.xaml"
+ ],
+ "title": "Apply map algebra"
+}
\ No newline at end of file
diff --git a/src/WinUI/readme.md b/src/WinUI/readme.md
index 4d3ccacfe1..b8a915a006 100644
--- a/src/WinUI/readme.md
+++ b/src/WinUI/readme.md
@@ -2,6 +2,7 @@
## Analysis
+* [Apply map algebra](ArcGIS.WinUI.Viewer/Samples/Analysis/ApplyMapAlgebra) - Apply map algebra to an elevation raster to floor, mask, and categorize the elevation values into discrete integer-based categories.
* [Distance measurement analysis](ArcGIS.WinUI.Viewer/Samples/Analysis/DistanceMeasurement) - Measure distances between two points in 3D.
* [Line of sight (geoelement)](ArcGIS.WinUI.Viewer/Samples/Analysis/LineOfSightGeoElement) - Show a line of sight between two moving objects.
* [Line of sight (location)](ArcGIS.WinUI.Viewer/Samples/Analysis/LineOfSightLocation) - Perform a line of sight analysis between two points in real time.