Adding a feature model
You can add and remove data on the Map using Map::getLayerList()
Map::getLayerList()
Map::getLayerList()
.
To add a feature model to the map, you:
-
Create a
FeatureLayer
FeatureLayer
FeatureLayer
based on the model and styling information (IFeaturePainter
IFeaturePainter
IFeaturePainter
)
This code snippet demonstrates how a feature model is added to the map, configured with a custom painter:
std::shared_ptr<IFeatureModel> geometryModel = CustomerGeometryModel::create();
std::shared_ptr<FeatureLayer> geometryLayer = FeatureLayer::newBuilder()
.model(geometryModel)
.editable(true)
.editCreateGeometryProvider(CustomerGeometryModel::createEditGeometryProvider())
.build();
map->getLayerList()->add(geometryLayer);
var geometryModel = CustomerGeometryModel.Create();
var geometryLayer = FeatureLayer.NewBuilder()
.Model(geometryModel)
.Editable(true)
.EditCreateGeometryProvider(CustomerGeometryModel.CreateEditGeometryProvider())
.Build();
Map.LayerList.Add(geometryLayer);
val geometryModel = CustomerGeometryModel.create()
val geometryLayer = FeatureLayer.newBuilder()
.model(geometryModel)
.editable(true)
.editCreateGeometryProvider(CustomerGeometryModel.createEditGeometryProvider())
.build()
map.layerList.add(geometryLayer)
Styling features
Apart from a mandatory IFeatureModel
IFeatureModel
IFeatureModel
parameter on its constructor, the
FeatureLayer::Builder
FeatureLayer::Builder
FeatureLayer::Builder
also accepts an optional
IFeaturePainter
IFeaturePainter
IFeaturePainter
, which you can use to set up custom styling of the
model features.
Creating your own IFeaturePainter
IFeaturePainter
IFeaturePainter
requires an implementation of two
methods:
-
IFeaturePainter::configureMetadata
IFeaturePainter::configureMetadata
IFeaturePainter::configureMetadata
: used to retrieve metadata about the painter. This metadata is used by the layer to determine when a feature needs to be re-processed by the painter. For example, a feature needs to be painted differently after a certain property of the feature has changed. For more information, see the documentation ofFeaturePainterMetadata
FeaturePainterMetadata
FeaturePainterMetadata
. -
IFeaturePainter::paint
IFeaturePainter::paint
IFeaturePainter::paint
: used to determine how to visualize a feature. Given aFeature
Feature
Feature
andcontext
context
context
, this method performsdraw
calls on theFeatureCanvas
FeatureCanvas
FeatureCanvas
parameter.
This code snippet shows an implementation of the
IFeaturePainter::paint
IFeaturePainter::paint
IFeaturePainter::paint
method:
void RoadsPainter::paint(const Feature& feature, const FeaturePainterContext& context, FeatureCanvas& canvas) const {
const std::optional<std::shared_ptr<Geometry>>& geometry = feature.findGeometry();
if (!geometry) {
std::cerr << "Geometry not found for the given feature: " << feature.getId() << std::endl;
return;
}
std::string roadType = feature.getValue<std::string>(_roadTypePropertyPath).value_or("unknown");
size_t detailLevel = context.getDetailLevel();
std::map<StyleKey, LineStyle> styleMap;
std::map<StyleKey, TextStyle> labelStyleMap;
if (context.isFeatureStateEnabled(FeatureState::selected())) {
styleMap = _selectedStyles;
labelStyleMap = _selectedLabelStyles;
} else if (context.isFeatureStateEnabled(FeatureState::hover())) {
styleMap = _hoverStyles;
labelStyleMap = _hoverLabelStyles;
} else {
styleMap = _regularStyles;
labelStyleMap = _regularLabelStyles;
}
StyleKey key = std::make_pair(detailLevel, roadType);
auto iterator = styleMap.find(key);
LineStyle style = iterator != styleMap.end() ? iterator->second : _fallbackStyle;
canvas.drawGeometry().geometry(*geometry).stroke(style).submit();
auto labelIterator = labelStyleMap.find(key);
bool foundLabel = labelIterator != labelStyleMap.end();
std::optional<std::string> name = feature.getValue<std::string>(_namePropertyPath);
if (foundLabel && name) {
TextStyle labelStyle = labelIterator->second;
canvas.drawLabel().anchor(*geometry).textStyle(labelStyle).text(*name).submit();
}
}
public void Paint(Feature feature, FeaturePainterContext context, FeatureCanvas canvas)
{
Geometry geometry = feature.FindGeometry();
if (geometry == null)
{
Console.WriteLine("Feature [" + feature.Id + "] without geometry!");
return;
}
Dictionary<StyleKey, LineStyle> styleMap;
Dictionary<StyleKey, TextStyle> labelStyleMap;
if (context.IsFeatureStateEnabled(FeatureState.Selected))
{
styleMap = SelectedStylesMap;
labelStyleMap = SelectedLabelStylesMap;
}
else if (context.IsFeatureStateEnabled(FeatureState.Hover))
{
styleMap = HoverStylesMap;
labelStyleMap = HoverLabelStylesMap;
}
else
{
styleMap = RegularStylesMap;
labelStyleMap = RegularLabelStylesMap;
}
string type = feature.GetValue<string>(_typePropertyPath);
var key = new StyleKey(context.DetailLevel, type);
if (!styleMap.TryGetValue(key, out var style))
{
style = FallbackStyle;
}
canvas.DrawGeometry().Geometry(geometry).Stroke(style).Draped(true).Submit();
if (labelStyleMap.TryGetValue(key, out var textStyle))
{
var name = feature.GetValue<string>(_namePropertyPath);
if (!string.IsNullOrEmpty(name))
{
canvas.DrawLabel().Anchor(geometry).TextStyle(textStyle).Text(name).Submit();
}
}
}
override fun paint(feature: Feature, context: FeaturePainterContext, canvas: FeatureCanvas) {
val geometry = feature.findGeometry()
if (geometry == null) {
Log.e("LUCIAD", "Feature [" + feature.id + "] without geometry!")
return
}
val styleMap: Map<StyleKey, LineStyle>
val labelStyleMap: Map<StyleKey, TextStyle>
if (context.isFeatureStateEnabled(FeatureState.Selected)) {
styleMap = SelectedStylesMap
labelStyleMap = SelectedLabelStylesMap
} else {
styleMap = RegularStylesMap
labelStyleMap = RegularLabelStylesMap
}
val type = feature.getValue<String>(_typePropertyPath)
val key = StyleKey(context.detailLevel, type!!)
val lineStyle = styleMap[key] ?: FallbackStyle
canvas.drawGeometry().geometry(geometry).stroke(lineStyle).draped(true).submit()
val name = feature.getValue<String>(_namePropertyPath)
name?.let { labelName ->
labelStyleMap[key]?.let { style ->
canvas.drawLabel().anchor(geometry).textStyle(style).text(labelName).submit()
}
}
}
Visualizing geometries
You can visualize geometries with the FeatureCanvas::drawGeometry
FeatureCanvas::drawGeometry
FeatureCanvas::drawGeometry
method. This method requires at least a Geometry
Geometry
Geometry
and a stroke and/or fill style.
You create Feature styles through builder methods on one of the style classes. The different types of feature styles are:
-
Fill StyleFill StyleFill Style: describes the style of a surface, a fill color or specific textures for example.
-
Line StyleLine StyleLine Style: describes the style of a line, a line color or width for example.
-
Complex Stroke Line StyleComplex Stroke Line StyleComplex Stroke Line Style: describes the style of a line with a complex stroke pattern, such as a dashed line.
Drawing icons and text
You can draw icons and text on the map with FeatureCanvas::drawIcon
FeatureCanvas::drawIcon
FeatureCanvas::drawIcon
and
FeatureCanvas::drawText
FeatureCanvas::drawText
FeatureCanvas::drawText
respectively.
Adding labels to features
You can attach icon and text labels to features with the FeatureCanvas::drawLabel
FeatureCanvas::drawLabel
FeatureCanvas::drawLabel
method. See related article on adding labels for more information.