private IEnumerable <EpsgCrsPathSearchNode> FindDirectTransformations(List <EpsgCrsPathSearchNode> fromStack, List <GeodeticCrsStackItem> toStack, SearchOptions searchOptions) { // TODO: make sure that operations respect the area of from & to var results = new List <EpsgCrsPathSearchNode>(); // TODO: Consider changing this to yield return foreach (var fromNode in fromStack) { var fromOpCodesForward = fromNode.GetFromOps(); var fromOpCodesInverse = fromNode.GetToOps(); if (fromOpCodesForward == null && fromOpCodesInverse == null) { continue; } for (int toCrsIndex = 0; toCrsIndex < toStack.Count; toCrsIndex++) { var toData = toStack[toCrsIndex]; var toOpCodesForward = toData.GetToOps(); var toOpCodesInverse = toData.GetFromOps(); if (toOpCodesForward == null && toOpCodesInverse == null) { continue; } var forwardIntersection = fromOpCodesForward == null || toOpCodesForward == null ? null : fromOpCodesForward.Intersect(toOpCodesForward); var inverseIntersection = fromOpCodesInverse == null || toOpCodesInverse == null ? null : fromOpCodesInverse.Intersect(toOpCodesInverse); foreach (var candidate in CreateNodeCandidates(forwardIntersection, inverseIntersection, toData.Crs, fromNode)) { var candidateOp = candidate.CoreOp; if (candidateOp.Area != null && !searchOptions.IntersectsAll(candidateOp.Area)) { continue; } var fullPath = AppendBacktrackingToStack(candidate.Node, toStack, toCrsIndex - 1); results.Add(fullPath); } } } return(results); }