async void OnDoneClick(object sender, EventArgs e)
        {
            if (ContentView.IsAnyRequiredFieldEmpty)
            {
                string text = "Please fill out all required fields";
                ContentView.Banner.SetInformationText(text, true);
                return;
            }

            ContentView.CancelCrosshairMode();
            PointClient.MarkerSource.Clear();
            ContentView.Popup.Hide();

            UIImage image = ContentView.Content.CameraField.Photo.Image;

            BucketResponse response1;

            if (image == null)
            {
                // Photo is an optional field.
                // Create a mock successful response,
                // if the user hasn't taken a photo
                response1      = new BucketResponse();
                response1.Path = "";
            }
            else
            {
                Stream stream = Camera.GetStreamFromImage(image);
                ContentView.Banner.ShowUploadingImage();
                string filename = ContentView.Content.CameraField.ImageName;
                response1 = await BucketClient.Upload(filename, stream);
            }

            if (response1.IsOk)
            {
                ContentView.Banner.ShowUploadingData();

                Data          item      = GetData(response1.Path);
                CartoResponse response2 = await Networking.Post(item);

                if (response2.IsOk)
                {
                    ContentView.Banner.Complete();
                }
                else
                {
                    ContentView.Banner.ShowFailedCartoUpload();
                    SQLClient.Instance.Insert(item);
                }
            }
            else
            {
                ContentView.Banner.ShowFailedAmazonUpload();
                Data item = GetData(Camera.LatestImageName);
                SQLClient.Instance.Insert(item);
            }

            ContentView.Content.Clear();
            PointClient.QueryPoints(delegate { });
        }
        void OnPopupClosed(object sender, EventArgs e)
        {
            PointClient.MarkerSource.Clear();
            ContentView.CancelCrosshairMode();

            ContentView.Content.EndEditing(true);
        }
        void OnLocationChosen(object sender, EventArgs e)
        {
            // Scale needs to be accounted for separetly,
            // multiply all iOS view coordinates by scale to get real values
            nfloat scale = UIScreen.MainScreen.Scale;

            // Crosshair is a regular ImageView centered on the MapView,
            // Translate crosshair's coordinates to a position on the map
            var parameters = ContentView.Crosshair.Frame;
            var x          = (parameters.X + parameters.Width / 2) * scale;
            var y          = (parameters.Y + parameters.Height / 2 - Device.TrueY0) * scale;
            var screen     = new ScreenPos((float)x, (float)y);

            ContentView.MapView.ScreenToMap(screen);

            MapPos position = ContentView.MapView.ScreenToMap(screen);

            PointClient.AddUserMarker(position);

            // Center marker on currently visible area (partically hidden by popup)
            var mapBounds = new MapBounds(position, position);

            y      = (ContentView.Popup.VisibleY / 2) * scale;
            screen = new ScreenPos((float)x, (float)y);
            var screenBounds = new ScreenBounds(screen, screen);

            ContentView.MapView.MoveToFitBounds(mapBounds, screenBounds, false, 0.2f);

            // Translate internal units to lat/lon
            position = PointClient.Projection.ToLatLong(position.X, position.Y);

            LocationClient.MarkerLatitude  = position.X;
            LocationClient.MarkerLongitude = position.Y;

            InvokeOnMainThread(delegate
            {
                ContentView.Popup.Show();
                ContentView.CancelCrosshairMode();
            });
        }
 void OnLocationChoiceCancelled(object sender, EventArgs e)
 {
     ContentView.CancelCrosshairMode();
 }
        async void OnDoneClick(object sender, EventArgs e)
        {
            if (ContentView.IsAnyRequiredFieldEmpty)
            {
                ContentView.Banner.SetInformationText("Please fill our all required fields", true);
                return;
            }

            ContentView.CancelCrosshairMode();

            PointClient.MarkerSource.Clear();
            ContentView.Popup.Hide();
            ContentView.Banner.SetInformationText("Compressing image...", false);

            using (var stream = new MemoryStream())
            {
                Bitmap bitmap = ContentView.Content.CameraField.Photo;

                BucketResponse response1;
                string         filename;

                if (bitmap == null)
                {
                    // Photo is an optional field.
                    // Create a mock successful response,
                    // if the user hasn't taken a photo
                    response1      = new BucketResponse();
                    response1.Path = "";
                    filename       = "";
                }
                else
                {
                    bitmap.Compress(Bitmap.CompressFormat.Png, Quality, stream);

                    filename = ContentView.Content.CameraField.ImageName;

                    ContentView.Banner.ShowUploadingImage();

                    response1 = await BucketClient.Upload(filename, stream);
                }

                if (response1.IsOk)
                {
                    ContentView.Banner.ShowUploadingData();

                    Data          item      = GetData(response1.Path);
                    CartoResponse response2 = await Networking.Post(item);

                    if (response2.IsOk)
                    {
                        ContentView.Banner.Complete();
                    }
                    else
                    {
                        ContentView.Banner.ShowFailedCartoUpload();
                        SQLClient.Instance.Insert(item);
                    }
                }
                else
                {
                    ContentView.Banner.ShowFailedAmazonUpload();
                    Data item = GetData(filename);
                    SQLClient.Instance.Insert(item);
                }

                ContentView.Content.Clear();
                PointClient.QueryPoints(delegate { });
            }
        }
 void OnPopupClosed(object sender, EventArgs e)
 {
     ContentView.CancelCrosshairMode();
     PointClient.MarkerSource.Clear();
 }