use of com.vividsolutions.jts.geom.GeometryFactory in project OpenTripPlanner by opentripplanner.
the class GraphUtils method geometryCollectionFromVertices.
private static GeometryCollection geometryCollectionFromVertices(Graph graph) {
GeometryFactory gf = GeometryUtils.getGeometryFactory();
Collection<Vertex> vertices = graph.getVertices();
Geometry[] points = new Geometry[vertices.size()];
int i = 0;
for (Vertex v : vertices) {
points[i++] = gf.createPoint(v.getCoordinate());
}
GeometryCollection geometries = new GeometryCollection(points, gf);
return geometries;
}
use of com.vividsolutions.jts.geom.GeometryFactory in project OpenTripPlanner by opentripplanner.
the class AreaEdgeList method addVertex.
/**
* Safely add a vertex to this area. This creates edges to all other vertices unless those edges would cross one of the original edges.
*/
public void addVertex(IntersectionVertex newVertex, Graph graph) {
GeometryFactory geometryFactory = GeometryUtils.getGeometryFactory();
if (edges.size() == 0) {
throw new RuntimeException("Can't add a vertex to an empty area");
}
@SuppressWarnings("unchecked") HashSet<IntersectionVertex> verticesCopy = (HashSet<IntersectionVertex>) vertices.clone();
VERTEX: for (IntersectionVertex v : verticesCopy) {
LineString newGeometry = geometryFactory.createLineString(new Coordinate[] { newVertex.getCoordinate(), v.getCoordinate() });
// fall into any holes
if (!originalEdges.union(originalEdges.getBoundary()).contains(newGeometry)) {
continue VERTEX;
}
// check to see if this splits multiple NamedAreas. This code is rather similar to
// code in OSMGBI, but the data structures are different
createSegments(newVertex, v, areas, graph);
}
vertices.add(newVertex);
}
use of com.vividsolutions.jts.geom.GeometryFactory in project OpenTripPlanner by opentripplanner.
the class EdgeVertexTileRenderer method renderTile.
@Override
public void renderTile(TileRenderContext context) {
float lineWidth = (float) (1.0f + 3.0f / Math.sqrt(context.metersPerPixel));
// Grow a bit the envelope to prevent rendering glitches between tiles
Envelope bboxWithMargins = context.expandPixels(lineWidth * 2.0, lineWidth * 2.0);
Collection<Vertex> vertices = context.graph.streetIndex.getVerticesForEnvelope(bboxWithMargins);
Collection<Edge> edges = context.graph.streetIndex.getEdgesForEnvelope(bboxWithMargins);
Set<Edge> edgesSet = new HashSet<>(edges);
/*
* Some edges do not have geometry and thus do not get spatial-indexed. Add
* outgoing/incoming edges of all vertices. This is not perfect, as if the edge cross a tile
* it will not be rendered on it.
*/
for (Vertex vertex : vertices) {
edgesSet.addAll(vertex.getIncoming());
edgesSet.addAll(vertex.getOutgoing());
}
// Note: we do not use the transform inside the shapeWriter, but do it ourselves
// since it's easier for the offset to work in pixel size.
ShapeWriter shapeWriter = new ShapeWriter(new IdentityPointTransformation(), new PointShapeFactory.Point());
GeometryFactory geomFactory = new GeometryFactory();
Stroke stroke = new BasicStroke(lineWidth * 1.4f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
Stroke halfStroke = new BasicStroke(lineWidth * 0.6f + 1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
Stroke halfDashedStroke = new BasicStroke(lineWidth * 0.6f + 1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 1.0f, new float[] { 4 * lineWidth, lineWidth }, 2 * lineWidth);
Stroke arrowStroke = new ShapeStroke(new Polygon(new int[] { 0, 0, 30 }, new int[] { 0, 20, 10 }, 3), lineWidth / 2, 5.0f * lineWidth, 2.5f * lineWidth);
BasicStroke thinStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
Font font = new Font(Font.SANS_SERIF, Font.PLAIN, Math.round(lineWidth));
Font largeFont = new Font(Font.SANS_SERIF, Font.PLAIN, Math.round(lineWidth * 1.5f));
FontMetrics largeFontMetrics = context.graphics.getFontMetrics(largeFont);
context.graphics.setFont(largeFont);
context.graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
context.graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
BufferParameters bufParams = new BufferParameters();
bufParams.setSingleSided(true);
bufParams.setJoinStyle(BufferParameters.JOIN_BEVEL);
// Render all edges
EdgeVisualAttributes evAttrs = new EdgeVisualAttributes();
for (Edge edge : edgesSet) {
evAttrs.color = null;
evAttrs.label = null;
Geometry edgeGeom = edge.getGeometry();
boolean hasGeom = true;
if (edgeGeom == null) {
Coordinate[] coordinates = new Coordinate[] { edge.getFromVertex().getCoordinate(), edge.getToVertex().getCoordinate() };
edgeGeom = GeometryUtils.getGeometryFactory().createLineString(coordinates);
hasGeom = false;
}
boolean render = evRenderer.renderEdge(edge, evAttrs);
if (!render)
continue;
Geometry midLineGeom = context.transform.transform(edgeGeom);
OffsetCurveBuilder offsetBuilder = new OffsetCurveBuilder(new PrecisionModel(), bufParams);
Coordinate[] coords = offsetBuilder.getOffsetCurve(midLineGeom.getCoordinates(), lineWidth * 0.4);
if (coords.length < 2)
// Can happen for very small edges (<1mm)
continue;
LineString offsetLine = geomFactory.createLineString(coords);
Shape midLineShape = shapeWriter.toShape(midLineGeom);
Shape offsetShape = shapeWriter.toShape(offsetLine);
context.graphics.setStroke(hasGeom ? halfStroke : halfDashedStroke);
context.graphics.setColor(evAttrs.color);
context.graphics.draw(offsetShape);
if (lineWidth > 6.0f) {
context.graphics.setColor(Color.WHITE);
context.graphics.setStroke(arrowStroke);
context.graphics.draw(offsetShape);
}
if (lineWidth > 4.0f) {
context.graphics.setColor(Color.BLACK);
context.graphics.setStroke(thinStroke);
context.graphics.draw(midLineShape);
}
if (evAttrs.label != null && lineWidth > 8.0f) {
context.graphics.setColor(Color.BLACK);
context.graphics.setStroke(new TextStroke(" " + evAttrs.label + " ", font, false, true));
context.graphics.draw(offsetShape);
}
}
// Render all vertices
VertexVisualAttributes vvAttrs = new VertexVisualAttributes();
for (Vertex vertex : vertices) {
vvAttrs.color = null;
vvAttrs.label = null;
Point point = geomFactory.createPoint(new Coordinate(vertex.getLon(), vertex.getLat()));
boolean render = evRenderer.renderVertex(vertex, vvAttrs);
if (!render)
continue;
Point tilePoint = (Point) context.transform.transform(point);
Shape shape = shapeWriter.toShape(tilePoint);
context.graphics.setColor(vvAttrs.color);
context.graphics.setStroke(stroke);
context.graphics.draw(shape);
if (vvAttrs.label != null && lineWidth > 6.0f && context.bbox.contains(point.getCoordinate())) {
context.graphics.setColor(Color.BLACK);
int labelWidth = largeFontMetrics.stringWidth(vvAttrs.label);
/*
* Poor man's solution: stay on the tile if possible. Otherwise the renderer would
* need to expand the envelope by an unbounded amount (max label size).
*/
double x = tilePoint.getX();
if (x + labelWidth > context.tileWidth)
x -= labelWidth;
context.graphics.drawString(vvAttrs.label, (float) x, (float) tilePoint.getY());
}
}
}
use of com.vividsolutions.jts.geom.GeometryFactory in project OpenTripPlanner by opentripplanner.
the class TestHalfEdges method createGeometry.
public LineString createGeometry(Vertex a, Vertex b) {
GeometryFactory factory = new GeometryFactory();
Coordinate[] cs = new Coordinate[2];
cs[0] = a.getCoordinate();
cs[1] = b.getCoordinate();
return factory.createLineString(cs);
}
use of com.vividsolutions.jts.geom.GeometryFactory in project OpenTripPlanner by opentripplanner.
the class TestTriangle method testTriangle.
public void testTriangle() {
Coordinate c1 = new Coordinate(-122.575033, 45.456773);
Coordinate c2 = new Coordinate(-122.576668, 45.451426);
StreetVertex v1 = new IntersectionVertex(null, "v1", c1.x, c1.y, (NonLocalizedString) null);
StreetVertex v2 = new IntersectionVertex(null, "v2", c2.x, c2.y, (NonLocalizedString) null);
GeometryFactory factory = new GeometryFactory();
LineString geometry = factory.createLineString(new Coordinate[] { c1, c2 });
double length = 650.0;
StreetWithElevationEdge testStreet = new StreetWithElevationEdge(v1, v2, geometry, "Test Lane", length, StreetTraversalPermission.ALL, false);
// a safe street
testStreet.setBicycleSafetyFactor(0.74f);
Coordinate[] profile = new Coordinate[] { // slope = 0.1
new Coordinate(0, 0), new Coordinate(length / 2, length / 20.0), // slope = -0.1
new Coordinate(length, 0) };
PackedCoordinateSequence elev = new PackedCoordinateSequence.Double(profile);
testStreet.setElevationProfile(elev, false);
SlopeCosts costs = ElevationUtils.getSlopeCosts(elev, true);
double trueLength = costs.lengthMultiplier * length;
double slopeWorkLength = testStreet.getSlopeWorkCostEffectiveLength();
double slopeSpeedLength = testStreet.getSlopeSpeedEffectiveLength();
RoutingRequest options = new RoutingRequest(TraverseMode.BICYCLE);
options.optimize = OptimizeType.TRIANGLE;
options.bikeSpeed = 6.0;
options.walkReluctance = 1;
options.setTriangleSafetyFactor(0);
options.setTriangleSlopeFactor(0);
options.setTriangleTimeFactor(1);
State startState = new State(v1, options);
State result = testStreet.traverse(startState);
double timeWeight = result.getWeight();
double expectedTimeWeight = slopeSpeedLength / options.getSpeed(TraverseMode.BICYCLE);
assertTrue(Math.abs(expectedTimeWeight - timeWeight) < 0.00001);
options.setTriangleSafetyFactor(0);
options.setTriangleSlopeFactor(1);
options.setTriangleTimeFactor(0);
startState = new State(v1, options);
result = testStreet.traverse(startState);
double slopeWeight = result.getWeight();
double expectedSlopeWeight = slopeWorkLength / options.getSpeed(TraverseMode.BICYCLE);
assertTrue(Math.abs(expectedSlopeWeight - slopeWeight) < 0.00001);
assertTrue(length * 1.5 / options.getSpeed(TraverseMode.BICYCLE) < slopeWeight);
assertTrue(length * 1.5 * 10 / options.getSpeed(TraverseMode.BICYCLE) > slopeWeight);
options.setTriangleSafetyFactor(1);
options.setTriangleSlopeFactor(0);
options.setTriangleTimeFactor(0);
startState = new State(v1, options);
result = testStreet.traverse(startState);
double safetyWeight = result.getWeight();
double slopeSafety = costs.slopeSafetyCost;
double expectedSafetyWeight = (trueLength * 0.74 + slopeSafety) / options.getSpeed(TraverseMode.BICYCLE);
assertTrue(Math.abs(expectedSafetyWeight - safetyWeight) < 0.00001);
final double ONE_THIRD = 1 / 3.0;
options.setTriangleSafetyFactor(ONE_THIRD);
options.setTriangleSlopeFactor(ONE_THIRD);
options.setTriangleTimeFactor(ONE_THIRD);
startState = new State(v1, options);
result = testStreet.traverse(startState);
double averageWeight = result.getWeight();
assertTrue(Math.abs(safetyWeight * ONE_THIRD + slopeWeight * ONE_THIRD + timeWeight * ONE_THIRD - averageWeight) < 0.00000001);
}
Aggregations