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 OnLocationChosen(object sender, EventArgs e)
        {
            // Crosshair is a regular ImageView centered on the MapView,
            // Translate crosshair's coordinates to a position on the map
            var parameters = (RelativeLayout.LayoutParams)ContentView.Crosshair.LayoutParameters;
            var x          = parameters.LeftMargin + parameters.Width / 2;
            var y          = parameters.TopMargin + parameters.Height / 2;
            var screen     = new ScreenPos(x, 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;
            screen = new ScreenPos(x, 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;

            RunOnUiThread(delegate
            {
                ContentView.Popup.Show();
            });
        }
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            Window.SetSoftInputMode(SoftInput.AdjustPan);

            ContentView = new MainView(this);
            SetContentView(ContentView);

            LocationClient = new LocationClient(ContentView.MapView);

            if (IsMarshmallow)
            {
                RequestPermissions(Permissions);
            }
            else
            {
                OnPermissionsGranted();
            }

            PointClient = new PointClient(ContentView.MapView);

            var bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.icon_pin_red);

            PointClient.Bitmap = BitmapUtils.CreateBitmapFromAndroidBitmap(bitmap);

            bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.icon_banner_info);
            // Scale down, as our original image is too large
            int size = (int)(20 * ContentView.Density);

            bitmap = Bitmap.CreateScaledBitmap(bitmap, size, size, false);
            PointClient.PointListener.LeftImage = BitmapUtils.CreateBitmapFromAndroidBitmap(bitmap);

            PointClient.QueryPoints(delegate { });

            MapListener = new MapClickListener();

            List <Data> items = SQLClient.Instance.GetAll();

            if (items.Count > 0)
            {
                ShowSyncAlert(items.Count);
            }
        }
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            Title = "Data Collection";

            ContentView = new MainView();
            View        = ContentView;

            LocationManager = new LocationManager();

            LocationClient = new LocationClient(ContentView.MapView);

            PointClient        = new PointClient(ContentView.MapView);
            PointClient.Bitmap = BitmapUtils.CreateBitmapFromUIImage(UIImage.FromFile("icon_pin_red.png"));

            MapListener = new MapClickListener();

            string text = "QUERYING POINTS...";

            ContentView.Banner.SetLoadingText(text, false);

            List <Data> items = SQLClient.Instance.GetAll();

            if (items.Count > 0)
            {
                ShowSyncAlert(items.Count);
            }

            PointClient.QueryPoints(delegate
            {
                InvokeOnMainThread(delegate
                {
                    ContentView.Banner.Hide();
                });
            });

            var image = UIImage.FromFile("icon_banner_info.png");

            image = ImageUtils.Resize(image, 70.0f);

            PointClient.PointListener.LeftImage = BitmapUtils.CreateBitmapFromUIImage(image);
        }
        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();
            });
        }
        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 { });
            }
        }