public FiberCableCommandHandler(IAggregateRepository aggregateRepository, IRouteNetworkState routeNetworkQueryService, IConduitNetworkQueryService conduitNetworkQueryService, IFiberNetworkQueryService fiberNetworkQueryService) { this.repo = aggregateRepository; this.conduitNetworkQueryService = conduitNetworkQueryService; this.routeNetworkQueryService = routeNetworkQueryService; this.fiberNetworkQueryService = fiberNetworkQueryService; }
public FiberCableInfoProjection(IRouteNetworkState routeNetworkQueryService, IFiberNetworkQueryService fiberNetworkQueryService) { this.routeNetworkQueryService = routeNetworkQueryService; this.fiberNetworkQueryService = (FiberNetworkQueryService)fiberNetworkQueryService; ProjectEvent <FiberCablePlaced>(OnFiberCablePlaced); }
public DemoNetwork(IHostingEnvironment env, IDocumentStore documentStore, IMediator commandBus, IConduitClosureRepository conduitClosureRepository, IRouteNetworkState routeNetwork, IConduitNetworkQueryService conduitNetwork, IFiberNetworkQueryService fiberNetworkQueryService) { Description = "API for invoking the demo/test data builder"; Field <StringGraphType>( "rebuild", description: "Deletes the database and rebuild the demo data from the GeoJson files created using QGIS", resolve: context => { try { // First delete everything in the database documentStore.Advanced.Clean.CompletelyRemoveAll(); // Clean everything in projected in-memory read models routeNetwork.Clean(); conduitNetwork.Clean(); conduitClosureRepository.Clean(); fiberNetworkQueryService.Clean(); var iisExpressFolder = AppDomain.CurrentDomain.BaseDirectory; var pathToData = env.ContentRootPath; if (iisExpressFolder.Contains("Debug\\netcoreapp")) { pathToData = iisExpressFolder; } pathToData += Path.DirectorySeparatorChar.ToString() + "Data" + Path.DirectorySeparatorChar.ToString(); // Rebuild demo data RouteNetworkBuilder.Run(pathToData, commandBus); ConduitBuilder.Run(conduitNetwork, commandBus); EquipmentBuilder.Run(routeNetwork, conduitNetwork, commandBus); // Reload everything again routeNetwork.Clean(); conduitNetwork.Clean(); conduitClosureRepository.Clean(); fiberNetworkQueryService.Clean(); return("Read models cleaned and test data was rebuilt."); } catch (Exception ex) { context.Errors.Add(new ExecutionError(ex.Message, ex)); return("Failed"); } } ); }
public Diagram Build(Guid nodeId, IRouteNetworkState routeNetworkQueryService, IConduitNetworkQueryService conduitNetworkEqueryService, IFiberNetworkQueryService fiberNetworkService, IConduitClosureRepository conduitClosureRepository) { _routeNetworkQueryService = routeNetworkQueryService; _conduitNetworkQueryService = conduitNetworkEqueryService; _traversalHelper = new TraversalHelper(_routeNetworkQueryService); DiagramBuilder builder = new DiagramBuilder(); double minWidth = 300; double offsetY = 0; ConduitClosureInfo conduitClosureInfo = null; if (conduitClosureRepository.CheckIfRouteNodeContainsConduitClosure(nodeId)) { conduitClosureInfo = conduitClosureRepository.GetConduitClosureInfoByRouteNodeId(nodeId); } // Add cables passing through var cableSegmentRels = fiberNetworkService.GetLineSegmentsRelatedToPointOfInterest(nodeId); offsetY += AddCablePassThroughBlock(builder, cableSegmentRels, offsetY, 300); // Add multi conduit passing through var conduitSegmentRels = conduitNetworkEqueryService.GetConduitSegmentsRelatedToPointOfInterest(nodeId); foreach (var conduitSegmentRel in conduitSegmentRels) { // pass by multi conduit if (conduitSegmentRel.RelationType == SegmentRelationTypeEnum.PassThrough && conduitSegmentRel.Segment.Line.LineKind == LineKindEnum.MultiConduit) { // check if outside conduit closure if (conduitClosureInfo != null && conduitClosureInfo.Sides.Exists(s => s.Ports.Exists(p => p.MultiConduitId == conduitSegmentRel.Segment.Line.Id))) { } else { offsetY += AddMultiConduitPassThroughBlock(builder, (ConduitSegmentInfo)conduitSegmentRel.Segment, minWidth, offsetY); } } } // Add conduit closure offsetY += 20; if (conduitClosureInfo != null) { offsetY += AddConduitClosureBlock(builder, conduitClosureInfo, minWidth, offsetY); } Diagram diagram = builder.CreateDiagram(); return(diagram); LineBlock junctionBlock = new LineBlock(30, 0); junctionBlock.MinWidth = 300; // Add first vest port with 5 terminal AddMultiConduitPort(junctionBlock, BlockSideEnum.Vest, 10, "Orange"); // Add second vest port with 7 terminal AddMultiConduitPort(junctionBlock, BlockSideEnum.Vest, 7, "Orange"); // Add fist east port with 10 terminal AddMultiConduitPort(junctionBlock, BlockSideEnum.East, 10, "Orange"); // Add second east port with 7 terminal AddMultiConduitPort(junctionBlock, BlockSideEnum.East, 7, "Orange"); // Add north big conduit port 1 with 3 terminal AddBigConduitPort(junctionBlock, BlockSideEnum.North, 3, "Red"); // Add north big conduit port 2 with 5 terminal AddBigConduitPort(junctionBlock, BlockSideEnum.North, 5, "Red"); junctionBlock.AddTerminalConnection(BlockSideEnum.Vest, 1, 1, BlockSideEnum.East, 1, 1, null, "InnerConduitBlue", LineShapeTypeEnum.Polygon); junctionBlock.AddTerminalConnection(BlockSideEnum.Vest, 1, 2, BlockSideEnum.North, 1, 1, null, "InnerConduitBlue", LineShapeTypeEnum.Polygon); /* * * // Feeder calbe from central office * junctionBlock.AddConnection(BlockSideEnum.Vest, 2, 5, BlockSideEnum.North, 1, 1, "192", "CableInsideWell"); * * // Transit feeder cable to other flex points * junctionBlock.AddConnection(BlockSideEnum.Vest, 1, 4, BlockSideEnum.North, 1, 2, "96", "CableInsideWell"); * junctionBlock.AddConnection(BlockSideEnum.East, 1, 10, BlockSideEnum.North, 1, 3, "96", "CableInsideWell"); * * // Sp connections * junctionBlock.AddConnection(BlockSideEnum.East, 1, 1, BlockSideEnum.North, 2, 2, "24", "CableInsideWell"); * junctionBlock.AddConnection(BlockSideEnum.East, 1, 2, BlockSideEnum.North, 2, 3, "48", "CableInsideWell"); * junctionBlock.AddConnection(BlockSideEnum.East, 1, 3, BlockSideEnum.North, 2, 4, "48", "CableInsideWell"); * junctionBlock.AddConnection(BlockSideEnum.East, 1, 4, BlockSideEnum.North, 2, 5, "48", "CableInsideWell"); * junctionBlock.AddConnection(BlockSideEnum.Vest, 2, 2, BlockSideEnum.North, 2, 1, "48", "CableInsideWell"); * */ builder.ContentObjects.Add(junctionBlock); junctionBlock.Measure(new Layout.Size()); ////////////////////////////////////////////////////////// /// well north label block LineBlock wellNorthLabelBlock = new LineBlock(30, junctionBlock.DesiredSize.Height, LineBlockTypeEnum.Simple); wellNorthLabelBlock.MinHeight = 30; // Add north port with 3 terminal AddBigConduitPort(wellNorthLabelBlock, BlockSideEnum.North, 3); // Add north port with 5 terminal AddBigConduitPort(wellNorthLabelBlock, BlockSideEnum.North, 5); // Add south port with 3 terminal AddBigConduitPort(wellNorthLabelBlock, BlockSideEnum.South, 3); // Add south port with 5 terminal AddBigConduitPort(wellNorthLabelBlock, BlockSideEnum.South, 5); wellNorthLabelBlock.AddTerminalConnection(BlockSideEnum.North, 1, 1, BlockSideEnum.South, 1, 1, "GSS 1 (1-16)", "CableOutsideWell"); wellNorthLabelBlock.AddTerminalConnection(BlockSideEnum.North, 1, 2, BlockSideEnum.South, 1, 2, "GSS 1 (1-8)", "CableOutsideWell"); wellNorthLabelBlock.AddTerminalConnection(BlockSideEnum.North, 1, 3, BlockSideEnum.South, 1, 3, "GSS 1 (9-16)", "CableOutsideWell"); wellNorthLabelBlock.AddTerminalConnection(BlockSideEnum.North, 2, 1, BlockSideEnum.South, 2, 1, "GPS 1", "CableOutsideWell"); wellNorthLabelBlock.AddTerminalConnection(BlockSideEnum.North, 2, 2, BlockSideEnum.South, 2, 2, "GPS 1", "CableOutsideWell"); wellNorthLabelBlock.AddTerminalConnection(BlockSideEnum.North, 2, 3, BlockSideEnum.South, 2, 3, "GPS 2", "CableOutsideWell"); wellNorthLabelBlock.AddTerminalConnection(BlockSideEnum.North, 2, 4, BlockSideEnum.South, 2, 4, "GPS 2", "CableOutsideWell"); wellNorthLabelBlock.AddTerminalConnection(BlockSideEnum.North, 2, 5, BlockSideEnum.South, 2, 5, "GPS 2 & 3", "CableOutsideWell"); builder.ContentObjects.Add(wellNorthLabelBlock); wellNorthLabelBlock.Measure(new Layout.Size()); ////////////////////////////////////////////////////////// /// well vest label block LineBlock wellVestLabelBlock = new LineBlock(0, 0, LineBlockTypeEnum.Simple); wellVestLabelBlock.MinWidth = 30; // Add vest port with 5 terminal AddBigConduitPort(wellVestLabelBlock, BlockSideEnum.Vest, 5); // Add vest port with 7 terminal AddBigConduitPort(wellVestLabelBlock, BlockSideEnum.Vest, 7); // Add east port with 5 terminal AddBigConduitPort(wellVestLabelBlock, BlockSideEnum.East, 5); // Add east port with 7 terminal AddBigConduitPort(wellVestLabelBlock, BlockSideEnum.East, 7); wellVestLabelBlock.AddTerminalConnection(BlockSideEnum.Vest, 1, 4, BlockSideEnum.East, 1, 4, "PF-4200", "CableOutsideWell"); wellVestLabelBlock.AddTerminalConnection(BlockSideEnum.Vest, 2, 2, BlockSideEnum.East, 2, 2, "SP-5420", "CableOutsideWell"); wellVestLabelBlock.AddTerminalConnection(BlockSideEnum.Vest, 2, 5, BlockSideEnum.East, 2, 5, "CO-1010", "CableOutsideWell"); wellVestLabelBlock.Measure(new Layout.Size()); builder.ContentObjects.Add(wellVestLabelBlock); ////////////////////////////////////////////////////////// /// east label block LineBlock wellEastLabelBlock = new LineBlock(junctionBlock.DesiredSize.Width + 30, 0, LineBlockTypeEnum.Simple); wellEastLabelBlock.MinWidth = 30; wellEastLabelBlock.MinHeight = junctionBlock.DesiredSize.Height; // Add vest port with 10 terminal AddBigConduitPort(wellEastLabelBlock, BlockSideEnum.Vest, 10); // Add east port with 10 terminal AddBigConduitPort(wellEastLabelBlock, BlockSideEnum.East, 10); wellEastLabelBlock.AddTerminalConnection(BlockSideEnum.Vest, 1, 1, BlockSideEnum.East, 1, 1, "SP-5010", "CableOutsideWell"); wellEastLabelBlock.AddTerminalConnection(BlockSideEnum.Vest, 1, 2, BlockSideEnum.East, 1, 2, "SP-5011", "CableOutsideWell"); wellEastLabelBlock.AddTerminalConnection(BlockSideEnum.Vest, 1, 3, BlockSideEnum.East, 1, 3, "SP-5013", "CableOutsideWell"); wellEastLabelBlock.AddTerminalConnection(BlockSideEnum.Vest, 1, 4, BlockSideEnum.East, 1, 4, "SP-6002", "CableOutsideWell"); wellEastLabelBlock.AddTerminalConnection(BlockSideEnum.Vest, 1, 10, BlockSideEnum.East, 1, 10, "FP-4203", "CableOutsideWell"); wellEastLabelBlock.Measure(new Layout.Size()); builder.ContentObjects.Add(wellEastLabelBlock); ////////////////////////////////////////////////////////// /// well north corner 1 LineBlock wellNorthCorner1 = new LineBlock(30, junctionBlock.DesiredSize.Height + wellNorthLabelBlock.DesiredSize.Height, LineBlockTypeEnum.Simple); wellNorthCorner1.MinHeight = 20; // Add south port with 3 terminal AddBigConduitPort(wellNorthCorner1, BlockSideEnum.South, 3); // Add east port with 3 terminal AddBigConduitPort(wellNorthCorner1, BlockSideEnum.East, 3, null, 1, 1); wellNorthCorner1.AddTerminalConnection(BlockSideEnum.South, 1, 1, BlockSideEnum.East, 1, 1, "", "CableOutsideWell"); wellNorthCorner1.AddTerminalConnection(BlockSideEnum.South, 1, 2, BlockSideEnum.East, 1, 2, "", "CableOutsideWell"); wellNorthCorner1.AddTerminalConnection(BlockSideEnum.South, 1, 3, BlockSideEnum.East, 1, 3, "", "CableOutsideWell"); // Set margin on east side to 0 wellNorthCorner1.SetSideMargin(BlockSideEnum.East, 0); //builder.ContentObjects.Add(wellNorthCorner1); Diagram sdiagram = builder.CreateDiagram(); return(diagram); }
public DiagramServiceQuery(IRouteNetworkState routeNetworkQueryService, IConduitNetworkQueryService conduitNetworkEqueryService, IConduitClosureRepository conduitClosureRepository, IFiberNetworkQueryService fiberNetworkService, IDataLoaderContextAccessor dataLoader) { Description = "GraphQL API for generating fiber equiment diagrams."; Field <DiagramType>( "buildRouteNodeDiagram", arguments: new QueryArguments( new QueryArgument <NonNullGraphType <IdGraphType> > { Name = "routeNodeId" }, new QueryArgument <StringGraphType> { Name = "exportGeojsonFileName" } ), resolve: context => { var routeNodeId = context.GetArgument <Guid>("routeNodeId"); var jsonFilename = context.GetArgument <string>("exportGeojsonFileName"); var diagram = new ConduitClosureBuilder().Build(routeNodeId, routeNetworkQueryService, conduitNetworkEqueryService, fiberNetworkService, conduitClosureRepository); if (jsonFilename != null) { var export = new GeoJsonExporter(diagram); export.Export(jsonFilename); } return(diagram); } ); }
internal void ConnectFiber(Guid pointOfInterestId, int fiberSequenceNumber /*, ConduitEndKindEnum endKind */, Guid junctionId, IRouteNetworkState routeNetworkQueryService, IFiberNetworkQueryService fiberNetworkQueryService) { // Point of interest id check if (pointOfInterestId == null || pointOfInterestId == Guid.Empty) { throw new ArgumentException("PointOfInterestId cannot be null or empty"); } /* * // endKind check * if (endKind == 0) * throw new ArgumentException("End kind must be specified. Otherwise the system don't know with end of the segment to connect, if a conduit has been cut into two pieces in a node."); * * * var multiConduitInfo = conduitNetworkQueryService.GetMultiConduitInfo(Id); * * // Inner conduit number check * if (!multiConduitInfo.Children.OfType<ConduitInfo>().Any(i => i.SequenceNumber == sequenceNumber)) * throw new ArgumentException("Cannot find inner conduit number: " + sequenceNumber + " in multi conduit: " + Id); * * var singleConduitInfo = conduitNetworkQueryService.GetSingleConduitInfo(multiConduitInfo.Children.OfType<ConduitInfo>().Single(i => i.SequenceNumber == sequenceNumber).Id); * * if (!singleConduitInfo.Segments.Exists(s => s.FromRouteNodeId == pointOfInterestId || s.ToRouteNodeId == pointOfInterestId)) * throw new ArgumentException("Inner conduit number: " + sequenceNumber + " in multi conduit: " + Id + " is not cut at: " + pointOfInterestId); * * // Check that conduit is connected at a node part of conduit walk of interest * var walkOfInterest = routeNetworkQueryService.GetWalkOfInterestInfo(multiConduitInfo.WalkOfInterestId); * * if (!walkOfInterest.AllNodeIds.Contains(pointOfInterestId)) * throw new ArgumentException("The point of interest: " + pointOfInterestId + " was not found in walk of interest:" + multiConduitInfo.WalkOfInterestId + " of multi conduit: " + Id); * * // Check incomming * if (endKind == ConduitEndKindEnum.Incomming && !multiConduitInfo.Segments.Exists(s => s.ToRouteNodeId == pointOfInterestId)) * throw new ArgumentException("No segments are incomming to point of interest: " + pointOfInterestId + " in multi conduit: " + Id); * * // Check outgoing * if (endKind == ConduitEndKindEnum.Outgoing && !multiConduitInfo.Segments.Exists(s => s.FromRouteNodeId == pointOfInterestId)) * throw new ArgumentException("No segments are outgoing from point of interest: " + pointOfInterestId + " in multi conduit: " + Id); * * ILineSegment connectingSegment = null; * * // Check incomming inner conduit * if (endKind == ConduitEndKindEnum.Incomming) * { * if (!singleConduitInfo.Segments.Exists(s => s.ToRouteNodeId == pointOfInterestId)) * throw new ArgumentException("No inner conduit segments are incomming to point of interest: " + pointOfInterestId + " in single conduit: " + Id); * * connectingSegment = singleConduitInfo.Segments.Find(s => s.ToRouteNodeId == pointOfInterestId); * * // Check if already connect to a junction * if (connectingSegment.ToNodeId != Guid.Empty) * throw new ArgumentException("the incomming inner conduit segment: " + connectingSegment.Id + " is already connected to a junction: " + connectingSegment.ToNodeId); * } * // Check outgoing inner conduit * else * { * if (!singleConduitInfo.Segments.Exists(s => s.FromRouteNodeId == pointOfInterestId)) * throw new ArgumentException("No inner conduit segments are outgoing from point of interest: " + pointOfInterestId + " in single conduit: " + Id); * * connectingSegment = singleConduitInfo.Segments.Find(s => s.FromRouteNodeId == pointOfInterestId); * * // Check if already connect to a junction * if (connectingSegment.FromNodeId != Guid.Empty) * throw new ArgumentException("the outgoing inner conduit segment: " + connectingSegment.Id + " is already connected to a junction: " + connectingSegment.FromNodeId); * } * * * RaiseEvent(new MultiConduitInnerConduitConnected * { * MultiConduitId = Id, * PointOfInterestId = pointOfInterestId, * InnerConduitSequenceNumber = sequenceNumber, * ConnectedEndKind = endKind, * ConnectedJunctionId = junctionId * }); * */ }
public FiberCable(Guid fiberCableId, Guid walkOfInterestId, int numberOfFiber, string name, IFiberNetworkQueryService fiberNetworkQueryService) : this() { // Id check if (fiberCableId == null || fiberCableId == Guid.Empty) { throw new ArgumentException("Id cannot be null or empty"); } // Walk of interest id check if (walkOfInterestId == null || walkOfInterestId == Guid.Empty) { throw new ArgumentException("WalkOfInterestId cannot be null or empty"); } // Check that not already exists if (fiberNetworkQueryService.CheckIfFiberCableIdExists(fiberCableId)) { throw new ArgumentException("A fiber cable with id: " + fiberCableId + " already exists"); } var fiberCablePlaceEvent = new FiberCablePlaced() { WalkOfInterestId = walkOfInterestId, FiberCableId = fiberCableId, NumberOfFibers = numberOfFiber, }; RaiseEvent(fiberCablePlaceEvent); }
public RouteNodeType(IRouteNetworkState routeNetworkQueryService, IConduitNetworkQueryService conduitNetworkEqueryService, IFiberNetworkQueryService fiberNetworkQueryService, IConduitClosureRepository conduitClosureRepository, IDataLoaderContextAccessor dataLoader, IHttpContextAccessor httpContextAccessor) { this.routeNetworkQueryService = routeNetworkQueryService; this.conduitNetworkEqueryService = conduitNetworkEqueryService; this.conduitClosureRepository = conduitClosureRepository; Description = "A route node in a route network."; // Interface fields Interface <NodeInterface>(); Field(x => x.Id, type: typeof(IdGraphType)).Description("Guid property"); Field(x => x.Name, type: typeof(IdGraphType)).Description("Name of node managed by the utility"); // Additional fields Field <RouteNodeKindEnumType>("NodeKind", "Kind of node"); Field <RouteNodeFunctionKindEnumType>("NodeFunctionKind", "Function that the node do/provides"); Field <GeometryType>( "geometry", resolve: context => { return(new Geometry(context.Source.Geometry.GeoJsonType, context.Source.Geometry.GeoJsonCoordinates)); }); Field <LocationInfoType>( "locationInfo", resolve: context => { return(context.Source.LocationInfo); }); Field <ListGraphType <ConduitRelationType> >( "relatedConduits", arguments: new QueryArguments( new QueryArgument <BooleanGraphType> { Name = "includeMultiConduits" }, new QueryArgument <BooleanGraphType> { Name = "includeSingleConduits" }, new QueryArgument <BooleanGraphType> { Name = "includeInnerConduits" }, new QueryArgument <StringGraphType> { Name = "conduitSegmentId", Description = "Will be deleted. Use conduit id instead" }, new QueryArgument <StringGraphType> { Name = "conduitId", Description = "Id of conduit of conduit segment" } ), resolve: context => { var includeMultiConduits = context.GetArgument <Boolean>("includeMultiConduits", true); var includeSingleConduits = context.GetArgument <Boolean>("includeSingleConduits", true); var includeInnerConduits = context.GetArgument <Boolean>("includeInnerConduits", true); var conduitSegmentIdParam = context.GetArgument <string>("conduitSegmentId"); var conduitIdParam = context.GetArgument <string>("conduitId"); var conduitSegmentId = Guid.Empty; if (conduitSegmentIdParam != null) { if (!Guid.TryParse(conduitSegmentIdParam, out conduitSegmentId)) { context.Errors.Add(new ExecutionError("Wrong value for guid")); return(null); } } if (conduitIdParam != null) { if (!Guid.TryParse(conduitIdParam, out conduitSegmentId)) { context.Errors.Add(new ExecutionError("Wrong value for guid")); return(null); } } List <ConduitRelation> result = new List <ConduitRelation>(); var conduitSegmentRels = conduitNetworkEqueryService.GetConduitSegmentsRelatedToPointOfInterest(context.Source.Id, conduitSegmentId == Guid.Empty ? null : conduitSegmentId.ToString()); foreach (var conduitSegmentRel in conduitSegmentRels) { ConduitRelation rel = new ConduitRelation() { RelationType = Convert(conduitSegmentRel.RelationType), Conduit = ((ConduitSegmentInfo)conduitSegmentRel.Segment).Conduit, ConduitSegment = (ConduitSegmentInfo)conduitSegmentRel.Segment }; // Check if segment is related to a conduit closure { if (conduitClosureRepository.CheckIfRouteNodeContainsConduitClosure(context.Source.Id)) { var conduitClosureInfo = conduitClosureRepository.GetConduitClosureInfoByRouteNodeId(context.Source.Id); // If conduit closure contains a port or terminal related to the conduit segment, then it's related to the conduit closure if ( conduitClosureInfo.Sides.Exists(s => s.Ports.Exists(p => p.MultiConduitSegmentId == conduitSegmentRel.Segment.Id)) || conduitClosureInfo.Sides.Exists(s => s.Ports.Exists(p => p.Terminals.Exists(t => t.LineSegmentId == conduitSegmentRel.Segment.Id))) ) { rel.CanBeAttachedToConduitClosure = false; } else { rel.CanBeAttachedToConduitClosure = true; } } } // Check if segment is cut at node if (conduitSegmentRel.Segment.Line.Segments.Exists(s => s.FromRouteNodeId == context.Source.Id || s.ToRouteNodeId == context.Source.Id)) { rel.CanBeCutAtNode = false; } else { rel.CanBeCutAtNode = true; } if (includeMultiConduits && conduitSegmentRel.Segment.Line.LineKind == LineKindEnum.MultiConduit) { result.Add(rel); } if (includeInnerConduits && conduitSegmentRel.Segment.Line.LineKind == LineKindEnum.InnerConduit) { result.Add(rel); } if (includeSingleConduits && conduitSegmentRel.Segment.Line.LineKind == LineKindEnum.SingleConduit) { result.Add(rel); } } return(result); } ); Field <ConduitClosureType>( "conduitClosure", resolve: context => { if (conduitClosureRepository.CheckIfRouteNodeContainsConduitClosure(context.Source.Id)) { return(conduitClosureRepository.GetConduitClosureInfoByRouteNodeId(context.Source.Id)); } else { return(null); } }); Field <RouteNodeGraphFunctions>("graph", resolve: context => context.Source); Field <ListGraphType <SegmentInterface> >( "relatedSegments", arguments: new QueryArguments( new QueryArgument <StringGraphType> { Name = "lineId", Description = "Id of specific line og line segment to fetch" } ), resolve: context => { httpContextAccessor.HttpContext.Items.Add("routeNodeId", context.Source.Id); var lineIdParam = context.GetArgument <Guid>("lineId"); List <ISegment> result = new List <ISegment>(); var allSegments = new List <SegmentWithRouteNodeRelationInfo>(); // Add multi conduits and single conduits segments allSegments.AddRange(conduitNetworkEqueryService.GetConduitSegmentsRelatedToPointOfInterest(context.Source.Id).Where(c => c.Segment.Line.LineKind == LineKindEnum.MultiConduit || c.Segment.Line.LineKind == LineKindEnum.SingleConduit)); // Add fiber cable segments allSegments.AddRange(fiberNetworkQueryService.GetLineSegmentsRelatedToPointOfInterest(context.Source.Id).Where(c => c.Segment.Line.LineKind == LineKindEnum.FiberCable)); // Create fast lookup table to be used for parent check HashSet <Guid> segmentExistsLookup = new HashSet <Guid>(); foreach (var segmentWithRel in allSegments) { segmentExistsLookup.Add(segmentWithRel.Segment.Id); } // Iterate through all segments and decided if to return or not depending on if they are roots of the node or not foreach (var segmentWithRel in allSegments) { // Now check if the segment has a parent that is also related to the node. // If so, the segment is contained within another segment, and should not be returned as a root element to the node bool isContained = false; if (segmentWithRel.Segment.Parents != null) { foreach (var parent in segmentWithRel.Segment.Parents) { if (segmentExistsLookup.Contains(parent.Id)) { isContained = true; } } } if (!isContained) { if (lineIdParam != Guid.Empty) { if (segmentWithRel.Segment.Id == lineIdParam || segmentWithRel.Segment.Line.Id == lineIdParam) { result.Add(segmentWithRel.Segment); } } else { result.Add(segmentWithRel.Segment); } } } return(result); }); }