public void CreateSafetyImplicitZones(ArbiterIntersection ai) { if (ai.StoppedExits.Count > 0) { foreach (ITraversableWaypoint itw in ai.AllExits.Values) { if (itw is ArbiterWaypoint && !itw.IsStop) { ArbiterWaypoint aw = (ArbiterWaypoint)itw; ArbiterLane al = aw.Lane; LinePath.PointOnPath end = aw.Lane.LanePath().GetClosestPoint(aw.Position); double dist = -30; LinePath.PointOnPath begin = al.LanePath().AdvancePoint(end, ref dist); if (dist != 0) { EditorOutput.WriteLine("safety zone too close to start of lane, setting start to start of lane: " + aw.ToString()); begin = al.LanePath().StartPoint; } ArbiterSafetyZone asz = new ArbiterSafetyZone(al, end, begin); al.SafetyZones.Add(asz); al.Way.Segment.RoadNetwork.DisplayObjects.Add(asz); al.Way.Segment.RoadNetwork.ArbiterSafetyZones.Add(asz); if (aw != null && aw.IsExit == true) { asz.isExit = true; asz.Exit = aw; } // add to display this.rd.displayObjects.Add(asz); } } } }
/// <summary> /// Generates the xySegments into segments and inputs them into the input road network /// </summary> /// <param name="arn"></param> /// <returns></returns> public ArbiterRoadNetwork GenerateSegments(ArbiterRoadNetwork arn) { foreach (SimpleSegment ss in segments) { // seg ArbiterSegmentId asi = new ArbiterSegmentId(int.Parse(ss.Id)); ArbiterSegment asg = new ArbiterSegment(asi); arn.ArbiterSegments.Add(asi, asg); asg.RoadNetwork = arn; asg.SpeedLimits = new ArbiterSpeedLimit(); asg.SpeedLimits.MaximumSpeed = 13.4112; // 30mph max speed // way1 ArbiterWayId awi1 = new ArbiterWayId(1, asi); ArbiterWay aw1 = new ArbiterWay(awi1); aw1.Segment = asg; asg.Ways.Add(awi1, aw1); asg.Way1 = aw1; // way2 ArbiterWayId awi2 = new ArbiterWayId(2, asi); ArbiterWay aw2 = new ArbiterWay(awi2); aw2.Segment = asg; asg.Ways.Add(awi2, aw2); asg.Way2 = aw2; // make lanes foreach (SimpleLane sl in ss.Lanes) { // lane ArbiterLaneId ali; ArbiterLane al; // get way of lane id if (ss.Way1Lanes.Contains(sl)) { ali = new ArbiterLaneId(GenerationTools.GetId(sl.Id)[1], awi1); al = new ArbiterLane(ali); aw1.Lanes.Add(ali, al); al.Way = aw1; } else { ali = new ArbiterLaneId(GenerationTools.GetId(sl.Id)[1], awi2); al = new ArbiterLane(ali); aw2.Lanes.Add(ali, al); al.Way = aw2; } // add to display arn.DisplayObjects.Add(al); // width al.Width = sl.LaneWidth == 0 ? TahoeParams.T * 2.0 : sl.LaneWidth * 0.3048; if (sl.LaneWidth == 0) { Console.WriteLine("lane: " + ali.ToString() + " contains no lane width, setting to 4m"); } // lane boundaries al.BoundaryLeft = this.GenerateLaneBoundary(sl.LeftBound); al.BoundaryRight = this.GenerateLaneBoundary(sl.RightBound); // add lane to seg asg.Lanes.Add(ali, al); // waypoints List <ArbiterWaypoint> waypointList = new List <ArbiterWaypoint>(); // generate waypoints foreach (SimpleWaypoint sw in sl.Waypoints) { // waypoint ArbiterWaypointId awi = new ArbiterWaypointId(GenerationTools.GetId(sw.ID)[2], ali); ArbiterWaypoint aw = new ArbiterWaypoint(sw.Position, awi); aw.Lane = al; // stop if (sl.Stops.Contains(sw.ID)) { aw.IsStop = true; } // checkpoint foreach (SimpleCheckpoint sc in sl.Checkpoints) { if (sw.ID == sc.WaypointId) { aw.IsCheckpoint = true; aw.CheckpointId = int.Parse(sc.CheckpointId); arn.Checkpoints.Add(aw.CheckpointId, aw); } } // add asg.Waypoints.Add(awi, aw); arn.ArbiterWaypoints.Add(awi, aw); al.Waypoints.Add(awi, aw); waypointList.Add(aw); arn.DisplayObjects.Add(aw); arn.LegacyWaypointLookup.Add(sw.ID, aw); } al.WaypointList = waypointList; // lane partitions List <ArbiterLanePartition> alps = new List <ArbiterLanePartition>(); al.Partitions = alps; // generate lane partitions for (int i = 0; i < waypointList.Count - 1; i++) { // create lane partition ArbiterLanePartitionId alpi = new ArbiterLanePartitionId(waypointList[i].WaypointId, waypointList[i + 1].WaypointId, ali); ArbiterLanePartition alp = new ArbiterLanePartition(alpi, waypointList[i], waypointList[i + 1], asg); alp.Lane = al; waypointList[i].NextPartition = alp; waypointList[i + 1].PreviousPartition = alp; alps.Add(alp); arn.DisplayObjects.Add(alp); // crete initial user partition ArbiterUserPartitionId aupi = new ArbiterUserPartitionId(alp.PartitionId, waypointList[i].WaypointId, waypointList[i + 1].WaypointId); ArbiterUserPartition aup = new ArbiterUserPartition(aupi, alp, waypointList[i], waypointList[i + 1]); List <ArbiterUserPartition> aups = new List <ArbiterUserPartition>(); aups.Add(aup); alp.UserPartitions = aups; alp.SetDefaultSparsePolygon(); arn.DisplayObjects.Add(aup); } // path segments of lane List <IPathSegment> ips = new List <IPathSegment>(); List <Coordinates> pathSegments = new List <Coordinates>(); pathSegments.Add(alps[0].Initial.Position); // loop foreach (ArbiterLanePartition alPar in alps) { ips.Add(new LinePathSegment(alPar.Initial.Position, alPar.Final.Position)); // make new segment pathSegments.Add(alPar.Final.Position); } // generate lane partition path LinePath partitionPath = new LinePath(pathSegments); al.SetLanePath(partitionPath); al.PartitionPath = new Path(ips, CoordinateMode.AbsoluteProjected); // safeto zones foreach (ArbiterWaypoint aw in al.Waypoints.Values) { if (aw.IsStop) { LinePath.PointOnPath end = al.GetClosestPoint(aw.Position); double dist = -30; LinePath.PointOnPath begin = al.LanePath().AdvancePoint(end, ref dist); if (dist != 0) { begin = al.LanePath().StartPoint; } ArbiterSafetyZone asz = new ArbiterSafetyZone(al, end, begin); asz.isExit = true; asz.Exit = aw; al.SafetyZones.Add(asz); arn.DisplayObjects.Add(asz); arn.ArbiterSafetyZones.Add(asz); } } } } return(arn); }
/// <summary> /// When mouse clicked /// </summary> /// <param name="e"></param> protected override void OnMouseClick(MouseEventArgs e) { #region Left if (e.Button == MouseButtons.Left) { if (this.CurrentEditorTool is RulerTool) { RulerTool ruler = (RulerTool)this.CurrentEditorTool; if (ruler.Initial == null) { ruler.Initial = transform.GetWorldPoint(new PointF(e.X, e.Y)); if (this.SecondaryEditorTool != null && this.SecondaryEditorTool is PointAnalysisTool) { PointAnalysisTool pat = ((PointAnalysisTool)this.SecondaryEditorTool); pat.Save = new List<Coordinates>(); pat.Save.Add(ruler.Initial.Value); } } else if (ruler.Current != null) { ruler.Initial = null; ruler.Current = null; if (this.SecondaryEditorTool != null && this.SecondaryEditorTool is PointAnalysisTool) { PointAnalysisTool pat = ((PointAnalysisTool)this.SecondaryEditorTool); pat.Save = null; } } } else if (this.CurrentEditorTool is SparseTool) { ((SparseTool)this.CurrentEditorTool).Click(transform.GetWorldPoint(new PointF(e.X, e.Y))); } else if (this.CurrentEditorTool is AngleMeasureTool) { AngleMeasureTool amt = (AngleMeasureTool)this.CurrentEditorTool; if (amt.SetP1 == false) { amt.VSetP1(transform.GetWorldPoint(new PointF(e.X, e.Y)), this.SecondaryEditorTool); } else if (amt.SetP2 == false) { amt.VSetP2(transform.GetWorldPoint(new PointF(e.X, e.Y)), this.SecondaryEditorTool); } else if (amt.SetP3 == false) { amt.VSetP3(this.SecondaryEditorTool); } } else if (this.CurrentEditorTool is WaypointAdjustmentTool) { if (((WaypointAdjustmentTool)this.CurrentEditorTool).CheckInMove) { this.CurrentEditorTool = new WaypointAdjustmentTool(this.transform); } else { // create display object filter for waypoints DisplayObjectFilter dof = delegate(IDisplayObject target) { // check if target is network object if (target is IGenericWaypoint && target is IDisplayObject) return true; else return false; }; // perform hit test HitTestResult htr = this.HitTest(transform.GetWorldPoint(new PointF(e.X, e.Y)), dof); // check for validity if (htr.Hit) { // set adjust ((WaypointAdjustmentTool)this.CurrentEditorTool).SetWaypoint(htr.DisplayObject, ((IGenericWaypoint)htr.DisplayObject).Position); } } } else if (this.CurrentEditorTool is IntersectionPulloutTool) { IntersectionPulloutTool tool = (IntersectionPulloutTool)this.CurrentEditorTool; // get key current KeyStateInfo shiftKey = KeyboardInfo.GetKeyState(Keys.ShiftKey); if (!shiftKey.IsPressed) { if (tool.Mode == InterToolboxMode.SafetyZone) { // create display object filter for waypoints DisplayObjectFilter dof = delegate(IDisplayObject target) { // check if target is network object if (target is ArbiterLane) return true; else return false; }; // perform hit test HitTestResult htr = this.HitTest(transform.GetWorldPoint(new PointF(e.X, e.Y)), dof); // check for validity if (htr.Hit) { // set undo tool.ed.SaveUndoPoint(); // get lane ArbiterLane al = (ArbiterLane)htr.DisplayObject; // get point on lane LinePath.PointOnPath end = al.GetClosestPoint(transform.GetWorldPoint(new PointF(e.X, e.Y))); ArbiterWaypoint aw = al.GetClosestWaypoint(al.LanePath().GetPoint(end), 5); if (aw != null && aw.IsExit == true) { end = al.GetClosestPoint(aw.Position); } double dist = -30; LinePath.PointOnPath begin = al.LanePath().AdvancePoint(end, ref dist); if (dist != 0) { EditorOutput.WriteLine("safety zone too close to start of lane, setting start to start of lane"); begin = al.LanePath().StartPoint; } ArbiterSafetyZone asz = new ArbiterSafetyZone(al, end, begin); al.SafetyZones.Add(asz); al.Way.Segment.RoadNetwork.DisplayObjects.Add(asz); al.Way.Segment.RoadNetwork.ArbiterSafetyZones.Add(asz); if (aw != null && aw.IsExit == true) { asz.isExit = true; asz.Exit = aw; } // add to display this.displayObjects.Add(asz); } } else if (tool.Mode == InterToolboxMode.Helpers) { // create display object filter for waypoints DisplayObjectFilter dof = delegate(IDisplayObject target) { // check if target is network object if (target is ArbiterLane) return true; else return false; }; // perform hit test HitTestResult htr = this.HitTest(transform.GetWorldPoint(new PointF(e.X, e.Y)), dof); // check for validity if (htr.Hit) { // get lane ArbiterLane al = (ArbiterLane)htr.DisplayObject; // get point on lane tool.WrappingHelpers.Add(al.GetClosest(transform.GetWorldPoint(new PointF(e.X, e.Y)))); } } else if (tool.Mode == InterToolboxMode.Box) { // clicked point Coordinates c = transform.GetWorldPoint(new PointF(e.X, e.Y)); // add points if (tool.WrapInitial == null) { tool.WrapInitial = c; } else if (tool.WrapFinal != null && !tool.WrapInitial.Equals(c)) { tool.FinalizeIntersection(); } } } } else if (this.CurrentEditorTool is ZoneTool) { // get key current KeyStateInfo shiftKey = KeyboardInfo.GetKeyState(Keys.ShiftKey); ZoneTool zt = (ZoneTool)this.CurrentEditorTool; if (zt.moveNode != null) { zt.moveNode = null; zt.Reset(false); } else { if (!shiftKey.IsPressed) { // get key current KeyStateInfo wKey = KeyboardInfo.GetKeyState(Keys.W); if (!wKey.IsPressed) { // clicked point Coordinates c = transform.GetWorldPoint(new PointF(e.X, e.Y)); zt.Click(c); } else { // clicked point Coordinates c = transform.GetWorldPoint(new PointF(e.X, e.Y)); if (zt.zt.current != null && zt.zt.current.Perimeter.PerimeterPolygon.IsInside(c)) { zt.ed.SaveUndoPoint(); zt.BeginMove(c); } } } } } this.Invalidate(); } #endregion #region Right else if (e.Button == MouseButtons.Right) { if (this.CurrentEditorTool is ZoneTool) { // clicked point Coordinates c = transform.GetWorldPoint(new PointF(e.X, e.Y)); ZoneTool zt = (ZoneTool)this.CurrentEditorTool; if (zt.zt.current != null && zt.zt.current.Perimeter.PerimeterPolygon.IsInside(c)) { zt.RightClick(c); this.Invalidate(); if (zt.rightClickNode != null || zt.rightClickEdge != null) { this.removeToolStripMenuItem.Enabled = true; this.zoneContextMenuStrip.Show(this, e.X, e.Y); } else { this.removeToolStripMenuItem.Enabled = false; this.zoneContextMenuStrip.Show(this, e.X, e.Y); } } } else if (this.CurrentEditorTool != null && this.CurrentEditorTool is PartitionTools) { PartitionTools pt = (PartitionTools)this.CurrentEditorTool; if (!pt.RemoveUserWaypointMode) { // create display object filter for waypoints DisplayObjectFilter dof = delegate(IDisplayObject target) { // check if target is network object if (target is ArbiterLanePartition) return true; else return false; }; HitTestResult htr = this.HitTest(transform.GetWorldPoint(new PointF(e.X, e.Y)), dof); if (htr.DisplayObject != null && htr.DisplayObject is ArbiterLanePartition && htr.Hit) { this.selected = htr.DisplayObject; this.selected.Selected = SelectionType.SingleSelected; this.partitionContextMenuStrip.Show(this, e.X, e.Y); pt.HitPoint = transform.GetWorldPoint(new PointF(e.X, e.Y)); } else if (this.selected != null) { this.selected.Selected = SelectionType.NotSelected; } } else { // create display object filter for waypoints DisplayObjectFilter dof = delegate(IDisplayObject target) { // check if target is network object if (target is ArbiterUserWaypoint) return true; else return false; }; HitTestResult htr = this.HitTest(transform.GetWorldPoint(new PointF(e.X, e.Y)), dof); if (htr.DisplayObject != null && htr.DisplayObject is ArbiterUserWaypoint && htr.Hit) { this.selected = htr.DisplayObject; this.selected.Selected = SelectionType.SingleSelected; this.userWaypointContextMenuStrip.Show(this, e.X, e.Y); } else if (this.selected != null) { this.selected.Selected = SelectionType.NotSelected; } } this.Invalidate(); } else { // perform hit test HitTestResult htr = this.HitTest(transform.GetWorldPoint(new PointF(e.X, e.Y)), DrawingUtility.DefaultFilter); if (htr.DisplayObject == null) { } else if (htr.DisplayObject is ArbiterIntersection) { this.intersectionContextMenuStrip.Show(this, e.X, e.Y); this.selected = htr.DisplayObject; } else if (this.CurrentEditorTool is IntersectionPulloutTool && ((IntersectionPulloutTool)this.CurrentEditorTool).Mode == InterToolboxMode.SafetyZone) { // create display object filter for waypoints DisplayObjectFilter dof = delegate(IDisplayObject target) { // check if target is network object if (target is ArbiterSafetyZone) return true; else return false; }; htr = this.HitTest(transform.GetWorldPoint(new PointF(e.X, e.Y)), dof); if (htr.DisplayObject is ArbiterSafetyZone) { this.safetyZoneContextMenu.Show(this, e.X, e.Y); this.selected = htr.DisplayObject; } } } } #endregion }
/// <summary> /// Generates the xySegments into segments and inputs them into the input road network /// </summary> /// <param name="arn"></param> /// <returns></returns> public ArbiterRoadNetwork GenerateSegments(ArbiterRoadNetwork arn) { foreach (SimpleSegment ss in segments) { // seg ArbiterSegmentId asi = new ArbiterSegmentId(int.Parse(ss.Id)); ArbiterSegment asg = new ArbiterSegment(asi); arn.ArbiterSegments.Add(asi, asg); asg.RoadNetwork = arn; asg.SpeedLimits = new ArbiterSpeedLimit(); asg.SpeedLimits.MaximumSpeed = 13.4112; // 30mph max speed // way1 ArbiterWayId awi1 = new ArbiterWayId(1, asi); ArbiterWay aw1 = new ArbiterWay(awi1); aw1.Segment = asg; asg.Ways.Add(awi1, aw1); asg.Way1 = aw1; // way2 ArbiterWayId awi2 = new ArbiterWayId(2, asi); ArbiterWay aw2 = new ArbiterWay(awi2); aw2.Segment = asg; asg.Ways.Add(awi2, aw2); asg.Way2 = aw2; // make lanes foreach (SimpleLane sl in ss.Lanes) { // lane ArbiterLaneId ali; ArbiterLane al; // get way of lane id if (ss.Way1Lanes.Contains(sl)) { ali = new ArbiterLaneId(GenerationTools.GetId(sl.Id)[1], awi1); al = new ArbiterLane(ali); aw1.Lanes.Add(ali, al); al.Way = aw1; } else { ali = new ArbiterLaneId(GenerationTools.GetId(sl.Id)[1], awi2); al = new ArbiterLane(ali); aw2.Lanes.Add(ali, al); al.Way = aw2; } // add to display arn.DisplayObjects.Add(al); // width al.Width = sl.LaneWidth == 0 ? TahoeParams.T * 2.0 : sl.LaneWidth * 0.3048; if(sl.LaneWidth == 0) Console.WriteLine("lane: " + ali.ToString() + " contains no lane width, setting to 4m"); // lane boundaries al.BoundaryLeft = this.GenerateLaneBoundary(sl.LeftBound); al.BoundaryRight = this.GenerateLaneBoundary(sl.RightBound); // add lane to seg asg.Lanes.Add(ali, al); // waypoints List<ArbiterWaypoint> waypointList = new List<ArbiterWaypoint>(); // generate waypoints foreach (SimpleWaypoint sw in sl.Waypoints) { // waypoint ArbiterWaypointId awi = new ArbiterWaypointId(GenerationTools.GetId(sw.ID)[2], ali); ArbiterWaypoint aw = new ArbiterWaypoint(sw.Position, awi); aw.Lane = al; // stop if (sl.Stops.Contains(sw.ID)) { aw.IsStop = true; } // checkpoint foreach (SimpleCheckpoint sc in sl.Checkpoints) { if (sw.ID == sc.WaypointId) { aw.IsCheckpoint = true; aw.CheckpointId = int.Parse(sc.CheckpointId); arn.Checkpoints.Add(aw.CheckpointId, aw); } } // add asg.Waypoints.Add(awi, aw); arn.ArbiterWaypoints.Add(awi, aw); al.Waypoints.Add(awi, aw); waypointList.Add(aw); arn.DisplayObjects.Add(aw); arn.LegacyWaypointLookup.Add(sw.ID, aw); } al.WaypointList = waypointList; // lane partitions List<ArbiterLanePartition> alps = new List<ArbiterLanePartition>(); al.Partitions = alps; // generate lane partitions for (int i = 0; i < waypointList.Count-1; i++) { // create lane partition ArbiterLanePartitionId alpi = new ArbiterLanePartitionId(waypointList[i].WaypointId, waypointList[i + 1].WaypointId, ali); ArbiterLanePartition alp = new ArbiterLanePartition(alpi, waypointList[i], waypointList[i+1], asg); alp.Lane = al; waypointList[i].NextPartition = alp; waypointList[i + 1].PreviousPartition = alp; alps.Add(alp); arn.DisplayObjects.Add(alp); // crete initial user partition ArbiterUserPartitionId aupi = new ArbiterUserPartitionId(alp.PartitionId, waypointList[i].WaypointId, waypointList[i + 1].WaypointId); ArbiterUserPartition aup = new ArbiterUserPartition(aupi, alp, waypointList[i], waypointList[i + 1]); List<ArbiterUserPartition> aups = new List<ArbiterUserPartition>(); aups.Add(aup); alp.UserPartitions = aups; alp.SetDefaultSparsePolygon(); arn.DisplayObjects.Add(aup); } // path segments of lane List<IPathSegment> ips = new List<IPathSegment>(); List<Coordinates> pathSegments = new List<Coordinates>(); pathSegments.Add(alps[0].Initial.Position); // loop foreach(ArbiterLanePartition alPar in alps) { ips.Add(new LinePathSegment(alPar.Initial.Position, alPar.Final.Position)); // make new segment pathSegments.Add(alPar.Final.Position); } // generate lane partition path LinePath partitionPath = new LinePath(pathSegments); al.SetLanePath(partitionPath); al.PartitionPath = new Path(ips, CoordinateMode.AbsoluteProjected); // safeto zones foreach (ArbiterWaypoint aw in al.Waypoints.Values) { if(aw.IsStop) { LinePath.PointOnPath end = al.GetClosestPoint(aw.Position); double dist = -30; LinePath.PointOnPath begin = al.LanePath().AdvancePoint(end, ref dist); if (dist != 0) { begin = al.LanePath().StartPoint; } ArbiterSafetyZone asz = new ArbiterSafetyZone(al, end, begin); asz.isExit = true; asz.Exit = aw; al.SafetyZones.Add(asz); arn.DisplayObjects.Add(asz); arn.ArbiterSafetyZones.Add(asz); } } } } return arn; }
private void ShiftNetworkOkButton_Click(object sender, EventArgs e) { try { double east = double.Parse(this.ShiftNetworkEastTextBox.Text); double north = double.Parse(this.ShiftNetworkNorthTextBox.Text); Coordinates shift = new Coordinates(east, north); foreach (IArbiterWaypoint iaw in roads.ArbiterWaypoints.Values) { iaw.Position = iaw.Position + shift; } // safety zone filter DisplayObjectFilter f = delegate(IDisplayObject target) { // check if target is network object if (target is ArbiterSafetyZone) return true; else return false; }; // remove safety zones display.RemoveDisplayObjectType(f); // new safety roads.ArbiterSafetyZones = new List<ArbiterSafetyZone>(); // remove from network List<IDisplayObject> displayObjects = new List<IDisplayObject>(); foreach (IDisplayObject ido in roads.DisplayObjects) { if (!f(ido)) displayObjects.Add(ido); } // remove lane safety zones, create new partition paths foreach (ArbiterSegment asg in roads.ArbiterSegments.Values) { foreach (ArbiterLane al in asg.Lanes.Values) { al.SafetyZones = new List<ArbiterSafetyZone>(); // path segments of lane List<IPathSegment> pathSegments = new List<IPathSegment>(); // loop foreach (ArbiterLanePartition alPar in al.Partitions) { // make new segment pathSegments.Add(new LinePathSegment(alPar.Initial.Position, alPar.Final.Position)); } // generate lane partition path Path partitionPath = new Path(pathSegments); al.PartitionPath = partitionPath; } } // recreate safety zones foreach (IArbiterWaypoint iaw in roads.ArbiterWaypoints.Values) { if (iaw is ArbiterWaypoint) { ArbiterWaypoint aw = (ArbiterWaypoint)iaw; if (aw.IsStop) { ArbiterLane al = aw.Lane; LinePath.PointOnPath end = al.GetClosestPoint(aw.Position); double dist = -30; LinePath.PointOnPath begin = al.LanePath().AdvancePoint(end, ref dist); if (dist != 0) { EditorOutput.WriteLine(aw.ToString() + " safety zone too close to start of lane, setting start to start of lane"); begin = al.LanePath().StartPoint; } ArbiterSafetyZone asz = new ArbiterSafetyZone(al, end, begin); asz.isExit = true; asz.Exit = aw; al.SafetyZones.Add(asz); roads.DisplayObjects.Add(asz); roads.ArbiterSafetyZones.Add(asz); display.AddDisplayObject(asz); } } } // redraw this.display.Invalidate(); // notify EditorOutput.WriteLine("Shifted road network: east: " + east.ToString("F6") + ", north: " + north.ToString("F6")); EditorOutput.WriteLine("Recomputed position-dependent types"); // close form this.Close(); } catch (Exception ex) { EditorOutput.WriteLine("Shift of road network failed: \n" + ex.ToString()); } }