Exemplo n.º 1
0
 public void Duplicate(ref Point3[] Points, int i)
 {
     Circular node = this;
     do
     {
         Points[i++] = node.Point;
         node = node.Next;
     } while (node != this);
 }
Exemplo n.º 2
0
 public Circular(Point3 point)
 {
     Point = point;
     Next = this;
     Last = this;
 }
Exemplo n.º 3
0
 public bool Equals(Point3 point)
 {
     if (x == point.x && y == point.y)
         return true;
     else
         return false;
 }
Exemplo n.º 4
0
 public bool Smaller(Point3 point)
 {
     if ((x < point.x) || (x == point.x && y < point.y))
         return true;
     else
         return false;
 }
Exemplo n.º 5
0
 public static double check(Point3 point1, Point3 point2, Point3 point3)
 {
     return point1.x * (point2.y - point3.y) + point2.x * (point3.y - point1.y) + point3.x * (point1.y - point2.y);
 }
Exemplo n.º 6
0
        private static void sort(ref Point3[] Points, int start, int end)
        {
            if (start < end)
            {
                int i = start;
                int j = end;
                Point3 x = Points[(i + j) / 2];

                do
                {
                    while (Points[i].Smaller(x))
                        i++;

                    while (x.Smaller(Points[j]))
                        j--;

                    if (i <= j)
                    {
                        Point3 temp = Points[i];
                        Points[i] = Points[j];
                        Points[j] = temp;

                        i++; j--;
                    }
                } while (i <= j);

                sort(ref Points, start, j);
                sort(ref Points, i, end);
            }
        }
Exemplo n.º 7
0
        private static void increase1pc(ref Point3[] points)
        {
            Point3 cent = new Point3(0, 0);
            for (int i = 0; i < points.Length; i++)
            {
                cent.x += points[i].x;
                cent.y += points[i].y;
            }

            cent.x = cent.x / points.Length;
            cent.y = cent.y / points.Length;

            for (int i = 0; i < points.Length; i++)
            {
                points[i].x += (points[i].x - cent.x) * .01;
                points[i].y += (points[i].y - cent.y) * .01;
            }
        }
Exemplo n.º 8
0
        public static Point3[] getConvexPolygon(Point3[] points)
        {
            int num = points.Length;
            sort(ref points,0,points.Length-1);

            Point3 left = points[0];
            Point3 right = points[num - 1];

               Circular lower = new Circular(left);
            Circular upper = new Circular(left);

            for (int i = 0; i < num; i++)
            {
                double result = Point3.check(left, right, points[i]);
                if (result > 0)
                    upper = upper.Append(new Circular(points[i]));
                else if (result < 0)
                    lower = lower.Prepend(new Circular(points[i]));
            }
            lower = lower.Prepend(new Circular(right));
            upper = upper.Append(new Circular(right)).Next;

            minimize(lower);
            minimize(upper);

            if (lower.Last.Point.Equals(upper.Point))
                lower.Last.Remove();

            if (upper.Last.Point.Equals(lower.Point))
                upper.Last.Remove();

            Point3[] final = new Point3[lower.Length() + upper.Length() + 1];

            lower.Duplicate(ref final, 0);
            upper.Duplicate(ref final, lower.Length());
            final[lower.Length() + upper.Length()] = final[0];
            increase1pc(ref final);

            return final;
        }
        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);
            }
        }