/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is 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
* Lesser General Public License for more details.
*/
package org.geotools.graph.build.line;
import com.vividsolutions.jts.geom.*;
import org.geotools.graph.structure.Edge;
import org.geotools.graph.structure.Graphable;
import org.geotools.graph.structure.Node;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Builds a graph representing a line network in which edges in the network are
* represented by LineString geometries. This implementation is a wrapper around
* a LineGraphGenerator which sets underlying edge objects to be LineString
* objects, and underlying Node objects to be Point objects. While generating
* the graph, the generator uses the visited flag of created components to
* determine when to create underlying objects. For this reason it is not recommended
* to modify the visited flag of any graph components.
*
* @see com.vividsolutions.jts.geom.LineString
* @see com.vividsolutions.jts.geom.Point
*
* @author Justin Deoliveira, Refractions Research Inc, jdeolive@refractions.net
* @author Anders Bakkevold, Bouvet AS, bakkedev@gmail.com
*
* @source $URL$
*/
public class LineStringGraphGenerator extends BasicLineGraphGenerator {
private static GeometryFactory gf = new GeometryFactory();
public LineStringGraphGenerator(double tolerance) {
super(tolerance);
}
public LineStringGraphGenerator() {
}
public Graphable add(Object obj) {
LineString ls = null;
if (obj instanceof MultiLineString) {
ls = (LineString) ((MultiLineString) obj).getGeometryN(0);
}
else {
ls = (LineString) obj;
}
//parent class expects a line segment
Edge e = (Edge)super.add(
new LineSegment(
ls.getCoordinateN(0), ls.getCoordinateN(ls.getNumPoints()-1)
)
);
//check if the LineSegment has been changed
if (useTolerance()) {
LineSegment lineSegment = (LineSegment) e.getObject();
Coordinate[] coordinates = ls.getCoordinates();
List<Coordinate> coordinateList = Arrays.asList(coordinates);
// list from asList does not support add(index,object), must make an arraylist
List<Coordinate> nCoordinateList = new ArrayList<Coordinate>(coordinateList);
if (!ls.getCoordinateN(0).equals(lineSegment.p0)) {
nCoordinateList.add(0, lineSegment.p0);
} else if (!ls.getCoordinateN(ls.getNumPoints()-1).equals(lineSegment.p1)){
nCoordinateList.add(lineSegment.p1);
}
Coordinate[] newCoordinates = nCoordinateList.toArray(new Coordinate[nCoordinateList.size()]);
ls = gf.createLineString(newCoordinates);
}
//over write object to be the linestring
e.setObject(ls);
return(e);
}
protected LineSegment alterLine(LineSegment line, Node n1, Node n2) {
Point c1added = ((Point) n1.getObject());
Point c2added = ((Point) n2.getObject());
if (!c1added.getCoordinate().equals(line.p0) || c2added.getCoordinate().equals(line.p1)) {
line = new LineSegment(c1added.getCoordinate(), c2added.getCoordinate());
}
return line;
}
public Graphable remove(Object obj) {
LineString ls = (LineString)obj;
//parent ecpexts a line segment
return(
super.remove(
new LineSegment(
ls.getCoordinateN(0), ls.getCoordinateN(ls.getNumPoints()-1)
)
)
);
}
public Graphable get(Object obj) {
LineString ls = (LineString)obj;
//parent ecpexts a line segment
return(
super.get(
new LineSegment(
ls.getCoordinateN(0), ls.getCoordinateN(ls.getNumPoints()-1)
)
)
);
}
protected void setObject(Node n, Object obj) {
//set underlying object to be point instead of coordinate
Coordinate c = (Coordinate)obj;
n.setObject(gf.createPoint(c));
}
}