Example #1
0
        // A function that reads all values in the dialog (selected layers, color, size) to build the multilayer point symbol.
        private async Task <MultilayerPointSymbol> GetCurrentSymbol()
        {
            // Create a list of keys that identify the selected symbol layers.
            List <string> symbolKeys = new List <string>
            {
                _baseSymbolKey,
                _symbolLayersPickerModel.SelectedSymbolKey1,
                _symbolLayersPickerModel.SelectedSymbolKey2,
                _symbolLayersPickerModel.SelectedSymbolKey3
            };

            // Use the list of keys to return symbols from the mobile style (they will be combined and returned as a multilayer point symbol).
            MultilayerPointSymbol faceSymbol = await _emojiStyle.GetSymbolAsync(symbolKeys) as MultilayerPointSymbol;

            // Loop through all symbol layers and lock the color (changing the color property on the symbol will not affect these layers).
            foreach (SymbolLayer lyr in faceSymbol.SymbolLayers)
            {
                lyr.IsColorLocked = true;
            }

            // Unlock the color for the base (first) layer. Changing the symbol color will change this layer's color.
            faceSymbol.SymbolLayers.First().IsColorLocked = false;

            // Get the System.Drawing.Color from the color list that corresponds to the selected segment in the color control.
            System.Drawing.Color selectedUIColor = _colorList[(int)_colorSegments.SelectedSegment];

            // Set the symbol color using the selected color.
            faceSymbol.Color = selectedUIColor;

            // Set the symbol size from the slider.
            faceSymbol.Size = _sizeSlider.Value;

            // Return the multilayer point symbol.
            return(faceSymbol);
        }
        // A click handler for the button that dismisses the dialog.
        private async void SelectSymbolButtonClick(object sender, EventArgs e)
        {
            try
            {
                // Get the current symbol.
                MultilayerPointSymbol selectedSymbol = await GetCurrentSymbol();

                // Create a new OnSymbolCompleteEventArgs object to store the selected symbol.
                OnSymbolCompleteEventArgs symbolSelectedArgs = new OnSymbolCompleteEventArgs(selectedSymbol);

                // Raise the OnSaveClicked event so the main activity can handle the event and use the symbol.
                OnSymbolComplete?.Invoke(this, symbolSelectedArgs);

                // Close the dialog
                Dismiss();
            }
            catch (Exception ex)
            {
                // Show the exception message (dialog will stay open so user can try again)
                AlertDialog.Builder alertBuilder = new AlertDialog.Builder(Activity);
                alertBuilder.SetTitle("Error");
                alertBuilder.SetMessage(ex.Message);
                alertBuilder.Show();
            }
        }
        private void Initialize()
        {
            // Create new Map with a topographic basemap.
            Map myMap = new Map(Basemap.CreateTopographic());

            // Display the map in the map view.
            _myMapView.Map = myMap;

            // Create an overlay to display point graphics and add it to the map view.
            GraphicsOverlay overlay = new GraphicsOverlay();

            _myMapView.GraphicsOverlays.Add(overlay);

            // Handle the tap event on the map view to allow the user to place graphics.
            _myMapView.GeoViewTapped += GeoViewTapped;

            // Get the full path to the downloaded mobile style file (.stylx).
            string mobileStyleFilePath = DataManager.GetDataFolder("1bd036f221f54a99abc9e46ff3511cbf", "emoji-mobile.stylx");

            // Create the dialog for selecting symbol layers from the style.
            _symbolDialog = new SymbolDialogFragment(mobileStyleFilePath);

            // Handle the OnSymbolComplete event on the dialog to get the symbol the user created.
            _symbolDialog.OnSymbolComplete += (sender, e) => { _faceSymbol = e.SelectedPointSymbol; };
        }
        private async Task <MultilayerPointSymbol> GetCurrentSymbol()
        {
            // If the style hasn't been opened, return.
            if (_emojiStyle == null)
            {
                return(null);
            }

            MultilayerPointSymbol faceSymbol = null;

            try
            {
                // Get the key that identifies the selected eye symbol (or an empty string if none selected).
                SymbolLayerInfo eyeLayerInfo = (SymbolLayerInfo)EyeSymbolList.SelectedItem;
                string          eyeLayerKey  = eyeLayerInfo != null ? eyeLayerInfo.Key : string.Empty;

                // Get the key that identifies the selected mouth symbol (or an empty string if none selected).
                SymbolLayerInfo mouthLayerInfo = (SymbolLayerInfo)MouthSymbolList.SelectedItem;
                string          mouthLayerKey  = mouthLayerInfo != null ? mouthLayerInfo.Key : string.Empty;

                // Get the key that identifies the selected hat symbol (or an empty string if none selected).
                SymbolLayerInfo hatLayerInfo = (SymbolLayerInfo)HatSymbolList.SelectedItem;
                string          hatLayerKey  = hatLayerInfo != null ? hatLayerInfo.Key : string.Empty;

                // Create a list of the symbol keys that identify the selected symbol layers, including the base (circle) symbol.
                List <string> symbolKeys = new List <string>
                {
                    _baseSymbolKey, eyeLayerKey, mouthLayerKey, hatLayerKey
                };

                // Get a multilayer point symbol from the style that contains the selected symbol layers.
                faceSymbol = await _emojiStyle.GetSymbolAsync(symbolKeys) as MultilayerPointSymbol;

                // Loop through all symbol layers and lock the color.
                foreach (SymbolLayer lyr in faceSymbol.SymbolLayers)
                {
                    // Changing the color of the symbol will not affect this layer.
                    lyr.IsColorLocked = true;
                }

                // Unlock the color for the base (first) layer. Changing the symbol color will change this layer's color.
                faceSymbol.SymbolLayers.First().IsColorLocked = false;

                // Set the symbol color from the combo box.
                if (FaceColorComboBox.SelectedItem != null)
                {
                    faceSymbol.Color = (Color)FaceColorComboBox.SelectedItem;
                }

                // Set the symbol size from the slider.
                faceSymbol.Size = SizeSlider.Value;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unable to create symbol: " + ex.Message, "Exception");
            }

            // Return the multilayer point symbol.
            return(faceSymbol);
        }
Example #5
0
        // Handler for the tapped event on the map view.
        private async void GeoViewTapped(object sender, GeoViewInputEventArgs e)
        {
            // Call a function to get the currently defined multilayer point symbol.
            MultilayerPointSymbol faceSymbol = await GetCurrentSymbol();

            // Create a graphic for the tapped location using the current symbol and add it to the map view.
            Graphic graphic = new Graphic(e.Location, faceSymbol);

            MyMapView.GraphicsOverlays.First().Graphics.Add(graphic);
        }
Example #6
0
        // A handler for the GeoViewTapped event
        private void OnGeoViewTapped(object sender, GeoViewInputEventArgs e)
        {
            // Get the current symbol from the symbol selector dialog.
            MultilayerPointSymbol faceSymbol = _selectSymbolController.SelectedSymbol;

            // Create a graphic using the tap location and the selected symbol.
            Graphic tapGraphic = new Graphic(e.Location, faceSymbol);

            // Add the grapic to the first (and only) graphics overlay in the map view.
            _myMapView.GraphicsOverlays.First().Graphics.Add(tapGraphic);
        }
Example #7
0
        // A function that reads a mobile style file and builds a list for each of three symbol categories.
        private async Task ReadMobileStyle()
        {
            // Open a mobile style file.
            _emojiStyle = await SymbolStyle.OpenAsync(_mobileStyleFilePath);

            // Get the default style search parameters.
            SymbolStyleSearchParameters searchParams = await _emojiStyle.GetDefaultSearchParametersAsync();

            // Search the style with the default parameters to return all symbol results.
            IList <SymbolStyleSearchResult> styleResults = await _emojiStyle.SearchSymbolsAsync(searchParams);

            // Loop through the results and put symbols into the appropriate list according to category.
            foreach (SymbolStyleSearchResult result in styleResults)
            {
                // Get the symbol from the result.
                MultilayerPointSymbol multiLayerSym = result.Symbol as MultilayerPointSymbol;

                // Create an image from the symbol swatch.
                RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync();

                UIImage symbolImage = await swatch.ToImageSourceAsync();

                // Create an instance of the custom SymbolLayerInfo class to store info about this symbol: name, swatch image, unique ID (key).
                SymbolLayerInfo symbolInfo = new SymbolLayerInfo(result.Name, symbolImage, result.Key);

                // Check the category for this result and place it into the correct list.
                switch (result.Category)
                {
                case "Eyes":
                {
                    //
                    _eyeSymbolInfos.Add(symbolInfo);
                    break;
                }

                case "Mouth":
                {
                    _mouthSymbolInfos.Add(symbolInfo);
                    break;
                }

                case "Hat":
                {
                    _hatSymbolInfos.Add(symbolInfo);
                    break;
                }
                }
            }
        }
Example #8
0
        // A function to update the current multilayer symbol based on selections in the dialog.
        private async Task UpdateSymbol()
        {
            // Call a function to read the current settings and create the appropriate symbol.
            // Assign the symbol to the public SelectedSymbol property.
            SelectedSymbol = await GetCurrentSymbol();

            if (SelectedSymbol != null)
            {
                // Create an image of the symbol swatch to display as a preview.
                RuntimeImage swatch = await SelectedSymbol.CreateSwatchAsync(80, 80, 96, System.Drawing.Color.White);

                UIImage symbolImage = await swatch.ToImageSourceAsync();

                _symbolPreviewImageView.Image = symbolImage;
            }
        }
        // A function to get a multilayer point symbol that contains all selected symbol layers.
        private async Task <MultilayerPointSymbol> GetCurrentSymbol()
        {
            MultilayerPointSymbol faceSymbol = null;

            try
            {
                // Create a new list of strings with the key for the base (face) symbol and any additional selected layers.
                List <string> symbolKeys = new List <string>
                {
                    _baseSymbolKey, _selectedEyesKey, _selectedMouthKey, _selectedHatKey
                };

                // Use the keys to get the symbol layers as a multilayer symbol.
                faceSymbol = await _emojiStyle.GetSymbolAsync(symbolKeys) as MultilayerPointSymbol;

                // Loop through all symbol layers and lock the color.
                foreach (SymbolLayer lyr in faceSymbol.SymbolLayers)
                {
                    // Changing the color of the symbol will not affect this layer.
                    lyr.IsColorLocked = true;
                }

                // Unlock the color for the base (first) layer. Changing the symbol color will change this layer's color.
                faceSymbol.SymbolLayers.First().IsColorLocked = false;

                // Set the symbol color using the last selected color.
                System.Drawing.Color symbolColor = System.Drawing.Color.FromArgb(_faceColor.A, _faceColor.R, _faceColor.G, _faceColor.B);
                faceSymbol.Color = symbolColor;

                // Set the symbol size from the slider.
                faceSymbol.Size = _symbolSize;
            }
            catch (Exception ex)
            {
                // Show the exception message.
                AlertDialog.Builder alertBuilder = new AlertDialog.Builder(Activity);
                alertBuilder.SetTitle("Error creating symbol");
                alertBuilder.SetMessage(ex.Message);
                alertBuilder.Show();
            }

            // Return the constructed symbol.
            return(faceSymbol);
        }
        // Get the current symbol and update the preview image.
        private async Task UpdateSymbol()
        {
            // Call a function to get the currrent multilayer point symbol from the selected layers.
            MultilayerPointSymbol emojiSymbol = await GetCurrentSymbol();

            try
            {
                // Use a swatch from the symbol to create an image.
                RuntimeImage swatch = await emojiSymbol.CreateSwatchAsync(100, 100, 96, System.Drawing.Color.White);

                Bitmap symbolImage = await swatch.ToImageSourceAsync();

                // Display the preview image.
                _symbolPreviewImage.SetImageBitmap(symbolImage);
            }
            catch (Exception ex)
            {
                // Show the exception message.
                AlertDialog.Builder alertBuilder = new AlertDialog.Builder(Activity);
                alertBuilder.SetTitle("Error creating preview");
                alertBuilder.SetMessage(ex.Message);
                alertBuilder.Show();
            }
        }
Example #11
0
        private async Task ReadMobileStyle(string stylePath)
        {
            try
            {
                // Open the mobile style file at the provided path.
                _emojiStyle = await SymbolStyle.OpenAsync(stylePath);

                // Get the default style search parameters.
                SymbolStyleSearchParameters searchParams = await _emojiStyle.GetDefaultSearchParametersAsync();

                // Search the style with the default parameters to return all symbol results.
                IList <SymbolStyleSearchResult> styleResults = await _emojiStyle.SearchSymbolsAsync(searchParams);

                // Create an empty placeholder image to represent "no symbol" for each category.
                ImageSource emptyImage = null;

                // Create lists to contain the available symbol layers for each category of symbol and add an empty entry as default.
                List <SymbolLayerInfo> eyeSymbolInfos = new List <SymbolLayerInfo> {
                    new SymbolLayerInfo("", emptyImage, "")
                };
                List <SymbolLayerInfo> mouthSymbolInfos = new List <SymbolLayerInfo> {
                    new SymbolLayerInfo("", emptyImage, "")
                };
                List <SymbolLayerInfo> hatSymbolInfos = new List <SymbolLayerInfo>()
                {
                    new SymbolLayerInfo("", emptyImage, "")
                };

                // Loop through the results and put symbols into the appropriate list according to category.
                foreach (SymbolStyleSearchResult result in styleResults)
                {
                    // Get the symbol for this result.
                    MultilayerPointSymbol multiLayerSym = await result.GetSymbolAsync() as MultilayerPointSymbol;

                    // Create a swatch image from the symbol.
                    RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync();

                    ImageSource symbolImage = await swatch.ToImageSourceAsync();

                    // Create a symbol layer info object to represent the symbol in the list.
                    // The symbol key will be used to retrieve the symbol from the style.
                    SymbolLayerInfo symbolInfo = new SymbolLayerInfo(result.Name, symbolImage, result.Key);

                    // Add the symbol layer info to the correct list for its category.
                    switch (result.Category)
                    {
                    case "Eyes":
                    {
                        eyeSymbolInfos.Add(symbolInfo);
                        break;
                    }

                    case "Mouth":
                    {
                        mouthSymbolInfos.Add(symbolInfo);
                        break;
                    }

                    case "Hat":
                    {
                        hatSymbolInfos.Add(symbolInfo);
                        break;
                    }
                    }
                }

                // Show the symbols in the category list boxes.
                EyeSymbolList.ItemsSource   = eyeSymbolInfos;
                MouthSymbolList.ItemsSource = mouthSymbolInfos;
                HatSymbolList.ItemsSource   = hatSymbolInfos;

                // Call a function to construct the current symbol (default yellow circle).
                Symbol faceSymbol = await GetCurrentSymbol();

                // Call a function to show a preview image of the symbol.
                await UpdateSymbolPreview(faceSymbol);
            }
            catch (Exception ex)
            {
                // Report the exception.
                MessageDialog dialog = new MessageDialog("Error reading symbols from style: " + ex.Message);
                await dialog.ShowAsync();
            }
        }
 // Pass the multilayer point symbol to the constructor.
 public OnSymbolCompleteEventArgs(MultilayerPointSymbol symbol)
 {
     SelectedPointSymbol = symbol;
 }
        private async void ReadMobileStyle(string mobileStyleFilePath)
        {
            try
            {
                // Make sure the file exists.
                if (!System.IO.File.Exists(mobileStyleFilePath))
                {
                    throw new System.IO.FileNotFoundException("Mobile style file not found at " + mobileStyleFilePath);
                }

                // Open the mobile style file at the path provided.
                _emojiStyle = await SymbolStyle.OpenAsync(mobileStyleFilePath);

                // Get the default style search parameters.
                SymbolStyleSearchParameters searchParams = await _emojiStyle.GetDefaultSearchParametersAsync();

                // Search the style with the default parameters to return a list of all symbol results.
                IList <SymbolStyleSearchResult> styleResults = await _emojiStyle.SearchSymbolsAsync(searchParams);

                // Loop through the results and put symbols into the appropriate list according to category (eyes, mouth, hat).
                foreach (SymbolStyleSearchResult result in styleResults)
                {
                    // Get the result symbol as a multilayer point symbol.
                    MultilayerPointSymbol multiLayerSym = result.Symbol as MultilayerPointSymbol;

                    // Create a swatch for the symbol and use it to create a bitmap image.
                    RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync();

                    Bitmap symbolImage = await swatch.ToImageSourceAsync();

                    // Check the symbol category.
                    switch (result.Category)
                    {
                    // Add a new SymbolLayerInfo to represent the symbol and add it to its category list.
                    // SymbolLayerInfo is a custom class with properties for the symbol name, swatch image, and unique key.
                    case "Eyes":
                    {
                        _eyeSymbolInfos.Add(new SymbolLayerInfo(result.Name, symbolImage, result.Key));
                        break;
                    }

                    case "Mouth":
                    {
                        _mouthSymbolInfos.Add(new SymbolLayerInfo(result.Name, symbolImage, result.Key));
                        break;
                    }

                    case "Hat":
                    {
                        _hatSymbolInfos.Add(new SymbolLayerInfo(result.Name, symbolImage, result.Key));
                        break;
                    }

                    case "Face":
                    {
                        break;
                    }
                    }
                }
            }
            catch (Exception ex)
            {
                // Show the exception message.
                AlertDialog.Builder alertBuilder = new AlertDialog.Builder(Activity);
                alertBuilder.SetTitle("Error reading style");
                alertBuilder.SetMessage(ex.Message);
                alertBuilder.Show();
            }
        }
        private async Task ReadMobileStyle(string stylePath)
        {
            try
            {
                // Open the mobile style file at the provided path.
                _emojiStyle = await SymbolStyle.OpenAsync(stylePath);

                // Get the default style search parameters.
                SymbolStyleSearchParameters searchParams = await _emojiStyle.GetDefaultSearchParametersAsync();

                // Search the style with the default parameters to return all symbol results.
                IList <SymbolStyleSearchResult> styleResults = await _emojiStyle.SearchSymbolsAsync(searchParams);

                // Create lists to contain the available symbol layers for each category of symbol and add an empty entry as default.
                List <SymbolLayerInfo> eyeSymbolInfos = new List <SymbolLayerInfo> {
                    new SymbolLayerInfo("", null, "")
                };
                List <SymbolLayerInfo> mouthSymbolInfos = new List <SymbolLayerInfo> {
                    new SymbolLayerInfo("", null, "")
                };
                List <SymbolLayerInfo> hatSymbolInfos = new List <SymbolLayerInfo>()
                {
                    new SymbolLayerInfo("", null, "")
                };

                // Loop through the results and put symbols into the appropriate list according to category.
                foreach (SymbolStyleSearchResult result in styleResults)
                {
                    // Get the symbol for this result.
                    MultilayerPointSymbol multiLayerSym = result.Symbol as MultilayerPointSymbol;

                    // Create a swatch image from the symbol.
                    RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync(30, 30, 96, Color.White);

                    // Create an image source from the swatch.
                    Stream imageBuffer = await swatch.GetEncodedBufferAsync();

                    byte[] imageData = new byte[imageBuffer.Length];
                    imageBuffer.Read(imageData, 0, imageData.Length);
                    ImageSource symbolImage = ImageSource.FromStream(() => new MemoryStream(imageData));

                    // Create a symbol layer info object to represent the symbol in the list.
                    // The symbol key will be used to retrieve the symbol from the style.
                    SymbolLayerInfo symbolInfo = new SymbolLayerInfo(result.Name, symbolImage, result.Key);

                    // Add the symbol layer info to the correct list for its category.
                    switch (result.Category)
                    {
                    case "Eyes":
                    {
                        eyeSymbolInfos.Add(symbolInfo);
                        break;
                    }

                    case "Mouth":
                    {
                        mouthSymbolInfos.Add(symbolInfo);
                        break;
                    }

                    case "Hat":
                    {
                        hatSymbolInfos.Add(symbolInfo);
                        break;
                    }
                    }
                }

                // Show the symbols in the category list boxes.
                EyesListView.ItemsSource  = eyeSymbolInfos;
                MouthListView.ItemsSource = mouthSymbolInfos;
                HatListView.ItemsSource   = hatSymbolInfos;

                // Call a function to construct the current symbol (default yellow circle).
                Symbol faceSymbol = await GetCurrentSymbol();

                // Call a function to show a preview image of the symbol.
                await UpdateSymbolPreview(faceSymbol);
            }
            catch (Exception ex)
            {
                // Report the exception.
                await DisplayAlert("Error reading style", ex.Message, "OK");
            }
        }
        private async void RenderSymbols(Dictionary <string, object> info, bool initialize = false)
        {
            FeatureCollectionTable dTable;
            FeatureCollectionTable uTable;

            DictionaryRenderer  dRend;
            UniqueValueRenderer uRend;

            string[] codes = Newtonsoft.Json.JsonConvert.DeserializeObject <string[]>(info["codes"].ToString());
            int      page  = int.Parse(info["page"].ToString());

            if (initialize)
            {
                // Create the default symbol
                SimpleMarkerSymbol sms = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Circle, Colors.Red, 12)
                {
                    Outline = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, Colors.Black, 1)
                };

                // Create the Dictionary and Unique Value renderers
                dRend = new DictionaryRenderer(DictionarySymbolStyle.OpenAsync("mil2525c_b2", StylePath).Result);
                uRend = new UniqueValueRenderer(new[] { FieldName }, null, "MilSymbol", sms);

                // Create the fields for the Feature Collection table
                Field[] fields = { new Field(FieldType.Text, FieldName, FieldName, 15) };

                // Create the Feature Collection Tables
                dTable = new FeatureCollectionTable(fields, GeometryType.Point, SpatialReferences.WebMercator)
                {
                    Renderer = dRend
                };
                uTable = new FeatureCollectionTable(fields, GeometryType.Point, SpatialReferences.WebMercator)
                {
                    Renderer = uRend
                };

                // Add the tables to the feature collection
                FeatureCollection collection = new FeatureCollection(new[] { dTable, uTable });

                // Add the collection to the map
                MyMapView.Map.OperationalLayers.Add(new FeatureCollectionLayer(collection));
            }
            else
            {
                // Get the feature collection from the map
                FeatureCollection collection = (MyMapView.Map.OperationalLayers.First() as FeatureCollectionLayer).FeatureCollection;

                // Get the tables from the collection
                dTable = collection.Tables.First();
                uTable = collection.Tables.Last();

                // Clear the records from the table and overlay
                QueryParameters query = new QueryParameters {
                    WhereClause = "1=1"
                };
                await dTable.DeleteFeaturesAsync(dTable.QueryFeaturesAsync(query).Result);

                await uTable.DeleteFeaturesAsync(uTable.QueryFeaturesAsync(query).Result);

                MyMapView.GraphicsOverlays.First().Graphics.Clear();

                // Clear the symbols from the unique value renderer
                (uTable.Renderer as UniqueValueRenderer)?.UniqueValues.Clear();
            }

            // Show the Page #
            MapPoint   titleLocation = new MapPoint(AOI.GetCenter().X, AOI.Extent.YMax + 25);
            TextSymbol titleBar      = new TextSymbol
            {
                Text                = string.Format("Page: {0}", page),
                Color               = Colors.Black,
                BackgroundColor     = Colors.DodgerBlue,
                FontWeight          = Esri.ArcGISRuntime.Symbology.FontWeight.Bold,
                Size                = 50,
                HorizontalAlignment = Esri.ArcGISRuntime.Symbology.HorizontalAlignment.Center,
                VerticalAlignment   = Esri.ArcGISRuntime.Symbology.VerticalAlignment.Bottom,
                OutlineColor        = Colors.Black,
                OutlineWidth        = 2
            };

            MyMapView.GraphicsOverlays.First().Graphics.Add(new Graphic(titleLocation, titleBar));

            int rows = codes.Length / Columns;

            double rowMargin = (AOI.XMax - AOI.XMin) / (Columns - 1);
            double colMargin = (AOI.YMax - AOI.YMin) / rows;

            int count = 0;

            for (double x = AOI.XMin; x < AOI.XMax; x += rowMargin)
            {
                if (count >= codes.Length)
                {
                    break;
                }

                for (double y = AOI.YMax; y > AOI.YMin; y -= colMargin)
                {
                    if (count >= codes.Length)
                    {
                        break;
                    }

                    string code = codes[count];

                    if (code.Length != 15)
                    {
                        System.Diagnostics.Debug.WriteLine(string.Format("Possible invalid code: {0}", code));
                    }
                    else
                    {
                        // Create features with the sidc code
                        Feature dFeature = dTable.CreateFeature(new Dictionary <string, object> {
                            { FieldName, code }
                        }, new MapPoint(x, y, SpatialReferences.WebMercator));
                        Feature uFeature = uTable.CreateFeature(new Dictionary <string, object> {
                            { FieldName, code }
                        }, new MapPoint(x + (rowMargin * 0.5), y, SpatialReferences.WebMercator));

                        // Create a label to display the code
                        TextSymbol label = new TextSymbol
                        {
                            Text            = code,
                            FontWeight      = Esri.ArcGISRuntime.Symbology.FontWeight.Bold,
                            Color           = Colors.DarkGoldenrod,
                            BackgroundColor = Colors.Black,
                            FontFamily      = "Consolas",
                            Size            = 16
                        };

                        MapPoint labelPoint = new MapPoint(x + (rowMargin * 0.25), y - (colMargin * 0.25), SpatialReferences.WebMercator);
                        MyMapView.GraphicsOverlays.First().Graphics.Add(new Graphic(labelPoint, label));

                        // Add the feature to the table
                        await dTable.AddFeatureAsync(dFeature);

                        await uTable.AddFeatureAsync(uFeature);

                        // Triple the size of the Unique Value symbol
                        MultilayerPointSymbol symbol = (MultilayerPointSymbol)(dTable.Renderer as DictionaryRenderer).GetSymbol(dFeature);
                        symbol.Size *= 3;

                        // Add the military symbol to the unique value renderer
                        UniqueValue uval = new UniqueValue(code, code, symbol, code);
                        (uTable.Renderer as UniqueValueRenderer).UniqueValues.Add(uval);
                    }

                    count++;

                    System.Diagnostics.Debug.WriteLine(string.Format(@"Processed feature {0} for {1}...", count, codes.Length));
                }
            }
        }