Custom layers
Contents
Once a source is set and has data, a layer can reference it. Layers are used to visualize the data from a source. There are a variety of layer types including: Circle, Line, Fill and Symbol.
CircleLayer
A CircleLayer uses single coordinates from a source to display and render a circle at a location on a map. Circles can be styled with size options, coloring, opacity etc.
Using a JSON file
private async void DidFinishLoadingStyleAsync(MapStyle style)
{
try
{
source = new GeoJsonSource(SOURCE_ID, "dots.json") { IsLocal = true };
Map.Functions.AddSource(source);
CircleLayer circleLayer = new CircleLayer(SOURCE_ID, LAYER_ID);
circleLayer.CircleRadius = 4;
circleLayer.CircleStrokeColor = Color.FromRgb(255, 0, 0);
circleLayer.CircleStrokeWidth = 5;
circleLayer.CircleColor = Color.FromRgb(255, 255, 255);
// Add the CircleLayer to the map
Map.Functions.AddLayer(circleLayer);
}
catch (Exception e)
{
Console.WriteLine($"Error loading GeoJSON: {e.Message}");
}
}
Using a GeoJSON.Net.Geometry object
private async void DidFinishLoadingStyleAsync(MapStyle style)
{
try
{
var points = new List<GeoJSON.Net.Geometry.Point>();
// Note Position uses latitude, longitude while dots.json uses longitude, latitude
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.369863, -74.68954)));
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.36892, -74.687882)));
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.349811, -74.687007)));
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.36056, -74.68222)));
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.364475, -74.704292)));
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.360504, -74.710335)));
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.367119, -74.695556)));
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.354974, -74.694232)));
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.370361, -74.698967)));
points.Add(new GeoJSON.Net.Geometry.Point(new Position(41.360474, -74.709572)));
var multiPoint = new GeoJSON.Net.Geometry.MultiPoint(points);
source = new GeoJsonSource(SOURCE_ID, multiPoint) { IsLocal = true };
Map.Functions.AddSource(source);
CircleLayer circleLayer = new CircleLayer(SOURCE_ID, LAYER_ID);
circleLayer.CircleRadius = 4;
circleLayer.CircleStrokeColor = Color.FromRgb(255, 0, 0);
circleLayer.CircleStrokeWidth = 5;
circleLayer.CircleColor = Color.FromRgb(255, 255, 255);
// Add the CircleLayer to the map
Map.Functions.AddLayer(circleLayer);
}
catch (Exception e)
{
Console.WriteLine($"Error loading GeoJSON: {e.Message}");
}
}
A more detailed example of the CircleLayer in action can be found in the Dots on a Map code example.
LineLayer
The LineLayer is used to visualize a series of coordinates as a line on the map. A line is drawn between each coordinate provided in the LineString geometry in the source.
Using a JSON file
private async void DidFinishLoadingStyleAsync(MapStyle style)
{
try
{
source = new GeoJsonSource(SOURCE_ID, "lines.json") { IsLocal = true };
Map.Functions.AddSource(source);
LineLayer lineLayer = new LineLayer(SOURCE_ID, LAYER_ID);
lineLayer.LineColor = Color.FromRgb(255, 0, 0);
lineLayer.LineWidth = 4;
Map.Functions.AddLayer(lineLayer);
}
catch (Exception e)
{
Console.WriteLine($"Error loading GeoJSON: {e.Message}");
}
}
Using a GeoJSON.Net.Geometry object
private async void DidFinishLoadingStyleAsync(MapStyle style)
{
try
{
var coordinates = new List<IPosition>();
// Note Position uses latitude, longitude while lines.json uses longitude, latitude
coordinates.Add(new Position(44.08758502824516, -119.091796875));
coordinates.Add(new Position(44.213709909702054, -108.80859375));
coordinates.Add(new Position(44.213709909702054, -114.2578125));
coordinates.Add(new Position(36.31512514748051, -113.90625));
var lineString = new GeoJSON.Net.Geometry.LineString(coordinates);
source = new GeoJsonSource(SOURCE_ID, lineString) { IsLocal = true };
Map.Functions.AddSource(source);
LineLayer lineLayer = new(LAYER_ID, SOURCE_ID);
lineLayer.LineWidth = 6f;
lineLayer.LineColor = Color.FromRgb(0, 0, 255);
lineLayer.LineOpacity = .8f;
// Add the LineLayer to the map
Map.Functions.AddLayer(lineLayer);
}
catch (Exception e)
{
Console.WriteLine($"Error loading GeoJSON: {e.Message}");
}
}
Sample JSON (lines.json)
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-119.091796875, 44.08758502824516],
[-108.80859375, 44.213709909702054],
[-114.2578125, 44.213709909702054],
[-113.90625, 36.31512514748051]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-111.09374999999999, 36.94989178681327],
[-111.357421875, 42.5530802889558],
[-107.138671875, 41.83682786072714],
[-108.10546875, 39.36827914916014],
[-111.005859375, 39.30029918615029],
[-108.017578125, 36.80928470205937]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-105.64453124999999, 42.22851735620852],
[-100.1953125, 42.35854391749705],
[-102.919921875, 42.22851735620852],
[-103.0078125, 36.94989178681327],
[-105.908203125, 37.020098201368114],
[-99.931640625, 36.94989178681327]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-98.349609375, 36.87962060502676],
[-98.173828125, 42.48830197960227],
[-95.80078125, 39.33429742980725],
[-94.0869140625, 42.5530802889558],
[-94.04296874999999, 37.055177106660814]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-92.548828125, 42.48830197960227],
[-92.548828125, 36.73888412439431],
[-89.1650390625, 37.26530995561875],
[-89.4287109375, 39.50404070558415],
[-92.021484375, 39.842286020743394],
[-89.384765625, 40.51379915504413],
[-89.384765625, 42.391008609205045],
[-92.493896484375, 42.49640294093705]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-87.4072265625, 42.35854391749705],
[-87.9345703125, 37.23032838760387],
[-83.583984375, 37.19533058280065]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-78.837890625, 37.33522435930639],
[-82.4853515625, 37.3002752813443],
[-82.44140625, 39.774769485295465],
[-79.27734374999999, 39.70718665682654],
[-82.44140625, 40.01078714046552],
[-82.3974609375, 41.705728515237524],
[-79.1455078125, 41.672911819602085]
]
}
}
]
}
FillLayer
A FillLayer makes use of the Polygon geometry from the linked source. A shape is drawn enclosed on the map and the shape is filled in.
Using a JSON file
private async void DidFinishLoadingStyleAsync(MapStyle style)
{
try
{
source = new GeoJsonSource(SOURCE_ID, "fill.json") { IsLocal = true };
Map.Functions.AddSource(source);
FillLayer fillLayer = new FillLayer(SOURCE_ID, LAYER_ID);
fillLayer.FillColor = Color.FromRgb(255, 0, 0);
fillLayer.FillOpacity = 0.4f;
Map.Functions.AddLayer(fillLayer);
}
catch (Exception e)
{
Console.WriteLine($"Error loading GeoJSON: {e.Message}");
}
}
Using a GeoJSON.Net.Geometry object
private async void DidFinishLoadingStyleAsync(MapStyle style)
{
try
{
var coordinates = new List<IPosition>();
// Note Position uses latitude, longitude while fill.json uses longitude, latitude
coordinates.Add(new Position(40.355432904, -74.459080803));
coordinates.Add(new Position(40.356890788, -74.457104561));
coordinates.Add(new Position(40.356879989, -74.456823783));
coordinates.Add(new Position(40.357160767, -74.456704993));
coordinates.Add(new Position(40.35862945, -74.454404776));
coordinates.Add(new Position(40.35812189, -74.45058188));
coordinates.Add(new Position(40.356933985, -74.447028963));
coordinates.Add(new Position(40.352009577, -74.449609958));
coordinates.Add(new Position(40.351617629, -74.450583891));
coordinates.Add(new Position(40.351557156, -74.451490975));
coordinates.Add(new Position(40.352809797, -74.45561173));
coordinates.Add(new Position(40.35427841, -74.460121236));
coordinates.Add(new Position(40.355432904, -74.459080803));
var lineString = new GeoJSON.Net.Geometry.LineString(coordinates);
var polygon = new GeoJSON.Net.Geometry.Polygon(new List<GeoJSON.Net.Geometry.LineString> { lineString });
source = new GeoJsonSource(SOURCE_ID, polygon) { IsLocal = true };
Map.Functions.AddSource(source);
FillLayer fillLayer = new FillLayer(SOURCE_ID, LAYER_ID);
fillLayer.FillColor = Color.FromRgb(255, 0, 0);
fillLayer.FillOpacity = 0.4f;
Map.Functions.AddLayer(fillLayer);
}
catch (Exception e)
{
Console.WriteLine($"Error loading GeoJSON: {e.Message}");
}
}
Sample JSON (fill.json)
{
"type": "MultiPolygon",
"coordinates": [
[
[
[
-74.459080803,
40.355432904
],
[
-74.457104561,
40.356890788
],
[
-74.456823783,
40.356879989
],
[
-74.456704993,
40.357160767
],
[
-74.454404776,
40.35862945
],
[
-74.45058188,
40.35812189
],
[
-74.447028963,
40.356933985
],
[
-74.449609958,
40.352009577
],
[
-74.450583891,
40.351617629
],
[
-74.451490975,
40.351557156
],
[
-74.45561173,
40.352809797
],
[
-74.460121236,
40.35427841
],
[
-74.459080803,
40.355432904
]
]
]
]
}
SymbolLayer
The SymbolLayer is used for displaying text or icons on the map. The locations for rendering are pulled from the coordinates in the source’s data. The example below shows how you can use your own custom icon on the map:
public void DidFinishLoadingStyle(MapStyle style)
{
Map.Functions.AddStyleImage(new IconImageSource()
{
Id = HAZARD_ICON,
Source = ImageSource.FromResource("MapSDK.Sample.Resources.Images.hazard.png")
});
var symbol = GetSymbol(new TrimbleMaps.MapsSDK.LatLng(40.7135, -74.0066));
Map.Annotations = new[] { symbol };
}
private void DidTapOnMarker(string id)
{
var symbol = Map.Annotations.FirstOrDefault(x => x.Id == id) as SymbolAnnotation;
if (symbol == null) return;
var coords = symbol.Coordinates;
var position = new CameraPosition
{
Target = symbol.Coordinates,
Zoom = 19.0
};
Map.Functions.AnimateCamera(position, 300);
}
private SymbolAnnotation GetSymbol(TrimbleMaps.MapsSDK.LatLng point)
{
return new SymbolAnnotation
{
Coordinates = point,
IconImage = HAZARD_ICON,
IconSize = 0.6f,
TextField = "Hazard",
TextOffset = new[] { 0f, -1.6f },
TextColor = Color.FromRgb(255, 0, 0),
TextAnchor = "Bottom",
TextSize = 16f,
Id = Guid.NewGuid().ToString()
};
}
A more detailed example of the SymbolLayer in action can be found in the Icons on a Map code example.
Other layers
A variety of other layers are also available for use, such as the HeatmapLayer and the FillExtrusionLayer.