/// <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); }
/// <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); } } } }
/// <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); } } }
/// <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); }
/// <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); } } }
/// <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); } } } } }
/// <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)); }