I am trying to create Composite Symbols that contain both a Picture Marker Symbol and a Text Symbol.
for some reason, the picture Marker Symbol is not consistently created in the composite symbol. So I am hoping that someone here can see what has been done wrong and help me out. Using C#, here is my code:
private async void SetMapSymbols()
{
var previousLayer = GraphicsLayer[SEARCH_LAYER];
GraphicsLayer.Remove(previousLayer);
var graphicsOverlay = new GraphicsOverlay() { Id = SEARCH_LAYER };
var graphicList = new List<Graphic>();
int order = 0;
foreach (RequestInfoModel entry in PermitList)
{
order++;
if (entry.SiteGeoLat == null || entry.SiteGeoLong == null) continue;
var pointAttribList = ConvertObjectToDictionary(entry);
DictionaryUtility.AddItemTodictionaryAttribute(pointAttribList, ORDER_ATTRIBUTE, order.ToString());
var geo = entry.AltSiteGeoLat != null && entry.AltSiteGeoLong != null ? WebMercatorUtility.ConvertToMercator(entry.AltSiteGeoLong.Value, entry.AltSiteGeoLat.Value) : WebMercatorUtility.ConvertToMercator(entry.SiteGeoLong.Value, entry.SiteGeoLat.Value);
var graphic = new Graphic(
new MapPoint(geo.Lon, geo.Lat, new SpatialReference(SPATIAL_REFERENCE)),
pointAttribList,
string.IsNullOrEmpty(entry.InspectorArea) ? await SymbolUtility.CreateSymbols(order.ToString(), SymbolTypes.Blue, SymbolShapes.Pin) :
await SymbolUtility.CreateSymbols(order.ToString(), SymbolTypes.Red, SymbolShapes.Arrow));
if (entry.SiteGeoTypeCode != MAPPABLE)
{
graphic.Symbol = string.IsNullOrEmpty(entry.InspectorArea) ? await SymbolUtility.CreateSymbols(order.ToString(), SymbolTypes.Blue, SymbolShapes.Pin2) :
await SymbolUtility.CreateSymbols(order.ToString(), SymbolTypes.Red, SymbolShapes.Arrow2);
}
graphicList.Add(graphic);
}
graphicList.ForEach(x => graphicsOverlay.Graphics.Add(x));
GraphicsLayer.Add(graphicsOverlay);
}
as you can see, i am awaiting the SymbolUtility, so here is that code:
public static async Task<Symbol> CreateSymbols(string text, SymbolTypes type, SymbolShapes shape)
{
var iconPath = string.Empty;
iconPath = string.Format(@"pack://application:,,,/Images/{0}_{1}.png", type.ToString(), shape.ToString());
var pc = new PictureMarkerSymbol(new Uri(iconPath, UriKind.RelativeOrAbsolute));
pc.Width = 30;
pc.Height = 30;
var cm = new CompositeSymbol();
var ts = new TextSymbol()
{
Color = Colors.Black,
FontStyle = FontStyle.Normal,
FontDecoration = FontDecoration.None,
FontFamily = "Arial",
FontWeight = FontWeight.Bold,
Size = 14,
VerticalAlignment = VerticalAlignment.Middle,
HorizontalAlignment = HorizontalAlignment.Center,
OffsetY = shape == SymbolShapes.Arrow ? 5 : 0
};
ts.Text = text;
cm.Symbols.Add(pc);
cm.Symbols.Add(ts);
return await Task.Factory.StartNew<Symbol>(() => { return pc; });
}
here is a screen grab of 1 symbol that generated properly, and 2 that didn't:
I have created a thread on StackOverflow here, but a person there directed me here to ask. Thank you for reading this far. any help would be greatly appreciated.
UPDATE:
Here is the additional info requested below:
the graphic.Geometry :
{"x":-13703208.904060207,"y":5882055.3633824475,"spatialReference":{"wkid":102100,"latestWkid":3857}}
the Spatial Reference = 3857
Thank you for sharing here, in case other people have run into the same issues, they'd be able to chime in.
I'm not sure if you had a chance to try these suggestions so I'll post it here as well.
If icon path was used in an Image control, do you see the image? It may be that icon path is incorrect or build action or copy to output directory need to change (see: msdn doc) If the icon path is good, does the symbol render outside CompositeSymbol (using only PictureMarkerSymbol)? If yes, does it get fixed by updating SDK to 100.4 or maybe updating GraphicsRenderingMode or maybe as you zoom-in/out of the map?
I am not able to reproduce with the following code where note.png is added as Content, Copy if newer.
MyMapView.Map = new Map(SpatialReferences.Wgs84);
var symbol = new CompositeSymbol();
symbol.Symbols.Add(new PictureMarkerSymbol(new Uri("pack://application:,,,/note.png")));
symbol.Symbols.Add(new TextSymbol("1", Color.Black, 10, Esri.ArcGISRuntime.Symbology.HorizontalAlignment.Center, Esri.ArcGISRuntime.Symbology.VerticalAlignment.Middle));
var overlay = new GraphicsOverlay();
overlay.Graphics.Add(new Graphic(new MapPoint(0, 0), symbol));
MyMapView.GraphicsOverlays.Add(overlay);
I have tried to create the PictureMarkerSymbol without the text or composite symbols, and it behaved similarly, where sometimes all of the picture markers are there, and then sometimes when the map is refreshed, some of them don't show up. I also tried creating them like you did in your example, but the same issue occurred.
I could not find in my solution where i am setting the Rendering Mode, but by reading the description, it is set to Dynamic, since the icons stay the same regardless of zooming in and out.
I have been working to move to ArcGIS Runtime version 100.4, but since i have both 100.1 and 10.2.7.1234 in my solution, its a pretty intense change.
I just read your response in StackOverflow and I'm curious about this.
The only thing that fixes it is reloading the map
If you're able to share 1 graphic geometry and symbol, Map's SpatialReference/extent, I can try to reproduce. You can get geometry/symbol JSON using ToJson() and you can do MyMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry) to get more info. When you update to new SDK version, does it work?
I am going to edit the original question with the Geometry, extent, and the png file for the symbol
I have not yet completed moving to 100.4, but will let you know as soon as i do.
I just tried the code with Composite Symbol that I shared earlier against 100.1 and it still works for me. RenderingMode is a property of GraphicsOverlay. I think you're right Dynamic is default for points.
Another thing that caught my attention in your code is GraphicsLayer (this is v10.2.x class). Maybe the mix of SDK version is not working well. You can start a smaller application to maybe narrow down the issue?
Also, can you return composite symbol directly? There seems to be no need for this to be async process.
return await Task.Factory.StartNew<Symbol>(() => { return pc; });
Thanks for sharing symbol image and geometry. Another thought was maybe it detects collision and hide the picture symbol but they both show here:
Another thing you can do is identify graphic that has impartial symbol rendered and get its symbol ToJson(). CompositeSymbol might throw NotSupportedException, but its Symbols picture and text can be deserialized, you can check then if these seem correct. MapView.GeoViewTapped with MapView.IdentifyGraphicsOverlaysAsync will get you the graphic.
I was noticing the mixture of 100.1 and 10.2, while trying to get everything to 100.4, but thought it was by design. I can totally see that being an issue if the two versions aren't compatible.
I have taken the asynchronous calls out previously without changing how it is behaving.
In the screen shot that I provided above, there weren't any collisions with other icons on there and it doesn't seem to follow any pattern for which ones show the picture and which ones don't.
I am going to take some time to implement 100.1 completely, just to ensure that i am all on 1 version before i try anything else.
Thank you for your help. I will update this thread once I have finished that.
I am sorry for the misleading names. GraphicsLayer is a GraphicsOverlayCollection.
I am having an issue installing 100.4 to my solution, even after upgrading to .NET Framework v4.6.1. It says that my app supports 'Unsupported Version 0.0' and I should contact the author if the SDK to get it..
Yes, .Net Framework 4.6.1 is minimum requirement. I have not seen "Unsupported Version 0.0".. can you try uninstall nuget references first and then install v100.4?
It will install these two
When asked to resolve namespaces, there's a few of those between these two releases.. you can just define using statement, for example. Hopefully, you've got sample simplified just to see if render issue on picture symbol in composite symbol is resolved.
using Colors = System.Drawing.Color;