com.hazelcast.shaded.org.locationtech.jts.edgegraph.EdgeGraph Maven / Gradle / Ivy
/*
* Copyright (c) 2016 Vivid Solutions.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package com.hazelcast.shaded.org.locationtech.jts.edgegraph;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.hazelcast.shaded.org.locationtech.jts.geom.Coordinate;
/**
* A graph comprised of {@link HalfEdge}s.
* It supports tracking the vertices in the graph
* via edges incident on them,
* to allow efficient lookup of edges and vertices.
*
* This class may be subclassed to use a
* different subclass of HalfEdge,
* by overriding {@link #createEdge(Coordinate)}.
* If additional logic is required to initialize
* edges then {@link EdgeGraph#addEdge(Coordinate, Coordinate)}
* can be overridden as well.
*
* @author Martin Davis
*
*/
public class EdgeGraph
{
private Map vertexMap = new HashMap();
public EdgeGraph() {
}
/**
* Creates a single HalfEdge.
* Override to use a different HalfEdge subclass.
*
* @param orig the origin location
* @return a new HalfEdge with the given origin
*/
protected HalfEdge createEdge(Coordinate orig)
{
return new HalfEdge(orig);
}
/**
* Creates a HalfEge pair, using the HalfEdge type of the graph subclass.
*
* @param p0
* @param p1
* @return
*/
private HalfEdge create(Coordinate p0, Coordinate p1)
{
HalfEdge e0 = createEdge(p0);
HalfEdge e1 = createEdge(p1);
e0.link(e1);
return e0;
}
/**
* Adds an edge between the coordinates orig and dest
* to this graph.
* Only valid edges can be added (in particular, zero-length segments cannot be added)
*
* @param orig the edge origin location
* @param dest the edge destination location.
* @return the created edge
* @return null if the edge was invalid and not added
*
* @see #isValidEdge(Coordinate, Coordinate)
*/
public HalfEdge addEdge(Coordinate orig, Coordinate dest) {
if (! isValidEdge(orig, dest)) return null;
/**
* Attempt to find the edge already in the graph.
* Return it if found.
* Otherwise, use a found edge with same origin (if any) to construct new edge.
*/
HalfEdge eAdj = (HalfEdge) vertexMap.get(orig);
HalfEdge eSame = null;
if (eAdj != null) {
eSame = eAdj.find(dest);
}
if (eSame != null) {
return eSame;
}
HalfEdge e = insert(orig, dest, eAdj);
return e;
}
/**
* Tests if the given coordinates form a valid edge (with non-zero length).
*
* @param orig the start coordinate
* @param dest the end coordinate
* @return true if the edge formed is valid
*/
public static boolean isValidEdge(Coordinate orig, Coordinate dest) {
int cmp = dest.compareTo(orig);
return cmp != 0;
}
/**
* Inserts an edge not already present into the graph.
*
* @param orig the edge origin location
* @param dest the edge destination location
* @param eAdj an existing edge with same orig (if any)
* @return the created edge
*/
private HalfEdge insert(Coordinate orig, Coordinate dest, HalfEdge eAdj) {
// edge does not exist, so create it and insert in graph
HalfEdge e = create(orig, dest);
if (eAdj != null) {
eAdj.insert(e);
}
else {
// add halfedges to to map
vertexMap.put(orig, e);
}
HalfEdge eAdjDest = (HalfEdge) vertexMap.get(dest);
if (eAdjDest != null) {
eAdjDest.insert(e.sym());
}
else {
vertexMap.put(dest, e.sym());
}
return e;
}
/**
* Gets all {@link HalfEdge}s in the graph.
* Both edges of edge pairs are included.
*
* @return a collection of the graph edges
*/
public Collection getVertexEdges()
{
return vertexMap.values();
}
/**
* Finds an edge in this graph with the given origin
* and destination, if one exists.
*
* @param orig the origin location
* @param dest the destination location.
* @return an edge with the given orig and dest, or null if none exists
*/
public HalfEdge findEdge(Coordinate orig, Coordinate dest) {
HalfEdge e = (HalfEdge) vertexMap.get(orig);
if (e == null) return null;
return e.find(dest);
}
}