I'm trying to create a ClassBreakRenderer and set it on a GraphicsOvelay and cannot get it to work. The renderer works fine on a FeatureLayer, but doesn't work on a GraphicsOverlay that's been created using the same data as the FeatureLayer. I'm not sure what I'm missing here. Is there a sample somewhere that shows how to do this? I pasted the code below, and also attached the repro case, in case someone is up for giving me a hand in getting to the bottom of this. Working with 100.5. Thank you!!!
- Mara
private async void RenderData()
{
// Create a new map based on the streets base map.
Map newMap = new Map(Basemap.CreateStreets());
// Create an envelope that covers the continental US in the web Mercator spatial reference.
Envelope continentalUSEnvelope = new Envelope(-14193469.5655232, 2509617.28647268, -7228772.04749191, 6737139.97573925, SpatialReferences.WebMercator);
// Zoom the map to the extent of the envelope.
newMap.InitialViewpoint = new Viewpoint(continentalUSEnvelope);
// Assign the map to the MapView.
MyMapView.Map = newMap;
MyMapView.GraphicsOverlays.Add(new GraphicsOverlay());
// CHANGE THIS FLAG TO SWITCH TEST BETWEEN FEATURE LAYER AND GRAPHICS OVERLAY
var useFeatureLayer = true;
if (useFeatureLayer)
{
// set feature layer and renderer and add it to the map
var featureLayer = new FeatureLayer(new Uri("https://services8.arcgis.com/KsXZDThvSinzJ3pq/arcgis/rest/services/test_pipeline/FeatureServer/0"));
featureLayer.Renderer = CreateClassBreaksRenderer();
MyMapView.Map.OperationalLayers.Add(featureLayer);
}
else
{
// set feature table and query it to retrieve all features
var featTable = new ServiceFeatureTable(new Uri("https://services8.arcgis.com/KsXZDThvSinzJ3pq/arcgis/rest/services/test_pipeline/FeatureServer/0"));
var queryParams = new QueryParameters { WhereClause = "1=1" };
var featureResult = await featTable.QueryFeaturesAsync(queryParams, QueryFeatureFields.LoadAll);
// create graphics from the features and add them to the map in a graphics overlay
foreach (var result in featureResult)
{
var pipeSegment = result.Geometry;
var graphic = new Graphic(pipeSegment);
graphic.Attributes.Add("break", result.Attributes["break"]);
MyMapView.GraphicsOverlays[0].Graphics.Add(new Graphic(pipeSegment));
}
// create and set renderer for the graphics overlay
MyMapView.GraphicsOverlays[0].Renderer = CreateClassBreaksRenderer();
}
}
private ClassBreaksRenderer CreateClassBreaksRenderer()
{
// Create symbols
var symbol1 = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Red, 7);
var symbol2 = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Yellow, 7);
var symbol3 = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Color.Green, 7);
// Create class breaks
List<ClassBreak> listClassBreaks = new List<ClassBreak>
{
new ClassBreak("1", "1", 0, 1, symbol1),
new ClassBreak("2", "2", 1, 2, symbol2),
new ClassBreak("3", "3", 2, 3, symbol3),
};
// Create and return the a class break renderer for use with the "break" field
return new ClassBreaksRenderer("break", listClassBreaks);
}
Solved! Go to Solution.
Looks like you're adding the wrong graphic (a new instance that doesn't have that attribute set)
Change
MyMapView.GraphicsOverlays[0].Graphics.Add(new Graphic(pipeSegment));
to
MyMapView.GraphicsOverlays[0].Graphics.Add(graphic);
The DefaultSymbol for the ClassBreaksRenderer seems to be working fine when it is set. I believe the class breaks symbology not applying may be more an issue with the renderer not being able to reach the graphic's attributes but we'll need to test it further.
Looks like you're adding the wrong graphic (a new instance that doesn't have that attribute set)
Change
MyMapView.GraphicsOverlays[0].Graphics.Add(new Graphic(pipeSegment));
to
MyMapView.GraphicsOverlays[0].Graphics.Add(graphic);
I was afraid it was something silly like that. Thanks Morten!