コード例 #1
0
ファイル: GraphBuilder.cs プロジェクト: ExRam/DotSpatial-PCL
        /// <summary>
        /// 
        /// </summary>
        /// <param name="computer">
        /// A function that computes the weight 
        /// of any <see cref="ILineString">edge</see> of the graph
        /// </param>
        /// <returns></returns>
        public DijkstraShortestPathAlgorithm<IPoint, IEdge<IPoint>> PrepareAlgorithm(ComputeWeightDelegate computer)
        {
            if (strings.Count < 2)
                throw new TopologyException("you must specify two or more geometries to build a graph");

            IMultiLineString edges = BuildEdges();

            Dictionary<IEdge<IPoint>, double> consts = new Dictionary<IEdge<IPoint>, double>(edges.NumGeometries);
            AdjacencyGraph<IPoint, IEdge<IPoint>> graph = new AdjacencyGraph<IPoint, IEdge<IPoint>>(true);
            foreach (ILineString str in edges.Geometries)
            {
                IPoint vertex1 = str.StartPoint;
                Assert.IsTrue(vertex1 != null);
                if (!graph.ContainsVertex(vertex1))
                    graph.AddVertex(vertex1);

                IPoint vertex2 = str.EndPoint;
                Assert.IsTrue(vertex2 != null);
                if (!graph.ContainsVertex(vertex2))
                    graph.AddVertex(vertex2);

                double weight = computer(str);                
                Edge<IPoint> edge = new Edge<IPoint>(vertex1, vertex2);
                Assert.IsTrue(edge != null);

                graph.AddEdge(edge);
                consts.Add(edge, weight);
            }

            // Use Dijkstra
            return new DijkstraShortestPathAlgorithm<IPoint, IEdge<IPoint>>(graph, consts);
        }
コード例 #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="computer"></param>
        private void BuildEdges(ComputeWeightDelegate computer)
        {
            if (strings.Count < 2)
            {
                throw new TopologyException("you must specify two or more geometries to build a graph");
            }

            // Counts the number of edges in the set we pass to this method.
            int numberOfEdgesInLines = 0;

            foreach (ILineString str in strings)
            {
                int edges = str.Coordinates.GetUpperBound(0);
                numberOfEdgesInLines += edges;
            }

            // Double values because we use also reversed edges...
            if (bidirectional)
            {
                numberOfEdgesInLines *= 2;
            }

            consts = new Dictionary <IEdge <Coordinate>, double>(numberOfEdgesInLines);

            foreach (ILineString line in strings)
            {
                // A line has to have at least two dimensions
                int bound = line.Coordinates.GetUpperBound(0);
                if (bound > 0)
                {
                    for (int counter = 0; counter < bound; counter++)
                    {
                        // Prepare a segment
                        Coordinate src = line.Coordinates[counter];
                        Coordinate dst = line.Coordinates[counter + 1];

                        // Here we calculate the weight of the edge
                        ILineString lineString = factory.CreateLineString(
                            new[] { src, dst, });
                        double weight = computer(lineString);

                        // Add the edge
                        IEdge <Coordinate> localEdge = new Edge <Coordinate>(src, dst);
                        graph.AddEdge(localEdge);
                        consts.Add(localEdge, weight);

                        if (!bidirectional)
                        {
                            continue;
                        }

                        // Add the reversed edge
                        IEdge <Coordinate> localEdgeRev = new Edge <Coordinate>(dst, src);
                        graph.AddEdge(localEdgeRev);
                        consts.Add(localEdgeRev, weight);
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="computer"></param>
        private void BuildEdges(ComputeWeightDelegate computer)
        {
            if (strings.Count < 2)
            {
                throw new TopologyException("you must specify two or more geometries to build a graph");
            }

            // Counts the number of edges in the set we pass to this method.
            int numberOfEdgesInLines = strings.Count * 2;

            // Double values because we use also reversed edges...
            if (bidirectional)
            {
                numberOfEdgesInLines *= 2;
            }

            consts = new Dictionary <IEdge <Coordinate>, double>(numberOfEdgesInLines);

            foreach (var line in strings)
            {
                // Prepare a segment
                var coordinates = line.Coordinates;
                int start       = 0;
                int end         = coordinates.GetUpperBound(0);
                var src         = coordinates[start];
                var dst         = coordinates[end];

                // Here we calculate the weight of the edge
                double weight = computer(line);

                // Add the edge
                IEdge <Coordinate> localEdge = new Edge <Coordinate>(src, dst);
                graph.AddEdge(localEdge);
                consts.Add(localEdge, weight);

                if (bidirectional)
                {
                    // Add the reversed edge
                    IEdge <Coordinate> localEdgeRev = new Edge <Coordinate>(dst, src);
                    graph.AddEdge(localEdgeRev);
                    consts.Add(localEdgeRev, weight);
                }
            }
        }
コード例 #4
0
 /// <summary>
 /// Initialize the algorithm using the specified
 /// <paramref name="computer">weight computer</paramref>
 /// </summary>
 /// <param name="computer">
 /// A function that computes the weight
 /// of any <see cref="ILineString">edge</see> of the graph.
 /// </param>
 /// <exception cref="TopologyException">
 /// If you've don't added two or more geometries to the builder.
 /// </exception>
 /// <exception cref="ApplicationException">
 /// If builder is already initialized.
 /// </exception>
 public void Initialize(ComputeWeightDelegate computer)
 {
     BuildEdges(computer);
 }
コード例 #5
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="computer"></param>
        private void BuildEdges(ComputeWeightDelegate computer)
        {
            if (strings.Count < 2)
                throw new TopologyException("you must specify two or more geometries to build a graph");

            // Counts the number of edges in the set we pass to this method.             
            var numberOfEdgesInLines = strings.Count * 2;

            // Double values because we use also reversed edges...
            if (bidirectional)
                numberOfEdgesInLines *= 2;

            consts = new Dictionary<IEdge<Coordinate>, double>(numberOfEdgesInLines);

            foreach (var line in strings)
            {
                // Prepare a segment
                var coordinates = line.Coordinates;
                var start = 0;
                var end = coordinates.GetUpperBound(0);
                var src = coordinates[start];
                var dst = coordinates[end];

                // Here we calculate the weight of the edge                
                var weight = computer(line);

                // Add the edge
                IEdge<Coordinate> localEdge = new Edge<Coordinate>(src, dst);
                graph.AddEdge(localEdge);
                consts.Add(localEdge, weight);

                if (bidirectional)
                {
                    // Add the reversed edge
                    IEdge<Coordinate> localEdgeRev = new Edge<Coordinate>(dst, src);
                    graph.AddEdge(localEdgeRev);
                    consts.Add(localEdgeRev, weight);
                }                
            }            
        }
コード例 #6
0
 /// <summary>
 /// Initialize the algorithm using the specified 
 /// <paramref name="computer">weight computer</paramref>
 /// </summary>
 /// <param name="computer">
 /// A function that computes the weight 
 /// of any <see cref="ILineString">edge</see> of the graph.
 /// </param>
 /// <exception cref="TopologyException">
 /// If you've don't added two or more geometries to the builder.
 /// </exception>
 /// <exception cref="ApplicationException">
 /// If builder is already initialized.
 /// </exception>
 public void Initialize(ComputeWeightDelegate computer)
 {
     BuildEdges(computer);
 }
コード例 #7
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="computer"></param>
        private void BuildEdges(ComputeWeightDelegate computer)
        {
            if (strings.Count < 2)
                throw new TopologyException("you must specify two or more geometries to build a graph");

            // Counts the number of edges in the set we pass to this method.             
            int numberOfEdgesInLines = 0;
            foreach (ILineString str in strings)
            {
                int edges = str.Coordinates.GetUpperBound(0);
                numberOfEdgesInLines += edges;
            }

            // Double values because we use also reversed edges...
            if (bidirectional)
                numberOfEdgesInLines *= 2;

            consts = new Dictionary<IEdge<ICoordinate>, double>(numberOfEdgesInLines);

            foreach (ILineString line in strings)
            {
                // A line has to have at least two dimensions
                int bound = line.Coordinates.GetUpperBound(0);
                if (bound > 0)
                {
                    for (int counter = 0; counter < bound; counter++)
                    {
                        // Prepare a segment
                        ICoordinate src = line.Coordinates[counter];
                        ICoordinate dst = line.Coordinates[counter + 1];

                        // Here we calculate the weight of the edge
                        ILineString lineString = factory.CreateLineString(
                            new ICoordinate[] { src, dst, });
                        double weight = computer(lineString);

                        // Add the edge
                        IEdge<ICoordinate> localEdge = new Edge<ICoordinate>(src, dst);
                        graph.AddEdge(localEdge);
                        consts.Add(localEdge, weight);

                        if (bidirectional)
                        {
                            // Add the reversed edge
                            IEdge<ICoordinate> localEdgeRev = new Edge<ICoordinate>(dst, src);
                            graph.AddEdge(localEdgeRev);
                            consts.Add(localEdgeRev, weight);
                        }
                    }
                 }
            }            
        }
コード例 #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="computer">
        /// A function that computes the weight
        /// of any <see cref="ILineString">edge</see> of the graph
        /// </param>
        /// <returns></returns>
        public DijkstraShortestPathAlgorithm <IPoint, IEdge <IPoint> > PrepareAlgorithm(ComputeWeightDelegate computer)
        {
            if (strings.Count < 2)
            {
                throw new TopologyException("you must specify two or more geometries to build a graph");
            }

            IMultiLineString edges = BuildEdges();

            Dictionary <IEdge <IPoint>, double>      consts = new Dictionary <IEdge <IPoint>, double>(edges.NumGeometries);
            AdjacencyGraph <IPoint, IEdge <IPoint> > graph  = new AdjacencyGraph <IPoint, IEdge <IPoint> >(true);

            foreach (ILineString str in edges.Geometries)
            {
                IPoint vertex1 = str.StartPoint;
                Assert.IsTrue(vertex1 != null);
                if (!graph.ContainsVertex(vertex1))
                {
                    graph.AddVertex(vertex1);
                }

                IPoint vertex2 = str.EndPoint;
                Assert.IsTrue(vertex2 != null);
                if (!graph.ContainsVertex(vertex2))
                {
                    graph.AddVertex(vertex2);
                }

                double        weight = computer(str);
                Edge <IPoint> edge   = new Edge <IPoint>(vertex1, vertex2);
                Assert.IsTrue(edge != null);

                graph.AddEdge(edge);
                consts.Add(edge, weight);
            }

            // Use Dijkstra
            return(new DijkstraShortestPathAlgorithm <IPoint, IEdge <IPoint> >(graph, consts));
        }