Mini Kabibi Habibi

Current Path : C:/Users/Public/Documents/DXperience 13.1 Demos/WPF/CS/MapDemo.Wpf/InfromationLayer/
Upload File :
Current File : C:/Users/Public/Documents/DXperience 13.1 Demos/WPF/CS/MapDemo.Wpf/InfromationLayer/RouteModel.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Media.Effects;
using DevExpress.Xpf.Map;
using System.Windows.Data;
using System;
using System.Globalization;
using System.Windows;

namespace MapDemo {
    public enum RouteModelState {
        Normal,
        Drive
    }

    public class NavigatorDataModel : FrameworkElement, INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(string propertyName) {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        protected void NotifyPropertyChanged(object sender, PropertyChangedEventArgs e) {
            if (PropertyChanged != null)
                PropertyChanged(sender, e);
        }
    }

    public class RouteModel : NavigatorDataModel {
        public static readonly DependencyProperty MapCenterProperty = DependencyProperty.Register("MapCenter",
            typeof(GeoPoint), typeof(RouteModel), new PropertyMetadata(new GeoPoint(34.158506,-118.255629)));
        public static readonly DependencyProperty TimeScaleProperty = DependencyProperty.Register("TimeScale",
            typeof(double), typeof(RouteModel), new PropertyMetadata(1.0));

        Navigator navigator;
        ObservableCollection<MapItem> helpers;
        bool isCalculating;
        RouteModelState state;
        DriveModel driveModel;
        List<RouteWaypoint> waypoints;
        List<MapPushpin> routePushpins;
        List<GeoPoint> routePath;
        List<BingItineraryItem> itineraryItems;
        int waypointIndex;
        int searchPushpinsCount;
        double drivePathDistance;

        public ObservableCollection<MapItem> Helpers {
            get { return this.helpers; }
        }
        public bool IsCalculating {
            get { return this.isCalculating; }
            set {
                if (this.isCalculating != value) {
                    this.isCalculating = value;
                    NotifyPropertyChanged("IsCalculating");
                }
            }
        }
        public RouteModelState State {
            get { return this.state; }
            set {
                if (this.state != value) {
                    this.state = value;
                    OnStateChanged();
                    NotifyPropertyChanged("State");
                }
            }
        }
        public DriveModel DriveModel {
            get { return driveModel; }
            set {
                if (this.driveModel != value) {
                    this.driveModel = value;
                    NotifyPropertyChanged("DriveModel");
                }
            }
        }
        public Navigator Navigator {
            get { return this.navigator; }
            set {
                if (this.navigator != value) {
                    this.navigator = value;
                    NotifyPropertyChanged("Controller");
                }
            }
        }
        public List<GeoPoint> RoutePath {
            get { return routePath; }
        }
        public double DrivePathDistance {
            get { return this.drivePathDistance; }
            set { this.drivePathDistance = value; }
        }
        public List<BingItineraryItem> ItineraryItems {
            get { return this.itineraryItems; }
            set { this.itineraryItems = value; }
        }
        public List<MapPushpin> RoutePushpins {
            get { return this.routePushpins; }
            set { this.routePushpins = value; }
        }
        public string ActionText {
            get {
                if ((state == RouteModelState.Drive) && (driveModel != null)) {
                    return driveModel.ActionText;
                }
                else {
                    if (waypoints.Count == 0) {
                        if (searchPushpinsCount > 0)
                            return "Click the  pushpin to set a start point.";
                        else
                            return "Click the map or use Search to find a location.";
                    }
                    else if (waypoints.Count == 1) {
                        return "Set a finish point to calculate a route.";
                    }
                    else {
                        return "Set another finish point or click Drive.";
                    }
                }
            }
        }
        public GeoPoint MapCenter {
            get { return (GeoPoint)GetValue(MapCenterProperty); }
            set { SetValue(MapCenterProperty, value); }
        }
        public double TimeScale {
            get { return (double)GetValue(TimeScaleProperty); }
            set { SetValue(TimeScaleProperty, value); }
        }
        public List<RouteWaypoint> Waypoints {
            get { return this.waypoints; }
        }

        public RouteModel(Navigator navigator) {
            this.navigator = navigator;
            this.helpers = new ObservableCollection<MapItem>();
            this.waypoints = new List<RouteWaypoint>();
            this.routePushpins = new List<MapPushpin>();
            this.itineraryItems = new List<BingItineraryItem>();
        }

        void SendRouteRequest() {
            IsCalculating = true;
            if (waypoints.Count > 1)
                Navigator.RouteProvider.CalculateRoute(waypoints);
        }
        string NextWaypointLetter() {
            string letter = "" + (char)((byte)'A' + waypointIndex % 26);
            waypointIndex++;
            return letter;
        }
        void ExtractItineraryItems(BingRouteResult result) {
            itineraryItems.Clear();
            foreach (BingRouteLeg leg in result.Legs)
                foreach (BingItineraryItem item in leg.Itinerary)
                    itineraryItems.Add(item);
        }
        void BeginDrive() {
            if ((routePath != null) && (routePath.Count > 1)) {
                StopDrive();
                DriveModel = new DriveModel(this);
                Binding mapCenterBinding = new Binding("MapCenterBinding")
                {
                    Path = new PropertyPath("CurrentLocation"),
                    Source = DriveModel
                };
                SetBinding(MapCenterProperty, mapCenterBinding);
            }
        }
        void StopDrive() {
            if (DriveModel != null) {
                DriveModel.Cleanup();
                DriveModel = null;
                MapCenter = (GeoPoint)MapCenter;
            }
        }
        void OnStateChanged() {
            switch (State) {
                case RouteModelState.Drive:
                    BeginDrive();
                    break;
                case RouteModelState.Normal:
                    StopDrive();
                    break;
            }
            NotifyPropertyChanged("ActionText");
        }
        void CalculatePathDistance() {
            drivePathDistance = 0;
            if (routePath != null) {
                MapUnit? lastPoint = null;
                foreach (GeoPoint node in routePath) {
                    if (lastPoint != null) {
                        MapUnit currentPoint = Navigator.RouteLayer.GeoPointToMapUnit(node);
                        drivePathDistance += DriveModel.DistanceBetweenPoints(currentPoint, lastPoint.Value);
                        lastPoint = currentPoint;
                    }
                    else
                        lastPoint = Navigator.RouteLayer.GeoPointToMapUnit(node);
                }
            }
        }

        internal void NotifyDriveModelChanged() {
            NotifyPropertyChanged("ActionText");
        }

        internal void NotifySearchPushpinsChanged(int count) {
            searchPushpinsCount = count;
            NotifyPropertyChanged("ActionText");
        }

        public void AddWaypoint(string description, GeoPoint location) {
            RouteWaypoint waypoint = new RouteWaypoint(description, location);
            if (!waypoints.Contains(waypoint)) {
                MapPushpin pushpin = new MapPushpin();
                pushpin.Location = location;
                pushpin.Information = description;
                pushpin.Text = NextWaypointLetter();
                pushpin.TraceDepth = 0;
                pushpin.State = MapPushpinState.Busy;
                Helpers.Add(pushpin);
                waypoints.Add(waypoint);
                SendRouteRequest();
            }
            NotifyPropertyChanged("ActionText");
            NotifyPropertyChanged("Waypoints");
        }
        public void ProcessRouteItems(MapItem[] items) {
            waypointIndex = 0;
            routePushpins.Clear();
            foreach (MapItem item in items) {
                MapPushpin pushpin = item as MapPushpin;
                if (pushpin != null) {
                    pushpin.Text = NextWaypointLetter();
                    routePushpins.Add(pushpin);
                }
                MapPolyline polyline = item as MapPolyline;
                if (polyline != null)
                    polyline.Effect = new DropShadowEffect() { Direction = -90, ShadowDepth = 1 };
            }
            Helpers.Clear();
        }
        public void ProcessRouteResult(BingRouteResult result) {
            if (result != null) {
                ExtractItineraryItems(result);
                routePath = result.RoutePath;
            }
            else
                routePath = null;
            CalculatePathDistance();
        }
        public void Clear() {
            if (RoutePath != null)
                RoutePath.Clear();
            Helpers.Clear();
            RoutePushpins.Clear();
            ItineraryItems.Clear();
            DrivePathDistance = 0.0;
            waypoints.Clear();
            waypointIndex = 0;
            NotifySearchPushpinsChanged(0);
            NotifyPropertyChanged("Waypoints");
        }
    }

    public class RouteModelStateToButtonTextConverter : IValueConverter {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            if ((value != null) && (value.GetType() == typeof(RouteModelState))) {
                RouteModelState state = (RouteModelState)value;
                switch (state) {
                    case RouteModelState.Drive:
                        return "Stop";
                    case RouteModelState.Normal:
                        return "Drive";
                }
            }
            return string.Empty;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class RouteModelNormalStateToBoolConverter : IValueConverter {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            if ((value != null) && (value.GetType() == typeof(RouteModelState)))
                return ((RouteModelState)value) == RouteModelState.Normal;
            return false;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class WaypointsCountToDriveAbilityConverter : IValueConverter {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            if ((value != null) && (value.GetType() == typeof(int)))
                return ((int)value) > 1;
            return false;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            throw new NotImplementedException();
        }

        #endregion
    }
}