public static List <VehicleRestrictionsLaneRecord> GetLanes(ushort segmentId)
        {
            int maxLaneCount = segmentId.ToSegment().Info.m_lanes.Length;
            var ret          = new List <VehicleRestrictionsLaneRecord>(maxLaneCount);
            ExtSegmentManager extSegmentManager = ExtSegmentManager.Instance;
            var lanes = extSegmentManager.GetSortedLanes(
                segmentId,
                ref segmentId.ToSegment(),
                null,
                LANE_TYPES,
                VEHICLE_TYPES,
                sort: false);

            foreach (var lane in lanes)
            {
                VehicleRestrictionsLaneRecord laneData = new VehicleRestrictionsLaneRecord {
                    SegmentId = segmentId,
                    LaneId    = lane.laneId,
                    LaneIndex = lane.laneIndex,
                };
                ret.Add(laneData);
            }
            ret.TrimExcess();
            return(ret);
        }
Пример #2
0
        public static List <LaneArrowsRecord> GetLanes(ushort segmentId, bool startNode)
        {
            int maxLaneCount = segmentId.ToSegment().Info.m_lanes.Length;
            var ret          = new List <LaneArrowsRecord>(maxLaneCount);
            ExtSegmentManager extSegmentManager = ExtSegmentManager.Instance;
            var lanes = extSegmentManager.GetSortedLanes(
                segmentId,
                ref segmentId.ToSegment(),
                startNode,
                LaneArrowManager.LANE_TYPES,
                LaneArrowManager.VEHICLE_TYPES,
                sort: false);

            foreach (var lane in lanes)
            {
                LaneArrowsRecord laneData = new LaneArrowsRecord {
                    LaneId = lane.laneId,
                };
                ret.Add(laneData);
            }
            ret.TrimExcess();
            return(ret);
        }
Пример #3
0
        private static void FixSegmentRoundabout(ushort segmentId, ushort nextSegmentId) {
            if (OptionsMassEditTab.RoundAboutQuickFix_ParkingBanMainR) {
                ParkingRestrictionsManager.Instance.SetParkingAllowed(segmentId, false);
            }

            if (OptionsMassEditTab.RoundAboutQuickFix_RealisticSpeedLimits) {
                SpeedValue? targetSpeed = CalculatePreferedSpeed(segmentId);
                float defaultSpeed = SpeedLimitManager.Instance.CalculateCustomNetinfoSpeedLimit(segmentId.ToSegment().Info);

                if (targetSpeed != null && targetSpeed.Value.GetKmph() < defaultSpeed) {
                    SpeedLimitManager.Instance.SetSegmentSpeedLimit(
                        segmentId: segmentId,
                        finalDir: NetInfo.Direction.Forward,
                        action: SetSpeedLimitAction.SetOverride(targetSpeed.Value));
                    SpeedLimitManager.Instance.SetSegmentSpeedLimit(
                        segmentId: segmentId,
                        finalDir: NetInfo.Direction.Backward,
                        action: SetSpeedLimitAction.SetOverride(targetSpeed.Value));
                }
            }

            ushort nodeId = ExtSegmentManager.Instance.GetHeadNode(segmentId);

            if (OptionsMassEditTab.RoundAboutQuickFix_StayInLaneMainR && !HasJunctionFlag(nodeId)) {
                StayInLane(nodeId, StayInLaneMode.Both);
            }

            // allocation of dedicated exit lanes is supported only when the roundabout is round
            // in which case the next segment should be straigh ahead.
            bool isStraight = segEndMan.GetDirection(segmentId, nextSegmentId, nodeId) == ArrowDirection.Forward;

            if (OptionsMassEditTab.RoundAboutQuickFix_DedicatedExitLanes &&
                HasJunctionFlag(nodeId) &&
                SeparateTurningLanesUtil.CanChangeLanes(
                    segmentId, nodeId) == SetLaneArrow_Result.Success &&
                    isStraight) {

                bool startNode = (bool)ExtSegmentManager.Instance.IsStartNode(segmentId, nodeId);
                ExtSegmentManager extSegmentManager = ExtSegmentManager.Instance;
                IList<LanePos> laneList =
                    extSegmentManager.GetSortedLanes(
                        segmentId,
                        ref segmentId.ToSegment(),
                        startNode,
                        LaneArrowManager.LANE_TYPES,
                        LaneArrowManager.VEHICLE_TYPES,
                        true);
                int nSrc = laneList.Count;

                // check for exits.
                segEndMan.CalculateOutgoingLeftStraightRightSegments(
                    ref GetSegEnd(segmentId, nodeId),
                    ref nodeId.ToNode(),
                    out bool bLeft,
                    out bool bForward,
                    out bool bRight);

                //Set one dedicated exit lane per exit - if there are enough lanes that is.
                switch (nSrc) {
                    case 0:
                        Debug.LogAssertion("The road is the wrong way around.");
                        break;
                    case 1:
                        break; // not enough lanes Use default settings.
                    case 2:
                        if (bRight && bLeft) {
                            // not enough lanes, use default settings
                        } else if (bRight) {
                            LaneArrowManager.Instance.SetLaneArrows(laneList[0].laneId, LaneArrows.Forward);
                            LaneArrowManager.Instance.SetLaneArrows(laneList[1].laneId, LaneArrows.Right);
                        } else if (bLeft) {
                            LaneArrowManager.Instance.SetLaneArrows(laneList[0].laneId, LaneArrows.Left);
                            LaneArrowManager.Instance.SetLaneArrows(laneList[1].laneId, LaneArrows.Forward);
                        } else {
                            LaneArrowManager.Instance.SetLaneArrows(laneList[0].laneId, LaneArrows.Forward);
                            LaneArrowManager.Instance.SetLaneArrows(laneList[1].laneId, LaneArrows.Forward);
                        }
                        break;
                    default:
                        for (int i = 0; i < laneList.Count; ++i) {
                            LaneArrowManager.Instance.SetLaneArrows(laneList[i].laneId, LaneArrows.Forward);
                        }
                        if (bRight) {
                            LaneArrowManager.Instance.SetLaneArrows(laneList[nSrc - 1].laneId, LaneArrows.Right);
                        }
                        if (bLeft) {
                            LaneArrowManager.Instance.SetLaneArrows(laneList[0].laneId, LaneArrows.Left);
                        }
                        break;
                } // end switch
            } // end if
        }
        public static void Traverse(ushort initialSegmentId,
                                    TraverseDirection direction,
                                    TraverseSide side,
                                    LaneStopCriterion laneStopCrit,
                                    SegmentStopCriterion segStopCrit,
                                    NetInfo.LaneType?laneTypeFilter,
                                    VehicleInfo.VehicleType?vehicleTypeFilter,
                                    SegmentLaneVisitor laneVisitor)
        {
            IList <LanePos> initialSortedLanes = null;

            //-------------------------------------
            // Function applies via SegmentTraverser
            //-------------------------------------
            bool VisitorFun(SegmentVisitData segData)
            {
                bool isInitialSeg = segData.Initial;
                bool reverse      = !isInitialSeg && segData.ViaStartNode == segData.ViaInitialStartNode;
                bool ret          = false;

                //-------------------------------------
                // Function applies for each segment
                //-------------------------------------
                bool VisitorProcessFun(ushort segmentId, ref NetSegment segment)
                {
                    // Log._Debug($"SegmentLaneTraverser: Reached segment {segmentId}:
                    //     isInitialSeg={isInitialSeg} viaStartNode={segData.viaStartNode}
                    //     viaInitialStartNode={segData.viaInitialStartNode} reverse={reverse}");
                    ExtSegmentManager extSegmentManager = ExtSegmentManager.Instance;
                    IList <LanePos>   sortedLanes       = extSegmentManager.GetSortedLanes(
                        segmentId,
                        ref segment,
                        null,
                        laneTypeFilter,
                        vehicleTypeFilter,
                        reverse);

                    if (isInitialSeg)
                    {
                        initialSortedLanes = sortedLanes;
                    }
                    else if (initialSortedLanes == null)
                    {
                        throw new ApplicationException("Initial list of sorted lanes not set.");
                    }
                    else if (sortedLanes.Count != initialSortedLanes.Count &&
                             (laneStopCrit & LaneStopCriterion.LaneCount) !=
                             LaneStopCriterion.None)
                    {
                        // Log._Debug($"SegmentLaneTraverser: Stop criterion reached @ {segmentId}:
                        //     {sortedLanes.Count} current vs. {initialSortedLanes.Count} initial lanes");
                        return(false);
                    }

                    for (int i = 0; i < sortedLanes.Count; ++i)
                    {
                        // Log._Debug($"SegmentLaneTraverser: Traversing segment lane
                        //     {sortedLanes[i].laneIndex} @ {segmentId} (id {sortedLanes[i].laneId},
                        //     pos {sortedLanes[i].position})");

                        if (!laneVisitor(
                                new SegmentLaneVisitData(
                                    segData,
                                    i,
                                    sortedLanes[i],
                                    initialSortedLanes[i])))
                        {
                            return(false);
                        }
                    }

                    ret = true;
                    return(true);
                }

                ushort currentSegmentId = segData.CurSeg.segmentId;

                VisitorProcessFun(currentSegmentId, ref currentSegmentId.ToSegment());

                return(ret);
            }

            SegmentTraverser.Traverse(initialSegmentId, direction, side, segStopCrit, VisitorFun);
        }