コード例 #1
0
        public IEnumerable <ICoordinateOperationCrsPathInfo> Generate(EpsgCrs from, EpsgCrs to)
        {
            Contract.Requires(from != null);
            Contract.Requires(to != null);
            Contract.Ensures(Contract.Result <IEnumerable <ICoordinateOperationCrsPathInfo> >() != null);

            if (from.Kind == EpsgCrsKind.Compound || from.Kind == EpsgCrsKind.Engineering || from.Kind == EpsgCrsKind.Vertical)
            {
                throw new NotImplementedException(String.Format("Support for the from CRS kind {0} is not yet implemented.", from.Kind));
            }
            if (to.Kind == EpsgCrsKind.Compound || to.Kind == EpsgCrsKind.Engineering || to.Kind == EpsgCrsKind.Vertical)
            {
                throw new NotImplementedException(String.Format("Support for the to CRS kind {0} is not yet implemented.", to.Kind));
            }
            if (from.Code == to.Code)
            {
                throw new NotImplementedException("Empty conversion not yet handled.");
            }

            var startNode = new EpsgCrsPathSearchNode(from);

            Contract.Assume(to is EpsgCrsGeodetic);

            var searchRestrictions = new SearchOptions {
                SourceArea = from.Area,
                TargetArea = to.Area
            };

            var corePaths = FindAllCorePaths(startNode, (EpsgCrsGeodetic)to, searchRestrictions);

            return(corePaths.Select(node => node.BuildCoordinateOperationCrsPathInfo()));
        }
コード例 #2
0
        private IEnumerable <EpsgCrsPathSearchNode> FindAllCorePaths(EpsgCrsPathSearchNode fromNode, EpsgCrsGeodetic toCrs, SearchOptions searchOptions)
        {
            Contract.Requires(fromNode != null);
            Contract.Requires(fromNode.Crs is EpsgCrsGeodetic);
            Contract.Requires(toCrs != null);

            var earlyResults = new List <EpsgCrsPathSearchNode>();
            var fromCrs      = (EpsgCrsGeodetic)fromNode.Crs;

            // construct the hierarchy based on the from CRS
            var fromStack = new List <EpsgCrsPathSearchNode>();
            var fromStackConstructionNode = fromNode;

            do
            {
                fromStack.Add(fromStackConstructionNode);
                var currentCrs = (EpsgCrsGeodetic)fromStackConstructionNode.Crs;
                if (!currentCrs.HasBaseOperation)
                {
                    break;
                }

                var baseCrs      = currentCrs.BaseCrs;
                var fromBaseEdge = currentCrs.GetBaseOperation();
                Contract.Assume(baseCrs != null);
                Contract.Assume(fromBaseEdge != null);

                if (!fromBaseEdge.HasInverse)
                {
                    break; // we have to invert the edge to traverse up the stack
                }
                var toBaseEdge = fromBaseEdge.GetInverse();
                fromStackConstructionNode = new EpsgCrsPathSearchNode(baseCrs, toBaseEdge, fromStackConstructionNode);
            } while (true /*fromStackSearchNode != null*/);

            // construct the hierarchy based on the to CRS
            var toStack = new List <GeodeticCrsStackItem>();
            var toStackConstructionCrs = toCrs;

            do
            {
                toStack.Add(new GeodeticCrsStackItem {
                    Crs = toStackConstructionCrs
                });
                toStackConstructionCrs = toStackConstructionCrs.BaseCrs;
            } while (toStackConstructionCrs != null);

            var lowestStackIntersection = FindLowestStackIntersection(fromStack, toStack);

            if (lowestStackIntersection != null)
            {
                earlyResults.Add(lowestStackIntersection);
            }

            var directResults   = FindDirectTransformations(fromStack, toStack, searchOptions);
            var indirectResults = FindIndirectTransformations(fromStack, toStack, searchOptions);

            return(earlyResults.Concat(directResults).Concat(indirectResults));
        }
コード例 #3
0
 public EpsgCrsPathSearchNode(EpsgCrs crs, ICoordinateOperationInfo edgeFromParent, EpsgCrsPathSearchNode parent)
 {
     Contract.Requires(crs != null);
     Contract.Requires(edgeFromParent != null);
     Contract.Requires(parent != null);
     Crs            = crs;
     EdgeFromParent = edgeFromParent;
     Parent         = parent;
 }
コード例 #4
0
        private EpsgCrsPathSearchNode AppendBacktrackingToStack(EpsgCrsPathSearchNode fromNode, List <GeodeticCrsStackItem> toStack, int startIndex)
        {
            var node = fromNode;

            for (int backtrackIndex = startIndex; backtrackIndex >= 0; backtrackIndex--)
            {
                var crs = toStack[backtrackIndex].Crs;
                Contract.Assume(crs.HasBaseOperation);
                var edge = crs.GetBaseOperation();
                node = new EpsgCrsPathSearchNode(crs, edge, node);
            }
            return(node);
        }
コード例 #5
0
        private IEnumerable <OperationNodeCandidate> CreateNodeCandidates(IEnumerable <ushort> forwardOperationCodes, IEnumerable <ushort> inverseOperationCodes, EpsgCrs targetCrs, EpsgCrsPathSearchNode parentNode)
        {
            IEnumerable <OperationNodeCandidate> nodeCandidates = null;

            if (forwardOperationCodes != null)
            {
                Contract.Assume(nodeCandidates == null);
                nodeCandidates = CreateForwardNodeCandidates(forwardOperationCodes, targetCrs, parentNode);
            }
            if (inverseOperationCodes != null)
            {
                var inverseOpNodes = CreateInverseNodeCandidates(inverseOperationCodes, targetCrs, parentNode);
                nodeCandidates = nodeCandidates == null ? inverseOpNodes : nodeCandidates.Concat(inverseOpNodes);
            }
            if (nodeCandidates == null)
            {
                return(Enumerable.Empty <OperationNodeCandidate>());
            }

            return(nodeCandidates
                   .OrderBy(x => x.CoreOp.Deprecated)
                   .ThenByDescending(x => x.Accuracy.HasValue)
                   .ThenBy(x => x.Accuracy.GetValueOrDefault()));
        }
コード例 #6
0
 private IEnumerable <OperationNodeCandidate> CreateInverseNodeCandidates(IEnumerable <ushort> inverseOperationCodes, EpsgCrs targetCrs, EpsgCrsPathSearchNode parentNode)
 {
     Contract.Requires(inverseOperationCodes != null);
     Contract.Ensures(Contract.Result <IEnumerable <OperationNodeCandidate> >() != null);
     return(inverseOperationCodes
            .Select(code => EpsgMicroDatabase.Default.GetCoordinateTransformOrConcatenatedInfo(code))
            .Where(op => op != null && op.HasInverse)
            .Select(op => new OperationNodeCandidate {
         CoreOp = op,
         Accuracy = op.Accuracy,
         Node = new EpsgCrsPathSearchNode(targetCrs, op.GetInverse(), parentNode)
     }));
 }