private void AddHelicopter()
        {
            // TESTING
            Console.WriteLine("Entered Add Heli...");
            Position start = new Position(-37.9061137, 176.2050742);
            Position end   = new Position(-36.8613687, 174.7676895);

            Console.WriteLine("Set postitions...");

            Helicopter heli = new Helicopter()
            {
                startPosition       = start,
                destinationPosition = end
            };

            Console.WriteLine("Created Heli...");
            CustomPin heliPin = new CustomPin
            {
                CustomType        = ODMSPinType.HELICOPTER,
                Label             = "Heli",
                HelicopterDetails = heli,
                Position          = heli.startPosition,
                Address           = "1"
            };

            Console.WriteLine("Created Helipin...");
            customMap.HelicopterPins.Add(heliPin.Address, heliPin);
            customMap.Pins.Add(heliPin);
        }
        /// <summary>
        /// Refreshes the flight path if the helicopter is currently selected
        /// </summary>
        /// <param name="heliPin"></param>
        private void refreshFlightDetails(CustomPin heliPin)
        {
            if (heliPin.Address.Equals(selectedHeli))
            {
                clearFlightPath();
                clearOrganRange();

                if (!heliPin.HelicopterDetails.hasArrived(heliPin.Position))
                {
                    addFlightPath(heliPin);
                    addOrganRange(heliPin);
                }
            }
        }
        private async Task InitialiseHospitals()
        {
            ClinicianAPI clinicianApi = new ClinicianAPI();
            Tuple <HttpStatusCode, List <Hospital> > tuple = await clinicianApi.GetHospitals();

            switch (tuple.Item1)
            {
            case HttpStatusCode.OK:
                Console.WriteLine("Organ map hospitals retrieved successfully");
                hospitals = tuple.Item2;

                foreach (Hospital currentHospital in hospitals)
                {
                    Console.WriteLine("Tracking positions");
                    Position finalPosition = new Position(currentHospital.latitude, currentHospital.longitude);

                    var pin = new CustomPin
                    {
                        CustomType = ODMSPinType.HOSPITAL,
                        Position   = finalPosition,
                        Label      = currentHospital.name,
                        Address    = currentHospital.address,
                    };

                    // We add to this list to track our pins with additional information (like hospital or donor)
                    customMap.CustomPins.Add(pin.Position, pin);

                    lock (customMap.Pins)
                    {
                        customMap.Pins.Add(pin);
                    }
                }

                break;

            case HttpStatusCode.ServiceUnavailable:
                await DisplayAlert("",
                                   "Server unavailable, check connection",
                                   "OK");

                break;

            case HttpStatusCode.InternalServerError:
                await DisplayAlert("",
                                   "Server error retrieving hospitals, please try again (500)",
                                   "OK");

                break;
            }
        }
        /// <summary>
        /// Adds a bubble that reflects the expiry range of a helicopter carrying organ
        /// </summary>
        /// <param name="heliPin"></param>
        private void addOrganRange(CustomPin heliPin)
        {
            var circleOptions = new CircleOptions();

            circleOptions.InvokeCenter(new LatLng(heliPin.Position.Latitude, heliPin.Position.Longitude));

            // TODO adjust to organ countdown
            circleOptions.InvokeRadius(40000);

            circleOptions.InvokeFillColor(0X660000FF);
            circleOptions.InvokeStrokeColor(0X660000FF);
            circleOptions.InvokeStrokeWidth(0);

            highlightedOrganRange = new Tuple <CustomPin, Circle>(heliPin, NativeMap.AddCircle(circleOptions));
        }
        /// <summary>
        /// Generates marker options for a pin that contains information about a helicopter
        /// </summary>
        /// <param name="pin"></param>
        /// <returns></returns>
        private MarkerOptions CreateHelicopterMarker(CustomPin pin)
        {
            refreshFlightDetails(pin);

            // Create basic options
            var marker = new MarkerOptions();

            marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
            marker.SetTitle(pin.Label);

            // Snippet is set to store the unique heli identifier (dictionary key) so it can be recalled when searching for a customPin based on Marker
            marker.SetSnippet(pin.Address);

            marker.SetIcon(BitmapDescriptorFactory.FromBitmap(helicopterIcons[pin.OrganToTransport]));

            return(marker);
        }
        /// <summary>
        /// Adds a polyline path based on helicopter destination and current position
        /// </summary>
        /// <param name="heliPin"></param>
        private void addFlightPath(CustomPin heliPin)
        {
            var currentFlightPathOptions = new PolylineOptions();

            // Other colour constants can be found at https://developer.android.com/reference/android/graphics/Color#constants_1
            int BLUE = -16776961;

            currentFlightPathOptions.InvokeColor(BLUE);

            // Add current position (start of path)
            currentFlightPathOptions.Add(new LatLng(heliPin.Position.Latitude, heliPin.Position.Longitude));

            // Add destination position (end of path)
            currentFlightPathOptions.Add(new LatLng(heliPin.HelicopterDetails.destinationPosition.Latitude,
                                                    heliPin.HelicopterDetails.destinationPosition.Longitude));

            highlightedFlightPath = new Tuple <CustomPin, Polyline>(heliPin, NativeMap.AddPolyline(currentFlightPathOptions));
        }
        /// <summary>
        /// Toggles more details regarding a helicopter (organs + flight path)
        /// </summary>
        /// <param name="customPin"></param>
        private void processHelicopterTapped(CustomPin customPin)
        {
            clearFlightPath();
            clearOrganRange();

            // Heli is already highlighted, deselect
            if (customPin.Address.Equals(selectedHeli))
            {
                // Reset selected heli
                selectedHeli = null;
            }
            else
            {
                selectedHeli = customPin.Address;
                addFlightPath(customPin);
                addOrganRange(customPin);
            }
        }
        /// <summary>
        /// Generates marker options for a pin that contains information about a hospital
        /// </summary>
        /// <param name="pin"></param>
        /// <returns></returns>
        private MarkerOptions CreateHospitalMarker(CustomPin pin)
        {
            // Create basic options
            var marker = new MarkerOptions();

            marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
            marker.SetTitle(pin.Label);
            marker.SetSnippet(pin.Address);

            // Create the image
            Bitmap imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.hospital_icon, bitmapOptions);

            // Scale the image
            imageBitmap = Bitmap.CreateScaledBitmap(imageBitmap, 110, 110, false);

            marker.SetIcon(BitmapDescriptorFactory.FromBitmap(imageBitmap));

            return(marker);
        }
        /// <summary>
        /// Creates a MarkerOptions for a new pin on the map
        /// </summary>
        /// <param name="pin"></param>
        /// <returns></returns>
        protected override MarkerOptions CreateMarker(Pin pin)
        {
            MarkerOptions markerToAddOptions = null;

            // Find the correlating custom pin to get our extra parameters
            CustomPin foundCustomPin = GetCustomPin(pin);

            switch (foundCustomPin.CustomType)
            {
            case ODMSPinType.DONOR:
                markerToAddOptions = CreateDonorMarker(foundCustomPin);
                break;

            case ODMSPinType.HOSPITAL:
                markerToAddOptions = CreateHospitalMarker(foundCustomPin);
                break;

            case ODMSPinType.HELICOPTER:
                markerToAddOptions = CreateHelicopterMarker(foundCustomPin);
                break;
            }
            return(markerToAddOptions);
        }
        ///// <summary>
        ///// Activated whenever focus is on this page
        ///// </summary>
        protected override async void OnAppearing()
        {
            customMap = new CustomMap
            {
                MapType       = MapType.Street,
                WidthRequest  = 100,
                HeightRequest = 100,
            };


            customMap.CustomPins     = new Dictionary <Position, CustomPin> {
            };
            customMap.HelicopterPins = new Dictionary <String, CustomPin> {
            };

            //Center on New Zealand

            var centerPosition = new Position(-41.626217, 172.361873);

            customMap.MoveToRegion(MapSpan.FromCenterAndRadius(
                                       centerPosition, Distance.FromMiles(500.0)));



            var stack = new StackLayout {
                Spacing = 0
            };

            stack.Children.Add(customMap);
            Content = stack;
            Title   = "Available Donor Map";

            //Get all the organs from the database
            //Create pins for every organ
            UserAPI userAPI = new UserAPI();
            Tuple <HttpStatusCode, List <CustomMapObject> > tuple = await userAPI.GetOrgansForMap();

            Console.WriteLine("Initialising hoppis....");
            //await InitialiseHospitals();

            Console.WriteLine("Adding HeliChopper...");
            //AddHelicopter();
            Console.WriteLine("HeliChopper success, entering switch");
            switch (tuple.Item1)
            {
            case HttpStatusCode.OK:
                Console.WriteLine("Organ Map Objects Successfully received");
                users = tuple.Item2;

                Geocoder geocoder = new Geocoder();

                foreach (CustomMapObject user in users)
                {
                    if (user.organs.Count == 0)
                    {
                        continue;
                    }


                    IEnumerable <Position> position = await geocoder.GetPositionsForAddressAsync(user.cityOfDeath + ", " + user.regionOfDeath + ", " + user.countryOfDeath);

                    Position organPosition = new Position();
                    using (var sequenceEnum = position.GetEnumerator())
                    {
                        while (sequenceEnum.MoveNext())
                        {
                            organPosition = sequenceEnum.Current;
                        }
                    }
                    Random   rnd = new Random();
                    double   randomNumberLongitude = rnd.NextDouble() / 50.00;
                    double   randomNumberLatitude  = rnd.NextDouble() / 50.00;
                    Position finalPosition         = new Position(organPosition.Latitude + randomNumberLatitude, organPosition.Longitude + randomNumberLongitude);

                    List <string> organIcons = new List <string>();

                    foreach (string organ in user.organs)
                    {
                        string organLower  = organ.ToLower();
                        string imageString = "";
                        switch (organLower)
                        {
                        case ("pancreas"):
                            imageString = "pancreas_icon.png";
                            break;

                        case ("heart"):
                            imageString = "heart_icon.png";
                            break;

                        case ("liver"):
                            imageString = "liver_icon.png";
                            break;

                        case ("connective-tissue"):
                            imageString = "tissue_icon.png";
                            break;

                        case ("bone-marrow"):
                            imageString = "bone_icon.png";
                            break;

                        case ("skin"):
                            imageString = "skin_icon.png";
                            break;

                        case ("lung"):
                            imageString = "lungs_icon.png";
                            break;

                        case ("cornea"):
                            imageString = "eye_icon.png";
                            break;

                        case ("kidney"):
                            imageString = "kidney_icon.png";
                            break;

                        case ("intestine"):
                            imageString = "intestines_icon.png";
                            break;

                        case ("middle-ear"):
                            imageString = "ear_icon.png";
                            break;

                        case ("bone"):
                            imageString = "bone_icon.png";
                            break;
                        }
                        organIcons.Add(imageString);
                    }

                    //Used so that we can get the id when we want to view the user
                    organIcons.Add(user.id.ToString());

                    //SET GENDER ICON
                    //Randomize man or woman photo
                    //If other then set to a pin
                    //If none then also set to a pin

                    string genderIcon = "";
                    switch (user.gender)
                    {
                    case ("Male"):
                        int number = rnd.Next(1, 15);
                        genderIcon = "man" + number + ".png";
                        break;

                    case ("Female"):
                        number     = rnd.Next(1, 12);
                        genderIcon = "woman" + number + ".png";
                        break;

                    case ("Other"):
                        genderIcon = "other.png";
                        break;

                    default:
                        genderIcon = "other.png";
                        break;
                    }

                    //SET PROFILE PHOTO
                    //Get profile photo from users uploaded photo (if there is one)

                    string profilePhoto = "";
                    Tuple <HttpStatusCode, string> photoResponse = await userAPI.GetUserPhotoForMapObjects(user.id);

                    if (photoResponse.Item1 != HttpStatusCode.OK)
                    {
                        Console.WriteLine("Failed to retrieve profile photo or no profile photo found.");
                        Byte[] bytes;
                        if (Device.RuntimePlatform == Device.Android)
                        {
                        }
                        else
                        {
                            bytes        = File.ReadAllBytes("donationIcon.png");
                            profilePhoto = Convert.ToBase64String(bytes);
                        }
                    }
                    else
                    {
                        profilePhoto = photoResponse.Item2;
                    }


                    var pin = new CustomPin
                    {
                        CustomType = ODMSPinType.DONOR,
                        Position   = finalPosition,
                        Label      = user.firstName + " " + user.middleName + " " + user.lastName,
                        Address    = user.cityOfDeath + ", " + user.regionOfDeath + ", " + user.countryOfDeath,
                        Url        = String.Join(",", organIcons),
                        genderIcon = genderIcon,
                        userPhoto  = profilePhoto,
                        userId     = user.id
                    };
                    customMap.CustomPins.Add(pin.Position, pin);

                    lock (customMap.Pins)
                    {
                        customMap.Pins.Add(pin);
                    }
                }

                StartTimer(200);
                Console.WriteLine("Reached the end of OnAppearing");
                break;

            case HttpStatusCode.ServiceUnavailable:
                await DisplayAlert("",
                                   "Server unavailable, check connection",
                                   "OK");

                StartTimer(200);
                break;

            case HttpStatusCode.InternalServerError:
                await DisplayAlert("",
                                   "Server error retrieving organs, please try again (500)",
                                   "OK");

                StartTimer(200);
                break;
            }
        }
示例#11
0
        /// <summary>
        /// Generates marker options for a pin that contains information about a donor
        /// </summary>
        /// <param name="pin"></param>
        /// <returns></returns>
        private MarkerOptions CreateDonorMarker(CustomPin pin)
        {
            var marker = new MarkerOptions();

            marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
            marker.SetTitle(pin.Label);
            marker.SetSnippet(pin.Address);
            Bitmap imageBitmap;

            switch (pin.genderIcon)
            {
            case "man1.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man1, bitmapOptions);
                break;

            case "man2.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man2, bitmapOptions);
                break;

            case "man3.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man3, bitmapOptions);
                break;

            case "man4.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man4, bitmapOptions);
                break;

            case "man5.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man5, bitmapOptions);
                break;

            case "man6.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man6, bitmapOptions);
                break;

            case "man7.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man7, bitmapOptions);
                break;

            case "man8.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man8, bitmapOptions);
                break;

            case "man9.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man9, bitmapOptions);
                break;

            case "man10.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man10, bitmapOptions);
                break;

            case "man11.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man11, bitmapOptions);
                break;

            case "man12.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man12, bitmapOptions);
                break;

            case "man13.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man13, bitmapOptions);
                break;

            case "man14.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.man14, bitmapOptions);
                break;

            case "woman1.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman1, bitmapOptions);
                break;

            case "woman2.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman2, bitmapOptions);
                break;

            case "woman3.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman3, bitmapOptions);
                break;

            case "woman4.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman4, bitmapOptions);
                break;

            case "woman5.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman5, bitmapOptions);
                break;

            case "woman6.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman6, bitmapOptions);
                break;

            case "woman7.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman7, bitmapOptions);
                break;

            case "woman8.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman8, bitmapOptions);
                break;

            case "woman9.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman9, bitmapOptions);
                break;

            case "woman10.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman10, bitmapOptions);
                break;

            case "woman11.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.woman11, bitmapOptions);
                break;

            case "other.png":
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.other, bitmapOptions);
                break;

            default:
                imageBitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.other, bitmapOptions);
                break;
            }
            Bitmap resizedBitmap;

            if (pin.genderIcon.Equals("other.png"))
            {
                resizedBitmap = Bitmap.CreateScaledBitmap(imageBitmap, 110, 110, false);
            }
            else
            {
                resizedBitmap = Bitmap.CreateScaledBitmap(imageBitmap, 120, 120, false);
            }
            marker.SetIcon(BitmapDescriptorFactory.FromBitmap(resizedBitmap));

            return(marker);
        }