public Geometry getGeometry() { if (geometry == null) { Coordinate c1 = new Coordinate(start.getLon(), start.getLat()); Coordinate c2 = new Coordinate(end.getLon(), end.getLat()); geometry = GeometryUtils.getGeometryFactory().createLineString(new Coordinate[] {c1, c2}); } return geometry; }
/** * Create an edge. If twoWay, create two edges (back and forth). * * @param vA * @param vB * @param length * @param back true if this is a reverse edge */ private PlainStreetEdge edge(StreetVertex vA, StreetVertex vB, double length, boolean back) { String labelA = vA.getLabel(); String labelB = vB.getLabel(); String name = String.format("%s_%s", labelA, labelB); Coordinate[] coords = new Coordinate[2]; coords[0] = vA.getCoordinate(); coords[1] = vB.getCoordinate(); LineString geom = GeometryUtils.getGeometryFactory().createLineString(coords); StreetTraversalPermission perm = StreetTraversalPermission.ALL; return new PlainStreetEdge(vA, vB, geom, name, length, perm, back); }
private void finalizeLeg( Leg leg, State state, List<State> states, int start, int end, CoordinateArrayListSequence coordinates) { if (start != -1) { leg.walkSteps = getWalkSteps(states.subList(start, end + 1)); } leg.endTime = makeCalendar(state.getBackState()); Geometry geometry = GeometryUtils.getGeometryFactory().createLineString(coordinates); leg.legGeometry = PolylineEncoder.createEncodings(geometry); leg.to = makePlace(state, true); coordinates.clear(); }
private void finalizeLeg( Leg leg, State state, List<State> states, int start, int end, CoordinateArrayListSequence coordinates, Itinerary itinerary) { // this leg has already been added to the itinerary, so we actually want the penultimate leg, if // any if (states != null) { int extra = 0; WalkStep continuation = null; if (itinerary.legs.size() >= 2) { Leg previousLeg = itinerary.legs.get(itinerary.legs.size() - 2); if (previousLeg.walkSteps != null) { continuation = previousLeg.walkSteps.get(previousLeg.walkSteps.size() - 1); extra = 1; } } if (end == states.size() - 1) { extra = 1; } leg.walkSteps = getWalkSteps(states.subList(start, end + extra), continuation); } leg.endTime = makeCalendar(state.getBackState()); Geometry geometry = GeometryUtils.getGeometryFactory().createLineString(coordinates); leg.legGeometry = PolylineEncoder.createEncodings(geometry); Edge backEdge = state.getBackEdge(); String name; if (backEdge instanceof StreetEdge) { name = backEdge.getName(); } else { name = state.getVertex().getName(); } leg.to = makePlace(state, name, true); coordinates.clear(); }
@Test public final void testOnBoardDepartureTime() { Coordinate[] coordinates = new Coordinate[5]; coordinates[0] = new Coordinate(0.0, 0.0); coordinates[1] = new Coordinate(0.0, 1.0); coordinates[2] = new Coordinate(2.0, 1.0); coordinates[3] = new Coordinate(5.0, 1.0); coordinates[4] = new Coordinate(5.0, 5.0); PatternDepartVertex depart = mock(PatternDepartVertex.class); PatternArriveVertex dwell = mock(PatternArriveVertex.class); PatternArriveVertex arrive = mock(PatternArriveVertex.class); Graph graph = mock(Graph.class); RoutingRequest routingRequest = mock(RoutingRequest.class); ServiceDay serviceDay = mock(ServiceDay.class); when(graph.getTimeZone()).thenReturn(TimeZone.getTimeZone("GMT")); GeometryFactory geometryFactory = GeometryUtils.getGeometryFactory(); CoordinateSequenceFactory coordinateSequenceFactory = geometryFactory.getCoordinateSequenceFactory(); CoordinateSequence coordinateSequence = coordinateSequenceFactory.create(coordinates); LineString geometry = new LineString(coordinateSequence, geometryFactory); ArrayList<Edge> hops = new ArrayList<Edge>(2); RoutingContext routingContext = new RoutingContext(routingRequest, graph, null, arrive); AgencyAndId agencyAndId = new AgencyAndId("Agency", "ID"); Route route = new Route(); ArrayList<StopTime> stopTimes = new ArrayList<StopTime>(3); StopTime stopDepartTime = new StopTime(); StopTime stopDwellTime = new StopTime(); StopTime stopArriveTime = new StopTime(); Stop stopDepart = new Stop(); Stop stopDwell = new Stop(); Stop stopArrive = new Stop(); Trip trip = new Trip(); routingContext.serviceDays = new ArrayList<ServiceDay>(Collections.singletonList(serviceDay)); route.setId(agencyAndId); stopDepart.setId(agencyAndId); stopDwell.setId(agencyAndId); stopArrive.setId(agencyAndId); stopDepartTime.setStop(stopDepart); stopDepartTime.setDepartureTime(0); stopDwellTime.setArrivalTime(20); stopDwellTime.setStop(stopDwell); stopDwellTime.setDepartureTime(40); stopArriveTime.setArrivalTime(60); stopArriveTime.setStop(stopArrive); stopTimes.add(stopDepartTime); stopTimes.add(stopDwellTime); stopTimes.add(stopArriveTime); trip.setId(agencyAndId); trip.setTripHeadsign("The right"); TripTimes tripTimes = new TripTimes(trip, stopTimes, new Deduplicator()); StopPattern stopPattern = new StopPattern(stopTimes); TripPattern tripPattern = new TripPattern(route, stopPattern); when(depart.getTripPattern()).thenReturn(tripPattern); when(dwell.getTripPattern()).thenReturn(tripPattern); PatternHop patternHop0 = new PatternHop(depart, dwell, stopDepart, stopDwell, 0); PatternHop patternHop1 = new PatternHop(dwell, arrive, stopDwell, stopArrive, 1); hops.add(patternHop0); hops.add(patternHop1); when(graph.getEdges()).thenReturn(hops); when(depart.getCoordinate()).thenReturn(new Coordinate(0, 0)); when(dwell.getCoordinate()).thenReturn(new Coordinate(0, 0)); when(arrive.getCoordinate()).thenReturn(new Coordinate(0, 0)); when(routingRequest.getFrom()).thenReturn(new GenericLocation()); when(routingRequest.getStartingTransitTripId()).thenReturn(agencyAndId); when(serviceDay.secondsSinceMidnight(anyInt())).thenReturn(9); patternHop0.setGeometry(geometry); tripPattern.add(tripTimes); graph.index = new GraphIndex(graph); coordinates = new Coordinate[3]; coordinates[0] = new Coordinate(3.5, 1.0); coordinates[1] = new Coordinate(5.0, 1.0); coordinates[2] = new Coordinate(5.0, 5.0); coordinateSequence = coordinateSequenceFactory.create(coordinates); geometry = new LineString(coordinateSequence, geometryFactory); Vertex vertex = onBoardDepartServiceImpl.setupDepartOnBoard(routingContext); Edge edge = vertex.getOutgoing().toArray(new Edge[1])[0]; assertEquals(vertex, edge.getFromVertex()); assertEquals(dwell, edge.getToVertex()); assertEquals("The right", edge.getDirection()); assertEquals(geometry, edge.getGeometry()); assertEquals(coordinates[0].x, vertex.getX(), 0.0); assertEquals(coordinates[0].y, vertex.getY(), 0.0); }
/** * Get polygons covering the components of the graph. The largest component (in terms of number of * nodes) will not overlap any other components (it will have holes); the others may overlap each * other. * * @param dateTime */ public static List<Geometry> getComponentPolygons( Graph graph, RoutingRequest options, long time) { DisjointSet<Vertex> components = getConnectedComponents(graph); LinkedListMultimap<Integer, Coordinate> componentCoordinates = LinkedListMultimap.create(); options.setDummyRoutingContext(graph); for (Vertex v : graph.getVertices()) { for (Edge e : v.getOutgoing()) { State s0 = new State(v, time, options); State s1 = e.traverse(s0); if (s1 != null) { Integer component = components.find(e.getFromVertex()); Geometry geometry = s1.getBackEdge().getGeometry(); if (geometry != null) { List<Coordinate> coordinates = new ArrayList<Coordinate>(Arrays.asList(geometry.getCoordinates())); for (int i = 0; i < coordinates.size(); ++i) { Coordinate coordinate = new Coordinate(coordinates.get(i)); coordinate.x = Math.round(coordinate.x * PRECISION) / PRECISION; coordinate.y = Math.round(coordinate.y * PRECISION) / PRECISION; coordinates.set(i, coordinate); } componentCoordinates.putAll(component, coordinates); } } } } // generate convex hull of each component List<Geometry> geoms = new ArrayList<Geometry>(); int mainComponentSize = 0; int mainComponentIndex = -1; int component = 0; for (Integer key : componentCoordinates.keySet()) { List<Coordinate> coords = componentCoordinates.get(key); Coordinate[] coordArray = new Coordinate[coords.size()]; ConvexHull hull = new ConvexHull(coords.toArray(coordArray), GeometryUtils.getGeometryFactory()); Geometry geom = hull.getConvexHull(); // buffer components which are mere lines so that they do not disappear. if (geom instanceof LineString) { geom = geom.buffer(0.01); // ~10 meters } else if (geom instanceof Point) { geom = geom.buffer(0.05); // ~50 meters, so that it shows up } geoms.add(geom); if (mainComponentSize < coordArray.length) { mainComponentIndex = component; mainComponentSize = coordArray.length; } ++component; } // subtract small components out of main component // (small components are permitted to overlap each other) Geometry mainComponent = geoms.get(mainComponentIndex); for (int i = 0; i < geoms.size(); ++i) { Geometry geom = geoms.get(i); if (i == mainComponentIndex) { continue; } mainComponent = mainComponent.difference(geom); } geoms.set(mainComponentIndex, mainComponent); return geoms; }
@Override public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra) { final Parser parser[] = new Parser[] {new Parser()}; GeometryFactory geometryFactory = GeometryUtils.getGeometryFactory(); EarliestArrivalSPTService earliestArrivalSPTService = new EarliestArrivalSPTService(); earliestArrivalSPTService.maxDuration = (maxDuration); for (TransitStop ts : Iterables.filter(graph.getVertices(), TransitStop.class)) { // Only link street linkable stops if (!ts.isStreetLinkable()) continue; LOG.trace("linking stop '{}' {}", ts.getStop(), ts); // Determine the set of pathway/transfer destinations Set<TransitStop> pathwayDestinations = new HashSet<TransitStop>(); for (Edge e : ts.getOutgoing()) { if (e instanceof PathwayEdge || e instanceof SimpleTransfer) { if (e.getToVertex() instanceof TransitStop) { TransitStop to = (TransitStop) e.getToVertex(); pathwayDestinations.add(to); } } } int n = 0; RoutingRequest routingRequest = new RoutingRequest(TraverseMode.WALK); routingRequest.clampInitialWait = (0L); routingRequest.setRoutingContext(graph, ts, null); routingRequest.rctx.pathParsers = parser; ShortestPathTree spt = earliestArrivalSPTService.getShortestPathTree(routingRequest); if (spt != null) { for (State state : spt.getAllStates()) { Vertex vertex = state.getVertex(); if (ts == vertex) continue; if (vertex instanceof TransitStop) { TransitStop other = (TransitStop) vertex; if (!other.isStreetLinkable()) continue; if (pathwayDestinations.contains(other)) { LOG.trace("Skipping '{}', {}, already connected.", other.getStop(), other); continue; } double distance = 0.0; GraphPath graphPath = new GraphPath(state, false); CoordinateArrayListSequence coordinates = new CoordinateArrayListSequence(); for (Edge edge : graphPath.edges) { if (edge instanceof StreetEdge) { LineString geometry = edge.getGeometry(); if (geometry != null) { if (coordinates.size() == 0) { coordinates.extend(geometry.getCoordinates()); } else { coordinates.extend(geometry.getCoordinates(), 1); } } distance += edge.getDistance(); } } if (coordinates.size() < 2) { // Otherwise the walk step generator breaks. ArrayList<Coordinate> coordinateList = new ArrayList<Coordinate>(2); coordinateList.add(graphPath.states.get(1).getVertex().getCoordinate()); State lastState = graphPath.states.getLast().getBackState(); coordinateList.add(lastState.getVertex().getCoordinate()); coordinates = new CoordinateArrayListSequence(coordinateList); } LineString geometry = geometryFactory.createLineString( new PackedCoordinateSequence.Double(coordinates.toCoordinateArray())); LOG.trace(" to stop: '{}' {} ({}m) [{}]", other.getStop(), other, distance, geometry); new SimpleTransfer(ts, other, distance, geometry); n++; } } } LOG.trace("linked to {} others.", n); if (n == 0) { LOG.warn(graph.addBuilderAnnotation(new StopNotLinkedForTransfers(ts))); } } }