package maps.gml;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Path2D;
import java.awt.Shape;
import rescuecore2.misc.geometry.Point2D;
import rescuecore2.misc.geometry.Line2D;
/**
Useful tools for manipulating GML.
*/
public final class GMLTools {
private GMLTools() {
}
/**
Turn a list of coordinates into a string suitable for putting into an XML document.
@param coords The coordinate list.
@return A string version of the list.
*/
public static String getCoordinatesString(List<GMLCoordinates> coords) {
StringBuilder result = new StringBuilder();
for (Iterator<GMLCoordinates> it = coords.iterator(); it.hasNext();) {
GMLCoordinates next = it.next();
result.append(String.valueOf(next.getX()));
result.append(",");
result.append(String.valueOf(next.getY()));
if (it.hasNext()) {
result.append(" ");
}
}
return result.toString();
}
/**
Turn a coordinates string into a list of GMLCoordinates.
@param coords The coordinates string.
@return A list of GMLCoordinates.
*/
public static List<GMLCoordinates> getCoordinatesList(String coords) {
List<GMLCoordinates> result = new ArrayList<GMLCoordinates>();
StringTokenizer tokens = new StringTokenizer(coords, " ");
while (tokens.hasMoreTokens()) {
result.add(new GMLCoordinates(tokens.nextToken()));
}
return result;
}
/**
Convert a list of GMLCoordinates to Point2D objects.
@param coords The GMLCoordinates to convert.
@return A list of Point2D objects.
*/
public static List<Point2D> coordinatesAsPoints(List<GMLCoordinates> coords) {
List<Point2D> result = new ArrayList<Point2D>(coords.size());
for (GMLCoordinates next : coords) {
result.add(new Point2D(next.getX(), next.getY()));
}
return result;
}
/**
Get the bounds of a set of coordinates.
@param coords The coordinate list.
@return The bounds of the coordinates.
*/
public static Rectangle2D getBounds(List<GMLCoordinates> coords) {
if (coords.isEmpty()) {
return null;
}
double minX = Double.POSITIVE_INFINITY;
double minY = Double.POSITIVE_INFINITY;
double maxX = Double.NEGATIVE_INFINITY;
double maxY = Double.NEGATIVE_INFINITY;
for (GMLCoordinates next : coords) {
minX = Math.min(minX, next.getX());
minY = Math.min(minY, next.getY());
maxX = Math.max(maxX, next.getX());
maxY = Math.max(maxY, next.getY());
}
return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
}
/**
Get the bounds of a set of gml objects.
@param objects The object list.
@return The bounds of the objects.
*/
public static Rectangle2D getObjectBounds(List<? extends GMLObject> objects) {
Rectangle2D result = null;
for (GMLObject next : objects) {
result = expand(result, next);
}
return result;
}
/**
Turn a list of coordinates into a shape.
@param coords The coordinates.
@return A new shape.
*/
public static Shape coordsToShape(List<GMLCoordinates> coords) {
Path2D path = new Path2D.Double();
Iterator<GMLCoordinates> it = coords.iterator();
GMLCoordinates c = it.next();
path.moveTo(c.getX(), c.getY());
while (it.hasNext()) {
c = it.next();
path.lineTo(c.getX(), c.getY());
}
path.closePath();
return path;
}
/**
Turn a GMLNode into a Point2D.
@param node The node to convert.
@return A new Point2D.
*/
public static Point2D toPoint(GMLNode node) {
return new Point2D(node.getX(), node.getY());
}
/**
Turn a GMLEdge into a Line2D.
@param edge The edge to convert.
@return A new Line2D.
*/
public static Line2D toLine(GMLEdge edge) {
return new Line2D(toPoint(edge.getStart()), toPoint(edge.getEnd()));
}
private static Rectangle2D expand(Rectangle2D rect, double x, double y) {
if (rect == null) {
return new Rectangle2D.Double(x, y, 0, 0);
}
double newMinX = Math.min(x, rect.getX());
double newMaxX = Math.max(x, rect.getX() + rect.getWidth());
double newMinY = Math.min(y, rect.getY());
double newMaxY = Math.max(y, rect.getY() + rect.getHeight());
rect.setRect(newMinX, newMinY, newMaxX - newMinX, newMaxY - newMinY);
return rect;
}
private static Rectangle2D expand(Rectangle2D rect, GMLNode node) {
return expand(rect, node.getX(), node.getY());
}
private static Rectangle2D expand(Rectangle2D rect, GMLEdge edge) {
return expand(expand(rect, edge.getStart()), edge.getEnd());
}
private static Rectangle2D expand(Rectangle2D rect, GMLShape shape) {
for (GMLDirectedEdge next : shape.getEdges()) {
rect = expand(rect, next.getEdge());
}
return rect;
}
private static Rectangle2D expand(Rectangle2D rect, GMLObject object) {
if (object instanceof GMLNode) {
return expand(rect, (GMLNode)object);
}
if (object instanceof GMLEdge) {
return expand(rect, (GMLEdge)object);
}
if (object instanceof GMLShape) {
return expand(rect, (GMLShape)object);
}
return rect;
}
}