You can change the way military symbols are visualized by implementing your own IFeaturePainter
IFeaturePainter
IFeaturePainter
.
The IFeaturePainter
IFeaturePainter
IFeaturePainter
implementation needs to:
-
create/derive a
MilitarySymbol
MilitarySymbol
MilitarySymbol
andGeometry
Geometry
Geometry
that represent how and where the military symbol needs to be painted. For features that implement the Military Symbology DataTypeMilitary Symbology DataTypeMilitary Symbology DataType, you can useMilitarySymbol::create
MilitarySymbol::create
MilitarySymbol::create
. See this article if you want to visualize features with a data type other than military symbols. -
Use a
MilitarySymbologyCanvas
MilitarySymbologyCanvas
MilitarySymbologyCanvas
to submit the symbol and geometry as a draw command.
For example, the implementation below paints icon symbols with a surrounding rectangle when they are selected, and also adds an additional label below each symbol.
class MyMilitarySymbolPainter : public IFeaturePainter {
public:
MyMilitarySymbolPainter()
// Regular symbols are painted with a default style, while selected symbols are painted with a surrounding rectangle.
: _defaultStyle(MilitarySymbolStyle::newBuilder().build()), _selectedStyle(_defaultStyle->asBuilder().surroundingRectangleEnabled(true).build()) {
}
void configureMetadata(FeaturePainterMetadata& /*metadata*/) const override {
}
void paint(const Feature& feature, const FeaturePainterContext& context, FeatureCanvas& canvas) const override {
// Retrieve the geometry from the feature
auto geometry = feature.findGeometry();
if (!geometry) {
std::cerr << "Ignoring feature '" << feature.getId() << "'. It has no geometry." << std::endl;
return;
}
// Transform the feature to a military symbol.
auto symbol = MilitarySymbol::create(feature);
// Use a MilitarySymbologyCanvas to submit a draw command for the military symbol.
// The submitted symbol style depends on whether the feature is currently selected or not.
MilitarySymbologyCanvas(canvas)
.drawMilitarySymbol()
.symbol(symbol)
.geometry(geometry)
.style(context.isFeatureStateEnabled(FeatureState::selected()) ? _selectedStyle : _defaultStyle)
.submit();
// Paint the symbol code as an additional label, with a fixed offset below the symbol.
RelativePosition labelPosition{0, HorizontalAlignment::Center, VerticalAlignment::Top, 0, _defaultStyle->getIconSize() + 50.0};
canvas.drawText().text(symbol->getCode()).position(labelPosition).anchor(geometry).submit();
}
private:
std::shared_ptr<MilitarySymbolStyle> _defaultStyle;
std::shared_ptr<MilitarySymbolStyle> _selectedStyle;
};
public class MyMilitarySymbolPainter : IFeaturePainter
{
private readonly MilitarySymbolStyle _defaultStyle;
private readonly MilitarySymbolStyle _selectedStyle;
public MyMilitarySymbolPainter()
{
// Regular symbols are painted with a default style, while selected symbols are painted with a surrounding rectangle.
_defaultStyle = MilitarySymbolStyle.NewBuilder().Build();
_selectedStyle = _defaultStyle.AsBuilder().SurroundingRectangleEnabled(true).Build();
}
public void ConfigureMetadata(FeaturePainterMetadata metadata)
{
}
public void Paint(Feature feature, FeaturePainterContext context, FeatureCanvas canvas)
{
// Retrieve the geometry from the feature
var geometry = feature.FindGeometry();
if (geometry == null)
{
Console.Error.WriteLine("Ignoring feature '" + feature.Id + "'. It has no geometry.");
return;
}
// Transform the feature to a military symbol.
var symbol = MilitarySymbol.Create(feature);
// Use a MilitarySymbologyCanvas to submit a draw command for the military symbol.
// The submitted symbol style depends on whether the feature is currently selected or not.
new MilitarySymbologyCanvas(canvas)
.DrawMilitarySymbol()
.Symbol(symbol)
.Geometry(geometry)
.Style(context.IsFeatureStateEnabled(FeatureState.Selected) ? _selectedStyle : _defaultStyle)
.Submit();
// Paint the symbol code as an additional label, with a fixed offset below the symbol.
var labelPosition = new RelativePosition(0, HorizontalAlignment.Center, VerticalAlignment.Top, 0, _defaultStyle.IconSize + 50.0);
canvas.DrawText().Text(symbol.Code).Position(labelPosition).Anchor(geometry).Submit();
}
}
public static class MyMilitarySymbolPainter implements IFeaturePainter {
private final MilitarySymbolStyle _defaultStyle;
private final MilitarySymbolStyle _selectedStyle;
public MyMilitarySymbolPainter() {
// Regular symbols are painted with a default style, while selected symbols are painted with a surrounding rectangle.
_defaultStyle = MilitarySymbolStyle.newBuilder().build();
_selectedStyle = _defaultStyle.asBuilder().surroundingRectangleEnabled(true).build();
}
@Override
public void configureMetadata(FeaturePainterMetadata metadata) {
}
@Override
public void paint(Feature feature, FeaturePainterContext context, FeatureCanvas canvas) {
// Retrieve the geometry from the feature
Geometry geometry = feature.findGeometry();
if (geometry == null) {
Log.w("milsym", "Ignoring feature '" + feature.getId() + "'. It has no geometry.");
return;
}
// Transform the feature to a military symbol.
MilitarySymbol symbol = MilitarySymbol.create(feature);
// Use a MilitarySymbologyCanvas to submit a draw command for the military symbol.
// The submitted symbol style depends on whether the feature is currently selected or not.
new MilitarySymbologyCanvas(canvas)
.drawMilitarySymbol()
.symbol(symbol)
.geometry(geometry)
.style(context.isFeatureStateEnabled(FeatureState.Selected) ? _selectedStyle : _defaultStyle)
.submit();
// Paint the symbol code as an additional label, with a fixed offset below the symbol.
RelativePosition labelPosition = new RelativePosition(new Angle(0), HorizontalAlignment.Center, VerticalAlignment.Top, 0, _defaultStyle.getIconSize() + 50.0);
canvas.drawText().text(symbol.getCode()).position(labelPosition).anchor(geometry).submit();
}
}