public void Execute(params object[] args)
        {
            string statusMessage = "Clustering orders.";

            App.Current.Messenger.AddInfo(statusMessage);

            /////////////////////////////////
            // Find Current Schedule, Routes and Orders
            /////////////////////////////////
            ESRI.ArcLogistics.DomainObjects.Schedule schedule = new ESRI.ArcLogistics.DomainObjects.Schedule();

            int numSchedules = App.Current.Project.Schedules.Count;

            foreach (ESRI.ArcLogistics.DomainObjects.Schedule s in App.Current.Project.Schedules.Search(App.Current.CurrentDate))
            {
                if (s.Name == "Current")
                {
                    schedule = s;
                    break;
                }
            }

            //Get number of Routes on current Schedule
            int numRoutes = schedule.Routes.Count;

            //Get number of Orders for current Date
            int numOrders = App.Current.Project.Orders.GetCount(App.Current.CurrentDate);

            if (numRoutes > 0 && numOrders > numRoutes)
            {
                /////////////////////////////////
                // Create Dataset
                /////////////////////////////////
                Point2[] data    = new Point2[numOrders];
                Point2[] centres = new Point2[numRoutes];

                List <ESRI.ArcLogistics.DomainObjects.Order> oList = App.Current.Project.Orders.Search(App.Current.CurrentDate).ToList();
                for (int i = 0; i < numOrders; i++)
                {
                    ESRI.ArcLogistics.DomainObjects.Order o = oList.ElementAt(i);
                    Point2 p2 = new Point2(0, o.GeoLocation.Value.X, o.GeoLocation.Value.Y);
                    data[i] = p2;
                }

                /////////////////////////////////
                // Perform Clustering
                /////////////////////////////////

                int iterations = cluster(ref data, ref centres);

                /////////////////////////////////
                // Delete all previous zones from the project
                /////////////////////////////////

                for (int c = App.Current.Project.Zones.Count - 1; c >= 0; c--)
                {
                    ESRI.ArcLogistics.DomainObjects.Zone z = App.Current.Project.Zones.ElementAt(c);
                    App.Current.Project.Zones.Remove(z);
                }

                /////////////////////////////////
                // Delete all previous zones from the current day's routes
                /////////////////////////////////

                for (int j = 0; j < numRoutes; j++)
                {
                    for (int c = schedule.Routes[j].Zones.Count - 1; c >= 0; c--)
                    {
                        ESRI.ArcLogistics.DomainObjects.Zone z = schedule.Routes[j].Zones.ElementAt(c);
                        schedule.Routes[j].Zones.Remove(z);
                    }
                }


                /////////////////////////////////
                // Find Convex Hull, create Soft Zones and assign them to routes
                /////////////////////////////////

                List <Point3>[] DataList = new List <Point3> [numRoutes];
                for (int j = 0; j < numRoutes; j++)
                {
                    DataList[j] = new List <Point3>();
                }

                for (int i = 0; i < numOrders; i++)
                {
                    Point3 p3 = new Point3(data[i].X, data[i].Y);
                    DataList[data[i].cluster].Add(p3);
                }

                for (int j = 0; j < numRoutes; j++)
                {
                    // Dont create zones for less than 3 orders
                    if (DataList[j].Count <= 2)
                    {
                        continue;
                    }

                    // Get Convex Hull
                    Point3[] chpts = ConvexPolygon.getConvexPolygon(DataList[j].ToArray());


                    // Convert Point3 array to Geometry Point array
                    ESRI.ArcLogistics.Geometry.Point[] polyPoints = new ESRI.ArcLogistics.Geometry.Point[chpts.Length];
                    for (int k = 0; k < chpts.Length; k++)
                    {
                        Point3 p3 = chpts[k];

                        ESRI.ArcLogistics.Geometry.Point geoP = new ESRI.ArcLogistics.Geometry.Point();
                        geoP.X = p3.x;
                        geoP.Y = p3.y;

                        polyPoints[k] = geoP;
                    }


                    // Create soft zone, and add to Project and to a Route
                    ESRI.ArcLogistics.Geometry.Polygon   p = new ESRI.ArcLogistics.Geometry.Polygon(polyPoints);
                    ESRI.ArcLogistics.DomainObjects.Zone z = new ESRI.ArcLogistics.DomainObjects.Zone();
                    z.CreationTime = DateTime.Now.Ticks;
                    z.Geometry     = p;
                    z.Name         = String.Format("Zone {0}", j + 1);

                    App.Current.Project.Zones.Add(z);
                    schedule.Routes[j].Zones.Add(z);
                    schedule.Routes[j].HardZones = false;
                }
                App.Current.Project.Save();
                statusMessage = "Finished clustering orders.";
                App.Current.Messenger.AddInfo(statusMessage);
            }
            else
            {
                statusMessage = "";

                if (numOrders == 0)
                {
                    statusMessage = "No Orders found.";
                }
                else if (numRoutes == 0)
                {
                    statusMessage = "No Routes found.";
                }
                else if (numRoutes > numOrders)
                {
                    statusMessage = "Insufficient number of orders.";
                }

                App.Current.Messenger.AddError(statusMessage);
            }
        }
        public void Execute(params object[] args)
        {
            string statusMessage = "Clustering orders.";
            App.Current.Messenger.AddInfo(statusMessage);

            /////////////////////////////////
            // Find Current Schedule, Routes and Orders
            /////////////////////////////////
            ESRI.ArcLogistics.DomainObjects.Schedule schedule = new ESRI.ArcLogistics.DomainObjects.Schedule();

            int numSchedules = App.Current.Project.Schedules.Count;

            foreach (ESRI.ArcLogistics.DomainObjects.Schedule s in App.Current.Project.Schedules.Search(App.Current.CurrentDate))
            {
                if (s.Name == "Current")
                {
                    schedule = s;
                    break;
                }
            }

            //Get number of Routes on current Schedule
            int numRoutes = schedule.Routes.Count;

            //Get number of Orders for current Date
            int numOrders = App.Current.Project.Orders.GetCount(App.Current.CurrentDate);

            if (numRoutes > 0 && numOrders > numRoutes)
            {
                /////////////////////////////////
                // Create Dataset
                /////////////////////////////////
                Point2[] data = new Point2[numOrders];
                Point2[] centres = new Point2[numRoutes];

                List<ESRI.ArcLogistics.DomainObjects.Order> oList = App.Current.Project.Orders.Search(App.Current.CurrentDate).ToList();
                for (int i = 0; i < numOrders; i++)
                {
                    ESRI.ArcLogistics.DomainObjects.Order o = oList.ElementAt(i);
                    Point2 p2 = new Point2(0, o.GeoLocation.Value.X, o.GeoLocation.Value.Y);
                    data[i] = p2;
                }

                /////////////////////////////////
                // Perform Clustering
                /////////////////////////////////

                int iterations = cluster(ref data, ref centres);

                /////////////////////////////////
                // Delete all previous zones from the project
                /////////////////////////////////

                for (int c = App.Current.Project.Zones.Count - 1; c >= 0; c--)
                {
                    ESRI.ArcLogistics.DomainObjects.Zone z = App.Current.Project.Zones.ElementAt(c);
                    App.Current.Project.Zones.Remove(z);
                }

                /////////////////////////////////
                // Delete all previous zones from the current day's routes
                /////////////////////////////////

                for (int j = 0; j < numRoutes; j++)
                {
                    for (int c = schedule.Routes[j].Zones.Count - 1; c >= 0; c--)
                    {
                        ESRI.ArcLogistics.DomainObjects.Zone z = schedule.Routes[j].Zones.ElementAt(c);
                        schedule.Routes[j].Zones.Remove(z);
                    }
                }

                /////////////////////////////////
                // Find Convex Hull, create Soft Zones and assign them to routes
                /////////////////////////////////

                List<Point3>[] DataList = new List<Point3>[numRoutes];
                for (int j = 0; j < numRoutes; j++)
                    DataList[j] = new List<Point3>();

                for (int i = 0; i < numOrders; i++)
                {
                    Point3 p3 = new Point3(data[i].X, data[i].Y);
                    DataList[data[i].cluster].Add(p3);
                }

                for (int j = 0; j < numRoutes; j++)
                {
                    // Dont create zones for less than 3 orders
                    if (DataList[j].Count <= 2)
                        continue;

                    // Get Convex Hull
                    Point3[] chpts = ConvexPolygon.getConvexPolygon(DataList[j].ToArray());

                    // Convert Point3 array to Geometry Point array
                    ESRI.ArcLogistics.Geometry.Point[] polyPoints = new ESRI.ArcLogistics.Geometry.Point[chpts.Length];
                    for (int k = 0; k < chpts.Length; k++)
                    {
                        Point3 p3 = chpts[k];

                        ESRI.ArcLogistics.Geometry.Point geoP = new ESRI.ArcLogistics.Geometry.Point();
                        geoP.X = p3.x;
                        geoP.Y = p3.y;

                        polyPoints[k] = geoP;
                    }

                    // Create soft zone, and add to Project and to a Route
                    ESRI.ArcLogistics.Geometry.Polygon p = new ESRI.ArcLogistics.Geometry.Polygon(polyPoints);
                    ESRI.ArcLogistics.DomainObjects.Zone z = new ESRI.ArcLogistics.DomainObjects.Zone();
                    z.CreationTime = DateTime.Now.Ticks;
                    z.Geometry = p;
                    z.Name = String.Format("Zone {0}", j+1);

                    App.Current.Project.Zones.Add(z);
                    schedule.Routes[j].Zones.Add(z);
                    schedule.Routes[j].HardZones = false;

                }
                App.Current.Project.Save();
                statusMessage = "Finished clustering orders.";
                App.Current.Messenger.AddInfo(statusMessage);
            }
            else
            {
                statusMessage="";

                if(numOrders==0)
                    statusMessage = "No Orders found.";
                else if(numRoutes==0)
                    statusMessage = "No Routes found.";
                else if (numRoutes > numOrders)
                    statusMessage = "Insufficient number of orders.";

                App.Current.Messenger.AddError(statusMessage);
            }
        }