Пример #1
0
        void AllocateBundleBases()
        {
            externalBases = new Dictionary <ICurve, List <BundleBase> >();
            internalBases = new Dictionary <ICurve, List <BundleBase> >();
            Bundles       = new List <BundleInfo>();

            foreach (var station in metroGraphData.Stations)
            {
                if (station.BoundaryCurve == null)
                {
                    station.BoundaryCurve = new Ellipse(station.Radius, station.Radius, station.Position);
                }
            }

            foreach (var station in metroGraphData.Stations)
            {
                foreach (Station neighbor in station.Neighbors)
                {
                    if (station < neighbor)
                    {
                        var bb = new BundleBase(metroGraphData.RealEdgeCount(station, neighbor), station.BoundaryCurve, station.Position, station.IsRealNode, neighbor.SerialNumber);
                        station.BundleBases[neighbor] = bb;

                        var bb2 = new BundleBase(metroGraphData.RealEdgeCount(station, neighbor), neighbor.BoundaryCurve, neighbor.Position, neighbor.IsRealNode, station.SerialNumber);
                        neighbor.BundleBases[station] = bb2;

                        if (Curve.PointRelativeToCurveLocation(neighbor.Position, station.BoundaryCurve) != PointLocation.Outside)
                        {
                            bb.IsParent = true;
                            CollectionUtilities.AddToMap(internalBases, station.BoundaryCurve, bb);
                            CollectionUtilities.AddToMap(externalBases, neighbor.BoundaryCurve, bb2);
                        }
                        else if (Curve.PointRelativeToCurveLocation(station.Position, neighbor.BoundaryCurve) != PointLocation.Outside)
                        {
                            bb2.IsParent = true;
                            CollectionUtilities.AddToMap(externalBases, station.BoundaryCurve, bb);
                            CollectionUtilities.AddToMap(internalBases, neighbor.BoundaryCurve, bb2);
                        }
                        else
                        {
                            CollectionUtilities.AddToMap(externalBases, station.BoundaryCurve, bb);
                            CollectionUtilities.AddToMap(externalBases, neighbor.BoundaryCurve, bb2);
                        }

                        Set <Polyline> obstaclesToIgnore = metroGraphData.tightIntersections.ObstaclesToIgnoreForBundle(station, neighbor);
                        var            bundle            = new BundleInfo(bb, bb2, obstaclesToIgnore, bundlingSettings.EdgeSeparation, metroOrdering.GetOrder(station, neighbor).Select(l => l.Width / 2).ToArray());
                        bb.OutgoingBundleInfo = bb2.IncomingBundleInfo = bundle;
                        Bundles.Add(bundle);
                    }
                }
            }

            //neighbors
            SetBundleBaseNeighbors();
        }
        double ComputeCostDeltaAfterNodeGluing(Station i, Station j, Dictionary <Station, Station> gluingMap)
        {
            double d = (i.Position - j.Position).Length;

            if (i.Radius >= d || j.Radius >= d)
            {
                return(1.0);
            }

            double gain = 0;

            //ink
            double oldInk = metroGraphData.Ink;
            double newInk = metroGraphData.Ink - (j.Position - i.Position).Length;

            foreach (var adj in i.Neighbors)
            {
                var k = Glued(adj, gluingMap);
                newInk -= (k.Position - i.Position).Length;
                newInk += (metroGraphData.RealEdgeCount(k, j) == 0 ? (k.Position - j.Position).Length : 0);
            }

            gain += CostCalculator.InkError(oldInk, newInk, bundlingSettings);

            //path lengths
            foreach (var metroInfo in metroGraphData.MetroNodeInfosOfNode(i))
            {
                double oldLength = metroInfo.Metroline.Length;
                double newLength = metroInfo.Metroline.Length;

                PolylinePoint pi = metroInfo.PolyPoint;
                PolylinePoint pa = pi.Prev;
                PolylinePoint pb = pi.Next;

                newLength -= (pa.Point - i.Position).Length + (pb.Point - i.Position).Length;
                newLength += (pa.Point - j.Position).Length + (pb.Point - j.Position).Length;

                gain += CostCalculator.PathLengthsError(oldLength, newLength, metroInfo.Metroline.IdealLength,
                                                        bundlingSettings);
            }

            return(gain);
        }