Color Map Layers: Difference between revisions

From Maria GDK Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(11 intermediate revisions by the same user not shown)
Line 11: Line 11:


== Low Level API ==
== Low Level API ==
The MariaGDK API allows you to define map layers that are generated dynamically based on some data input combined with a color palette and some conversion function. Typically this can be to assign colors to certain elevation values, or by converting an elevation data set to a slope map and coloring the slope values according to the slope values.
=== Color Map Data Provider ===
The low level map data provider which takes raster data as input and produces an output color map is usually a '''ColorMapDataProvider''' which has various methods for converting input single channel raster values to output colors by mapping values to a color table.
Most applications will register a default ColorMapDataProvider to handle ElevationData
<source lang="c#">
_elevationColorMapProvider = new ColorMapDataProvider(new TileCacheSpec(), _elevationData, colorTableManager);
_tileCacheManager.AddMapDataProvider(MapContentType.ElevationColorMap, _elevationColorMapProvider);
</source>
Any ColorMapLayer defined with MapContentType = ElevationColorMap will use this provider.
You can also define custom color map layers which use other data providers. These providers will be generated based on the input data, as described below.


=== Color Map Layer ===
=== Color Map Layer ===
Line 22: Line 39:
       ...
       ...
         /// <summary>
         /// <summary>
         /// Create a named color map layer with the given data provider.
         /// Create a named color map layer with the given input data.
         /// </summary>
         /// </summary>
         /// <param name="name">Name for the new layer.</param>
         /// <param name="layerSignature">Name for the new layer.</param>
         /// <param name="provider">Data provider. Should be of type ElevationColorMapProvider.</param>
         /// <param name ="paletteId">ID of the palette to be used. This palette name must be available in the requested data provider.</param>
         /// <param name ="paletteId">ID of the palette to be used. This palette name must be available in the given data provider.</param>
         /// <param name="rasterData">Raster dataset to use as input for the color map layer</param>
         /// <param name="smoothInterpolation">Enable smooth interpolation of the map colors.</param>
         /// <param name="smoothInterpolation">Enable smooth interpolation of the map colors.</param>
         /// <returns>A new raster layer with the given properties.</returns>
         /// <returns>A new raster layer with the given properties.</returns>
         IMapServiceRasterLayerData AddColorMapLayer(string name, IMapDataProvider provider, string paletteId, bool smoothInterpolation = true);
         IMapServiceRasterLayerData AddColorMapLayer(string layerSignature, string paletteId, IGenericRasterDataset rasterData, bool smoothInterpolation);
 
        /// <summary>
        /// Add elevation color map layer. This method will create an elevation color map based on
        /// the global data provider for ElevationColorMaps. This usually means all enabled elevation data
        /// layers in the main ElevationDataManager.
        /// </summary>
        /// <param name="layerSignature">Name for the new data layer.</param>
        /// <param name ="paletteId">ID of the palette to be used. This palette name must be available in the global ElevationColorMap data provider.</param>
        /// <param name="smoothInterpolation">Enable smooth interpolation of the map colors.</param>
        /// <returns></returns>
        IMapServiceRasterLayerData AddElevationColorMapLayer(string layerSignature, string paletteId, bool smoothInterpolation);


         /// <summary>
         /// <summary>
Line 49: Line 77:
The default implementation of this interface is typically '''TPG.GeoFramework.MapLayer.NativeMapLayerViewModel'''.  
The default implementation of this interface is typically '''TPG.GeoFramework.MapLayer.NativeMapLayerViewModel'''.  


The smoothInterpolation parameter controls wether or not the output should be smoothed, i.e if the colors should be interpolated between neighboring points. This should be combined with the InterpolationMethod property of the ElevationColorMapProvider used to produce the actual data (see below).
As we can see, there are two methods for creating Color map layers, one of which takes an '''IGenericRasterDataSet''' as input (See [[Generic raster data]]). The simple version, with no dataset specified will assume that you want elevation data as input, and will
 
use the default color map data provider registered for the ElevationColorMap MapContentType as described above.
 
=== Data Provider ===
In order to fill this layer with input data, you need an '''IMapDataProvider''', more specifically an '''ElevationColorMapProvider'''. Note that the "Elevation" part of this type name is more for historical reasons. The input data need not be elevation, but it should be single channel.


This data provider needs to be set up with two things:
The other version registers a new '''ColorMapDataProvider''' with the given '''IGenericRasterDataSet''' as input and can be used to produce color maps based on any single channel input data.


* A ''color palette'' with an ID matching the color palette in the color map layer.
==== Color Palettes ====
* An '''IElevationData''' with at least one map data signature as input.


==== Color Palette ====
The "paletteId" parameter in the API above refers to a color table which must be registered in the '''IColorInterpolationTableManager''' which can be accessed through the the '''IMapLayerViewModel.ColorTableManager''' property. The default ColorInterpolationTableManager implementation will set up the following standard palettes:
The color palette is an object of type '''TPG.GeoFramework.MapLayer.ColorInterpolationTable''' and is assigned to the data provider through the ''ColorTables'' property. The '''ElevationColorMapProvider''' will by default be set up with the following standard palettes:


* '''elevation''' - Elevation color values from 0 to 7000m
* '''elevation''' - Elevation color values from 0 to 7000m
Line 70: Line 93:
See the code doc for more info on how to set up a custom palette, but it is fairly self explanatory. You simply fill in a table mapping input data values to output colors.
See the code doc for more info on how to set up a custom palette, but it is fairly self explanatory. You simply fill in a table mapping input data values to output colors.


==== Elevation Data ====
=== Color Map Layers in Templates ===
The actual data values are served through the '''IElevationData''' interface to the '''ElevationColorMapProvider'''. Again, the name indicates that this must be elevation data, but it can in fact be any single channel raster data. The '''IElevationData''' can be set up with data either directly by setting a template, or by using an '''ElevationDataManager''' in which you can enable/disable specific data layers.  
In order to handle custom data color map templates, you need to set up a template layer handler for this. This will set up data providers based on the template data and assign them to color map layers that reference these data. Note that this handler is not necessary if you are only using color maps based on the default elevation data.
 
== Example ==


The following code example sets up a color map layer with a single data layer (provided as a ''MapEntry''), using the standard "elevation" palette and nearest point interpolation.  
This handler needs a ColorTableManager for handling the palettes used in the color map layers.


<source lang="c#">
<source lang="c#">
 
   // Automatically create color map layers from template data.
void CreateColorMapLayer(MapEntry mapEntry, INativeTileCacheManager tileCacheManager)
   _mapController.TemplateLayerHandlers.Insert(0, new ColorMapLayerTemplateHandler(_tileCacheManager, _mapCatalogServiceClient, colorTableManager));
{
  // Create dedicated IElevationData and ElevationColorMapProvider for this layer.
  var elevationInterfacer = new ElevationDataInterfacer(tileCacheManager);
  var elevationData = new ElevationDataFactory().New(elevationInterfacer);
  var elevationMapProvider = new ElevationColorMapProvider(new TileCacheSpec(), elevationData);
  elevationMapProvider.InterpolationMethod = InterpolationMethod.Nearest;
 
   // Create new color map layer
  var rasterLayer = _mapLayerViewModel.AddColorMapLayer("ColorMapLayer:" + mapEntry.MapSignature, elevationMapProvider, "elevation", false);
   rasterLayer.Visible = true;
           
  // Update elevation data
  var template = CreateElevationTemplate(mapEntry);
  elevationData.SetTemplate(template);
}
</source>
 
For completeness, here is a utility method to convert a MapEntry into an elevation data template:
 
<source lang="c#">
MapTemplate CreateElevationTemplate(MapEntry mapEntry)
{
    var elevTemplate = new MapTemplate();
 
    var elevationDataSource = new ServiceDatasourceInfo()
    {
        MapSignature = mapEntry.MapSignature,
        WantedMapContentType = mapEntry.MapType,
    };
 
    var elevTemplateLayer = new MapTemplateLayer()
    {
        DatasourceInfo = elevationDataSource,
        LayerType = TemplateLayerType.ElevationLayer,
        Name = mapEntry.MapSignature
    };
 
    elevTemplate.TemplateLayers.Add(elevTemplateLayer);
 
    return elevTemplate;
}
</source>
</source>


Line 138: Line 118:
         IColorMapHandler CreateColorMapHandler();
         IColorMapHandler CreateColorMapHandler();


        /// <summary>
        /// Create a color map layer from the given raster data set.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        IColorMapHandler CreateColorMapHandler(IGenericRasterDataset data);
     }
     }
}
}
Line 145: Line 131:
     public interface IColorMapHandler : IDisposable
     public interface IColorMapHandler : IDisposable
     {
     {
        /// <summary>
      /// <summary>
         /// Get or set the name of the color palette to use as layer colors.
         /// Get or set the name of the color palette to use as layer colors.
         /// </summary>
         /// </summary>
         string ActiveColorPalette { get; set; }
         string ActiveColorPalette { get; set; }


         // <summary>
         /// <summary>
         /// Get color palette with given name.
         /// Get or set the interpolation method to use for elevation data calculations.
         /// </summary>
         /// </summary>
         /// <param name="name">Name of color palette to retrieve.</param>
         ResamplingMethod Resampling { get; set; }
        /// <returns>Color palette or null if not found.</returns>
        ColorInterpolationTable GetColorPalette(string name);


         /// <summary>
         /// <summary>
         /// Add a new color palette or update an existing color palette.
         /// The underlying raster data set for this color map layer
         /// </summary>
         /// </summary>
         /// <param name="name">Name of color palette.</param>
        IGenericRasterDataset Data { get; }
         /// <param name="colorInterpolationTable">Color palette instance to add or update.</param>
       
         void AddOrUpdateColorPalette(string name, ColorInterpolationTable colorInterpolationTable);
         /// <summary>
        /// Name identifier for the raster map layer
         /// </summary>
         string LayerName { get; set; }


         /// <summary>
         /// <summary>
         /// Remove a color palette with given name.
         /// Include all MapEntries tagged with any of these tags in the dataset. If empty,
        /// ignore tags.
         /// </summary>
         /// </summary>
         /// <param name="name">Name of color palette to remove.</param>
         List<string> Tags { get; set; }
        void RemoveColorPalette(string name);


         /// <summary>
         /// <summary>
         /// Get or set the interpolation method to use for elevation data calculations.
         /// Include all these map signatures in the dataset. If empty, include all
        /// signatures.
        /// </summary>
        List<string> MapSignatures { get; set; }
 
        /// <summary>
        /// Include only MapEntries of this type in the dataset.
        /// </summary>
        MapContentType ContentType { get; set; }
 
        /// <summary>
        /// Update data sources and generate color map layer.
         /// </summary>
         /// </summary>
         InterpolationMethod Resampling { get; set; }
         void UpdateData();


         /// <summary>
         /// <summary>
         /// Set the elevation map entry to use for the paletted map layer.
         /// Force clear all map layer data for this color map layer.
         /// </summary>
         /// </summary>
        /// <param name="mapEntry"></param>
         void ClearData();
         void SetElevationMapEntry(MapEntry mapEntry);
     }
     }
}
}
</source>
</source>


The following example shows how to create or update a color map layer through the MARIA API. Color palettes are created in the same way as in the "Low Level API" and added or updated using "AddOrUpdateColorPalette" and removed using "RemoveColorPalette".  
There are two methods for creating ColorMapHandlers, one of which can take a custom IGenericRasterDataset as input. The other will generate the necessary objects internally.


<source lang="c#">
Color palettes are created in the same way as in the "Low Level API" and are accessed through the '''IMariaMapLayer.ColorTableManager''' property.
var elevationMapEntry = ...;
var colorMapHandler = _mapLayer.CreateColorMapHandler();


// The active color palette name is set to one of the elevation providers color palette names
=== Example ===
colorMapHandler.ActiveColorPalette = "PaletteName";
The following example shows how to set up a color map layer for clutter data through the Maria API. Note that the Maria Map layer must be initialized before calling CreateColorMapHandler(). This can for example be run on the MariaMapLayer.LayerInitialized event.
colorMapHandler.SetElevationMapEntry(elevationMapEntry);
</source>


The following example shows how to remove a color map layer through the MARIA API.
<source lang="c#">
// Add color table
var clutterTable = new ColorInterpolationTable("clutter_palette", "value");
var colorRange = new ColorValueRange();
colorRange.Add(0.0f, Color.FromArgb(0, 0, 0, 0));
colorRange.Add(1.0f, Color.FromArgb(180, 255, 218, 185));
colorRange.Add(14.0f, Color.FromArgb(180, 255, 255, 255));
...
clutterTable.ColorRanges.Add(colorRange);
_mapLayer.ColorTableManager.AddColorTable("clutter_palette", clutterTable);


<source lang="c#">
var colorMapHandler = _mapLayer.CreateColorMapHandler();
var colorMapHandler = _mapLayer.CreateColorMapHandler();
...
colorMapHandler.Tags.Add("clutter");
colorMapHandler.Dispose();
colorMapHandler.ContentType = MapContentType.GenericData;
colorMapHandler.LayerName = "Clutter Color Map";
colorMapHandler.ActiveColorPalette = "clutter_palette";
colorMapHandler.Resampling = ResamplingMethod.Nearest;
colorMapHandler.UpdateData();
</source>
</source>


[[Category:MapLayer]]
[[Category:Map layers]]

Latest revision as of 11:09, 21 February 2022

General

Color map layers, or paletted data layers are single channel data layers, for example elevation data, which can be colored according to a user definable palette. Values in the map data are matched with colors in the palette, and the neighboring values may be interpolated over the span of colors in the palette.

Colors may be mapped directly to data values, or there may be a calculation involved. For example we have the possibility to assign colors based on slope or aspect of elevation data sets.

Low Level API

The MariaGDK API allows you to define map layers that are generated dynamically based on some data input combined with a color palette and some conversion function. Typically this can be to assign colors to certain elevation values, or by converting an elevation data set to a slope map and coloring the slope values according to the slope values.

Color Map Data Provider

The low level map data provider which takes raster data as input and produces an output color map is usually a ColorMapDataProvider which has various methods for converting input single channel raster values to output colors by mapping values to a color table.

Most applications will register a default ColorMapDataProvider to handle ElevationData

_elevationColorMapProvider = new ColorMapDataProvider(new TileCacheSpec(), _elevationData, colorTableManager);
_tileCacheManager.AddMapDataProvider(MapContentType.ElevationColorMap, _elevationColorMapProvider);

Any ColorMapLayer defined with MapContentType = ElevationColorMap will use this provider.

You can also define custom color map layers which use other data providers. These providers will be generated based on the input data, as described below.

Color Map Layer

The main API for creating elevation color map layers is through the IMapLayerViewModel interface with the following methods

namespace TPG.GeoFramework.MapLayer.Contracts
{
    public interface IMapLayerViewModel : IExportableLayer
    {
       ...
        /// <summary>
        /// Create a named color map layer with the given input data.
        /// </summary>
        /// <param name="layerSignature">Name for the new layer.</param>
        /// <param name ="paletteId">ID of the palette to be used. This palette name must be available in the requested data provider.</param>
        /// <param name="rasterData">Raster dataset to use as input for the color map layer</param>
        /// <param name="smoothInterpolation">Enable smooth interpolation of the map colors.</param>
        /// <returns>A new raster layer with the given properties.</returns>
        IMapServiceRasterLayerData AddColorMapLayer(string layerSignature, string paletteId, IGenericRasterDataset rasterData, bool smoothInterpolation);

        /// <summary>
        /// Add elevation color map layer. This method will create an elevation color map based on
        /// the global data provider for ElevationColorMaps. This usually means all enabled elevation data
        /// layers in the main ElevationDataManager.
        /// </summary>
        /// <param name="layerSignature">Name for the new data layer.</param>
        /// <param name ="paletteId">ID of the palette to be used. This palette name must be available in the global ElevationColorMap data provider.</param>
        /// <param name="smoothInterpolation">Enable smooth interpolation of the map colors.</param>
        /// <returns></returns>
        IMapServiceRasterLayerData AddElevationColorMapLayer(string layerSignature, string paletteId, bool smoothInterpolation);

        /// <summary>
        ///  Return raster layer for elevation color map (if any).
        /// </summary>
        /// <returns></returns>
        IRasterLayerData GetColorMapLayer(string name);

        /// <summary>
        /// Remove the given color map layer from the layer list.
        /// </summary>
        /// <param name="layer"></param>
        void RemoveColorMapLayer(IMapServiceRasterLayerData layer);

    }
}

The default implementation of this interface is typically TPG.GeoFramework.MapLayer.NativeMapLayerViewModel.

As we can see, there are two methods for creating Color map layers, one of which takes an IGenericRasterDataSet as input (See Generic raster data). The simple version, with no dataset specified will assume that you want elevation data as input, and will use the default color map data provider registered for the ElevationColorMap MapContentType as described above.

The other version registers a new ColorMapDataProvider with the given IGenericRasterDataSet as input and can be used to produce color maps based on any single channel input data.

Color Palettes

The "paletteId" parameter in the API above refers to a color table which must be registered in the IColorInterpolationTableManager which can be accessed through the the IMapLayerViewModel.ColorTableManager property. The default ColorInterpolationTableManager implementation will set up the following standard palettes:

  • elevation - Elevation color values from 0 to 7000m
  • bathymetry - Elevation color values from -500 to 0m
  • slope - Slope values from 24 to 50 degrees.
  • aspect - 0 - 360 degrees.

See the code doc for more info on how to set up a custom palette, but it is fairly self explanatory. You simply fill in a table mapping input data values to output colors.

Color Map Layers in Templates

In order to handle custom data color map templates, you need to set up a template layer handler for this. This will set up data providers based on the template data and assign them to color map layers that reference these data. Note that this handler is not necessary if you are only using color maps based on the default elevation data.

This handler needs a ColorTableManager for handling the palettes used in the color map layers.

   // Automatically create color map layers from template data.
   _mapController.TemplateLayerHandlers.Insert(0, new ColorMapLayerTemplateHandler(_tileCacheManager, _mapCatalogServiceClient, colorTableManager));

MARIA API

The MARIA API for creating elevation color map layers is through the IMariaMapLayer and IColorMapHandler interfaces with the following methods.

namespace TPG.Maria.MapContracts
{
    public interface IMariaMapLayer : IMariaLayer
    {
       ...
        /// <summary>
        /// Get handler for a paletted data layer.
        /// </summary>
        /// <returns>New ColorMapHandler instance.</returns>
        IColorMapHandler CreateColorMapHandler();

        /// <summary>
        /// Create a color map layer from the given raster data set.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        IColorMapHandler CreateColorMapHandler(IGenericRasterDataset data);
    }
}

namespace TPG.Maria.MapContracts
{
    public interface IColorMapHandler : IDisposable
    {
      /// <summary>
        /// Get or set the name of the color palette to use as layer colors.
        /// </summary>
        string ActiveColorPalette { get; set; }

        /// <summary>
        /// Get or set the interpolation method to use for elevation data calculations.
        /// </summary>
        ResamplingMethod Resampling { get; set; }

        /// <summary>
        /// The underlying raster data set for this color map layer
        /// </summary>
        IGenericRasterDataset Data { get; }
        
        /// <summary>
        /// Name identifier for the raster map layer
        /// </summary>
        string LayerName { get; set; }

        /// <summary>
        /// Include all MapEntries tagged with any of these tags in the dataset. If empty,
        /// ignore tags.
        /// </summary>
        List<string> Tags { get; set; }

        /// <summary>
        /// Include all these map signatures in the dataset. If empty, include all 
        /// signatures.
        /// </summary>
        List<string> MapSignatures { get; set; }

        /// <summary>
        /// Include only MapEntries of this type in the dataset. 
        /// </summary>
        MapContentType ContentType { get; set; }

        /// <summary>
        /// Update data sources and generate color map layer.
        /// </summary>
        void UpdateData();

        /// <summary>
        /// Force clear all map layer data for this color map layer.
        /// </summary>
        void ClearData();
    }
}

There are two methods for creating ColorMapHandlers, one of which can take a custom IGenericRasterDataset as input. The other will generate the necessary objects internally.

Color palettes are created in the same way as in the "Low Level API" and are accessed through the IMariaMapLayer.ColorTableManager property.

Example

The following example shows how to set up a color map layer for clutter data through the Maria API. Note that the Maria Map layer must be initialized before calling CreateColorMapHandler(). This can for example be run on the MariaMapLayer.LayerInitialized event.

// Add color table
var clutterTable = new ColorInterpolationTable("clutter_palette", "value");
var colorRange = new ColorValueRange();
colorRange.Add(0.0f, Color.FromArgb(0, 0, 0, 0));
colorRange.Add(1.0f, Color.FromArgb(180, 255, 218, 185));
colorRange.Add(14.0f, Color.FromArgb(180, 255, 255, 255));
...
clutterTable.ColorRanges.Add(colorRange);
_mapLayer.ColorTableManager.AddColorTable("clutter_palette", clutterTable);

var colorMapHandler = _mapLayer.CreateColorMapHandler();
colorMapHandler.Tags.Add("clutter");
colorMapHandler.ContentType = MapContentType.GenericData;
colorMapHandler.LayerName = "Clutter Color Map";
colorMapHandler.ActiveColorPalette = "clutter_palette";
colorMapHandler.Resampling = ResamplingMethod.Nearest;
colorMapHandler.UpdateData();