Some services, such as HERE Maps, require you to display attributions when using their data on the map. LuciadCPillar keeps track of the attributions from all layers that provide attribution data, and exposes an API to retrieve these attributions.

Retrieving the attributions on a map
The attributions on a map are exposed through MapAttributions
MapAttributions
MapAttributions
. You can get attributions from all layers, or request the attributions of a specific layer. Layers that aren’t visible aren’t
included.
const MapAttributions& mapAttributions = map->getAttributions();
const std::vector<DataAttribution>& allDataAttributions = mapAttributions.getAllAttributions();
std::optional<DataAttribution> attributionForOneLayer = mapAttributions.getAttribution(layerId);
MapAttributions mapAttributions = map.Attributions;
IList<DataAttribution> allDataAttributions = mapAttributions.AllAttributions;
DataAttribution attributionForOneLayer = mapAttributions.GetAttribution(layerId);
MapAttributions mapAttributions = map.getAttributions();
List<DataAttribution> allDataAttributions = mapAttributions.getAllAttributions();
DataAttribution attributionForOneLayer = mapAttributions.getAttribution(layerId);
To receive events when any of these attributions change, register an IMapObserver
IMapObserver
IMapObserver
on the map and filter on the attributions property:
map->addObserver(IMapObserver::create([](const MapEvent& event) {
if (event.getChangedProperty() != Map::propertyAttributions()) {
return;
}
// Do something with the attributions, e.g. format and show on the UI
std::stringstream ss;
const MapAttributions& mapAttributions = event.getMap()->getAttributions();
const auto& attributions = mapAttributions.getAllAttributions();
for (auto it = attributions.rbegin(); it != attributions.rend(); it++) {
const auto& attribution = *it;
for (const auto& attributionString : attribution.getAttributionStrings()) {
ss << attributionString << "\n";
}
}
std::cout << "New attributions:\n" << ss.str();
}));
class MyMapObserver : IMapObserver
{
public void OnMapChanged(MapEvent mapEvent)
{
if (mapEvent.ChangedProperty != Map.PropertyAttributions)
{
return;
}
// Do something with the attributions, e.g. format and show on the UI
string total = "";
var mapAttributions = mapEvent.Map.Attributions;
var attributions = mapAttributions.AllAttributions;
foreach (var attribution in attributions.Reverse())
{
foreach (var attributionString in attribution.AttributionStrings)
{
total += "\n" + attributionString;
}
}
Console.WriteLine("New attributions:\n" + total);
}
}
var myMapObserver = new MyMapObserver();
map.AddObserver(myMapObserver);
map.addObserver(mapEvent -> {
if (!mapEvent.getChangedProperty().equals(Map.PropertyAttributions)) {
return;
}
// Do something with the attributions, e.g. format and show on the UI
StringBuilder total = new StringBuilder();
var mapAttributions = mapEvent.getMap().getAttributions();
var attributions = mapAttributions.getAllAttributions();
for (int i = attributions.size() - 1; i >= 0; i--) {
var attribution = attributions.get(i);
for (var attributionString : attribution.getAttributionStrings()) {
total.append(attributionString + "\n");
}
}
Log.d("Attributions", "New attributions:\n" + total);
});
Providing attribution data
For a RasterLayer
RasterLayer
RasterLayer
with a multi-level tiled raster model or quad tree raster model, you can provide your own attribution based on the currently
displayed tiles using an IMultilevelTiledAttributionProvider
IMultilevelTiledAttributionProvider
IMultilevelTiledAttributionProvider
.
QuadTreeRasterModel
.
std::shared_ptr<IMultilevelTiledAttributionProvider> myAttributionProvider = IMultilevelTiledAttributionProvider::create(
[](const std::vector<MultilevelTileInfo>& /*tiles*/, const CancellationToken& /*cancellationToken*/) {
// Search through the tiles and return the appropriate attribution strings
std::vector<std::string> strings{"Attribution 1", "Attribution 2"};
return DataAttribution{strings};
});
auto model = QuadTreeRasterModelBuilder::newBuilder()
.attributionProvider(myAttributionProvider)
...
.build();
class MyAttributionProvider : IMultilevelTiledAttributionProvider
{
public DataAttribution GetAttribution(IList<MultilevelTileInfo> tiles, CancellationToken cancellationToken)
{
// Search through the tiles and return the appropriate attribution strings
List<string> strings = new List<string> { "Attribution 1", "Attribution 2" };
return new DataAttribution(strings);
}
}
var myAttributionProvider = new MyAttributionProvider();
var model = QuadTreeRasterModelBuilder.NewBuilder()
.AttributionProvider(myAttributionProvider)
...
.Build();
IMultilevelTiledAttributionProvider myAttributionProvider = (tiles, cancellationToken) -> {
// Search through the tiles and return the appropriate attribution strings
List<String> strings = List.of("Attribution 1", "Attribution 2");
return new DataAttribution(strings);
};
var model = QuadTreeRasterModelBuilder.newBuilder()
.attributionProvider(myAttributionProvider)
...
.build();