public void setUp() throws Exception { context = GtfsLibrary.readGtfs(new File(ConstantsForTests.FAKE_GTFS)); graph = new Graph(); GTFSPatternHopFactory factory = new GTFSPatternHopFactory(context); factory.run(graph); graph.putService( CalendarServiceData.class, GtfsLibrary.createCalendarServiceData(context.getDao())); String[] stops = { "agency:A", "agency:B", "agency:C", "agency:D", "agency:E", "agency:entrance_a", "agency:entrance_b" }; for (int i = 0; i < stops.length; ++i) { TransitStop stop = (TransitStop) (graph.getVertex(stops[i])); IntersectionVertex front = new IntersectionVertex( graph, "near_1_" + stop.getStopId(), stop.getX() + 0.0001, stop.getY() + 0.0001); IntersectionVertex back = new IntersectionVertex( graph, "near_2_" + stop.getStopId(), stop.getX() - 0.0001, stop.getY() - 0.0001); StreetEdge street1 = new StreetEdge( front, back, GeometryUtils.makeLineString( stop.getX() + 0.0001, stop.getY() + 0.0001, stop.getX() - 0.0001, stop.getY() - 0.0001), "street", 100, StreetTraversalPermission.ALL, false); StreetEdge street2 = new StreetEdge( back, front, GeometryUtils.makeLineString( stop.getX() - 0.0001, stop.getY() - 0.0001, stop.getX() + 0.0001, stop.getY() + 0.0001), "street", 100, StreetTraversalPermission.ALL, true); } NetworkLinker nl = new NetworkLinker(graph); nl.createLinkage(); }
private void makeEdges(StreetVertex v1, StreetVertex v2, String name) { LineString geometry = GeometryUtils.makeLineString( v1.getCoordinate().x, v1.getCoordinate().y, v2.getCoordinate().x, v2.getCoordinate().y); double length = SphericalDistanceLibrary.getInstance().distance(v1.getCoordinate(), v2.getCoordinate()); new PlainStreetEdge(v1, v2, geometry, name, length, StreetTraversalPermission.ALL, false); geometry = GeometryUtils.makeLineString( v2.getCoordinate().x, v2.getCoordinate().y, v1.getCoordinate().x, v1.getCoordinate().y); new PlainStreetEdge(v2, v1, geometry, name, length, StreetTraversalPermission.ALL, true); }
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(); }
/** Split this street edge and return the resulting street edges */ public P2<StreetEdge> split(SplitterVertex v) { P2<LineString> geoms = GeometryUtils.splitGeometryAtPoint(getGeometry(), v.getCoordinate()); StreetEdge e1 = new StreetEdge((StreetVertex) fromv, v, geoms.first, name, 0, permission, this.isBack()); StreetEdge e2 = new StreetEdge(v, (StreetVertex) tov, geoms.second, name, 0, permission, this.isBack()); // figure the lengths, ensuring that they sum to the length of this edge e1.calculateLengthFromGeometry(); e2.calculateLengthFromGeometry(); // we have this code implemented in both directions, because splits are fudged half a millimeter // when the length of this is odd. We want to make sure the lengths of the split streets end up // exactly the same as their backStreets so that if they are split again the error does not // accumulate // and so that the order in which they are split does not matter. if (!isBack()) { // cast before the divide so that the sum is promoted double frac = (double) e1.length_mm / (e1.length_mm + e2.length_mm); e1.length_mm = (int) (length_mm * frac); e2.length_mm = length_mm - e1.length_mm; } else { // cast before the divide so that the sum is promoted double frac = (double) e2.length_mm / (e1.length_mm + e2.length_mm); e2.length_mm = (int) (length_mm * frac); e1.length_mm = length_mm - e2.length_mm; } if (e1.length_mm < 0 || e2.length_mm < 0) { e1.tov.removeIncoming(e1); e1.fromv.removeOutgoing(e1); e2.tov.removeIncoming(e2); e2.fromv.removeOutgoing(e2); throw new IllegalStateException("Split street is longer than original street!"); } for (StreetEdge e : new StreetEdge[] {e1, e2}) { e.setBicycleSafetyFactor(getBicycleSafetyFactor()); e.setHasBogusName(hasBogusName()); e.setStairs(isStairs()); e.setWheelchairAccessible(isWheelchairAccessible()); e.setBack(isBack()); } return new P2<StreetEdge>(e1, e2); }
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); }
/** * Returns the chunk of the given geometry between the two given coordinates. * * <p>Assumes that "second" is after "first" along the input geometry. */ public static LineString getInteriorSegment( Geometry geomerty, Coordinate first, Coordinate second) { P2<LineString> splitGeom = GeometryUtils.splitGeometryAtPoint(geomerty, first); splitGeom = GeometryUtils.splitGeometryAtPoint(splitGeom.second, second); return splitGeom.first; }
/** * 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))); } } }
public void setUp() { graph = new Graph(); // a 0.1 degree x 0.1 degree square top = new StreetVertex( "top", GeometryUtils.makeLineString(-74.01, 40.01, -74.0, 40.01), "top", 1500, false, null); bottom = new StreetVertex( "bottom", GeometryUtils.makeLineString(-74.01, 40.0, -74.0, 40.0), "bottom", 1500, false, null); left = new StreetVertex( "left", GeometryUtils.makeLineString(-74.01, 40.0, -74.01, 40.01), "left", 1500, false, null); right = new StreetVertex( "right", GeometryUtils.makeLineString(-74.0, 40.0, -74.0, 40.01), "right", 1500, false, null); StreetVertex topBack = new StreetVertex( "topBack", GeometryUtils.makeLineString(-74.0, 40.01, -74.01, 40.01), "topBack", 1500, true, null); StreetVertex bottomBack = new StreetVertex( "bottomBack", GeometryUtils.makeLineString(-74.0, 40.0, -74.01, 40.0), "bottomBack", 1500, true, null); leftBack = new StreetVertex( "leftBack", GeometryUtils.makeLineString(-74.01, 40.01, -74.01, 40.0), "leftBack", 1500, true, null); rightBack = new StreetVertex( "rightBack", GeometryUtils.makeLineString(-74.0, 40.01, -74.0, 40.0), "rightBack", 1500, true, null); right.setPermission(StreetTraversalPermission.PEDESTRIAN); graph.addVertex(top); graph.addVertex(bottom); graph.addVertex(left); graph.addVertex(right); graph.addVertex(topBack); graph.addVertex(bottomBack); graph.addVertex(leftBack); graph.addVertex(rightBack); EndpointVertex tlIn = (EndpointVertex) graph.addVertex(new EndpointVertex("tl in", -74.01, 40.01)); EndpointVertex trIn = (EndpointVertex) graph.addVertex(new EndpointVertex("tr in", -74.0, 40.01)); EndpointVertex blIn = (EndpointVertex) graph.addVertex(new EndpointVertex("bl in", -74.0, 40.0)); EndpointVertex brIn = (EndpointVertex) graph.addVertex(new EndpointVertex("br in", -74.01, 40.0)); Vertex tlOut = graph.addVertex(new EndpointVertex("tl out", -74.01, 40.01)); trOut = graph.addVertex(new EndpointVertex("tr out", -74.0, 40.01)); Vertex blOut = graph.addVertex(new EndpointVertex("bl out", -74.0, 40.0)); brOut = graph.addVertex(new EndpointVertex("br out", -74.01, 40.0)); graph.addEdge(new FreeEdge(tlOut, top)); graph.addEdge(new FreeEdge(tlOut, leftBack)); graph.addEdge(new FreeEdge(trOut, topBack)); graph.addEdge(new FreeEdge(trOut, rightBack)); graph.addEdge(new FreeEdge(blOut, bottom)); graph.addEdge(new FreeEdge(blOut, left)); graph.addEdge(new FreeEdge(brOut, bottomBack)); graph.addEdge(new FreeEdge(brOut, right)); graph.addEdge(new OutEdge(topBack, tlIn)); graph.addEdge(new OutEdge(left, tlIn)); graph.addEdge(new OutEdge(top, trIn)); graph.addEdge(new OutEdge(right, trIn)); graph.addEdge(new OutEdge(bottomBack, blIn)); graph.addEdge(new OutEdge(leftBack, blIn)); graph.addEdge(new OutEdge(bottom, brIn)); graph.addEdge(new OutEdge(rightBack, brIn)); graph.addEdge(new TurnEdge(top, rightBack)); graph.addEdge(new TurnEdge(rightBack, bottomBack)); graph.addEdge(new TurnEdge(bottomBack, left)); graph.addEdge(new TurnEdge(left, top)); graph.addEdge(new TurnEdge(topBack, leftBack)); graph.addEdge(new TurnEdge(leftBack, bottom)); graph.addEdge(new TurnEdge(bottom, right)); graph.addEdge(new TurnEdge(right, topBack)); station1 = new TransitStop( "transitVertex 1", -74.005, 40.0099999, "transitVertex 1", new AgencyAndId("A", "fleem station"), null); graph.addVertex(station1); station2 = new TransitStop( "transitVertex 2", -74.002, 40.0099999, "transitVertex 2", new AgencyAndId("A", "morx station"), null); graph.addVertex(station2); }