private static PolygonList GetSingleResultPolygonList(Polygon resultPolygon) { PolygonList result = new PolygonList(); result.Add(resultPolygon); return(result); }
public ActionResult ChangeType(int target, int type) { var dlo = DB.DeliveryListOrders.FirstOrDefault(x => x.ID == target); if (dlo != null) { dlo.Type = null; dlo.CarID = null; dlo.WorkerID = null; dlo.Order.OrderDelivery.DeliveryType = type; DB.SubmitChanges(); if (dlo.Order.ShopID.HasValue) { var poly = new PolygonList(dlo.Order.ShopID.Value); if (type == (int)SectorTypes.CarSector) { var cars = poly.GetDefaultCars(dlo.Order); if (cars.Any()) { dlo.CarID = cars.First().ID; } } if (type == (int)SectorTypes.CourierSector) { var cars = poly.GetDefaultCouriers(dlo.Order); if (cars.Any()) { dlo.CarID = cars.First().ID; } } DB.SubmitChanges(); } } return(new ContentResult()); }
public void OffsetPolygonByHalfTest() { Polygon input = Polygon.AsRectangle(new Vector(10, 10)); Polygon expectedOutput = Polygon.AsRectangle(new Vector(5, 5), new Vector(2.5, 2.5)); PolygonList output = ClipperUtility.OffsetPolygon(input, -2.5f); Assert.AreEqual(1, output.Count); Polygon actualOutput = output[0]; Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(expectedOutput, actualOutput)); }
public void SimpleOverlapTest() { Polygon a = Polygon.AsRectangle(new Vector(2, 2)); Polygon b = Polygon.AsRectangle(new Vector(2, 2), new Vector(1, 1)); Polygon expectedPolygon = Polygon.AsRectangle(new Vector(1, 1), new Vector(1, 1)); PolygonList resultIntersection = ClipperUtility.Intersection(a, b); Assert.AreEqual(1, resultIntersection.Count); Polygon resultPolygon = resultIntersection[0]; Assert.IsTrue(ClipperUtility.HaveIntersection(a, b)); Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(expectedPolygon, resultPolygon)); }
public void LineIntersectionTest() { Polygon line = Polygon.AsLine(Vector.Zero, Vector.One); Polygon rectangle = Polygon.AsRectangle(Vector.One); PolygonList output = ClipperUtility.Intersection(line, rectangle); Assert.AreEqual(1, output.Count); Polygon actualOutput = output[0]; Assert.IsTrue(ClipperUtility.EqualWithinEpsilon(line, actualOutput, epsilon: 15 * Vector.Scale * 15 * Vector.Scale)); }
void ISerializableObject.Write(EndianBinaryWriter writer, object context) { writer.ScheduleWriteOffsetAligned(4, () => { VertexList.ForEach(x => x?.Write(writer)); sEndChunk32.Write(writer); }); writer.ScheduleWriteOffsetAligned(4, () => { PolygonList.ForEach(x => { x.Write(writer); writer.WriteAlignmentPadding(4); }); sEndChunk16.Write(writer); }); writer.Write(BoundingSphere); }
public Dictionary <int, Polygon> GetAreasForPositions(Dictionary <int, Vector> idToPosition) { Dictionary <Vector, MIVector> vectorToMiVectorMapping = new Dictionary <Vector, MIVector>(); idToPosition.ForEachValue(vector => vectorToMiVectorMapping[vector] = new MIVector(vector.X, vector.Z)); // add fake generators vectorToMiVectorMapping.Add(new Vector(0, 10), new MIVector(0, 10)); vectorToMiVectorMapping.Add(new Vector(10, 0), new MIVector(10, 0)); vectorToMiVectorMapping.Add(new Vector(0, -10), new MIVector(0, -10)); vectorToMiVectorMapping.Add(new Vector(-10, 0), new MIVector(-10, 0)); Dictionary <MIVector, VoronoiCell> positionsToVoronoi = GetAreasForPositions(vectorToMiVectorMapping.Values.ToList()); Dictionary <int, Polygon> idsToVoronoi = new Dictionary <int, Polygon>(); foreach (KeyValuePair <int, Vector> pair in idToPosition) { if (!positionsToVoronoi.ContainsKey(vectorToMiVectorMapping[pair.Value])) { continue; } PolygonList intersection = ClipperUtility.Intersection( _wrapperPolygon, new PolygonList(positionsToVoronoi[vectorToMiVectorMapping[pair.Value]] .CellVertices .Select((p) => { List <Vector> list = p.Select(mi => new Vector(mi.X, mi.Z)).ToList(); Polygon poly = new Polygon(list); poly.MakeContour(); return(poly); }) .ToList()) ); if (intersection.Count > 0) { idsToVoronoi[pair.Key] = intersection.First(); } } return(idsToVoronoi); }
public static void Run() { Logger.SetLevel(Logger.Level.Debug); string[] allInfoLines = File.ReadAllLines(Config.CsvStudyInfoFilePath); var infoSelections = (from line in allInfoLines.Skip(1) let data = line.Split(';') select new { PartId = data[0], StartOffset = Helper.ConvertToLong(data[2]), StudyType = data[1] }).Distinct(); string[] allLines = File.ReadAllLines(Config.CsvFilePath); // select var selections = (from line in allLines.Skip(1) let data = line.Split(';') select new { PartId = data[1], Game = data[5], StudyType = data[2] }).Distinct(); // for each selection if (selections.Count() != 32) { Logger.Warn("Expecting 32 different conditions for participants"); } foreach (var selection in selections) { var query = from line in allLines.Skip(1) let data = line.Split(';') where data[5] == selection.Game && data[1] == selection.PartId && data[2] == selection.StudyType && infoSelections .First(infoSelection => infoSelection.PartId == selection.PartId && infoSelection.StudyType == selection.StudyType).StartOffset < Helper.ConvertToLong(data[9]) select new { PartId = Helper.ConvertToInteger(data[1]), Timestamp = Helper.ConvertToLong(data[9]), Game = data[5], StudyType = data[2], Rotation = Helper.ConvertToDouble(data[8]), PositionX = Helper.ConvertToDouble(data[11]), PositionY = Helper.ConvertToDouble(data[12]) }; //var minOffsetTime = // infoSelections.First(select => select.PartId == selection.PartId && select.StudyType == selection.StudyType).StartOffset; // BASIC STEPS FOR FIRST 100 ENTRIES //i = 0; //foreach (var row in query) //{ // Logger.Debug($"Part = {row.PartId}, Study type = {row.StudyType}, Game = {row.Game}, Rotation = {row.Rotation}, Position = {row.PositionX}, {row.PositionY}"); // i++; // if (i > 100) break; //} // USED AREA var radius = .3f; var circleSubsteps = 32; var usedPlayArea = new PolygonList(); foreach (var row in query) { //if (row.Timestamp < minOffsetTime) continue; var position = new Vector(row.PositionX, row.PositionY); position.RotateCounter(-row.Rotation / 180 * Math.PI); var positionPolygon = Polygon.AsCircle(radius, position, circleSubsteps); usedPlayArea = ClipperUtility.Union(usedPlayArea, positionPolygon); } var usedArea = ClipperUtility.GetArea(usedPlayArea); Logger.Debug($"{selection.PartId};{selection.Game};{selection.StudyType};{usedArea}"); // DURATION, MIN/MAX TIME //var min = double.MaxValue; //var max = double.MinValue; //foreach (var row in query) //{ // if (row.Timestamp < minOffsetTime) continue; // if (row.Timestamp < min) min = row.Timestamp; // if (max < row.Timestamp) max = row.Timestamp; //} //Logger.Debug($"{selection.PartId};{selection.StudyType};{min};{max};0;{max-min}"); } //i = 0; //foreach (var row in query) //{ // Logger.Debug($"Part = {row.PartId}, Study type = {row.StudyType}, Game = {row.Game}, Rotation = {row.Rotation}, Position = {row.PositionX}, {row.PositionY}"); // i++; // if (i > 100) break; //} Console.ReadKey(); }
public Map Generate(Vector2 dimensions, int generations, PolygonList.FaceType faceType, EnvironmentConstructionScript.FunctionType functionType, float height, AnimationCurve heightMap, int regionCount, int relaxationCount, float radius) { data = new Map(); data.generations = generations; this.height = height; this.heigtMap = heightMap; islandShape = new EnvironmentConstructionScript(generations, dimensions.x, dimensions.y, functionType); rectangle = new Rectangle(0, 0, dimensions.x, dimensions.y); if (faceType == PolygonList.FaceType.Hexagon || faceType == PolygonList.FaceType.Square) { relaxationCount = 0; // relaxation is used to create accurate polygon size } // no specific value for rectangle - able to resize in the editor Polygon polygon = PolygonList.Create(dimensions, generations, faceType, regionCount, radius); VoronoiBase voronoi = GenerateVoronoi(ref polygon, relaxationCount); Build(polygon, voronoi); ImproveBorders(); // Determine the elevations and water at Voronoi corners. Elevation.AssignCorner(ref data, islandShape, faceType == PolygonList.FaceType.Hexagon || faceType == PolygonList.FaceType.Square); // Determine polygon and corner type: ocean, coast, land. CheckingScript.AssignSeaSealandAndLand(ref data); // Rescale elevations so that the highest is 1.0, and they're // distributed well. Lower elevations will be more common // than higher elevations. List <Characteristics.Corner> corners = LandCorners(data.corners); Elevation.Readjust(ref corners); // elevations assigned to water corners foreach (var q in data.corners) { if (q.sea || q.sealine) { q.built = 0.0f; } } // Polygon elevations are the average of their corners Elevation.AllocatePolygon(ref data); // Determine humidity at corners, starting at rivers // and lakes, but not oceans. Then redistribute // humidity to cover the entire range evenly from 0.0 // to 1.0. Then assign polygon humidity as the average // of the corner humidity. Humidity.AccountEdge(ref data); Humidity.Redistribute(ref corners); Humidity.AssignPolygon(ref data); CheckingScript.AssignHabitat(ref data); return(data); }
/// <summary> /// Setup constructor /// </summary> public PolygonLists( PolygonList[] lists, Point2[] points ) { m_Lists = lists; m_Points = points; }
public static Vector[] WeilerAthertonClipping(Vector[] _ClipReg, Func <Vector, bool> IsInClipReg, Vector[] _SubjPoly) { // ========================= // checking the input // ========================= if (_ClipReg.Length < 3) { throw new ArgumentException(); } if (_SubjPoly.Length < 3) { throw new ArgumentException(); } foreach (Vector v in _ClipReg) { if (v.Dim != 2) { throw new ArgumentException(); } if (!IsInClipReg(v)) { throw new ArgumentException(); } } foreach (Vector v in _SubjPoly) { if (v.Dim != 2) { throw new ArgumentException(); } } // Given polygon A as the clipping region and polygon B as the subject polygon to be clipped, // the algorithm consists of the following steps: // // 1. List the vertices of the clipping-region polygon A and those of the subject polygon B. // 2. Label the listed vertices of subject polygon B as either inside or outside of clipping region A. // 3. Find all the polygon intersections and insert them into both lists, linking the lists at the intersections. // 4. Generate a list of "inbound" intersections – the intersections where the vector from the intersection // to the subsequent vertex of subject polygon B begins inside the clipping region. // 5. Follow each intersection clockwise around the linked lists until the start position is found. // // If there are no intersections then one of three conditions must be true: // i. A is inside B – return A for clipping, B for merging. // ii. B is inside A – return B for clipping, A for merging. // iii. A and B do not overlap – return None for clipping or A & B for merging. // // (from https://en.wikipedia.org/wiki/Weiler%E2%80%93Atherton_clipping_algorithm) // ================= // step 1: // ================= //List<Vector> ClipReg = _ClipReg.ToList(); //List<Vector> SubjPoly = _SubjPoly.ToList(); var ClipReg = PolygonList.FromEnum(_ClipReg); var SubjPoly = PolygonList.FromEnum(_SubjPoly); _ClipReg = null; // avoid accidental use _SubjPoly = null; // avoid accidental use // ================= // step 2: // ================= //List<int> SubjInside = SubjPoly.Select(X => IsInClipReg(X) ? 1 : -1).ToList(); bool AllInside = true; bool AllOutSide = true; for (var node = SubjPoly; node != null; node = node.next) { bool isin = IsInClipReg(node.v); node.inside = isin ? 1 : -1; AllInside = AllInside && isin; AllOutSide = AllOutSide && !isin; } for (var node = ClipReg; node.next != null; node = node.next) { node.inside = 1; } //if (SubjInside.All(node => node.ins > 0)) if (AllInside) { // case (ii) return(SubjPoly.ToVecArray()); } if (AllOutSide) { // case (iii) // for the moment, we ignore case (i) return(null); } // ================= // step 3: // ================= //List<MyTuple> links = new List<MyTuple>(); //for(int iEdgeSub = 1; iEdgeSub <= SubjPoly.Count; iEdgeSub++) { for (var node_S = SubjPoly; node_S != null; node_S = node_S.next) { //Vector V1 = SubjPoly[iEdgeSub - 1]; //Vector V2 = SubjPoly[iEdgeSub % SubjPoly.Count]; var V1 = node_S; var V2 = node_S.next != null ? node_S.next : SubjPoly; List <Tuple <double, PolygonList> > Alpha1sAndNodes = new List <Tuple <double, PolygonList> >(); // test against all edges //for(int iEdgeClip = 1; iEdgeClip <= ClipReg.Count; iEdgeClip++) { for (var node_C = ClipReg; node_C.next != null; node_C = node_C.next) { //Vector S1 = ClipReg[iEdgeClip - 1]; //Vector S2 = ClipReg[iEdgeClip % ClipReg.Count]; var S1 = node_C; var S2 = node_C.next != null ? node_C.next : ClipReg; bool Intersect = ComputeIntersection(V1.v, V2.v, S1.v, S2.v, out double alpha1, out double alpha2, out Vector I); if (Intersect) { if (alpha1 >= 0.0 && alpha1 <= 1.0 && alpha2 >= 0.0 && alpha2 <= 1.0) { //int iEdgeSubInsert; PolygonList SubjInsert; if (alpha1 <= 0.0) { SubjInsert = V1; SubjInsert.inside = 0; } else if (alpha1 >= 1.0) { SubjInsert = V2; SubjInsert.inside = 0; } else { //iEdgeSubInsert = iEdgeSub; //SubjPoly.Insert(iEdgeSub, I); //iEdgeSub++; SubjInsert = V1.InsertAfter(I); SubjInsert.inside = 0; node_S = SubjInsert; Alpha1sAndNodes.Add(new Tuple <double, PolygonList>(alpha1, SubjInsert)); } //ClipReg.Insert(iEdgeClip, I); // //for(int i = 0; i < links.Count; i++) { // if (links[i].iClip_2 >= iEdgeClip) { // var a = links[i]; // a.iClip_2++; // links[i] = a; // } //} //Debug.Assert(links.Count <= 0 || iEdgeSubInsert > links.Max(tt => tt.iSubj_1)); //links.Add(new MyTuple(iEdgeSubInsert, iEdgeClip)); //SubjInside.Insert(iEdgeSub, 0); //iEdgeClip++; PolygonList ClipInsert; if (alpha2 <= 0.0) { ClipInsert = S1; } else if (alpha2 >= 1.0) { ClipInsert = S2; } else { //iEdgeSubInsert = iEdgeSub; //SubjPoly.Insert(iEdgeSub, I); //iEdgeSub++; ClipInsert = S1.InsertAfter(I); node_C = ClipInsert; } ClipInsert.crossJoin = SubjInsert; SubjInsert.crossJoin = ClipInsert; } else { // somewhere outside } } else { // parallel } } // multiple cuts per edge are probably not handeled correctly { if (Alpha1sAndNodes.Count > 1) { for (int i = 1; i < Alpha1sAndNodes.Count; i++) { double alpha1_prev = Alpha1sAndNodes[i - 1].Item1; double alpha1 = Alpha1sAndNodes[i].Item1; if (alpha1_prev >= alpha1) { throw new ArithmeticException("nodes not inserted in correct order - todo: implement resorting"); } } } } // ================= // step 4 & 5 // ================= if (SubjPoly.Where(node => node.inside == 0).Count() % 2 != 0) { throw new ArithmeticException("un-even number of intersections."); } PolygonList start = SubjPoly; while (start.inside <= 0) { start = start.next; } int Lmax = SubjPoly.Count() + ClipReg.Count(); SubjPoly.Tail.next = SubjPoly; ClipReg.Tail.next = ClipReg; List <Vector> R = new List <Vector>(); PolygonList current = start; int lcur = 0; do { R.Add(current.v); PolygonList next; if (current.crossJoin != null) { next = current.crossJoin.next; } else { next = current.next; } current = next; if (lcur > Lmax) { throw new ApplicationException("running into infinity loop."); } lcur++; } while (!object.ReferenceEquals(start, current)); //Debug.Assert(SubjPoly.Count == SubjInside.Count); //Debug.Assert(SubjInside.Where(b => b > 0).Count() >= 1); /* * int iStart = -1; * for(int i = 0; i < SubjInside.Count; i++) { * if(SubjInside[i] > 0) { * iStart = i; * break; * } * } * * List<Vector> R = new List<Vector>(); * * int iCurrent = iStart; * bool bOnSub = true; * //int iNext = -1; * int linksPointer = 0; * Debug.Assert(linksPointer >= links.Count || iCurrent < links[linksPointer].iSubj_1); * * do { * int L; * if (bOnSub) { * R.Add(SubjPoly[iCurrent]); * L = SubjPoly.Count; * } else { * R.Add(ClipReg[iCurrent]); * L = ClipReg.Count; * } * * int iNext = iCurrent; * iNext++; * if (iNext >= L) * iNext = 0; * * if(bOnSub) { * Debug.Assert(SubjInside[iNext] >= 0); * Debug.Assert(linksPointer >= links.Count || iCurrent < links[linksPointer].iSubj_1); * * if(linksPointer < links.Count && iNext == links[linksPointer].iSubj_1) { * // switch to clipping polygon * * Debug.Assert(SubjInside[iNext] == 0); * iNext = links[linksPointer].iClip_2; * bOnSub = false; * linksPointer++; * } * * * } else { * Debug.Assert(linksPointer < links.Count); // we are on clipping poly; ther must be still one link that brings us back on subject poly * //Debug.Assert(iCurrent < links[linksPointer].iClip_2); * * if(iNext == links[linksPointer].iClip_2) { * iNext = links[linksPointer].iSubj_1; * bOnSub = true; * linksPointer++; * } * } * * iCurrent = iNext; * * } while (!bOnSub || iCurrent != iStart); * */ // ================= // return // ================= return(R.ToArray()); }
private void ReadPolygonList(EndianBinaryReader reader) { while (true) { var header = reader.ReadUInt16(); var flags = ( byte )(header >> 8); var type = ( ChunkType )( byte )header; if (type == ChunkType.End) { break; } else if (type == ChunkType.Null) { continue; } Chunk16 chunk; switch (type) { case ChunkType.BlendAlpha: chunk = new BlendAlphaChunk(); break; case ChunkType.MipmapDAdjust: chunk = new MipmapDAdjustChunk(); break; case ChunkType.SpecularExponent: chunk = new SpecularExponentChunk(); break; case ChunkType.CachePolygonList: chunk = new CachePolygonListChunk(); break; case ChunkType.DrawPolygonList: chunk = new DrawPolygonListChunk(); break; case ChunkType.TextureId: chunk = new TextureIdChunk(); break; case ChunkType.TextureId2: chunk = new TextureId2Chunk(); break; case ChunkType.MaterialDiffuse: chunk = new MaterialDiffuseChunk(); break; case ChunkType.MaterialAmbient: chunk = new MaterialAmbientChunk(); break; case ChunkType.MaterialDiffuseAmbient: chunk = new MaterialDiffuseAmbientChunk(); break; case ChunkType.MaterialSpecular: chunk = new MaterialSpecularChunk(); break; case ChunkType.MaterialDiffuseSpecular: chunk = new MaterialDiffuseSpecularChunk(); break; case ChunkType.MaterialAmbientSpecular: chunk = new MaterialAmbientSpecularChunk(); break; case ChunkType.MaterialDiffuseAmbientSpecular: chunk = new MaterialDiffuseAmbientSpecularChunk(); break; case ChunkType.MaterialBump: chunk = new MaterialBumpChunk(); break; case ChunkType.MaterialDiffuse2: chunk = new MaterialDiffuse2Chunk(); break; case ChunkType.MaterialAmbient2: chunk = new MaterialAmbient2Chunk(); break; case ChunkType.MaterialDiffuseAmbient2: chunk = new MaterialDiffuseAmbient2Chunk(); break; case ChunkType.MaterialSpecular2: chunk = new MaterialSpecular2Chunk(); break; case ChunkType.MaterialDiffuseSpecular2: chunk = new MaterialDiffuseSpecular2Chunk(); break; case ChunkType.MaterialAmbientSpecular2: chunk = new MaterialAmbientSpecular2Chunk(); break; case ChunkType.MaterialDiffuseAmbientSpecular2: chunk = new MaterialDiffuseAmbientSpecular2Chunk(); break; case ChunkType.Strip: chunk = new StripChunk(); break; case ChunkType.StripUVN: chunk = new StripUVNChunk(); break; case ChunkType.StripUVH: chunk = new StripUVHChunk(); break; case ChunkType.StripVN: chunk = new StripVNChunk(); break; case ChunkType.StripUVNVN: chunk = new StripUVNVNChunk(); break; case ChunkType.StripUVHVN: chunk = new StripUVHVNChunk(); break; case ChunkType.StripD8: chunk = new StripD8Chunk(); break; case ChunkType.StripUVND8: chunk = new StripUVND8Chunk(); break; case ChunkType.StripUVHD8: chunk = new StripUVHD8Chunk(); break; case ChunkType.Strip2: chunk = new Strip2Chunk(); break; case ChunkType.StripUVN2: chunk = new StripUVN2Chunk(); break; case ChunkType.StripUVH2: chunk = new StripUVH2Chunk(); break; case ChunkType.VolumeTristrip: chunk = new VolumeTristripChunk(); break; default: throw new NotImplementedException($"Found unexpected chunk type in polygon list: {type}"); } chunk.ReadBody(-1, flags, reader); PolygonList.Add(chunk); } }
public ActionResult CheckList(string Date, int ShopID) { var d = Date.ToDate(); if (!d.HasValue) { return(new ContentResult()); } /* * var options = new DataLoadOptions(); * options.LoadWith((DeliveryListOrder x) => x.Order); * DB.LoadOptions = options; */ var list = DB.DeliveryLists.FirstOrDefault(x => x.Date.Date == d.Value.Date && x.ShopID == ShopID); /* * var dtl = (DateTime?)Session["CheckList_" + Date.Date.ToString("yy-mm-dd")]; * if (dtl.HasValue && DateTime.Now.Subtract(dtl.Value).TotalSeconds < 2) * { * return list; * } * else * { * Session["CheckList_" + Date.Date.ToString("yy-mm-dd")] = null; * } * Session["CheckList_" + Date.Date.ToString("yy-mm-dd")] = DateTime.Now; * */ var orders = DB.Orders.Where( x => x.DeliveryDate.HasValue && x.DeliveryDate.Value.Date == d.Value.Date && x.ShopID == ShopID) .ToList(); var poly = new PolygonList(ShopID); foreach (var order in orders) { if (order.OrderDelivery == null) { var delivery = new DeliveryAddress() { DeliveryType = (int)SectorTypes.CarSector }; DB.DeliveryAddresses.InsertOnSubmit(delivery); order.OrderDelivery = delivery; DB.SubmitChanges(); } if (order.OrderDelivery.DeliveryType == (int)SectorTypes.CarSector && !order.CarID.HasValue) { var cars = poly.GetDefaultCars(order); if (cars.Any()) { order.CarID = cars.First().ID; } } if (order.OrderDelivery.DeliveryType == (int)SectorTypes.CourierSector && !order.WorkerID.HasValue) { var couriers = poly.GetDefaultCouriers(order); if (couriers.Any()) { order.WorkerID = couriers.First().ID; } } } DB.SubmitChanges(); var stores = DB.Stores.Where(x => x.ShopStores.Any(z => z.ShopID == ShopID)).ToList(); if (list == null) { list = new DeliveryList() { Approved = false, Date = d.Value.Date, ShopID = ShopID }; DB.DeliveryLists.InsertOnSubmit(list); DB.SubmitChanges(); int add = 1; if (stores.Any() && orders.Any()) { var workers = orders.Where(x => x.WorkerID.HasValue).Select(x => x.WorkerID).Distinct().ToList(); foreach (var worker in workers) { DB.DeliveryListOrders.InsertAllOnSubmit( stores.Select( (x, index) => new DeliveryListOrder() { ListID = list.ID, StoreID = x.ID, OrderNum = index + add, Type = (int)SectorTypes.CourierSector, WorkerID = worker }) .ToList()); DB.SubmitChanges(); add += stores.Count; var workerOrders = orders.Where(x => x.WorkerID == worker).ToList(); DB.DeliveryListOrders.InsertAllOnSubmit( workerOrders.Select( (x, index) => new DeliveryListOrder() { ListID = list.ID, OrderID = x.ID, OrderNum = index + add }) .ToList()); DB.SubmitChanges(); add += workerOrders.Count; } var cars = orders.Where(x => x.CarID.HasValue).Select(x => x.CarID).Distinct().ToList(); foreach (var car in cars) { DB.DeliveryListOrders.InsertAllOnSubmit( stores.Select( (x, index) => new DeliveryListOrder() { ListID = list.ID, StoreID = x.ID, OrderNum = index + add, Type = (int)SectorTypes.CarSector, CarID = car }) .ToList()); add += stores.Count; var carOrders = orders.Where(x => x.CarID == car).ToList(); DB.DeliveryListOrders.InsertAllOnSubmit( carOrders.Select( (x, index) => new DeliveryListOrder() { ListID = list.ID, OrderID = x.ID, OrderNum = index + add }) .ToList()); DB.SubmitChanges(); add += carOrders.Count; } var another = orders.Where(x => !x.WorkerID.HasValue && !x.CarID.HasValue); DB.DeliveryListOrders.InsertAllOnSubmit( another.Select( (x, index) => new DeliveryListOrder() { ListID = list.ID, OrderID = x.ID, OrderNum = index + add }) .ToList()); DB.SubmitChanges(); } } else { var old = DB.DeliveryListOrders.Where(x => x.ListID == list.ID && x.Store == null && x.Order == null).ToList(); if (old.Any()) { DB.DeliveryListOrders.DeleteAllOnSubmit(old); DB.SubmitChanges(); } var newOrders = orders.Where(x => list.DeliveryListOrders.All(z => z.OrderID != x.ID)).ToList(); if (newOrders.Any()) { var min = list.DeliveryListOrders.Any() ? (list.DeliveryListOrders.Max(x => x.OrderNum) + 1) : 1; DB.DeliveryListOrders.InsertAllOnSubmit(newOrders.Select((x, index) => new DeliveryListOrder() { ListID = list.ID, OrderID = x.ID, OrderNum = min + index })); DB.SubmitChanges(); } var orderList = DB.DeliveryListOrders.Where(x => x.ListID == list.ID && (x.Order.CarID.HasValue || x.Order.WorkerID.HasValue)).ToList(); foreach (var listOrder in orderList) { if (listOrder.Order.OrderDelivery.DeliveryType == (int)SectorTypes.CarSector) { var storeCheck = DB.DeliveryListOrders.Where( x => x.StoreID.HasValue && x.ListID == list.ID && x.CarID.HasValue && !x.OrderID.HasValue && x.CarID == listOrder.Order.CarID); if (!storeCheck.Any()) { var stl = stores.Select( (x, index) => new DeliveryListOrder() { ListID = list.ID, StoreID = x.ID, OrderNum = listOrder.OrderNum - index - 1, Type = (int)SectorTypes.CarSector, CarID = listOrder.Order.CarID }) .ToList(); DB.DeliveryListOrders.InsertAllOnSubmit(stl); DB.SubmitChanges(); } } if (listOrder.Order.OrderDelivery.DeliveryType == (int)SectorTypes.CourierSector) { var storeCheck = DB.DeliveryListOrders.Where( x => x.StoreID.HasValue && x.ListID == list.ID && x.WorkerID.HasValue && !x.OrderID.HasValue && x.WorkerID == listOrder.Order.WorkerID); if (!storeCheck.Any()) { var stl = stores.Select( (x, index) => new DeliveryListOrder() { ListID = list.ID, StoreID = x.ID, OrderNum = listOrder.OrderNum - index - 1, Type = (int)SectorTypes.CourierSector, WorkerID = listOrder.Order.WorkerID }) .ToList(); DB.DeliveryListOrders.InsertAllOnSubmit(stl); DB.SubmitChanges(); } } } var emptyCheck = DB.DeliveryListOrders.Where( x => !x.OrderID.HasValue && x.ListID == list.ID && x.StoreID.HasValue).ToList(); foreach (var st in emptyCheck) { var suitable = DB.DeliveryListOrders.Any( x => x.OrderID.HasValue && x.ListID == list.ID && x.Order.OrderDelivery != null && x.Order.OrderDelivery.DeliveryType > 0 && (x.Order.OrderDelivery.DeliveryType == (int)SectorTypes.CarSector ? x.Order.CarID == st.CarID : x.Order.WorkerID == st.WorkerID)); if (!suitable) { DB.DeliveryListOrders.DeleteOnSubmit(st); } } DB.SubmitChanges(); } return(new ContentResult()); }