/// <summary>
        /// Adds a pin to the current map.
        /// </summary>
        /// <param name="pin">A pin to add.</param>
        private void AddPin(MapExPin pin)
        {
            // Insert the push pin to the map
            var pushPin = new MapExPushPin(pin);

            this.Control.Children.Add(pushPin);
            pushPin.Tapped += this.OnPushPinTapped;
        }
        /// <summary>
        /// Removes a pin from the current map.
        /// </summary>
        /// <param name="pin">A pin to remove.</param>
        private void RemovePin(MapExPin pin)
        {
            // Find the annotation to remove
            if (pin.InternalId != null)
            {
                ((MKMapView)this.Control).RemoveAnnotation((IMKAnnotation)pin.InternalId);
            }

            // Remove event handler
            pin.PropertyChanged -= this.OnPinPropertyChanged;
        }
        /// <summary>
        /// Gets the detail view for annotation display.
        /// </summary>
        /// <param name="customPin">The custom pin to create annotation for.</param>
        /// <returns>The annotation detail view to display.</returns>
        // ReSharper disable once MemberCanBeMadeStatic.Local
        private UIView DetailViewForAnnotation(MapExPin customPin)
        {
            // Create a new view for annotation details
            // ReSharper disable once UseObjectOrCollectionInitializer
            var view = new UIView();

            view.BackgroundColor = UIColor.White;
            view.TranslatesAutoresizingMaskIntoConstraints = false;

            // Create the locate vehicle button
            // ReSharper disable once UseObjectOrCollectionInitializer
            var labelSchedule = new UILabel();

            labelSchedule.Text = customPin.Address;
            labelSchedule.TranslatesAutoresizingMaskIntoConstraints = false;
            view.AddSubview(labelSchedule);

            // Create the locate vehicle button
            var buttonLocate = new UIButton(UIButtonType.Custom);

            buttonLocate.SetTitle("Ubicar camion", UIControlState.Normal);
            buttonLocate.SetTitleColor(UIColor.Blue, UIControlState.Normal);
            buttonLocate.TranslatesAutoresizingMaskIntoConstraints = false;
            buttonLocate.TouchUpInside += (s, e) => customPin.LocateVehicleCommand.Execute(null);
            view.AddSubview(buttonLocate);

            // Create the report button
            var buttonReport = new UIButton(UIButtonType.Custom);

            buttonReport.SetTitle("Reportar", UIControlState.Normal);
            buttonReport.SetTitleColor(UIColor.Blue, UIControlState.Normal);
            buttonReport.TranslatesAutoresizingMaskIntoConstraints = false;
            buttonReport.TouchUpInside += (s, e) => customPin.ReportIncidentCommand.Execute(null);
            view.AddSubview(buttonReport);

            // Create sub view dictionary
            NSDictionary views = NSDictionary.FromObjectsAndKeys(
                new NSObject[] { labelSchedule, buttonLocate, buttonReport },
                new NSObject[] { new NSString("labelSchedule"), new NSString("buttonLocate"), new NSString("buttonReport") });

            // Add view constraints
            view.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|[labelSchedule]|", 0, null, views));
            view.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|[buttonLocate]|", 0, null, views));
            view.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|[buttonReport]|", 0, null, views));
            view.AddConstraints(
                NSLayoutConstraint.FromVisualFormat("V:|[labelSchedule]-[buttonLocate]-[buttonReport]|", 0, null, views));

            // Return the created view
            return(view);
        }
        /// <summary>
        /// Adds a pin to the current map.
        /// </summary>
        /// <param name="pin">A pin to add.</param>
        private void AddPin(MapExPin pin)
        {
            // Prepare a new annotation for the map
            // ReSharper disable once UseObjectOrCollectionInitializer
            var annotation = new MKPointAnnotation();

            annotation.Title    = string.IsNullOrEmpty(pin.Label) ? "NO DATA" : pin.Label;
            annotation.Subtitle = string.IsNullOrEmpty(pin.Address) ? string.Empty : pin.Address;
            annotation.SetCoordinate(new CLLocationCoordinate2D(pin.Position.Latitude, pin.Position.Longitude));
            pin.InternalId = annotation;

            // Add the annotation to the map
            ((MKMapView)this.Control).AddAnnotation(annotation);

            // Add event handlers
            pin.PropertyChanged += this.OnPinPropertyChanged;
        }
        /// <summary>
        /// Removes a pin from the current map.
        /// </summary>
        /// <param name="pin">A pin to remove.</param>
        private void RemovePin(MapExPin pin)
        {
            // If map is not present
            if (this.map == null)
            {
                return;
            }

            // Find the marker to remove
            var marker = this.markers?.FirstOrDefault(m => m.Id.Equals((string)pin.InternalId));

            if (marker != null)
            {
                // Remove the pin form the map
                marker.Remove();
                this.markers.Remove(marker);
            }

            // Remove event handler
            pin.PropertyChanged -= this.OnPinPropertyChanged;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MapExAnnotation"/> class.
        /// </summary>
        /// <param name="pin">The map pin to show annotation for.</param>
        internal MapExAnnotation(MapExPin pin)
        {
            if (pin == null)
            {
                throw new ArgumentNullException();
            }

            // Load the content template
            this.Pin             = pin;
            this.ContentTemplate = this.GetDataTemplate();

            // Set the data context
            this.Content     = pin;
            this.DataContext = pin;

            // Update the pin location
            this.UpdateLocation();

            // Subscribe to events
            this.Loaded   += this.OnLoaded;
            this.Unloaded += this.OnUnloaded;
        }
        /// <summary>
        /// Removes a pin from the current map.
        /// </summary>
        /// <param name="pin">A pin to remove.</param>
        private void RemovePin(MapExPin pin)
        {
            var pushPin = this.Control.Children.FirstOrDefault(
                c =>
            {
                var pPin = c as MapExPushPin;
                return((pPin != null) && pPin.Pin.Equals(pin));
            });

            if (pushPin != null)
            {
                ((MapExPushPin)pushPin).Tapped -= this.OnPushPinTapped;
                this.Control.Children.Remove(pushPin);
            }

            // If the annotation is for the removed pin
            if ((this.annotation != null) && this.annotation.Pin.Equals(pin))
            {
                this.Control.Children.Remove(this.annotation);
                this.annotation = null;
            }
        }
        /// <summary>
        /// Adds a pin to the current map.
        /// </summary>
        /// <param name="pin">A pin to add.</param>
        private void AddPin(MapExPin pin)
        {
            // If map is not present
            if (this.map == null)
            {
                return;
            }

            // Create a new marker collection
            if (this.markers == null)
            {
                this.markers = new List <Marker>();
            }

            // Setup market options
            var markerOptions = new MarkerOptions();

            markerOptions.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
            markerOptions.Anchor(0.5f, 0.5f);
            markerOptions.SetTitle(pin.Label);
            markerOptions.SetSnippet(pin.Address);
            markerOptions.InfoWindowAnchor(0.5f, 0.5f);

            // Setup marker icon
            var icon = MapExRenderer.GetResourceId(pin.Type);

            markerOptions.SetIcon(BitmapDescriptorFactory.FromResource(icon));

            // Add marker to the map
            var marker = this.map.AddMarker(markerOptions);

            this.markers.Add(marker);
            pin.InternalId = marker.Id;

            // Add event handlers
            pin.PropertyChanged += this.OnPinPropertyChanged;
        }