Graph
The gt-graph
package defines the concept of a graph (or network) made up of GeoTools Features.
gt-graph包定义了由GeoTools要素构成的图(或网络)的概念。
Maven:
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-graph</artifactId>
<version>${geotools.version}</version>
</dependency>
Graph Model 图模型
The graph module provides a convenient, flexible and efficient API for graph construction and query. In additional to generic Graph support, it implements directed and undirected networks.
图模块提供了一种便捷的、弹性的和有效的API,用于图的构建和查询。除了支持一般的图之外,它还实现了有向和无向的网络。
This code was originally developed at Refractions Research and has been used in Jump before being ported to GeoTools.
该代码最初由折射研究所开发,在移植到GeoTools之前已在Jump中使用。
Use of GeoTools
The Graph module makes use of concepts and (classes) from the GeoTools core:
图模块利用了GeoTools核心概念和类。
Feature
- atomic unit of geographic information- 要素 - 地理信息原子单位
FeatureType
- keeps track of what attributes each Feature can hold- 要素类型 - 跟踪每个特征可以包含哪些属性
FeatureID
- a unique id associated with each Feature (must start with a non-numeric character)- 要素ID - 每个要素都有一个唯一的ID(必须以非数字字符开始)。
In addition to the Feature API from core, the graph module makes use of relationships. Usually relationships are based on spatial comparisons between features, although you may be able to quickly establish a relationship using your feature attributes.
除了来自core的功能API之外,graph模块还利用了关系。通常,关系基于要素之间的空间比较,尽管可以使用要素属性快速建立关系。
- Graph constructed from
LineStrings
based on “shared end points” - 通过LineStrings构建的图基于“共享端点”。
Example a road network used for navigation.
示例用于导航的道路网络。
- Graph constructed from
Polygons
based on “touches” - 通过多边形构建的图基于“接触”。
Example graph of watersheds used for ground water analysis.
用于地下水分析的流域示例图。
Graph(Graph类)
The basic layout of a Graph is a collection of edges joined together at nodes.
Graph的基本结构是一组边基于节点连接在一起。
Graph 图
The core graph data structure is a collection of nodes and edges, a range of methods are available allowing access using visitors.
核心Graph数据结构是节点和边的集合,有一系列方法可供使用,允许使用访问者进行访问。
Node 节点
Represents a node in the graph.
表示图中的一个节点。
Edge 边
Represents the graph edge between two nodes; with a range of methods to both access and compare.
表示两个节点之间的边;有一系列的方法来获取和比较。
Graphable
We store the following common information for both nodes and edges:
我们为节点和边存储了如下的一般信息:
- visited: Used during traversal to mark visited components
- 已访问:在遍历期间用于标记访问的组件。
- count: In a similar fashion count is stored
- 计数:以类似的方式存储计数
- object: Used to store the Feature used during creation.
- 对象:用于在创建期间储存要素。
Depending on the graph constructed you may end up storing the features along the edges (say for a road network) or at each node (say for a watershed network).
根据构建的图形,最终可能会沿边缘(例如道路网络)或每个节点(例如流域网络)存储特征。
Graph Access 图的获取
A Graph supports simple direct access is supported using:
一个图支持简单的直接获取:
Graph.getNodes()
Graph.getEdges()
You can also pass in a visitor in order to traverse the graph contents:
你还可以传入一个访问者来遍历图形内容:
Graph.visitNodes( visitor )
Graph.visitEdges( visitor )
The visitor can also control when to stop the process using:
访问者还可以控制何时停止该过程:
Graph.queryNodes( visitor )
Graph.queryEdges( visitor )
To provide control your visitor can indicate when it wants to stop, backtrack or continue using:
要提供控制,您的访问者可以使用以下命令指示何时停止、回溯或继续:
GraphTraversal.CONTINUE
GraphTraversal.KILL_BRANCH
GraphTraversal.STOP
GraphTraversal.SUSPEND
Graph Traversal 图的遍历
An alternative to direct access is the configure a GraphTraversal using:
直接访问的另一种选择是使用以下方式配置GraphTraversal:
- GraphIterator: iterator specifying the order in which to visit components of the graph during the traversal.
- 图迭代器:迭代器,指定遍历期间访问图组件的顺序。
- GraphWalker: walker being iterated over the graph (usually to accomplish a specific goal)
- 图步行者:遍历图形的walker(通常是为了完成特定的目标)
GeoTools provides out of the box implementations for many common problems: finding the shortest path, partition a graph into sections, or visiting all the elements.
GeoTools为许多常见问题提供了现成的实现:查找最短路径、将图形划分为多个部分或访问所有元素。
Directed Graph 有向图
We also have a straight extension of these ideas to represent a directed graph in which each edge has a direction in which it can be traversed. This is the difference between considering each edge a simple connection vs thinking of each edge as an arrow.
我们还有一个直接的扩展,来表示有向图,每一条边都有一个方向。
Building构建
GraphBuilder图构建器
At a low level graph creation is handled using a GraphBuilder
. We have a range of implementations available. The important point is that you control them by calling buildNode
, and buildEdge
repeatedly allowing it to build up an internal representation of your Graph.
在底层,图的创建是通过一个叫GraphBuilder的东西来处理的。我们有很多种实现方法。重要的一点是,您可以通过反复调用buildNode和buildEdge来控制它们,从而构建图形的内部表示。。
When you are satisfied with the result you can call getGraph()
to retrieve the result.
当你对结果满意时,你可以调用getGraph()来获取结果。
Example例子
- Building a Line network:构建一个线网络:
final LineGraphGenerator generator = new BasicLineGraphGenerator();
SimpleFeatureCollection fc = featureSource.getFeatures();
fc.accepts(
new FeatureVisitor() {
public void visit(Feature feature) {
generator.add(feature);
}
},
null);
Graph graph = generator.getGraph();
- To make use of your graph we will use a
GraphVisitor
:要使用图形,我们将使用GraphVisitor:
The followingOrphanVistor
is called for “each”GraphComponent
where it has a chance to check if theGraphComponent
is an orphan (i.e. has no relationships) or not.
对于“每个”GraphComponent,调用下面的OrphanVistor,它有机会检查GraphComponent是否为孤儿(即没有关系)。
class OrphanVisitor implements GraphVisitor {
private int count = 0;
public int getCount() {
return count;
}
public int visit(Graphable component) {
Iterator related = component.getRelated();
if (related.hasNext() == false) {
// no related components makes this an orphan
count++;
}
return GraphTraversal.CONTINUE;
}
}
OrphanVisitor graphVisitor = new OrphanVisitor();
SimpleGraphWalker sgv = new SimpleGraphWalker(graphVisitor);
GraphIterator iterator = new BreadthFirstIterator();
BasicGraphTraversal bgt = new BasicGraphTraversal(graph, sgv, iterator);
bgt.traverse();
System.out.println("Found orphans: " + graphVisitor.getCount());
For those familiar with the Builder Pattern (GOF Design Patterns) this will look familiar.
对于熟悉Builder Pattern的人来说,这个看着很熟悉。
GraphGenerator图生成器
The other approach is we have a number of generators which will automatically create a Graph for you based on information you feed in. The GraphGenerators
use a GraphBuilder
to build up each node and edge internally; so you will need to be careful to construct them with the correct builder for the problem you are wishing to solve.
另一种方法是我们有许多生成器,它们会根据您输入的信息自动为您创建一个图表。GraphGenerators使用GraphBuilder在内部构建每个节点和边;因此,您需要小心地使用正确的生成器来构建它们,以解决您希望解决的问题。
Each one of these implementations is set up to handle different kinds of data (Features
, LineStrings
, etc…) so please be sure to read the javadocs.
这些实现中的每一个都是为处理不同类型的数据(要素、线字符串等)而设置的,因此请务必阅读javadocs。
Building Graph from a FeatureCollection 通过一个FeatureCollection来构建图
We have a number of generators that can be used to process a feature collection in different ways in order to build up an appropriate Graph.
我们有很多的生成器可以用来处理要素集。它们以不同的方式来建立一个合适的图。
- This example can be used if you want to build a graph from a feature collection made up of linear features:
这个例子可以用,如果你想通过线要素的集合来构建一个图。
// get a feature collection somehow
SimpleFeatureCollection fCollection = featureSource.getFeatures();
//create a linear graph generate
LineStringGraphGenerator lineStringGen = new LineStringGraphGenerator();
//wrap it in a feature graph generator
FeatureGraphGenerator featureGen = new FeatureGraphGenerator( lineStringGen );
//throw all the features into the graph generator
FeatureIterator iter = fCollection.features();
try {
while(iter.hasNext()){
Feature feature = iter.next();
featureGen.add( feature );
}
} finally {
iter.close();
}
Graph graph = featureGen.getGraph()
Building Graph from Line Segments 通过线的分段来构建图
- This example can be used to build a graph from just a set of line segments:
这个例子可以用来构建图,通过一系列的线的分段:
//we have some line segments
LineSegment[] lines = ...
//create the graph generator
BasicLineGraphGenerator graphGen = new BasicLineGraphGenerator();
//add the lines to the graph
for ( int i = 0; i < lines.length; i++ ) {
graphGen.add( lines[i] );
}
Graph graph = graphGen.getGraph()
Building a FeatureCollection from your Graph 通过图构建要素集FeatureCollection
Once the graph is built each, edge.getObject()
will hold the original feature used to built it.
一旦图构建完了,每一个edge.getObject()将保留用于构建它的原始要素。
You can traverse your graph and build up FeatureCollection
as you go.:
你可以追踪你的图,然后构建FeatureCollection:
SimpleFeatureCollection features = new DefaultFeatureCollection();
for ( Iterator e = graph.getEdges().iterator(); e.hasNext(); ) {
Edge edge = (Edge) e.next();
SimpleFeature feature = (SimpleFeature) e.getObject();
features.add( feature );
}
Shortest Path最短路径
We have a number of ways to calculate the shortest path between two nodes:
我们有很多种方式来计算两个节点的最短路径:
- The class DijkstraShortestPathFinder can be used to calculate a path using Dijkstra’s Shortest Path algorithm.:
DijkstraShortestPathFinder使用Dijkstra最短路径算法来计算路径:
//reference to a graph, already built
Graph graph = ...see above...
//find a source node (usually your user chooses one)
Node start = ..
// create a strategy for weighting edges in the graph
// in this case we are using geometry length
DijkstraIterator.EdgeWeigter weighter = new DijkstraIterator.EdgeWeighter() {
public double getWeight(Edge e) {
SimpleFeature feature = (SimpleFeature) e.getObject();
Geometry geometry = (Geometry) feature.getDefaultGeometry();
return gometry.getLength();
}
}
// Create GraphWalker - in this case DijkstraShortestPathFinder
DijkstraShortestPathFinder pf = new DijkstraShortestPathFinder( graph, start, weighter );
pf.calculate();
//find some destinations to calculate paths to
List<Node> destinations = ...
//calculate the paths
for ( Iterator d = destinations.iterator(); d.hasNext(); ) {
Node destination = (Node) d.next();
Path path = pf.getPath( destination );
//do something with the path
}
- AStarShortestPathFinder can be used in a similar fashion (and is often quicker)
https://docs.geotools.org/latest/userguide/extension/graph/
如何获取Node。。。
package org.geotools.graph.structure;
import java.util.List;
/**
* Represents a node in a graph. A node is a point in a graph which is iadjacent to 0 or more edges.
* The collection of edges that are incident/ adjacent to the node, is referred to as the "adjacency
* list" of the node.表示图中的一个节点。节点是图中与0条或多条边相邻的点。与节点相关/相邻的边集合称为该节点的“邻接列表”。
*
* @see Graph
* @see Edge
* @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net
*/
public interface Node extends Graphable {
/**
* Adds an edge to the adjacency list of the node.添加一条边到该节点的邻接列表。
*
* @param e Adjacent edge to add.要添加的邻接边。
*/
public void add(Edge e);
/**
* Removes an edge from the adjacency list of the node.从该节点的邻接列表中移除一条边。
*
* @param e Adjacent edge to remove.
*/
public void remove(Edge e);
/**
* Returns an edge in the adjacency list of the node that is adjacent to another specified node.
* 返回节点邻接列表中与另一个指定节点相邻的边。
* <br>
* <br>
* Note: It is possible for two nodes to share multiple edges between them. In this case,
* getEdges(Node other) can be used to obtain a complete list.
*
* @param other The other node that the desired edge to return is adjacent to.
* @return The first edge that is found to be adjacent to the specified node.
*/
public Edge getEdge(Node other);
/**
* Returns a collection of edges in the adjacency list of the node that are adjacent to another
* specified node.
*
* @param other The other node that the desired edges to return are adjacent to.
* @return List of all edges that are found to be adjacent to the specified node.
*/
public List<? extends Edge> getEdges(Node other);
/**
* Returns the edge adjacency list of the node.
*
* @return A list containing all edges that are adjacent to the node.
*/
public List<? extends Edge> getEdges();
/**
* Returns the degree of the node. The degree of a node is defined as the number of edges that
* are adjacent to the node.
*
* @return int Degree of node.
*/
public int getDegree();
}