TextSymbol from DynamicMapService via fromJson

902
5
03-04-2013 11:23 AM
PhilipKnight1
Occasional Contributor
I am trying to grab the labeling info from a DynamicMapServiceLayer and add that to my featurelayer. Currently, a query is sent to the DynamicMapService and returns with the requested FeatureSet.

FYI, part of the reason we are doing it this way is so that we can add customized flare clusters.

At this point, we'd like to grab the labeling info and add to the map.

            
JObject obj = JObject.Parse(strConfig);
string strRenderer = (obj["drawingInfo"]["renderer"]).ToString();
_resultRenderer = Renderer.FromJson(strRenderer);

_textRenderer = (obj["drawingInfo"]["labelingInfo"]).ToString();
TextSymbol textSymbol = (TextSymbol)TextSymbol.FromJson(_textRenderer);


Note: _resultRenderer returns a valid object, but textSymbol ALWAYS returns null. If I don't put it in the correct format the .FromJson method will complain, so it doesn't appear to be a formatting issue.

Here is the string "_textRenderer":
"[\r\n  {\r\n    \"labelPlacement\": \"esriServerPointLabelPlacementCenterCenter\",\r\n    \"labelExpression\": \"[NOTIFICATIONTYPE]\",\r\n    \"useCodedValues\": true,\r\n    \"symbol\": {\r\n      \"type\": \"esriTS\",\r\n      \"color\": [\r\n        255,\r\n        255,\r\n        255,\r\n        255\r\n      ],\r\n      \"backgroundColor\": null,\r\n      \"borderLineColor\": null,\r\n      \"verticalAlignment\": \"bottom\",\r\n      \"horizontalAlignment\": \"center\",\r\n      \"rightToLeft\": false,\r\n      \"angle\": 0,\r\n      \"xoffset\": 0,\r\n      \"yoffset\": 0,\r\n      \"font\": {\r\n        \"family\": \"Arial\",\r\n        \"size\": 6,\r\n        \"style\": \"normal\",\r\n        \"weight\": \"normal\",\r\n        \"decoration\": \"none\"\r\n      }\r\n    },\r\n    \"minScale\": 0,\r\n    \"maxScale\": 0\r\n  }\r\n]";
            
0 Kudos
5 Replies
DominiqueBroux
Esri Frequent Contributor
"labellingInfo" contains not only the symbol but additionaly, "labelPlacement", "labelExpression",...

To get the symbol, you could try:
_textRenderer = (obj["drawingInfo"]["labelingInfo"]["symbol"]).ToString();

Not tested though.
0 Kudos
PhilipKnight1
Occasional Contributor
"labellingInfo" contains not only the symbol but additionaly, "labelPlacement", "labelExpression",...

To get the symbol, you could try:
_textRenderer = (obj["drawingInfo"]["labelingInfo"]["symbol"]).ToString();

Not tested though.


That code returns a ArgumentException: "Accessed JArray values with invalid key value: "symbol". Array position index expected."


But I was able to get the symbol text via this code:

            
JObject obj2 = JObject.Parse(array[0].ToString());
string sym  = obj2["symbol"].ToString();


But, still doing this just returns null from the FromJson method.

Any ideas?
0 Kudos
PhilipKnight1
Occasional Contributor
We decided to take a hammer to the situation and just create a class that builds a TextSymbol from Json...

Here's the code that uses TexTSymbolBuilder

            _textRenderer = (obj["drawingInfo"]["labelingInfo"]).ToString();
            JArray array = JArray.Parse(_textRenderer);
            JObject obj2 = JObject.Parse(array[0].ToString());
            string tsym = array[0].ToString();
            Graphic grtext;
            foreach (Graphic graphic in featureSet.Features)
            {
                Dictionary<string,string> aliases =  featureSet.FieldAliases;
                graphic.Symbol = _resultRenderer.GetSymbol(graphic);
                FrameworkElement maptip = getMapTip(graphic, aliases);
                graphic.MapTip = maptip;

                //text renderer
                grtext = new Graphic();
                grtext.Geometry = graphic.Geometry;
                grtext.Symbol = TexTSymbolBuilder.BuildSymbolFromJson(tsym, graphic);


Here's the TexTSymbolBuilder code:
    
    public static class TexTSymbolBuilder
    {


        public static TextSymbol BuildSymbolFromJson(string json,Graphic gr)
        {
            JObject obj2 = JObject.Parse(json);
            string tsym = obj2["symbol"].ToString();
            string lblExpression = obj2["labelExpression"].ToString().Replace("[", "").Replace("]", "");
            string labelPlacement = obj2["labelPlacement"].ToString();

            TextSymbol sym = new TextSymbol();

            JObject objSym =( JObject)obj2["symbol"];
            JObject Font = (JObject)objSym["font"];

            sym.FontFamily = new FontFamily(Font["family"].ToString());
            sym.FontSize = double.Parse(Font["size"].ToString());
            sym.Foreground = ColorFromJson(objSym["color"].ToString());
            Size labelSize = GetLabelWidth(gr.Attributes[lblExpression].ToString(),sym.FontSize);
            switch (labelPlacement)
            {
                case "esriServerPointLabelPlacementCenterCenter":

                    sym.Text =gr.Attributes[lblExpression].ToString();
                    sym.OffsetX = labelSize.Width/2;//((gr.Attributes[lblExpression].ToString().Length * sym.FontSize) / 4); 
                    sym.OffsetY = labelSize.Height/2;//(sym.FontSize / 2);
                    break;
            }




            return sym;
        }

        private static Size GetLabelWidth(string value,double fontsize)
        {
            Size sz = new Size();
            TextBlock blk = new TextBlock();
            blk.FontSize = fontsize;
            blk.Text = value;
            sz.Width = blk.ActualWidth;
            sz.Height = blk.ActualHeight;
            return sz;
        }


        private static Brush ColorFromJson(string p)
        {
            string clipped = p.Replace("[", "").Replace("]", "");
            string[] vals = clipped.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            Color clr = Color.FromArgb(byte.Parse(vals[3]),byte.Parse(vals[0]),byte.Parse(vals[1]),byte.Parse(vals[2]));

            Brush br = new SolidColorBrush(clr);
            return br;
        }
    }



Hopefully this helps anyone what ran into the same issue
0 Kudos
EddieJesinsky
New Contributor
Just wanted to mention that this appears to be a bug in the latest version of the api:

                var textSymbol = new TextSymbol();
                textSymbol.FontFamily = new FontFamily("Arial");
                textSymbol.FontSize = 25;
                textSymbol.Foreground = new SolidColorBrush(Colors.Red);
                textSymbol.Text = "test";

                var testJson = textSymbol.ToJson();
                var testSym = Symbol.FromJson(testJson); //returns null
0 Kudos
DominiqueBroux
Esri Frequent Contributor
Just wanted to mention that this appears to be a bug in the latest version of the api:

                var textSymbol = new TextSymbol();
                textSymbol.FontFamily = new FontFamily("Arial");
                textSymbol.FontSize = 25;
                textSymbol.Foreground = new SolidColorBrush(Colors.Red);
                textSymbol.Text = "test";

                var testJson = textSymbol.ToJson();
                var testSym = Symbol.FromJson(testJson); //returns null

You are right. We'll try getting it fixed in a future version.

Thanks for reporting that.
0 Kudos