private async Task DeleteAttachment(Attachment attachmentToDelete)
        {
            try
            {
                // Delete the attachment.
                await _selectedFeature.DeleteAttachmentAsync(attachmentToDelete);

                // Get a reference to the feature's service feature table.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;

                // Apply the edits to the service feature table.
                await serviceTable.ApplyEditsAsync();

                // Update UI.
                _selectedFeature.Refresh();
                _featureAttachments = await _selectedFeature.GetAttachmentsAsync();

                UpdateUIForFeature();
                ShowMessage("Successfully deleted attachment", "Success!");
            }
            catch (Exception exception)
            {
                ShowMessage(exception.ToString(), "Error deleting attachment");
            }
        }
        private async void AddAttachment(Android.Net.Uri imageUri)
        {
            string contentType = "image/jpeg";

            // Read the image into a stream.
            Stream stream = ContentResolver.OpenInputStream(imageUri);

            // Read from the stream into the byte array.
            byte[] attachmentData;
            using (var memoryStream = new MemoryStream())
            {
                stream.CopyTo(memoryStream);
                attachmentData = memoryStream.ToArray();
            }

            // Add the attachment.
            // The contentType string is the MIME type for JPEG files, image/jpeg.
            await _selectedFeature.AddAttachmentAsync(imageUri.LastPathSegment + ".jpg", contentType, attachmentData);

            // Get a reference to the feature's service feature table.
            ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;

            // Apply the edits to the service feature table.
            await serviceTable.ApplyEditsAsync();

            // Update UI.
            _selectedFeature.Refresh();
            _featureAttachments = await _selectedFeature.GetAttachmentsAsync();

            UpdateUIForFeature();
            ShowMessage("Successfully added attachment", "Success!");
        }
Example #3
0
        private async void DeleteAttachment_Click(object sender, EventArgs e)
        {
            AttachmentActivityIndicator.IsVisible = true;

            try
            {
                // Get the attachment that should be deleted.
                Button     sendingButton      = (Button)sender;
                Attachment selectedAttachment = (Attachment)sendingButton.BindingContext;

                // Delete the attachment.
                await _selectedFeature.DeleteAttachmentAsync(selectedAttachment);

                // Get a reference to the feature's service feature table.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;

                // Apply the edits to the service feature table.
                await serviceTable.ApplyEditsAsync();

                // Update UI.
                _selectedFeature.Refresh();
                AttachmentsListBox.ItemsSource = await _selectedFeature.GetAttachmentsAsync();

                // Show success message.
                await Application.Current.MainPage.DisplayAlert("Success!", "Successfully deleted attachment", "OK");
            }
            catch (Exception exception)
            {
                await Application.Current.MainPage.DisplayAlert("Error deleting attachment", exception.ToString(), "OK");
            }
            finally
            {
                AttachmentActivityIndicator.IsVisible = false;
            }
        }
Example #4
0
        private async void UpdateDamageType(string selectedAttributeValue)
        {
            try
            {
                // Load the feature.
                await _selectedFeature.LoadAsync();

                // Update the attribute value.
                _selectedFeature.SetAttributeValue(AttributeFieldName, selectedAttributeValue);

                // Update the table.
                await _selectedFeature.FeatureTable.UpdateFeatureAsync(_selectedFeature);

                // Update the service.
                ServiceFeatureTable table = (ServiceFeatureTable)_selectedFeature.FeatureTable;
                await table.ApplyEditsAsync();

                ShowMessage("Success!", $"Edited feature {_selectedFeature.Attributes["objectid"]}");
            }
            catch (Exception ex)
            {
                ShowMessage("Failed to edit feature", ex.ToString());
            }
            finally
            {
                // Clear the selection.
                _damageLayer.ClearSelection();
                _selectedFeature = null;

                // Dismiss any callout.
                _myMapView.DismissCallout();
            }
        }
Example #5
0
        /// <summary>
        /// Enables attribute editing, submits attribute edit back to the server and refreshes dynamic layer.
        /// </summary>
        private async void ChoiceList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ChoiceList.SelectionChanged -= ChoiceList_SelectionChanged;
            var    featureID = (Int64)AttributeEditor.Tag;
            var    selected  = (KeyValuePair <object, string>)ChoiceList.SelectedItem;
            var    layer     = MyMapView.Map.Layers["PoolPermit"] as ArcGISDynamicMapServiceLayer;
            var    overlay   = MyMapView.GraphicsOverlays["Highlighter"] as GraphicsOverlay;
            string message   = null;

            try
            {
                if (table == null)
                {
                    // Creates table based on visible layer of dynamic layer
                    // using FeatureServer specifying has_pool field to enable editing.
                    var id  = layer.VisibleLayers[0];
                    var url = layer.ServiceUri.Replace("MapServer", "FeatureServer");
                    url   = string.Format("{0}/{1}", url, id);
                    table = await ServiceFeatureTable.OpenAsync(new Uri(url), null, MyMapView.SpatialReference);

                    table.OutFields = new OutFields(new string[] { "has_pool" });
                }
                // Retrieves feature identified by ID and updates its attributes.
                var feature = await table.QueryAsync(featureID);

                feature.Attributes["has_pool"] = selected.Key;
                await table.UpdateAsync(feature);

                if (table.HasEdits)
                {
                    // Pushes attribute edits back to the server.
                    var result = await table.ApplyEditsAsync();

                    if (result.UpdateResults == null || result.UpdateResults.Count < 1)
                    {
                        return;
                    }
                    var updateResult = result.UpdateResults[0];
                    if (updateResult.Error != null)
                    {
                        message = updateResult.Error.Message;
                    }
                    // Refreshes layer to reflect attribute edits.
                    layer.Invalidate();
                }
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }
            finally
            {
                overlay.Graphics.Clear();
                SetAttributeEditor();
            }
            if (!string.IsNullOrWhiteSpace(message))
            {
                MessageBox.Show(message);
            }
        }
Example #6
0
            private async void DeleteAttachment(Attachment attachmentToDelete, UITableView tableView)
            {
                try
                {
                    // Delete the attachment.
                    await _selectedFeature.DeleteAttachmentAsync(attachmentToDelete);

                    // Get a reference to the feature's service feature table.
                    ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;

                    // Apply the edits to the service feature table.
                    await serviceTable.ApplyEditsAsync();

                    // Update UI.
                    _selectedFeature.Refresh();
                    _attachments = await _selectedFeature.GetAttachmentsAsync();

                    tableView.ReloadData();
                    _viewController.ShowMessage("Successfully deleted attachment", "Success!");
                }
                catch (Exception exception)
                {
                    _viewController.ShowMessage(exception.ToString(), "Error deleting attachment");
                }
            }
Example #7
0
            private async void AddAttachment(UITableView tableView)
            {
                // Get the image to upload.
                Stream imageStream = await GetImageStreamAsync();

                if (imageStream == null)
                {
                    return;
                }

                // Convert the image stream into a byte array.
                byte[] attachmentData = new byte[imageStream.Length];
                imageStream.Read(attachmentData, 0, attachmentData.Length);

                // Determine the file name.
                string filename = _filename ?? "iOS_image_1.jpg";

                // Add the attachment.
                // The contentType string is the MIME type for JPEG files, image/jpeg.
                await _selectedFeature.AddAttachmentAsync(filename, "image/jpeg", attachmentData);

                // Get a reference to the feature's service feature table.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;

                // Apply the edits to the service feature table.
                await serviceTable.ApplyEditsAsync();

                // Update UI.
                _selectedFeature.Refresh();
                _attachments = await _selectedFeature.GetAttachmentsAsync();

                tableView.ReloadData();
                _viewController.ShowMessage("Successfully added attachment", "Success!");
            }
        private async void DeleteButton_Click(object sender, EventArgs e)
        {
            // Reconfigure the button.
            DeleteButton.IsEnabled = false;
            DeleteButton.Text      = "Delete feature";

            // Guard against null.
            if (_tappedFeature == null)
            {
                return;
            }

            try
            {
                // Delete the feature.
                await _damageLayer.FeatureTable.DeleteFeatureAsync(_tappedFeature);

                // Sync the change with the service.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_damageLayer.FeatureTable;
                await serviceTable.ApplyEditsAsync();

                // Show a message confirming the deletion.
                await Application.Current.MainPage.DisplayAlert("Success!", $"Deleted feature with ID {_tappedFeature.Attributes["objectid"]}", "OK");
            }
            catch (Exception ex)
            {
                await Application.Current.MainPage.DisplayAlert("Error", ex.ToString(), "OK");
            }
        }
Example #9
0
        private async void MyMapView_GeoViewTapped(object sender, Esri.ArcGISRuntime.UI.Controls.GeoViewInputEventArgs mapClickPoint)
        {
            IdentifyLayerResult idResult = await MyMapView.IdentifyLayerAsync(serviceRequestLayer, mapClickPoint.Position, 5, false);

            ArcGISFeature serviceRequestFeature = idResult.GeoElements.FirstOrDefault() as ArcGISFeature;

            if (serviceRequestFeature == null)
            {
                return;
            }

            // Create a new feature in the comments table
            ArcGISFeature newComment = relatedTable.CreateFeature() as ArcGISFeature;


            // Add comment text to the 'comments' attribute
            newComment.Attributes["comments"] = "Please show up on time!";


            // Relate the selected service request to the new comment
            serviceRequestFeature.RelateFeature(newComment);
            await relatedTable.AddFeatureAsync(newComment);

            var results = await relatedTable.ApplyEditsAsync();
        }
Example #10
0
        private async void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            // Dismiss the callout.
            MyMapView.DismissCallout();

            try
            {
                // Get the feature to delete from the layer.
                Button  deleteButton    = (Button)sender;
                Feature featureToDelete = (Feature)deleteButton.Tag;

                // Delete the feature.
                await _damageLayer.FeatureTable.DeleteFeatureAsync(featureToDelete);

                // Sync the change with the service.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_damageLayer.FeatureTable;
                await serviceTable.ApplyEditsAsync();

                // Show a message confirming the deletion.
                MessageBox.Show("Deleted feature with ID " + featureToDelete.Attributes["objectid"], "Success!");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Couldn't delete feature");
            }
        }
        private async void MapView_Tapped(object sender, GeoViewInputEventArgs e)
        {
            try
            {
                // Create the feature.
                ArcGISFeature feature = (ArcGISFeature)_damageFeatureTable.CreateFeature();

                // Get the normalized geometry for the tapped location and use it as the feature's geometry.
                MapPoint tappedPoint = (MapPoint)GeometryEngine.NormalizeCentralMeridian(e.Location);
                feature.Geometry = tappedPoint;

                // Set feature attributes.
                feature.SetAttributeValue("typdamage", "Minor");
                feature.SetAttributeValue("primcause", "Earthquake");

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

                // Apply the edits to the service.
                await _damageFeatureTable.ApplyEditsAsync();

                // Update the feature to get the updated objectid - a temporary ID is used before the feature is added.
                feature.Refresh();

                // Confirm feature addition.
                MessageBox.Show("Created feature " + feature.Attributes["objectid"], "Success!");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error adding feature");
            }
        }
Example #12
0
        private async Task CreateFeature(Image capturedImage, int healthValue)
        {
            _helpLabel.Text = "Adding feature...";

            try
            {
                // Get the geometry of the feature.
                MapPoint featurePoint = _graphicsOverlay.Graphics.First().Geometry as MapPoint;

                // Create attributes for the feature using the user selected health value.
                IEnumerable <KeyValuePair <string, object> > featureAttributes = new Dictionary <string, object>()
                {
                    { "Health", (short)healthValue }, { "Height", 3.2 }, { "Diameter", 1.2 }
                };

                // Ensure that the feature table is loaded.
                if (_featureTable.LoadStatus != Esri.ArcGISRuntime.LoadStatus.Loaded)
                {
                    await _featureTable.LoadAsync();
                }

                // Create the new feature
                ArcGISFeature newFeature = _featureTable.CreateFeature(featureAttributes, featurePoint) as ArcGISFeature;

                // Convert the Image from ARCore into a JPEG byte array.
                byte[] attachmentData = await ConvertImageToJPEG(capturedImage);

                // Add the attachment.
                // The contentType string is the MIME type for JPEG files, image/jpeg.
                await newFeature.AddAttachmentAsync("tree.jpg", "image/jpeg", attachmentData);

                // Add the newly created feature to the feature table.
                await _featureTable.AddFeatureAsync(newFeature);

                // Apply the edits to the service feature table.
                await _featureTable.ApplyEditsAsync();

                // Reset the user interface.
                _helpLabel.Text = "Tap to create a feature";
                _graphicsOverlay.Graphics.Clear();
                _addButton.Enabled = false;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ShowMessage("Could not create feature", "Error");
            }
        }
        private async void DeleteFeature(Feature featureToDelete)
        {
            try
            {
                // Delete the feature.
                await _damageLayer.FeatureTable.DeleteFeatureAsync(featureToDelete);

                // Sync the change with the service.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_damageLayer.FeatureTable;
                await serviceTable.ApplyEditsAsync();

                // Show a message confirming the deletion.
                ShowMessage($"Deleted feature with ID {featureToDelete.Attributes["objectid"]}", "Success!");
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString(), "Couldn't delete feature");
            }
        }
        private async void DamageType_Changed(object sender, SelectionChangedEventArgs e)
        {
            // Skip if nothing is selected.
            if (DamageTypeDropDown.SelectedIndex == -1)
            {
                return;
            }

            try
            {
                // Get the new value.
                string selectedAttributeValue = DamageTypeDropDown.SelectedValue.ToString();

                // Load the feature.
                await _selectedFeature.LoadAsync();

                // Update the attribute value.
                _selectedFeature.SetAttributeValue(AttributeFieldName, selectedAttributeValue);

                // Update the table.
                await _selectedFeature.FeatureTable.UpdateFeatureAsync(_selectedFeature);

                // Update the service.
                ServiceFeatureTable table = (ServiceFeatureTable)_selectedFeature.FeatureTable;
                await table.ApplyEditsAsync();

                MessageBox.Show("Edited feature " + _selectedFeature.Attributes["objectid"], "Success!");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Failed to edit feature");
            }
            finally
            {
                // Clear the selection.
                _damageLayer.ClearSelection();
                _selectedFeature = null;

                // Update the UI.
                DamageTypeDropDown.IsEnabled     = false;
                DamageTypeDropDown.SelectedIndex = -1;
            }
        }
        private async void DamageType_Changed(object sender, EventArgs e)
        {
            // Skip if nothing is selected.
            if (DamageTypePicker.SelectedIndex == -1)
            {
                return;
            }

            try
            {
                // Get the new value.
                string selectedAttributeValue = DamageTypePicker.SelectedItem.ToString();

                // Load the feature.
                await _selectedFeature.LoadAsync();

                // Update the attribute value.
                _selectedFeature.SetAttributeValue(AttributeFieldName, selectedAttributeValue);

                // Update the table.
                await _selectedFeature.FeatureTable.UpdateFeatureAsync(_selectedFeature);

                // Update the service.
                ServiceFeatureTable table = (ServiceFeatureTable)_selectedFeature.FeatureTable;
                await table.ApplyEditsAsync();

                await Application.Current.MainPage.DisplayAlert("Success!", $"Edited feature {_selectedFeature.Attributes["objectid"]}", "OK");
            }
            catch (Exception ex)
            {
                await Application.Current.MainPage.DisplayAlert("Failed to edit feature", ex.ToString(), "OK");
            }
            finally
            {
                // Clear the selection.
                _damageLayer.ClearSelection();
                _selectedFeature = null;

                // Update the UI.
                DamageTypePicker.IsEnabled     = false;
                DamageTypePicker.SelectedIndex = -1;
            }
        }
Example #16
0
        private async Task CreateFeature(int healthValue)
        {
            HelpLabel.Text = "Adding feature...";

            try
            {
                // Get the geometry of the feature.
                MapPoint featurePoint = _graphicsOverlay.Graphics.First().Geometry as MapPoint;

                // Create attributes for the feature using the user selected health value.
                IEnumerable <KeyValuePair <string, object> > featureAttributes = new Dictionary <string, object>()
                {
                    { "Health", (short)healthValue }, { "Height", 3.2 }, { "Diameter", 1.2 }
                };

                // Ensure that the feature table is loaded.
                if (_featureTable.LoadStatus != Esri.ArcGISRuntime.LoadStatus.Loaded)
                {
                    await _featureTable.LoadAsync();
                }

                // Create the new feature
                ArcGISFeature newFeature = _featureTable.CreateFeature(featureAttributes, featurePoint) as ArcGISFeature;

                // Add the newly created feature to the feature table.
                await _featureTable.AddFeatureAsync(newFeature);

                // Apply the edits to the service feature table.
                await _featureTable.ApplyEditsAsync();

                // Reset the user interface.
                HelpLabel.Text = "Tap to create a feature";
                _graphicsOverlay.Graphics.Clear();
                AddButton.IsEnabled = false;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                await Application.Current.MainPage.DisplayAlert("Error", "Could not create feature", "OK");
            }
        }
Example #17
0
        private async void DeleteAttachment_Click(object sender, RoutedEventArgs e)
        {
            ActivityIndicator.Visibility = Visibility.Visible;

            try
            {
                // Get a reference to the button that raised the event.
                Button sendingButton = (Button)sender;

                // Get the attachment from the button's DataContext. The button's DataContext is set by the list box.
                Attachment selectedAttachment = (Attachment)sendingButton.DataContext;

                // Delete the attachment.
                await _selectedFeature.DeleteAttachmentAsync(selectedAttachment);

                // Get a reference to the feature's service feature table.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;

                // Apply the edits to the service feature table.
                await serviceTable.ApplyEditsAsync();

                // Update UI.
                _selectedFeature.Refresh();
                AttachmentsListBox.ItemsSource = await _selectedFeature.GetAttachmentsAsync();

                // Show success message.
                await new MessageDialog2("Successfully deleted attachment", "Success!").ShowAsync();
            }
            catch (Exception exception)
            {
                await new MessageDialog2(exception.ToString(), "Error deleting attachment").ShowAsync();
            }
            finally
            {
                ActivityIndicator.Visibility = Visibility.Collapsed;
            }
        }
        private async void MoveSelectedFeature(Esri.ArcGISRuntime.Xamarin.Forms.GeoViewInputEventArgs tapEventDetails)
        {
            try
            {
                // Get the MapPoint from the EventArgs for the tap.
                MapPoint destinationPoint = tapEventDetails.Location;

                // Normalize the point - needed when the tapped location is over the international date line.
                destinationPoint = (MapPoint)GeometryEngine.NormalizeCentralMeridian(destinationPoint);

                // Load the feature.
                await _selectedFeature.LoadAsync();

                // Update the geometry of the selected feature.
                _selectedFeature.Geometry = destinationPoint;

                // Apply the edit to the feature table.
                await _selectedFeature.FeatureTable.UpdateFeatureAsync(_selectedFeature);

                // Push the update to the service.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;
                await serviceTable.ApplyEditsAsync();

                await Application.Current.MainPage.DisplayAlert("Success!", $"Moved feature {_selectedFeature.Attributes["objectid"]}", "OK");
            }
            catch (Exception ex)
            {
                await Application.Current.MainPage.DisplayAlert("Error when moving feature", ex.ToString(), "OK");
            }
            finally
            {
                // Reset the selection.
                _damageLayer.ClearSelection();
                _selectedFeature = null;
            }
        }
Example #19
0
        private async void MoveSelectedFeature(GeoViewInputEventArgs tapEventDetails)
        {
            try
            {
                // Get the MapPoint from the EventArgs for the tap.
                MapPoint destinationPoint = tapEventDetails.Location;

                // Normalize the point - needed when the tapped location is over the international date line.
                destinationPoint = (MapPoint)GeometryEngine.NormalizeCentralMeridian(destinationPoint);

                // Load the feature.
                await _selectedFeature.LoadAsync();

                // Update the geometry of the selected feature.
                _selectedFeature.Geometry = destinationPoint;

                // Apply the edit to the feature table.
                await _selectedFeature.FeatureTable.UpdateFeatureAsync(_selectedFeature);

                // Push the update to the service.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;
                await serviceTable.ApplyEditsAsync();

                MessageBox.Show("Moved feature " + _selectedFeature.Attributes["objectid"], "Success!");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error when moving feature.");
            }
            finally
            {
                // Reset the selection.
                _damageLayer.ClearSelection();
                _selectedFeature = null;
            }
        }
Example #20
0
        private async Task ScrapeArtistInfo(FullArtist artist)
        {
            string bioUrl      = $"https://open.spotify.com/artist/{artist.Id}/about";
            string pageContent = "";

            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("User-Agent", "C# console program");
                pageContent = await client.GetStringAsync(bioUrl);
            }

            var artistResults = _artistScraping.Extract(pageContent);
            var cities        = artistResults["listeners-city"];
            var listeners     = artistResults["listeners"];
            var bio           = artistResults["about"];

            // if there's no bio, we can't find locations :(
            if (bio == null)
            {
                return;
            }

            string fullBio     = bio.ToString() + artistResults["more"].ToString();
            int    shortBioEnd = System.Math.Min(fullBio.Length, 255);
            string shortBio    = fullBio.Substring(0, shortBioEnd);

            Dictionary <string, int> listenerCities = new Dictionary <string, int>();

            for (int i = 0; i < listeners.Count(); i++)
            {
                string listenersString = listeners[i].ToString().Replace("LISTENERS", "").Replace(",", "").Trim();
                int    numListeners    = int.Parse(listenersString);
                listenerCities.Add(cities[i].ToString(), numListeners);
            }

            string aboutArtistJson = JsonConvert.SerializeObject(fullBio, Newtonsoft.Json.Formatting.Indented);
            string classifiedXml   = _classifier.classifyWithInlineXML(aboutArtistJson);

            // HACK: fix "city, state" locations that are split into two:
            //       "<LOCATION>Logan</LOCATION>, <LOCATION>Utah</LOCATION>" => "<LOCATION>Logan, Utah</LOCATION>"
            classifiedXml = classifiedXml.Replace("</LOCATION>, <LOCATION>", ", ");
            MatchCollection locationMatches = _locationRx.Matches(classifiedXml);

            Dictionary <string, Graphic> artistLocations = new Dictionary <string, Graphic>();
            //UNCOMMENT
            //// Build artist locations
            //for (int i = 0; i < locationMatches.Count; i++)
            //{
            //    var m = locationMatches[i];
            //    string loc = m.Groups[1].Value;
            //    MapPoint geocodedLocation = await GeocodeArtistPlacename(loc);
            //    if (geocodedLocation == null) { continue; }

            //    // If the place name was geocoded, create a new feature to store it
            //    // (first one is considered the hometown) :\
            //    if (i == 0)
            //    {
            //        Feature newHometownFeature = _hometownTable.CreateFeature();
            //        newHometownFeature.Geometry = geocodedLocation;
            //        newHometownFeature.Attributes["placename"] = loc;
            //        newHometownFeature.Attributes["artistname"] = artist.Name;
            //        newHometownFeature.Attributes["artistid"] = artist.Id;
            //        newHometownFeature.Attributes["imageurl"] = artist.Images.Last().Url;
            //        newHometownFeature.Attributes["bioshort"] = shortBio;

            //        await _hometownTable.AddFeatureAsync(newHometownFeature);
            //    }
            //    else
            //    {
            //        if (!artistLocations.ContainsKey(loc))
            //        {
            //            Feature otherFeature = _otherPointsTable.CreateFeature();
            //            otherFeature.Geometry = geocodedLocation;
            //            otherFeature.Attributes["placename"] = loc;
            //            otherFeature.Attributes["artistname"] = artist.Name;
            //            otherFeature.Attributes["artistid"] = artist.Id;

            //            await _otherPointsTable.AddFeatureAsync(otherFeature);
            //        }
            //    }
            //}

            //// Apply edits to the hometown table (will apply other edits after adding listener cities)
            //await _hometownTable.ApplyEditsAsync();
            //**UNCOMMENT

            // Create points for the listener cities
            int r = 0;

            foreach (var lc in listenerCities)
            {
                r++;
                MapPoint geocodedLocation = await GeocodeArtistPlacename(lc.Key);

                if (geocodedLocation == null)
                {
                    continue;
                }

                Feature otherFeature = _listenerTable.CreateFeature();
                otherFeature.Geometry = geocodedLocation;
                otherFeature.Attributes["placename"]     = lc.Key;
                otherFeature.Attributes["artistname"]    = artist.Name;
                otherFeature.Attributes["artistid"]      = artist.Id;
                otherFeature.Attributes["listenercount"] = lc.Value;
                otherFeature.Attributes["listenerrank"]  = r;

                await _listenerTable.AddFeatureAsync(otherFeature);
            }

            // Apply edits to the other locations table
            await _listenerTable.ApplyEditsAsync();

            ArtistProgressList.Items.Add(artist.Name);
        }
Example #21
0
        public static async Task <ArcCrudEnum> AddBin(BinViewModel binViewModel)
        {
            IBinstance            bin = binViewModel.Binstance;
            IEnumerable <YTYData> yTY = bin.YTYDatas;

            try
            {
                await _featureTable.LoadAsync();

                var attributes = new Dictionary <string, object>();
                attributes.Add("identifier", bin.Identifier);
                attributes.Add("created_by", bin.CreatedBy);
                attributes.Add("modified_by", bin.ModifiedBy);

                switch (bin.BinType)
                {
                case BinTypeEnum.RoundStorage:
                    attributes.Add("bin_type", "round_storage");
                    break;

                case BinTypeEnum.GravityWagon:
                    attributes.Add("bin_type", "gravity_wagon");
                    break;

                case BinTypeEnum.PolygonStructure:
                    attributes.Add("bin_type", "polygon_structure");
                    break;

                case BinTypeEnum.FlatStructure:
                    attributes.Add("bin_type", "flat_structure");
                    break;
                }

                attributes.Add("year_collected", bin.YearCollected);

                if (bin.IsLeased.HasValue)
                {
                    attributes.Add("owned_or_leased", bin.IsLeased.Value ? "leased" : "owned");
                }

                if (bin.HasDryingDevice.HasValue)
                {
                    attributes.Add("drying_device", bin.HasDryingDevice.Value ? "true" : "false");
                }

                if (bin.HasGrainHeightIndicator.HasValue)
                {
                    attributes.Add("bin_level_indicator_device", bin.HasGrainHeightIndicator.Value ? "true" : "false");
                }

                switch (bin.LadderType)
                {
                case Ladder.None:
                    attributes.Add("ladder_type", "none");
                    break;

                case Ladder.Ladder:
                    attributes.Add("ladder_type", "ladder");
                    break;

                case Ladder.Stairs:
                    attributes.Add("ladder_type", "stairs");
                    break;
                }

                attributes.Add("notes", bin.Notes);

                //bin type specific logic below
                Type t = bin.GetType();
                if (bin.BinType == BinTypeEnum.FlatStructure)
                {
                    if (t.Equals(typeof(FlatBin)))
                    {
                        FlatBin flat = (FlatBin)bin;
                        attributes.Add("crib_height", flat.CribLength);
                        attributes.Add("crib_width", flat.CribWidth);
                    }
                }
                else if (bin.BinType == BinTypeEnum.GravityWagon)
                {
                    if (t.Equals(typeof(GravityBin)))
                    {
                        GravityBin gravityBin = (GravityBin)bin;
                        attributes.Add("chute_length", gravityBin.ChuteLength);
                        attributes.Add("hopper_height", gravityBin.HopperHeight);
                        attributes.Add("rectangle_height", gravityBin.RectangleHeight);
                        attributes.Add("rectangle_length", gravityBin.RectangleLength);
                        attributes.Add("rectangle_width", gravityBin.RectangleWidth);
                    }
                }
                else if (bin.BinType == BinTypeEnum.PolygonStructure)
                {
                    if (t.Equals(typeof(PolygonBin)))
                    {
                        PolygonBin polygonBin = (PolygonBin)bin;
                        attributes.Add("side_height", polygonBin.SideHeight);
                        attributes.Add("side_width", polygonBin.SideWidth);
                        attributes.Add("number_of_sides", polygonBin.NumberOfSides);
                    }
                }
                else if (bin.BinType == BinTypeEnum.RoundStorage)
                {
                    if (t.Equals(typeof(RoundBin)))
                    {
                        RoundBin round = (RoundBin)bin;
                        if (round.HasHopper.HasValue)
                        {
                            attributes.Add("has_hopper", round.HasHopper.Value ? "true" : "false");
                        }
                        attributes.Add("radius", round.Radius);
                        attributes.Add("wall_height", round.WallHeight);
                        attributes.Add("roof_height", round.RoofHeight);
                        attributes.Add("hopper_height", round.HopperHeight);
                    }
                }

                MapPoint mp;
                double   lat = 0;
                double   lon = 0;

                try
                {
                    var locator = CrossGeolocator.Current;
                    locator.DesiredAccuracy = 1000;
                    var position = await locator.GetPositionAsync();

                    if (position == null)
                    {
                        Console.WriteLine("Location Service error");
                    }
                    lat = position.Latitude;
                    lon = position.Longitude;
                }
                catch { }

                string   lonS      = lon.ToString();
                string[] split     = lonS.Split('.');
                var      charArray = split[1].ToCharArray();
                //seperate good location, make third if necassary
                string first     = charArray[0].ToString();
                string second    = charArray[1].ToString();
                string third     = charArray[2].ToString();
                Random random    = new Random();
                int    addition  = random.Next(25, 75);
                string additionS = addition.ToString();
                string newLong   = split[0] + '.' + first + second + third + additionS;
                //latitude
                string   latS       = lat.ToString();
                string[] splitL     = latS.Split('.');
                var      charArrayL = splitL[1].ToCharArray();
                //seperate good location, make third if necassary
                string firstL             = charArrayL[0].ToString();
                string secondL            = charArrayL[1].ToString();
                string thirdL             = charArrayL[2].ToString();
                int    additionL          = random.Next(25, 75);
                string additionSL         = additionL.ToString();
                string newLat             = splitL[0] + '.' + firstL + secondL + thirdL + additionSL;
                double clusteredLongitude = double.Parse(newLong);
                double clusteredLatitude  = double.Parse(newLat);

                mp = new MapPoint(clusteredLongitude, clusteredLatitude);

                binViewModel.ArcGISFeature = (ArcGISFeature)_featureTable.CreateFeature(attributes, mp);

                await _featureTable.AddFeatureAsync(binViewModel.ArcGISFeature);

                await binViewModel.ArcGISFeature.LoadAsync();

                if (DeviceInfo.DeviceType == DeviceType.Physical)
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        bin.Image.GetStream().CopyTo(memoryStream);
                        // add an attachment - pass the name, mime type, and attachment data (bytes, etc.)
                        await binViewModel.ArcGISFeature.AddAttachmentAsync("Photo.jpg", "image/jpg", memoryStream.ToArray()); //agsFeature
                    }
                }

                if (yTY == null)
                {
                    yTY = new List <YTYData>();
                }

                //create json
                string jsonString = JsonConvert.SerializeObject(yTY);
                byte[] byteArray  = Encoding.UTF8.GetBytes(jsonString);

                List <Attachment>          attachmentsToRemove = new List <Attachment>();
                IReadOnlyList <Attachment> attachments         = await binViewModel.ArcGISFeature.GetAttachmentsAsync();

                foreach (Attachment attachment in attachments)
                {
                    if (attachment.Name.Equals(YTY_FILE_NAME))
                    {
                        attachmentsToRemove.Add(attachment);
                    }
                }

                await binViewModel.ArcGISFeature.DeleteAttachmentsAsync(attachmentsToRemove);

                await binViewModel.ArcGISFeature.AddAttachmentAsync(YTY_FILE_NAME, "application/json", byteArray); //agsFeature

                await _featureTable.UpdateFeatureAsync(binViewModel.ArcGISFeature);                                //agsFeature

                // push to ArcGIS Online feature service
                IReadOnlyList <EditResult> editResults = await _featureTable.ApplyEditsAsync();

                // check results for errors
                foreach (var er in editResults)
                {
                    if (er.CompletedWithErrors)
                    {
                        return(ArcCrudEnum.Failure);
                    }
                }

                return(ArcCrudEnum.Success);
            }
            catch (ArcGISWebException)
            {
                return(ArcCrudEnum.Exception);
            }
        }
        /// <summary>
        /// Enables geometry editing, submits geometry edit back to the server and refreshes dynamic layer.
        /// </summary>
        private async void EditButton_Click(object sender, RoutedEventArgs e)
        {
            var    layer     = MyMapView.Map.Layers["RecreationalArea"] as ArcGISDynamicMapServiceLayer;
            var    overlay   = MyMapView.GraphicsOverlays["Highlighter"] as GraphicsOverlay;
            var    featureID = (long)EditButton.Tag;
            string message   = null;

            try
            {
                // Hides graphic from overlay and dynamic layer while its geometry is being modified.
                overlay.Graphics.Clear();
                // Negative IDs indicate they do not exist on server yet.
                if (featureID > 0)
                {
                    if (layer.LayerDefinitions == null)
                    {
                        layer.LayerDefinitions = new ObservableCollection <LayerDefinition>();
                    }
                    else
                    {
                        layer.LayerDefinitions.Clear();
                    }
                    layer.LayerDefinitions.Add(new LayerDefinition()
                    {
                        LayerID    = layer.VisibleLayers[0],
                        Definition = string.Format("Objectid <> {0}", featureID)
                    });
                }
                if (table == null)
                {
                    // Creates table based on visible layer of dynamic layer
                    // using FeatureServer specifying shape field to enable editing.
                    var id  = layer.VisibleLayers[0];
                    var url = layer.ServiceUri.Replace("MapServer", "FeatureServer");
                    url   = string.Format("{0}/{1}", url, id);
                    table = await ServiceFeatureTable.OpenAsync(new Uri(url), null, MyMapView.SpatialReference);
                }
                // Retrieves feature identified by ID and updates its geometry
                // using GeometryEngine to correct ring orientation.
                var feature = await table.QueryAsync(featureID);

                var geometry = await MyMapView.Editor.EditGeometryAsync(feature.Geometry);

                feature.Geometry = GeometryEngine.Simplify(geometry);
                await table.UpdateAsync(feature);

                if (table.HasEdits)
                {
                    // Pushes geometry edits back to the server.
                    var result = await table.ApplyEditsAsync();

                    if (result.UpdateResults == null || result.UpdateResults.Count < 1)
                    {
                        return;
                    }
                    var updateResult = result.UpdateResults[0];
                    if (updateResult.Error != null)
                    {
                        message = updateResult.Error.Message;
                    }
                }
            }
            catch (TaskCanceledException te)
            {
                // Handles canceling out of Editor.
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }
            finally
            {
                SetGeometryEditor();
                if (layer.LayerDefinitions != null)
                {
                    layer.LayerDefinitions.Clear();
                    // Refreshes layer to reflect geometry edits.
                    layer.Invalidate();
                }
            }
            if (!string.IsNullOrWhiteSpace(message))
            {
                MessageBox.Show(message);
            }
        }
Example #23
0
        public static async Task <ArcCrudEnum> EditBin(BinViewModel binViewModel)
        {
            IBinstance    bin           = binViewModel.Binstance;
            ArcGISFeature featureToEdit = binViewModel.ArcGISFeature;

            try
            {
                await featureToEdit.LoadAsync();

                featureToEdit.Attributes["identifier"]  = bin.Identifier;
                featureToEdit.Attributes["modified_by"] = binViewModel.EmpoyeeNumber;

                switch (bin.BinType)
                {
                case BinTypeEnum.RoundStorage:
                    featureToEdit.Attributes["bin_type"] = "round_storage";
                    break;

                case BinTypeEnum.GravityWagon:
                    featureToEdit.Attributes["bin_type"] = "gravity_wagon";
                    break;

                case BinTypeEnum.PolygonStructure:
                    featureToEdit.Attributes["bin_type"] = "polygon_structure";
                    break;

                case BinTypeEnum.FlatStructure:
                    featureToEdit.Attributes["bin_type"] = "flat_structure";
                    break;
                }

                featureToEdit.Attributes["year_collected"] = bin.YearCollected;


                if (bin.IsLeased.HasValue)
                {
                    featureToEdit.Attributes["owned_or_leased"] = bin.IsLeased.Value ? "leased" : "owned";
                }

                if (bin.HasDryingDevice.HasValue)
                {
                    featureToEdit.Attributes["drying_device"] = bin.HasDryingDevice.Value ? "true" : "false";
                }

                if (bin.HasGrainHeightIndicator.HasValue)
                {
                    featureToEdit.Attributes["bin_level_indicator_device"] = bin.HasGrainHeightIndicator.Value ? "true" : "false";
                }

                switch (bin.LadderType)
                {
                case Ladder.None:
                    featureToEdit.Attributes["ladder_type"] = "none";
                    break;

                case Ladder.Ladder:
                    featureToEdit.Attributes["ladder_type"] = "ladder";
                    break;

                case Ladder.Stairs:
                    featureToEdit.Attributes["ladder_type"] = "stairs";
                    break;
                }

                featureToEdit.Attributes["notes"] = bin.Notes;

                double dr;
                //double.TryParse(bin.BinVolume, out dr);
                //featureToEdit.Attributes["bin_volume"] = dr;

                //bin type specific logic below
                Type t = bin.GetType();
                if (bin.BinType == BinTypeEnum.FlatStructure)
                {
                    if (t.Equals(typeof(FlatBin)))
                    {
                        FlatBin flat = (FlatBin)bin;
                        featureToEdit.Attributes["crib_height"] = flat.CribLength;
                        featureToEdit.Attributes["crib_width"]  = flat.CribWidth;
                    }
                }
                else if (bin.BinType == BinTypeEnum.GravityWagon)
                {
                    if (t.Equals(typeof(GravityBin)))
                    {
                        GravityBin gravityBin = (GravityBin)bin;
                        featureToEdit.Attributes["chute_length"]     = gravityBin.ChuteLength;
                        featureToEdit.Attributes["hopper_height"]    = gravityBin.HopperHeight;
                        featureToEdit.Attributes["rectangle_height"] = gravityBin.RectangleHeight;
                        featureToEdit.Attributes["rectangle_length"] = gravityBin.RectangleLength;
                        featureToEdit.Attributes["rectangle_width"]  = gravityBin.RectangleWidth;
                    }
                }
                else if (bin.BinType == BinTypeEnum.PolygonStructure)
                {
                    if (t.Equals(typeof(PolygonBin)))
                    {
                        PolygonBin polygonBin = (PolygonBin)bin;
                        featureToEdit.Attributes["side_height"]     = polygonBin.SideHeight;
                        featureToEdit.Attributes["side_width"]      = polygonBin.SideWidth;
                        featureToEdit.Attributes["number_of_sides"] = polygonBin.NumberOfSides;
                    }
                }
                else if (bin.BinType == BinTypeEnum.RoundStorage)
                {
                    if (t.Equals(typeof(PolygonBin)))
                    {
                        RoundBin round = (RoundBin)bin;
                        if (round.HasHopper.HasValue)
                        {
                            featureToEdit.Attributes["has_hopper"] = round.HasHopper.Value ? "true" : "false";
                        }

                        featureToEdit.Attributes["radius"]        = round.Radius;
                        featureToEdit.Attributes["wall_height"]   = round.WallHeight;
                        featureToEdit.Attributes["roof_height"]   = round.RoofHeight;
                        featureToEdit.Attributes["hopper_height"] = round.HopperHeight;
                    }
                }


                // can't be null
                if (binViewModel.Binstance.YTYDatas == null)
                {
                    binViewModel.Binstance.YTYDatas = new List <YTYData>();
                }
                //use data in _binViewModel

                System.Diagnostics.Debug.Print("Feature can edit attachments" + (featureToEdit.CanEditAttachments ? "Yes" : "No"));
                //-------- Formatting --------
                //create json
                string jsonString = JsonConvert.SerializeObject(binViewModel.Binstance.YTYDatas);

                //System.Diagnostics.Debug.Print(jsonString);
                //System.Diagnostics.Debug.Print(((Binstance)(binViewModel.Binstance)).YTYDatasString());
                // convert json to byte array
                byte[] byteArray = Encoding.UTF8.GetBytes(jsonString);


                //-------- ARC Connection --------
                //remove old YTYData
                List <Attachment>          attachmentsToRemove = new List <Attachment>();
                IReadOnlyList <Attachment> attachments         = await featureToEdit.GetAttachmentsAsync();

                foreach (Attachment attachment in attachments)
                {
                    System.Diagnostics.Debug.Print(attachment.Name);
                    if (attachment.Name.Equals(YTY_FILE_NAME))
                    {
                        System.Diagnostics.Debug.Print("Found YTY attachment");
                        attachmentsToRemove.Add(attachment);
                    }
                }
                System.Diagnostics.Debug.Print("Attachments to remove:");
                foreach (Attachment attachment in attachments)
                {
                    System.Diagnostics.Debug.Print(attachment.Name);
                }

                if (attachmentsToRemove.Any())
                {
                    //update the json file
                    await featureToEdit.UpdateAttachmentAsync(attachmentsToRemove.First(), YTY_FILE_NAME, "application/json", byteArray);
                }

                _featureTable = (ServiceFeatureTable)featureToEdit.FeatureTable;

                // update feature after attachment added
                await _featureTable.UpdateFeatureAsync(featureToEdit); //agsFeature

                System.Diagnostics.Debug.Print("Feature table updated");

                // push to ArcGIS Online feature service
                IReadOnlyList <EditResult> editResults = await _featureTable.ApplyEditsAsync();

                System.Diagnostics.Debug.Print("Arc updated");

                foreach (var er in editResults)
                {
                    if (er.CompletedWithErrors)
                    {
                        // handle error (er.Error.Message)
                        return(ArcCrudEnum.Failure);
                    }
                }

                return(ArcCrudEnum.Success);
            }
            catch (ArcGISWebException)
            {
                return(ArcCrudEnum.Exception);
            }
        }
Example #24
0
        private async void AddAttachment_Click(object sender, RoutedEventArgs e)
        {
            if (_selectedFeature == null)
            {
                return;
            }

            // Adjust the UI.
            AddAttachmentButton.IsEnabled = false;
            ActivityIndicator.Visibility  = Visibility.Visible;

            try
            {
                // Show a file dialog.
                // Allow the user to specify a file path - create the dialog.
                OpenFileDialog dlg = new OpenFileDialog
                {
                    DefaultExt       = ".jpg",
                    Filter           = "Image Files(*.JPG;*.JPEG)|*.JPG;*.JPEG",
                    InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
                };

                // Show the dialog and get the results.
                bool?result = dlg.ShowDialog();

                // Take action if the user selected a file.
                if (result != true)
                {
                    return;
                }

                // Get the name of the file from the full path (dlg.FileName is the full path).
                string filename = Path.GetFileName(dlg.FileName);

                // Create a stream for reading the file.
                FileStream fs = new FileStream(dlg.FileName,
                                               FileMode.Open,
                                               FileAccess.Read);

                // Create a binary reader from the stream.
                BinaryReader br = new BinaryReader(fs);

                // Populate the attachment data with the binary content.
                long   numBytes       = new FileInfo(dlg.FileName).Length;
                byte[] attachmentData = br.ReadBytes((int)numBytes);

                // Close the stream.
                fs.Close();

                // Add the attachment.
                // The contentType string is the MIME type for JPEG files, image/jpeg.
                await _selectedFeature.AddAttachmentAsync(filename, "image/jpeg", attachmentData);

                // Get a reference to the feature's service feature table.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;

                // Apply the edits to the service feature table.
                await serviceTable.ApplyEditsAsync();

                // Update UI.
                _selectedFeature.Refresh();
                AttachmentsListBox.ItemsSource = await _selectedFeature.GetAttachmentsAsync();

                MessageBox.Show("Successfully added attachment", "Success!");
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.ToString(), "Error adding attachment");
            }
            finally
            {
                // Adjust the UI.
                AddAttachmentButton.IsEnabled = true;
                ActivityIndicator.Visibility  = Visibility.Collapsed;
            }
        }
Example #25
0
        private async void AddAttachment_Click(object sender, EventArgs e)
        {
            if (_selectedFeature == null)
            {
                return;
            }

            // Adjust the UI.
            AddAttachmentButton.IsEnabled         = false;
            AttachmentActivityIndicator.IsVisible = true;

            // Get the file.
            string contentType = "image/jpeg";

            try
            {
                byte[] attachmentData;
                string filename;

                // Xamarin.Plugin.FilePicker shows the iCloud picker (not photo picker) on iOS.
                // This iOS code shows the photo picker.
#if __IOS__
                Stream imageStream = await GetImageStreamAsync();

                if (imageStream == null)
                {
                    return;
                }

                attachmentData = new byte[imageStream.Length];
                imageStream.Read(attachmentData, 0, attachmentData.Length);
                filename = _filename ?? "file1.jpeg";
#else
                // Show a file picker - this uses the Xamarin.Plugin.FilePicker NuGet package.
                FileData fileData = await CrossFilePicker.Current.PickFile(new[] { ".jpg", ".jpeg" });

                if (fileData == null)
                {
                    return;
                }

                if (!fileData.FileName.EndsWith(".jpg") && !fileData.FileName.EndsWith(".jpeg"))
                {
                    await Application.Current.MainPage.DisplayAlert("Try again!", "This sample only allows uploading jpg files.", "OK");

                    return;
                }

                attachmentData = fileData.DataArray;
                filename       = fileData.FileName;
#endif
                // Add the attachment.
                // The contentType string is the MIME type for JPEG files, image/jpeg.
                await _selectedFeature.AddAttachmentAsync(filename, contentType, attachmentData);

                // Get a reference to the feature's service feature table.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;

                // Apply the edits to the service feature table.
                await serviceTable.ApplyEditsAsync();

                // Update UI.
                _selectedFeature.Refresh();
                AttachmentsListBox.ItemsSource = await _selectedFeature.GetAttachmentsAsync();

                await Application.Current.MainPage.DisplayAlert("Success!", "Successfully added attachment", "OK");
            }
            catch (Exception exception)
            {
                await Application.Current.MainPage.DisplayAlert("Error adding attachment", exception.ToString(), "OK");
            }
            finally
            {
                // Adjust the UI.
                AddAttachmentButton.IsEnabled         = true;
                AttachmentActivityIndicator.IsVisible = false;
            }
        }
Example #26
0
        private async void AddAttachment_Click(object sender, RoutedEventArgs e)
        {
            if (_selectedFeature == null)
            {
                return;
            }

            // Adjust the UI.
            AddAttachmentButton.IsEnabled = false;
            ActivityIndicator.Visibility  = Visibility.Visible;

            // Get the file.
            string contentType = "image/jpeg";

            byte[] attachmentData;

            try
            {
                // Show a file picker.
                // Allow the user to specify a file path - create the picker.
                FileOpenPicker openPicker = new FileOpenPicker();
                openPicker.FileTypeFilter.Add(".jpg");

                // Show the picker.
                StorageFile file = await openPicker.PickSingleFileAsync();

                // Take action if the user selected a file.
                if (file == null)
                {
                    return;
                }

                // Read the file contents into memory.
                Stream dataStream = await file.OpenStreamForReadAsync();

                attachmentData = new byte[dataStream.Length];
                dataStream.Read(attachmentData, 0, attachmentData.Length);
                dataStream.Close();

                // Add the attachment.
                // The contentType string is the MIME type for JPEG files, image/jpeg.
                await _selectedFeature.AddAttachmentAsync(file.Name, contentType, attachmentData);

                // Get a reference to the feature's service feature table.
                ServiceFeatureTable serviceTable = (ServiceFeatureTable)_selectedFeature.FeatureTable;

                // Apply the edits to the service feature table.
                await serviceTable.ApplyEditsAsync();

                // Update UI.
                _selectedFeature.Refresh();
                AttachmentsListBox.ItemsSource = await _selectedFeature.GetAttachmentsAsync();

                await new MessageDialog2("Successfully added attachment", "Success!").ShowAsync();
            }
            catch (Exception exception)
            {
                await new MessageDialog2(exception.ToString(), "Error adding attachment").ShowAsync();
            }
            finally
            {
                // Adjust the UI.
                AddAttachmentButton.IsEnabled = true;
                ActivityIndicator.Visibility  = Visibility.Collapsed;
            }
        }