/*
* This file is part of the Trickl Open Source Libraries.
*
* Trickl Open Source Libraries - http://open.trickl.com/
*
* Copyright (C) 2011 Tim Gee.
*
* Trickl Open Source Libraries are free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Trickl Open Source Libraries are distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this project. If not, see <http://www.gnu.org/licenses/>.
*/
package com.trickl.graph.planar;
import com.trickl.graph.GraphArgumentException;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.LineSegment;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.jgrapht.Graphs;
/**
*
* @author tgee
* @param <V>
* @param <E>
*/
public class ValidatingMapPlanarLayout<V, E> extends MapPlanarLayout<V> {
PlanarGraph<V, E> graph;
private double tolerance = 1e-5;
public ValidatingMapPlanarLayout(PlanarGraph<V, E> graph) {
super();
this.graph = graph;
}
public ValidatingMapPlanarLayout(PlanarGraph<V, E> graph, Map<V, Coordinate> vertexCoordinateMap) {
super(vertexCoordinateMap);
this.graph = graph;
}
@Override
public void setCoordinate(V vertex, Coordinate coord) {
super.setCoordinate(vertex, coord);
List<LineSegment> existingLines = new LinkedList<>();
graph.edgeSet().stream().forEach((edge) -> {
V source = graph.getEdgeSource(edge);
V target = graph.getEdgeTarget(edge);
if (!(vertex == source || vertex == target)) {
Coordinate sourceCoord = getCoordinate(source);
Coordinate targetCoord = getCoordinate(target);
if (sourceCoord != null && targetCoord != null) {
LineSegment existingLine = new LineSegment(sourceCoord, targetCoord);
existingLines.add(existingLine);
}
}
});
for (E edge : graph.edgesOf(vertex)) {
V oppositeVertex = Graphs.getOppositeVertex(graph, edge, vertex);
Coordinate oppositeCoord = getCoordinate(oppositeVertex);
if (oppositeCoord != null) {
LineSegment line = new LineSegment(coord, oppositeCoord);
for (LineSegment existingLine : existingLines) {
Coordinate intersection = line.intersection(existingLine);
if (intersection != null
&& !intersection.equals2D(existingLine.p0, tolerance)
&& !intersection.equals2D(existingLine.p1, tolerance)
&& !intersection.equals2D(line.p0, tolerance)
&& !intersection.equals2D(line.p1, tolerance)) {
// There is an intersection betweent the lines that is
// not at an endpoint.
throw new GraphArgumentException(graph,
new IllegalArgumentException("Setting coordinate for vertex " + vertex + " at " + coord + " would make the line to " +
oppositeVertex + " at "+ oppositeCoord + " overlap the existing graph."));
}
}
}
}
}
}