Elevation data: Difference between revisions
No edit summary |
No edit summary |
||
Line 28: | Line 28: | ||
The format of this elevation data template is described here: [[Elevation_layers_in_templates#Elevation_data_layers|Elevation layers in templates]] | The format of this elevation data template is described here: [[Elevation_layers_in_templates#Elevation_data_layers|Elevation layers in templates]] | ||
=== Elevation queries === | |||
The main purpose of the IElevationData interface is to calculate elevation values in a certain geographical point or area. The following methods are supported for this: | |||
<source lang="c#"> | <source lang="c#"> | ||
Line 51: | Line 54: | ||
/// </returns> | /// </returns> | ||
List<ElevationResult> CalcElevations(double lat, double lon, ElevationQueryParams queryParams); | List<ElevationResult> CalcElevations(double lat, double lon, ElevationQueryParams queryParams); | ||
/// <summary> | |||
/// Synchronously calculate an elevation map covering the given raster projector. | |||
/// </summary> | |||
/// <param name="rp">Raster projector defining the area and projection of the elevation map.</param> | |||
/// <param name="queryParams">Parameters for the elevation query.</param> | |||
/// <returns>A bitmap of floating point elevation samples.</returns> | |||
BitmapFloatData CalcElevationMap(IRasterProjector rp, ElevationQueryParams queryParams); | |||
/// <summary> | |||
/// Calculate a normal map covering the given raster projector. The normal vectors are encoded as | |||
/// XYZ -> RGB values. The alpha channel is not used. | |||
/// </summary> | |||
/// <param name="rp">Raster projector defining the area and projection of the elevation map.</param> | |||
/// <param name="interpolationMethod">Method of resampling/interpolation. Nearest is usually sufficient here.</param> | |||
/// <param name="timeoutMs">Timeout in ms. If 0, block indefinitely.</param> | |||
/// <returns></returns> | |||
Bitmap32Data CalcNormalMap(IRasterProjector rp, InterpolationMethod interpolationMethod = InterpolationMethod.Nearest, int timeoutMs = 0); | |||
</source> | |||
As we can see all these methods require an '''ElevationQueryParams''' object as input. This query object contains all the parameters for the elevation query, such as what data elevation data types to look for, what resolution we require, interpolation method etc. The elevation data query is actually a specialization of the more general raster data query: | |||
<source lang="c#"> | |||
public class RasterQueryParams | |||
{ | |||
/// <summary> | |||
/// Method of resampling/interpolation (Nearest or Bilinear). | |||
/// </summary> | |||
public InterpolationMethod interpolationMethod = InterpolationMethod.Bilinear; | |||
/// <summary> | |||
/// Only include data from data sets with any of the given tags | |||
/// </summary> | |||
public string Tags { get; set; } | |||
/// <summary> | |||
/// Minimum resolution (in m/pixel) of the data we want to base the calculation on. | |||
/// </summary> | |||
public double resolution = 0.0; | |||
/// <summary> | |||
/// Timeout in ms when waiting for data. If 0, wait indefinitely. | |||
/// </summary> | |||
public int timeoutMs = 0; | |||
}; | |||
/// <summary> | |||
/// Parameter class for elevation data queries. | |||
/// </summary> | |||
public class ElevationQueryParams : RasterQueryParams | |||
{ | |||
/// <summary> | |||
/// Query data type, only return samples of this data type. Ignored if set to Undefined. | |||
/// </summary> | |||
public ElevationDataType dataType = ElevationDataType.Undefined; | |||
}; | |||
</source> | </source> | ||
The single point elevation data queries return an '''ElevationResult''' which looks like this: | |||
<source lang="c#"> | |||
public class ElevationResult | |||
{ | |||
public enum StatusCode | |||
{ | |||
Undefined = 0, | |||
/// <summary> | |||
/// The query finished successfully | |||
/// </summary> | |||
OK, | |||
/// <summary> | |||
/// No data could be found at the given position. | |||
/// </summary> | |||
Missing, | |||
/// <summary> | |||
/// The query took longer than the given timeout values | |||
/// </summary> | |||
Timeout, | |||
/// <summary> | |||
/// Some unspecified error caused the query to fail. | |||
/// </summary> | |||
Error | |||
}; | |||
/// <summary> | |||
/// The result status of the query. | |||
/// </summary> | |||
public StatusCode Status { get; set; } | |||
== | /// <summary> | ||
/// The actual elevation value, if status == OK | |||
/// </summary> | |||
public double Value { get; set; } | |||
/// <summary> | |||
/// Estimated data resolution (in m/pixel) of the dataset from which the result was taken. | |||
/// </summary> | |||
public double Resolution { get; set; } | |||
/// <summary> | |||
/// Identifier for the elevation data layer that was used to produce this sample. | |||
/// This value can be used to look up further info about the data source by resolving | |||
/// it in ElevationDataManager.DataSources | |||
/// </summary> | |||
public int LayerId { get; set; } | |||
/// <summary> | |||
/// Type of elevation data (TerrainModel, Bathymetry, etc). | |||
/// </summary> | |||
public ElevationDataType DataType { get; set; } | |||
} | |||
</source> | |||
As we can see the result contains information on the sample we found in the given input position. In order to get more information on the underlying data layer, you need an '''ElevationDataManager''' handling the layers. | |||
== IElevationDataManager == | |||
=== Note on async methods === | === Note on async methods === |
Revision as of 11:35, 22 December 2021
Elevation data and other single channel data can be used for various analysis and visualization purposes throughout the Maria system. This page shows an overview of the elevation data programming API's
The two main interfaces for elevation data are IElevationData (implemented by the NativeElevationData class) and IElevationDataManager (implemented by ElevationDataManager).
IElevationData
This interface contains methods for querying elevation data from a set of data layers.
Data layers
An elevation data set consists of one or more elevation data map entries stored on a Maria raster data service. The set of available map entries can be queried from the catalog service and any MapEntry with MapContentType = ElevationData can be used.
The elevation data layers are usually managed by the ElevationDataManager, but you can also specify them explicitly through a MapTemplate with the SetTemplate method
/// <summary>
/// Setup elevation data layers from the given template.
/// This method will clear the current elevation data set.
/// </summary>
void SetTemplate(MapTemplate template);
/// <summary>
/// Get the currently active elevation data template.
/// </summary>
/// <returns></returns>
MapTemplate GetTemplate();
The format of this elevation data template is described here: Elevation layers in templates
Elevation queries
The main purpose of the IElevationData interface is to calculate elevation values in a certain geographical point or area. The following methods are supported for this:
/// <summary>
/// Generalized API for elevation queries.
/// </summary>
/// <param name="lat">Latitude of the query point</param>
/// <param name="lon">Longitude of the query point</param>
/// <param name="queryParams">Parameters for the elevation query.</param>
/// <returns>An ElevationResult containing the elevation and resolution of the source data</returns>
ElevationResult CalcElevation(double lat, double lon, ElevationQueryParams queryParams);
/// <summary>
/// Calculate multiple elevations for a given point.
/// </summary>
/// <param name="lat">Latitude of the query point</param>
/// <param name="lon">Longitude of the query point</param>
/// <param name="queryParams">Parameters for the elevation query.</param>
/// <returns>
/// A list of ElevationResults containing the elevation and resolution of each layer in the source data.
/// To get further info on each of the layers, you can look up the matching ElevationDataSource entry in
/// IElevationDataManager.
/// </returns>
List<ElevationResult> CalcElevations(double lat, double lon, ElevationQueryParams queryParams);
/// <summary>
/// Synchronously calculate an elevation map covering the given raster projector.
/// </summary>
/// <param name="rp">Raster projector defining the area and projection of the elevation map.</param>
/// <param name="queryParams">Parameters for the elevation query.</param>
/// <returns>A bitmap of floating point elevation samples.</returns>
BitmapFloatData CalcElevationMap(IRasterProjector rp, ElevationQueryParams queryParams);
/// <summary>
/// Calculate a normal map covering the given raster projector. The normal vectors are encoded as
/// XYZ -> RGB values. The alpha channel is not used.
/// </summary>
/// <param name="rp">Raster projector defining the area and projection of the elevation map.</param>
/// <param name="interpolationMethod">Method of resampling/interpolation. Nearest is usually sufficient here.</param>
/// <param name="timeoutMs">Timeout in ms. If 0, block indefinitely.</param>
/// <returns></returns>
Bitmap32Data CalcNormalMap(IRasterProjector rp, InterpolationMethod interpolationMethod = InterpolationMethod.Nearest, int timeoutMs = 0);
As we can see all these methods require an ElevationQueryParams object as input. This query object contains all the parameters for the elevation query, such as what data elevation data types to look for, what resolution we require, interpolation method etc. The elevation data query is actually a specialization of the more general raster data query:
public class RasterQueryParams
{
/// <summary>
/// Method of resampling/interpolation (Nearest or Bilinear).
/// </summary>
public InterpolationMethod interpolationMethod = InterpolationMethod.Bilinear;
/// <summary>
/// Only include data from data sets with any of the given tags
/// </summary>
public string Tags { get; set; }
/// <summary>
/// Minimum resolution (in m/pixel) of the data we want to base the calculation on.
/// </summary>
public double resolution = 0.0;
/// <summary>
/// Timeout in ms when waiting for data. If 0, wait indefinitely.
/// </summary>
public int timeoutMs = 0;
};
/// <summary>
/// Parameter class for elevation data queries.
/// </summary>
public class ElevationQueryParams : RasterQueryParams
{
/// <summary>
/// Query data type, only return samples of this data type. Ignored if set to Undefined.
/// </summary>
public ElevationDataType dataType = ElevationDataType.Undefined;
};
The single point elevation data queries return an ElevationResult which looks like this:
public class ElevationResult
{
public enum StatusCode
{
Undefined = 0,
/// <summary>
/// The query finished successfully
/// </summary>
OK,
/// <summary>
/// No data could be found at the given position.
/// </summary>
Missing,
/// <summary>
/// The query took longer than the given timeout values
/// </summary>
Timeout,
/// <summary>
/// Some unspecified error caused the query to fail.
/// </summary>
Error
};
/// <summary>
/// The result status of the query.
/// </summary>
public StatusCode Status { get; set; }
/// <summary>
/// The actual elevation value, if status == OK
/// </summary>
public double Value { get; set; }
/// <summary>
/// Estimated data resolution (in m/pixel) of the dataset from which the result was taken.
/// </summary>
public double Resolution { get; set; }
/// <summary>
/// Identifier for the elevation data layer that was used to produce this sample.
/// This value can be used to look up further info about the data source by resolving
/// it in ElevationDataManager.DataSources
/// </summary>
public int LayerId { get; set; }
/// <summary>
/// Type of elevation data (TerrainModel, Bathymetry, etc).
/// </summary>
public ElevationDataType DataType { get; set; }
}
As we can see the result contains information on the sample we found in the given input position. In order to get more information on the underlying data layer, you need an ElevationDataManager handling the layers.
IElevationDataManager
Note on async methods
The IElevationData interface currently contains a set of methods with Async in their names which return Task objects. We don't really recommend using these, and they may be obsoleted in a future version. Instead, wrap any time consuming elevation methods in your own async caller method to have better control over these operations.