├── .github
└── workflows
│ └── gradle.yml
├── .gitignore
├── LICENSE
├── README.md
├── analysis.properties.template
├── analysis.properties.test
├── build.gradle
├── census
├── downloadData.py
├── geobuf.proto
├── randomizeCsv.py
└── seamless-census.md
├── docs
├── README.r5.md
├── advanced-usage.md
├── debug-interface.png
├── fares
│ ├── fareto.png
│ ├── index.md
│ └── newyork.md
├── index.md
├── mkdocs.yml
└── static-output.md
├── pom.xml
├── settings.gradle
└── src
├── main
├── java
│ ├── com
│ │ └── conveyal
│ │ │ ├── analysis
│ │ │ ├── AnalysisServerException.java
│ │ │ ├── BackendConfig.java
│ │ │ ├── BackendMain.java
│ │ │ ├── BackendVersion.java
│ │ │ ├── RegionalAnalysisStatus.java
│ │ │ ├── SelectingGridReducer.java
│ │ │ ├── UserPermissions.java
│ │ │ ├── components
│ │ │ │ ├── Authentication.java
│ │ │ │ ├── Component.java
│ │ │ │ ├── Components.java
│ │ │ │ ├── Compute.java
│ │ │ │ ├── HttpApi.java
│ │ │ │ ├── LocalAuthentication.java
│ │ │ │ ├── LocalComponents.java
│ │ │ │ ├── LocalWorkerLauncher.java
│ │ │ │ ├── TaskScheduler.java
│ │ │ │ ├── WorkerLauncher.java
│ │ │ │ ├── broker
│ │ │ │ │ ├── Broker.java
│ │ │ │ │ ├── Job.java
│ │ │ │ │ ├── JobStatus.java
│ │ │ │ │ ├── RedeliveryTest.java
│ │ │ │ │ ├── WorkerCatalog.java
│ │ │ │ │ ├── WorkerObservation.java
│ │ │ │ │ ├── WorkerStartupScriptTestHook.java
│ │ │ │ │ └── WorkerTags.java
│ │ │ │ └── eventbus
│ │ │ │ │ ├── CrudEvent.java
│ │ │ │ │ ├── Event.java
│ │ │ │ │ ├── EventBus.java
│ │ │ │ │ ├── FileUploadEvent.java
│ │ │ │ │ ├── RegionalAnalysisEvent.java
│ │ │ │ │ ├── SinglePointEvent.java
│ │ │ │ │ └── WorkerEvent.java
│ │ │ ├── controllers
│ │ │ │ ├── AggregationAreaController.java
│ │ │ │ ├── BrokerController.java
│ │ │ │ ├── BundleController.java
│ │ │ │ ├── FileStorageController.java
│ │ │ │ ├── GTFSGraphQLController.java
│ │ │ │ ├── HttpController.java
│ │ │ │ ├── ModificationController.java
│ │ │ │ ├── OpportunityDatasetController.java
│ │ │ │ ├── ProjectController.java
│ │ │ │ ├── RegionalAnalysisController.java
│ │ │ │ ├── TimetableController.java
│ │ │ │ ├── WrappedFeedInfo.java
│ │ │ │ └── package-info.java
│ │ │ ├── grids
│ │ │ │ └── SeamlessCensusGridExtractor.java
│ │ │ ├── models
│ │ │ │ ├── AbstractTimetable.java
│ │ │ │ ├── AddStreets.java
│ │ │ │ ├── AddTripPattern.java
│ │ │ │ ├── AdjustDwellTime.java
│ │ │ │ ├── AdjustSpeed.java
│ │ │ │ ├── AggregationArea.java
│ │ │ │ ├── AnalysisRequest.java
│ │ │ │ ├── BaseModel.java
│ │ │ │ ├── Bounds.java
│ │ │ │ ├── Bundle.java
│ │ │ │ ├── ConvertToFrequency.java
│ │ │ │ ├── CustomModificationHolder.java
│ │ │ │ ├── FileInfo.java
│ │ │ │ ├── JsonViews.java
│ │ │ │ ├── Model.java
│ │ │ │ ├── Modification.java
│ │ │ │ ├── ModificationStop.java
│ │ │ │ ├── ModifyStreets.java
│ │ │ │ ├── OpportunityDataset.java
│ │ │ │ ├── Project.java
│ │ │ │ ├── Region.java
│ │ │ │ ├── RegionalAnalysis.java
│ │ │ │ ├── RemoveStops.java
│ │ │ │ ├── RemoveTrips.java
│ │ │ │ ├── Reroute.java
│ │ │ │ └── Segment.java
│ │ │ ├── persistence
│ │ │ │ ├── AnalysisCollection.java
│ │ │ │ ├── AnalysisDB.java
│ │ │ │ ├── MongoMap.java
│ │ │ │ └── Persistence.java
│ │ │ ├── results
│ │ │ │ ├── CsvResultWriter.java
│ │ │ │ ├── GridResultWriter.java
│ │ │ │ ├── MultiOriginAssembler.java
│ │ │ │ └── ResultWriter.java
│ │ │ └── util
│ │ │ │ ├── BsonObjectIdModule.java
│ │ │ │ ├── FileItemInputStreamProvider.java
│ │ │ │ ├── HttpStatus.java
│ │ │ │ ├── HttpUtils.java
│ │ │ │ ├── Jobs.java
│ │ │ │ └── JsonUtil.java
│ │ │ ├── data
│ │ │ ├── census
│ │ │ │ ├── CensusExtractor.java
│ │ │ │ ├── CensusLoader.java
│ │ │ │ ├── FileSeamlessSource.java
│ │ │ │ ├── LodesSource.java
│ │ │ │ ├── S3SeamlessSource.java
│ │ │ │ ├── SeamlessSource.java
│ │ │ │ ├── ShapeDataStore.java
│ │ │ │ └── TigerLineSource.java
│ │ │ └── geobuf
│ │ │ │ ├── GeobufDecoder.java
│ │ │ │ ├── GeobufEncoder.java
│ │ │ │ ├── GeobufFeature.java
│ │ │ │ └── ShapefileToGeobuf.java
│ │ │ ├── file
│ │ │ ├── FileStorage.java
│ │ │ ├── FileStorageFormat.java
│ │ │ ├── FileStorageKey.java
│ │ │ ├── FileUtils.java
│ │ │ ├── LocalFileStorage.java
│ │ │ └── S3FileStorage.java
│ │ │ ├── gtfs
│ │ │ ├── CropGTFS.java
│ │ │ ├── GTFSCache.java
│ │ │ ├── GTFSFeed.java
│ │ │ ├── Geometries.java
│ │ │ ├── TripPatternKey.java
│ │ │ ├── api
│ │ │ │ ├── ApiMain.java
│ │ │ │ ├── graphql
│ │ │ │ │ ├── GeoJsonCoercing.java
│ │ │ │ │ ├── GraphQLGtfsSchema.java
│ │ │ │ │ ├── WrappedEntityFieldFetcher.java
│ │ │ │ │ ├── WrappedGTFSEntity.java
│ │ │ │ │ ├── fetchers
│ │ │ │ │ │ ├── FeedFetcher.java
│ │ │ │ │ │ ├── PatternFetcher.java
│ │ │ │ │ │ ├── RouteFetcher.java
│ │ │ │ │ │ ├── StopFetcher.java
│ │ │ │ │ │ ├── StopTimeFetcher.java
│ │ │ │ │ │ └── TripDataFetcher.java
│ │ │ │ │ └── types
│ │ │ │ │ │ ├── FeedType.java
│ │ │ │ │ │ ├── PatternType.java
│ │ │ │ │ │ ├── RouteType.java
│ │ │ │ │ │ ├── StopTimeType.java
│ │ │ │ │ │ ├── StopType.java
│ │ │ │ │ │ └── TripType.java
│ │ │ │ └── util
│ │ │ │ │ ├── GeomUtil.java
│ │ │ │ │ └── GraphQLUtil.java
│ │ │ ├── error
│ │ │ │ ├── DateParseError.java
│ │ │ │ ├── DuplicateKeyError.java
│ │ │ │ ├── DuplicateStopError.java
│ │ │ │ ├── DuplicateTripError.java
│ │ │ │ ├── EmptyFieldError.java
│ │ │ │ ├── EmptyTableError.java
│ │ │ │ ├── GTFSError.java
│ │ │ │ ├── GeneralError.java
│ │ │ │ ├── MisplacedStopError.java
│ │ │ │ ├── MissingColumnError.java
│ │ │ │ ├── MissingShapeError.java
│ │ │ │ ├── MissingTableError.java
│ │ │ │ ├── NewGTFSError.java
│ │ │ │ ├── NewGTFSErrorType.java
│ │ │ │ ├── NoAgencyInFeedError.java
│ │ │ │ ├── NoTripsForRouteError.java
│ │ │ │ ├── NumberParseError.java
│ │ │ │ ├── OverlappingTripsInBlockError.java
│ │ │ │ ├── RangeError.java
│ │ │ │ ├── ReferentialIntegrityError.java
│ │ │ │ ├── ReversedTripShapeError.java
│ │ │ │ ├── SQLErrorStorage.java
│ │ │ │ ├── ShapeMissingCoordinatesError.java
│ │ │ │ ├── TableInSubdirectoryError.java
│ │ │ │ ├── TimeParseError.java
│ │ │ │ ├── TimeZoneError.java
│ │ │ │ ├── URLParseError.java
│ │ │ │ ├── UnusedStopError.java
│ │ │ │ └── package-info.java
│ │ │ ├── loader
│ │ │ │ ├── BooleanField.java
│ │ │ │ ├── CSVResultSetAdapter.java
│ │ │ │ ├── ColorField.java
│ │ │ │ ├── CurrencyField.java
│ │ │ │ ├── DateField.java
│ │ │ │ ├── DoubleField.java
│ │ │ │ ├── EntityPopulator.java
│ │ │ │ ├── Field.java
│ │ │ │ ├── IntegerField.java
│ │ │ │ ├── LanguageField.java
│ │ │ │ ├── Requirement.java
│ │ │ │ ├── SQLEntityFetcher.java
│ │ │ │ ├── ShortField.java
│ │ │ │ ├── StringField.java
│ │ │ │ ├── Table.java
│ │ │ │ ├── TableReader.java
│ │ │ │ ├── TimeField.java
│ │ │ │ └── URLField.java
│ │ │ ├── model
│ │ │ │ ├── Agency.java
│ │ │ │ ├── Calendar.java
│ │ │ │ ├── CalendarDate.java
│ │ │ │ ├── Entity.java
│ │ │ │ ├── Fare.java
│ │ │ │ ├── FareAttribute.java
│ │ │ │ ├── FareRule.java
│ │ │ │ ├── FeedInfo.java
│ │ │ │ ├── Frequency.java
│ │ │ │ ├── Pattern.java
│ │ │ │ ├── Route.java
│ │ │ │ ├── Service.java
│ │ │ │ ├── Shape.java
│ │ │ │ ├── ShapeMap.java
│ │ │ │ ├── ShapePoint.java
│ │ │ │ ├── Stop.java
│ │ │ │ ├── StopTime.java
│ │ │ │ ├── Transfer.java
│ │ │ │ ├── Trip.java
│ │ │ │ └── package-info.java
│ │ │ ├── storage
│ │ │ │ ├── BooleanAsciiGrid.java
│ │ │ │ └── StorageException.java
│ │ │ ├── util
│ │ │ │ ├── Deduplicator.java
│ │ │ │ ├── GeometryUtil.java
│ │ │ │ ├── Renamer.java
│ │ │ │ ├── Util.java
│ │ │ │ └── json
│ │ │ │ │ ├── JacksonSerializers.java
│ │ │ │ │ ├── JsonManager.java
│ │ │ │ │ ├── Rectangle2DDeserializer.java
│ │ │ │ │ └── Rectangle2DMixIn.java
│ │ │ └── validator
│ │ │ │ ├── model
│ │ │ │ ├── DuplicateStops.java
│ │ │ │ └── Priority.java
│ │ │ │ └── service
│ │ │ │ ├── GeoUtils.java
│ │ │ │ └── ProjectedCoordinate.java
│ │ │ ├── osmlib
│ │ │ ├── DeflatedBlockReader.java
│ │ │ ├── DeflatedBlockWriter.java
│ │ │ ├── Node.java
│ │ │ ├── NodeTracker.java
│ │ │ ├── OSM.java
│ │ │ ├── OSMChangeParser.java
│ │ │ ├── OSMEntity.java
│ │ │ ├── OSMEntitySink.java
│ │ │ ├── OSMEntitySource.java
│ │ │ ├── PBFInput.java
│ │ │ ├── PBFOutput.java
│ │ │ ├── Relation.java
│ │ │ ├── StringTable.java
│ │ │ ├── TagCounter.java
│ │ │ ├── TextOutput.java
│ │ │ ├── TileOSMSource.java
│ │ │ ├── Updater.java
│ │ │ ├── VEXBlock.java
│ │ │ ├── VarIntInputStream.java
│ │ │ ├── VarIntOutputStream.java
│ │ │ ├── VexFormat.java
│ │ │ ├── VexInput.java
│ │ │ ├── VexOutput.java
│ │ │ ├── Way.java
│ │ │ ├── WebMercatorTile.java
│ │ │ ├── display
│ │ │ │ ├── Display.java
│ │ │ │ ├── GraphicsSink.java
│ │ │ │ └── WebMercatorTile.java
│ │ │ ├── main
│ │ │ │ ├── Converter.java
│ │ │ │ └── SpeedSetter.java
│ │ │ ├── package-info.java
│ │ │ └── serializer
│ │ │ │ ├── NodeSerializer.java
│ │ │ │ ├── VarInt.java
│ │ │ │ ├── WaySerializer.java
│ │ │ │ └── package-info.java
│ │ │ └── r5
│ │ │ ├── OneOriginResult.java
│ │ │ ├── R5Main.java
│ │ │ ├── analyst
│ │ │ ├── AccessibilityResult.java
│ │ │ ├── BootstrappingTravelTimeReducer.java
│ │ │ ├── ByteArrayOutputInputStream.java
│ │ │ ├── FileCategory.java
│ │ │ ├── FilePersistence.java
│ │ │ ├── FreeFormPointSet.java
│ │ │ ├── Grid.java
│ │ │ ├── GridTransformWrapper.java
│ │ │ ├── IsochroneFeature.java
│ │ │ ├── LinkageCache.java
│ │ │ ├── LittleEndianIntOutputStream.java
│ │ │ ├── MakeFreeFormTestCSV.java
│ │ │ ├── NetworkPreloader.java
│ │ │ ├── PathScorer.java
│ │ │ ├── PersistenceBuffer.java
│ │ │ ├── PointSet.java
│ │ │ ├── PointSetCache.java
│ │ │ ├── S3FilePersistence.java
│ │ │ ├── SelectingGridReducer.java
│ │ │ ├── TravelTimeComputer.java
│ │ │ ├── TravelTimeReducer.java
│ │ │ ├── WebMercatorExtents.java
│ │ │ ├── WebMercatorGridPointSet.java
│ │ │ ├── WebMercatorGridPointSetCache.java
│ │ │ ├── WorkerCategory.java
│ │ │ ├── cluster
│ │ │ │ ├── AnalysisWorker.java
│ │ │ │ ├── AnalysisWorkerController.java
│ │ │ │ ├── AnalysisWorkerTask.java
│ │ │ │ ├── BundleManifest.java
│ │ │ │ ├── EC2Info.java
│ │ │ │ ├── GridResultAssembler.java
│ │ │ │ ├── JobSimulator.java
│ │ │ │ ├── PathWriter.java
│ │ │ │ ├── RegionalTask.java
│ │ │ │ ├── RegionalWorkResult.java
│ │ │ │ ├── ScenarioCache.java
│ │ │ │ ├── ThroughputTracker.java
│ │ │ │ ├── TimeGridWriter.java
│ │ │ │ ├── TravelTimeResult.java
│ │ │ │ ├── TravelTimeSurfaceTask.java
│ │ │ │ ├── WorkerNotReadyException.java
│ │ │ │ └── WorkerStatus.java
│ │ │ ├── decay
│ │ │ │ ├── DecayFunction.java
│ │ │ │ ├── ExponentialDecayFunction.java
│ │ │ │ ├── FixedExponentialDecayFunction.java
│ │ │ │ ├── LinearDecayFunction.java
│ │ │ │ ├── LogisticDecayFunction.java
│ │ │ │ └── StepDecayFunction.java
│ │ │ ├── error
│ │ │ │ ├── ScenarioApplicationException.java
│ │ │ │ ├── TaskError.java
│ │ │ │ └── UnsupportedGeometryException.java
│ │ │ ├── fare
│ │ │ │ ├── BogotaInRoutingFareCalculator.java
│ │ │ │ ├── BogotaMixedInRoutingFareCalculator.java
│ │ │ │ ├── BostonInRoutingFareCalculator.java
│ │ │ │ ├── ChicagoInRoutingFareCalculator.java
│ │ │ │ ├── FareBounds.java
│ │ │ │ ├── InRoutingFareCalculator.java
│ │ │ │ ├── ParetoServer.java
│ │ │ │ ├── RouteBasedFareRules.java
│ │ │ │ ├── SimpleInRoutingFareCalculator.java
│ │ │ │ ├── TransferAllowance.java
│ │ │ │ ├── ZoneBasedFareSystem.java
│ │ │ │ ├── nyc
│ │ │ │ │ ├── LIRRStop.java
│ │ │ │ │ ├── LIRRTransferAllowance.java
│ │ │ │ │ ├── NYCFareDataCache.java
│ │ │ │ │ ├── NYCInRoutingFareCalculator.java
│ │ │ │ │ ├── NYCPatternType.java
│ │ │ │ │ ├── NYCStaticFareData.java
│ │ │ │ │ └── NYCTransferAllowance.java
│ │ │ │ └── package-info.java
│ │ │ ├── progress
│ │ │ │ ├── NetworkPreloaderProgressListener.java
│ │ │ │ ├── NoopProgressListener.java
│ │ │ │ ├── ProgressListener.java
│ │ │ │ ├── Task.java
│ │ │ │ ├── TaskAction.java
│ │ │ │ └── TaskExecutor.java
│ │ │ └── scenario
│ │ │ │ ├── AddStreets.java
│ │ │ │ ├── AddTrips.java
│ │ │ │ ├── AdjustDwellTime.java
│ │ │ │ ├── AdjustFrequency.java
│ │ │ │ ├── AdjustSpeed.java
│ │ │ │ ├── CustomModificationHolder.java
│ │ │ │ ├── IndexedPolygonCollection.java
│ │ │ │ ├── Modification.java
│ │ │ │ ├── ModificationPolygon.java
│ │ │ │ ├── ModificationTypeResolver.java
│ │ │ │ ├── ModifyStreets.java
│ │ │ │ ├── PickupDelay.java
│ │ │ │ ├── PickupWaitTimes.java
│ │ │ │ ├── RemoveStops.java
│ │ │ │ ├── RemoveTrips.java
│ │ │ │ ├── Reroute.java
│ │ │ │ ├── RoadCongestion.java
│ │ │ │ ├── Scenario.java
│ │ │ │ ├── SetFareCalculator.java
│ │ │ │ ├── StopSpec.java
│ │ │ │ └── package-info.java
│ │ │ ├── api
│ │ │ ├── GraphQlRequest.java
│ │ │ ├── ProfileResponse.java
│ │ │ └── util
│ │ │ │ ├── AbsoluteDirection.java
│ │ │ │ ├── Alert.java
│ │ │ │ ├── BikeRentalStation.java
│ │ │ │ ├── Coordinate.java
│ │ │ │ ├── Elevation.java
│ │ │ │ ├── Fare.java
│ │ │ │ ├── Itinerary.java
│ │ │ │ ├── LegMode.java
│ │ │ │ ├── ModeStopIndex.java
│ │ │ │ ├── NonTransitMode.java
│ │ │ │ ├── ParkRideParking.java
│ │ │ │ ├── PointToPointConnection.java
│ │ │ │ ├── PolylineGeometry.java
│ │ │ │ ├── ProfileOption.java
│ │ │ │ ├── RelativeDirection.java
│ │ │ │ ├── Route.java
│ │ │ │ ├── SearchType.java
│ │ │ │ ├── SegmentPattern.java
│ │ │ │ ├── Stats.java
│ │ │ │ ├── Stop.java
│ │ │ │ ├── StopCluster.java
│ │ │ │ ├── StreetEdgeInfo.java
│ │ │ │ ├── StreetSegment.java
│ │ │ │ ├── Transfer.java
│ │ │ │ ├── TransitJourneyID.java
│ │ │ │ ├── TransitModes.java
│ │ │ │ ├── TransitSegment.java
│ │ │ │ ├── Trip.java
│ │ │ │ └── TripPattern.java
│ │ │ ├── common
│ │ │ ├── DirectionUtils.java
│ │ │ ├── GeoJsonFeature.java
│ │ │ ├── GeometryUtils.java
│ │ │ ├── JsonUtilities.java
│ │ │ ├── SphericalDistanceLibrary.java
│ │ │ └── Util.java
│ │ │ ├── kryo
│ │ │ └── KryoNetworkSerializer.java
│ │ │ ├── labeling
│ │ │ ├── LevelOfTrafficStressLabeler.java
│ │ │ ├── RoadPermission.java
│ │ │ ├── SpeedLabeler.java
│ │ │ ├── TraversalPermissionLabeler.java
│ │ │ ├── TypeOfEdgeLabeler.java
│ │ │ ├── USTraversalPermissionLabeler.java
│ │ │ └── package-info.java
│ │ │ ├── model
│ │ │ └── json_serialization
│ │ │ │ ├── BitSetDeserializer.java
│ │ │ │ ├── BitSetSerializer.java
│ │ │ │ ├── JavaLocalDateDeserializer.java
│ │ │ │ ├── JavaLocalDateSerializer.java
│ │ │ │ ├── LegModeSetDeserializer.java
│ │ │ │ ├── LegModeSetSerializer.java
│ │ │ │ ├── LineStringDeserializer.java
│ │ │ │ ├── LineStringSerializer.java
│ │ │ │ ├── ModeSetDeserializer.java
│ │ │ │ ├── ModeSetSerializer.java
│ │ │ │ ├── PolyUtil.java
│ │ │ │ ├── TransitModeSetDeserializer.java
│ │ │ │ ├── TransitModeSetSerializer.java
│ │ │ │ ├── ZoneIdDeserializer.java
│ │ │ │ └── ZoneIdSerializer.java
│ │ │ ├── point_to_point
│ │ │ ├── PointToPointRouterServer.java
│ │ │ └── builder
│ │ │ │ ├── PointToPointQuery.java
│ │ │ │ ├── RouterInfo.java
│ │ │ │ ├── SpeedConfig.java
│ │ │ │ ├── SpeedUnit.java
│ │ │ │ └── TNBuilderConfig.java
│ │ │ ├── profile
│ │ │ ├── DominatingList.java
│ │ │ ├── ExecutionTimer.java
│ │ │ ├── FareDominatingList.java
│ │ │ ├── FastRaptorWorker.java
│ │ │ ├── FrequencyRandomOffsets.java
│ │ │ ├── HashPath.java
│ │ │ ├── McRaptorSuboptimalPathProfileRouter.java
│ │ │ ├── Path.java
│ │ │ ├── PathWithTimes.java
│ │ │ ├── PerTargetPropagater.java
│ │ │ ├── ProfileRequest.java
│ │ │ ├── PropagationTimer.java
│ │ │ ├── RaptorState.java
│ │ │ ├── RaptorTimer.java
│ │ │ ├── StatsCalculator.java
│ │ │ ├── StreetMode.java
│ │ │ ├── StreetPath.java
│ │ │ └── SuboptimalDominatingList.java
│ │ │ ├── shapefile
│ │ │ └── ShapefileMain.java
│ │ │ ├── streets
│ │ │ ├── BasicTraversalTimeCalculator.java
│ │ │ ├── BikeRentalBuilder.java
│ │ │ ├── DebugRoutingVisitor.java
│ │ │ ├── EdgeStore.java
│ │ │ ├── EdgeTraversalTimes.java
│ │ │ ├── EgressCostTable.java
│ │ │ ├── IntHashGrid.java
│ │ │ ├── LaDotBikeCostSupplier.java
│ │ │ ├── LaDotCostTags.java
│ │ │ ├── LaDotWalkCostSupplier.java
│ │ │ ├── LinkedPointSet.java
│ │ │ ├── OSMCache.java
│ │ │ ├── ParkRideRouter.java
│ │ │ ├── PointSetTimes.java
│ │ │ ├── RoutingVisitor.java
│ │ │ ├── SingleModeTraversalTimes.java
│ │ │ ├── Split.java
│ │ │ ├── StreetLayer.java
│ │ │ ├── StreetRouter.java
│ │ │ ├── TarjanIslandPruner.java
│ │ │ ├── TraversalTimeCalculator.java
│ │ │ ├── TurnRestriction.java
│ │ │ ├── VertexStore.java
│ │ │ └── package-info.java
│ │ │ ├── transit
│ │ │ ├── DuplicateFeedException.java
│ │ │ ├── PickDropType.java
│ │ │ ├── RouteInfo.java
│ │ │ ├── RouteTopology.java
│ │ │ ├── TransferFinder.java
│ │ │ ├── TransitLayer.java
│ │ │ ├── TransportNetwork.java
│ │ │ ├── TransportNetworkCache.java
│ │ │ ├── TripFlag.java
│ │ │ ├── TripPattern.java
│ │ │ ├── TripSchedule.java
│ │ │ ├── fare
│ │ │ │ ├── DCFareCalculator.java
│ │ │ │ ├── FareTable.java
│ │ │ │ ├── RideType.java
│ │ │ │ └── package-info.java
│ │ │ └── package-info.java
│ │ │ ├── transitive
│ │ │ ├── TransitiveNetwork.java
│ │ │ ├── TransitivePattern.java
│ │ │ ├── TransitiveRoute.java
│ │ │ ├── TransitiveStop.java
│ │ │ └── package-info.java
│ │ │ ├── trove
│ │ │ ├── AugmentedList.java
│ │ │ ├── TDoubleAugmentedList.java
│ │ │ ├── TIntAugmentedList.java
│ │ │ └── TLongAugmentedList.java
│ │ │ └── util
│ │ │ ├── AsyncLoader.java
│ │ │ ├── EmptyTIntCollection.java
│ │ │ ├── EncodedPolylineSerializer.java
│ │ │ ├── ExceptionUtils.java
│ │ │ ├── Histogram.java
│ │ │ ├── InputStreamProvider.java
│ │ │ ├── LambdaCounter.java
│ │ │ ├── LocationIndexedLineInLocalCoordinateSystem.java
│ │ │ ├── P2.java
│ │ │ ├── ProgressListener.java
│ │ │ ├── S3Util.java
│ │ │ ├── ShapefileReader.java
│ │ │ ├── TIntIntHashMultimap.java
│ │ │ ├── TIntIntMultimap.java
│ │ │ ├── TIntObjectHashMultimap.java
│ │ │ └── TIntObjectMultimap.java
│ └── geobuf
│ │ └── Geobuf.java
└── resources
│ ├── com
│ └── conveyal
│ │ └── gtfs
│ │ └── storage
│ │ └── gpwv3-quarter-boolean.asc
│ ├── debug-plan
│ ├── debug.html
│ ├── images
│ │ ├── marker-flag-end-shadowed.png
│ │ └── marker-flag-start-shadowed.png
│ ├── index.html
│ ├── leaflet-sidebar.css
│ ├── leaflet_context
│ │ ├── leaflet.contextmenu.css
│ │ └── leaflet.contextmenu.js
│ ├── new.html
│ ├── oneway.json
│ ├── oneway.png
│ ├── oneway@2x.json
│ ├── oneway@2x.png
│ └── scripts
│ │ ├── config.js
│ │ ├── debug.js
│ │ ├── graphql_plan.js
│ │ ├── gui.js
│ │ ├── lib
│ │ └── leaflet-sidebar.js
│ │ ├── plan.js
│ │ ├── request_query.json
│ │ └── utils.js
│ ├── fares
│ ├── dc
│ │ ├── marc.csv
│ │ ├── metrorail.csv
│ │ └── vre.csv
│ └── nyc
│ │ ├── lirr
│ │ ├── README.txt
│ │ ├── descendants.csv
│ │ ├── lirr_stops_fare_zones.csv
│ │ ├── lirr_zonal_fares.csv
│ │ └── via_fares.csv
│ │ ├── mnr
│ │ └── mnr_fares.csv
│ │ └── mta
│ │ ├── express_bus_routes.csv
│ │ └── subway_transfers.csv
│ └── logback.xml
└── test
├── java
└── com
│ └── conveyal
│ ├── analysis
│ ├── AnalysisServerTest.java
│ ├── TestComponents.java
│ ├── TestUtils.java
│ └── controllers
│ │ ├── BundleControllerTest.java
│ │ └── TimetableControllerTest.java
│ ├── data
│ ├── census
│ │ └── IntegrationTest.java
│ └── geobuf
│ │ ├── IntegrationTest.java
│ │ └── MapDBTest.java
│ ├── gtfs
│ ├── GTFSFeedTest.java
│ ├── GeometriesTest.java
│ ├── TestUtils.java
│ ├── loader
│ │ └── FieldTests.java
│ ├── storage
│ │ └── BooleanAsciiGridTest.java
│ └── util
│ │ └── UtilTest.java
│ ├── osmlib
│ ├── NodeTest.java
│ ├── NodeTrackerTest.java
│ ├── OSMEntityTest.java
│ ├── OSMTest.java
│ ├── RelationTest.java
│ ├── RoundTripTest.java
│ └── WayTest.java
│ └── r5
│ ├── analyst
│ ├── GridTest.java
│ ├── InitialStopsTest.java
│ ├── WebMercatorGridPointSetTest.java
│ ├── core
│ │ └── LocalDateSerialization.java
│ ├── decay
│ │ └── TestDecayFunctions.java
│ └── scenario
│ │ ├── AddTripsTest.java
│ │ ├── AdjustDwellTest.java
│ │ ├── AdjustFrequencyTest.java
│ │ ├── AdjustSpeedTest.java
│ │ ├── ChecksumTest.java
│ │ ├── FakeGraph.java
│ │ ├── RelinkingTest.java
│ │ ├── RemoveStopsTest.java
│ │ ├── RemoveTripsTest.java
│ │ └── RerouteTest.java
│ ├── api
│ └── util
│ │ ├── AnglesTest.java
│ │ ├── RoadAnglesTest.java
│ │ └── StreetSegmentTest.java
│ ├── kryo
│ └── KryoNetworkSerializerTest.java
│ ├── labeling
│ ├── TestPermissionsLabeler.java
│ ├── TraversalPermissionLabelerTest.java
│ └── TypeOfEdgeLabelerTest.java
│ ├── profile
│ ├── ProfileRequestTest.java
│ └── PropagatedTimesStoreTest.java
│ ├── streets
│ ├── BasicTraversalTimeCalculatorTest.java
│ ├── ReverseRoutingTest.java
│ ├── StreetLayerTest.java
│ ├── TimeDependentRoutingTest.java
│ ├── TurnRestrictionTest.java
│ └── TurnTest.java
│ └── transit
│ └── FrequencyRandomOffsetsTest.java
└── resources
├── bangor_maine.osm.pbf
├── com
└── conveyal
│ ├── data
│ └── census
│ │ └── integrationTest.zip
│ ├── gtfs
│ └── null-island-ferry
│ │ ├── agency.txt
│ │ ├── calendar.txt
│ │ ├── feed_info.txt
│ │ ├── routes.txt
│ │ ├── stop_times.txt
│ │ ├── stops.txt
│ │ └── trips.txt
│ └── r5
│ ├── analyst
│ └── scenario
│ │ └── columbus.osm.pbf
│ ├── api
│ └── util
│ │ ├── streetSegmentCAR_ROUNDABOUT.json
│ │ └── streetSegmentWALK.json
│ └── streets
│ ├── cathedral-no-left.pbf
│ ├── reisterstown-via-restriction.pbf
│ ├── snake-rd.pbf
│ ├── speedFlagsTest.pbf
│ └── subgraph.pbf
├── fake-agency.zip
├── fake-agency
├── agency.txt
├── calendar.txt
├── calendar_dates.txt
├── fare_attributes.txt
├── fare_rules.txt
├── feed_info.txt
├── frequencies.txt
├── routes.txt
├── shapes.txt
├── stop_times.txt
├── stops.txt
├── transfers.txt
└── trips.txt
├── felton.pbf
├── logback-test.xml
└── porto_portugal.osm.pbf
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle/
2 | /build/
3 | /out/
4 |
5 | # Ignore Gradle GUI config
6 | gradle-app.setting
7 |
8 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
9 | !gradle-wrapper.jar
10 |
11 | # Cache of project
12 | .gradletasknamecache
13 |
14 | # Other gradle build objects
15 | gradle
16 | gradlew.bat
17 | gradlew
18 |
19 | # IntelliJ IDEA
20 | .idea/
21 |
22 | logs
23 | project/project
24 | project/target
25 | .target
26 | target
27 | .DS_Store
28 | tmp
29 | .history
30 | dist
31 | /.idea
32 | /*.iml
33 | /out
34 | /.idea_modules
35 | /.classpath
36 | /.project
37 | /RUNNING_PID
38 | /.settings
39 | /data
40 | s3credentials
41 | *.class
42 | /bin
43 | /cache/
44 | *~
45 | nbproject
46 | logentries.xml
47 | src/main/resources/git.properties
48 | pom.xml.versionsBackup
49 | analysis.properties
50 | /src/test/resources/snapshots/com/conveyal/analysis/controllers/
51 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Conveyal
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Conveyal Analysis Backend
2 |
3 | ## This repository is deprecated. It has been merged into Conveyal's main routing component R5.
4 | Development of the Conveyal Analysis backend is continuing in [the r5 repository](https://github.com/conveyal/r5), and existing issues are being migrated there. Please create any new issues or pull requests against that repository.
5 |
--------------------------------------------------------------------------------
/census/randomizeCsv.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # Take a CSV from LODES and make all values unique so we can be sure that our tests
3 | # are working. Some columns are all zeros or are (almost) collinear, so accidentally
4 | # switching them might not make the tests fail.
5 |
6 | from csv import DictReader, DictWriter
7 | from sys import argv
8 |
9 | ct = 0
10 | def nextVal():
11 | global ct
12 | ct += 1
13 | return ct
14 |
15 | with open(argv[1]) as infile:
16 | reader = DictReader(infile)
17 |
18 | with open(argv[2], 'w') as outfile:
19 | writer = DictWriter(outfile, reader.fieldnames)
20 | writer.writeheader()
21 |
22 | for row in reader:
23 | writer.writerow({k: nextVal() if k.startswith('C') else v for k, v in row.iteritems()})
24 |
--------------------------------------------------------------------------------
/docs/advanced-usage.md:
--------------------------------------------------------------------------------
1 |
2 | # Advanced Usage
3 |
4 | ## Debug Interface
5 |
6 | When running R5 as a point to point router (with the `--point` parameter), a debug web interface is available to visualize the details of the street graph.
7 | It is available at [http://localhost:8080/debug.html].
8 |
9 | 
10 |
--------------------------------------------------------------------------------
/docs/debug-interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/docs/debug-interface.png
--------------------------------------------------------------------------------
/docs/fares/fareto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/docs/fares/fareto.png
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # R5
2 |
3 | Selected documentation for the Conveyal routing engine (r5).
4 |
5 | More thorough documentation of Conveyal Analysis is available in the analysis-ui repo.
--------------------------------------------------------------------------------
/docs/mkdocs.yml:
--------------------------------------------------------------------------------
1 | site_name: r5
2 | site_url: https://r5.readthedocs.org
3 | repo_url: https://github.com/conveyal/analysis-internal
4 | site_dir: ../target/mkdocs
5 | docs_dir: ../docs
6 | theme: readthedocs
7 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'analysis-backend'
2 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/RegionalAnalysisStatus.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis;
2 |
3 |
4 | import com.conveyal.analysis.results.MultiOriginAssembler;
5 |
6 | import java.io.Serializable;
7 |
8 | /**
9 | * This model object is sent to the UI serialized as JSON in order to report regional job progress.
10 | */
11 | public final class RegionalAnalysisStatus implements Serializable {
12 | public int total;
13 | public int complete;
14 |
15 | public RegionalAnalysisStatus() { /* No-arg constructor for deserialization only. */ }
16 |
17 | public RegionalAnalysisStatus(MultiOriginAssembler assembler) {
18 | total = assembler.nOriginsTotal;
19 | complete = assembler.nComplete;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/UserPermissions.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis;
2 |
3 | import com.google.common.collect.Sets;
4 |
5 | import java.util.Set;
6 |
7 | /**
8 | * Groups together all information about what a user is allowed to do.
9 | * Currently all such information is known from the group ID.
10 | * In the future we might have an EnumSet of additional flags, or a simple enum of "power levels".
11 | */
12 | public class UserPermissions {
13 |
14 | public final String email;
15 |
16 | public final Set groups;
17 |
18 | public final boolean admin;
19 |
20 | public UserPermissions (String email, boolean admin, String... groups) {
21 | this.email = email;
22 | this.admin = admin;
23 | this.groups = Sets.newHashSet(groups);
24 | }
25 |
26 | @Override
27 | public String toString () {
28 | return "UserPermissions{" +
29 | "email='" + email + '\'' +
30 | ", groups='" + groups + '\'' +
31 | '}';
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/Authentication.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components;
2 |
3 | import com.conveyal.analysis.UserPermissions;
4 | import spark.Request;
5 |
6 | /**
7 | * An interface for determining who is issuing an HTTP request, and what permissions they have to act upon data in the
8 | * analysis system. Currently all permissions information is known from the group the user belongs to: a user may take
9 | * any action on objects belonging to their group.
10 | */
11 | public interface Authentication extends Component {
12 | /**
13 | * Given an incoming HTTP request, determine who the user is and create a UserPermissions object with that
14 | * information. If the user cannot be identified and/or authenticated, don't set those attributes and throw an
15 | * exception. Otherwise return a UserPermissions object.
16 | */
17 | UserPermissions authenticate (Request request);
18 | }
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/Component.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components;
2 |
3 | /**
4 | * These are the top-level modules of our analysis backend that are instantiated and wired up to one another when the
5 | * application starts up. There is typically only one instance of each component, and all references to the component
6 | * are final.
7 | *
8 | * Each component should encapsulate a distinct, well-defined set of functionality. Different implementations of
9 | * components allow running locally or in other environments like AWS or potentially other cloud service providers.
10 | * Currently this is a marker interface with no methods, just to indicate the role of certain classes in the project.
11 | */
12 | public interface Component {
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/Compute.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components;
2 |
3 | /**
4 | * This is a stub abstraction for a component performing accessibility analysis computations.
5 | * Computation could be on remote or local hardware, using code in this repo or a dependency.
6 | * This would encapsulate any logic that manages a compute cluster.
7 | * In practice, the backend currently relays the requests to a cluster of local or remote workers running R5.
8 | */
9 | public class Compute {
10 |
11 | public void handleRequest () {
12 |
13 | }
14 |
15 | /** Also allow swappable implementation of worker polling to avoid doing it over HTTP locally? */
16 | public void workerPollForWork() {
17 |
18 | }
19 |
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/LocalAuthentication.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components;
2 |
3 | import com.conveyal.analysis.UserPermissions;
4 | import spark.Request;
5 |
6 | /**
7 | * Working "offline", hard-wire the user and group names. We might want to use something like "_local_" or "NONE"
8 | * instead of "OFFLINE" for the group, since someone running locally doesn't necessarily feel that they are offline.
9 | */
10 | public class LocalAuthentication implements Authentication {
11 |
12 | public static final String LOCAL_USERNAME = "local";
13 |
14 | public static final String LOCAL_GROUP = LOCAL_USERNAME;
15 |
16 | @Override
17 | public UserPermissions authenticate (Request request) {
18 | UserPermissions userPermissions = new UserPermissions(LOCAL_USERNAME, true, LOCAL_GROUP);
19 | request.attribute("permissions", userPermissions);
20 | request.attribute("email", LOCAL_USERNAME);
21 | request.attribute("accessGroup", LOCAL_GROUP);
22 | return userPermissions;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/WorkerLauncher.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components;
2 |
3 | import com.conveyal.analysis.components.broker.WorkerTags;
4 | import com.conveyal.r5.analyst.WorkerCategory;
5 |
6 | /** Interface for Components that start workers. */
7 | public interface WorkerLauncher extends Component {
8 |
9 | /** Start worker instances to handle single point or regional tasks. */
10 | public void launch (WorkerCategory category, WorkerTags workerTags, int nOnDemand, int nSpot);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/broker/WorkerStartupScriptTestHook.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components.broker;
2 |
3 | import com.google.common.io.ByteStreams;
4 |
5 | import java.io.ByteArrayOutputStream;
6 | import java.io.InputStream;
7 | import java.text.MessageFormat;
8 |
9 | /**
10 | * Test hook (main class) that reads the worker startup script and substitutes in values.
11 | */
12 | public class WorkerStartupScriptTestHook {
13 | public static void main (String... args) throws Exception {
14 | InputStream scriptIs = Broker.class.getClassLoader().getResourceAsStream("worker.sh");
15 | ByteArrayOutputStream scriptBaos = new ByteArrayOutputStream();
16 | ByteStreams.copy(scriptIs, scriptBaos);
17 | scriptIs.close();
18 | scriptBaos.close();
19 | String scriptTemplate = scriptBaos.toString();
20 |
21 | String workerDownloadUrl = "https://r5-builds.s3.amazonaws.com/v2.3.1.jar";
22 | String logGroup = "test-log-group";
23 | String workerConfigString = "key=val\nkey2=val\n";
24 |
25 | String script = MessageFormat.format(scriptTemplate, workerDownloadUrl, logGroup, workerConfigString);
26 | System.out.println(script);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/broker/WorkerTags.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components.broker;
2 |
3 | import com.conveyal.analysis.models.RegionalAnalysis;
4 |
5 | /**
6 | * An immutable group of tags to be added to the worker instance to assist in usage analysis and cost breakdowns.
7 | * These Strings are purely for categorization of workers and should not be used for other purposes, only passed through
8 | * to the AWS SDK.
9 | */
10 | public class WorkerTags {
11 |
12 | /** The unique name of the permissions group under which the user is working. */
13 | public final String group;
14 |
15 | /** A unique ID for the user (the user's email address). */
16 | public final String user;
17 |
18 | /** The UUID for the project. */
19 | public final String projectId;
20 |
21 | /** The UUID for the project. */
22 | public final String regionId;
23 |
24 | public WorkerTags (String group, String user, String projectId, String regionId) {
25 | this.group = group;
26 | this.user = user;
27 | this.projectId = projectId;
28 | this.regionId = regionId;
29 | }
30 |
31 | public static WorkerTags fromRegionalAnalysis (RegionalAnalysis regionalAnalysis) {
32 | return new WorkerTags(
33 | regionalAnalysis.accessGroup,
34 | regionalAnalysis.createdBy,
35 | regionalAnalysis.projectId,
36 | regionalAnalysis.regionId
37 | );
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/eventbus/CrudEvent.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components.eventbus;
2 |
3 | /**
4 | * Signals that a user has created, read, updated, or deleted a domain model object from the database.
5 | */
6 | public class CrudEvent extends Event {
7 |
8 | enum Action {
9 | CREATE, READ, UPDATE, DELETE
10 | }
11 |
12 | public final Action action;
13 |
14 | public final String entityType;
15 |
16 | public final String entityId;
17 |
18 | public CrudEvent (Action action, String entityType, String entityId) {
19 | this.action = action;
20 | this.entityType = entityType;
21 | this.entityId = entityId;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/eventbus/FileUploadEvent.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components.eventbus;
2 |
3 | /**
4 | * Created by abyrd on 2020-06-12
5 | */
6 | public class FileUploadEvent extends Event {
7 |
8 | enum Status {
9 | BEGIN, PROCESSING, COMPLETE, ERRORED
10 | }
11 |
12 | enum FileType {
13 | GTFS, OSM, SHAPE
14 | }
15 |
16 | public final String fileId;
17 |
18 | public final FileType fileType;
19 |
20 | public final Status status;
21 |
22 | public FileUploadEvent (String fileId, FileType fileType, Status status) {
23 | this.fileId = fileId;
24 | this.fileType = fileType;
25 | this.status = status;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/eventbus/RegionalAnalysisEvent.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components.eventbus;
2 |
3 | /**
4 | * Represents the progress of a regional analysis over time.
5 | */
6 | public class RegionalAnalysisEvent extends Event {
7 |
8 | public enum State {
9 | ENQUEUED, STARTED, COMPLETED, CANCELED, ERRORED
10 | }
11 |
12 | public final String regionalAnalysisId;
13 |
14 | public final State state;
15 |
16 | public RegionalAnalysisEvent (String regionalAnalysisId, State state) {
17 | this.regionalAnalysisId = regionalAnalysisId;
18 | this.state = state;
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/eventbus/SinglePointEvent.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components.eventbus;
2 |
3 | import com.fasterxml.jackson.annotation.JsonTypeName;
4 |
5 | /**
6 | * Created by abyrd on 2020-06-12
7 | */
8 | @JsonTypeName("singpo")
9 | public class SinglePointEvent extends Event {
10 |
11 | public final String scenarioId;
12 |
13 | public final int durationMsec;
14 |
15 | public SinglePointEvent (String scenarioId, int durationMsec) {
16 | this.scenarioId = scenarioId;
17 | this.durationMsec = durationMsec;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/components/eventbus/WorkerEvent.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.components.eventbus;
2 |
3 | import com.conveyal.r5.analyst.WorkerCategory;
4 |
5 | /**
6 | * Created by abyrd on 2020-06-12
7 | */
8 | public class WorkerEvent extends Event {
9 |
10 | public enum Role {
11 | SINGLE_POINT, REGIONAL
12 | }
13 |
14 | public enum Action {
15 | REQUESTED, STARTED, SHUT_DOWN
16 | }
17 |
18 | public final Role role;
19 | public final WorkerCategory category;
20 | public final Action action;
21 | public final int quantity;
22 |
23 | public WorkerEvent (Role role, WorkerCategory category, Action action, int quantity) {
24 | this.role = role;
25 | this.category = category;
26 | this.action = action;
27 | this.quantity = quantity;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/controllers/HttpController.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.controllers;
2 |
3 | /**
4 | * All of our classes defining HTTP API endpoints implement this interface.
5 | * It has a single method that registers all the endpoints.
6 | * For most controllers, all those endpoints will be under a single base URL path.
7 | * Each controller implementation should have a constructor taking all the application Components it needs as arguments.
8 | */
9 | public interface HttpController {
10 |
11 | void registerEndpoints (spark.Service sparkService);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/controllers/WrappedFeedInfo.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.controllers;
2 |
3 | import com.conveyal.gtfs.api.graphql.WrappedGTFSEntity;
4 | import com.conveyal.gtfs.model.FeedInfo;
5 |
6 | /**
7 | * Wrap feed info with GTFS feed checksum and feed unique ID.
8 | */
9 | public class WrappedFeedInfo extends WrappedGTFSEntity {
10 | public long checksum;
11 |
12 |
13 | /**
14 | * Wrap the given GTFS entity with the unique Feed ID specified (this is not generally a GTFS feed ID as they
15 | * are not unique between different versions of the same feed. Also pass in feed checksum.
16 | */
17 | public WrappedFeedInfo(String feedUniqueID, FeedInfo entity, long checksum) {
18 | super(feedUniqueID, entity);
19 | this.checksum = checksum;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/controllers/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This package should contain only the HttpController interface and implementations of that interface.
3 | * These are the classes that define the endpoints of our HTTP API and are registered with the Spark framework.
4 | */
5 | package com.conveyal.analysis.controllers;
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/AddStreets.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import com.conveyal.r5.profile.StreetMode;
4 |
5 | import java.util.EnumSet;
6 |
7 | /**
8 | * Fields replicated from the R5 AddStreets modification.
9 | */
10 | public class AddStreets extends Modification {
11 |
12 | public double[][][] lineStrings;
13 | public EnumSet allowedModes;
14 | public Double carSpeedKph;
15 | public Double walkTimeFactor;
16 | public Double bikeTimeFactor;
17 | public Integer bikeLts;
18 | public boolean linkable;
19 |
20 | @Override
21 | public String getType() {
22 | return "add-streets";
23 | }
24 |
25 | @Override
26 | public com.conveyal.r5.analyst.scenario.Modification toR5() {
27 | com.conveyal.r5.analyst.scenario.AddStreets mod = new com.conveyal.r5.analyst.scenario.AddStreets();
28 | mod.comment = name;
29 |
30 | mod.lineStrings = lineStrings;
31 | mod.allowedModes = allowedModes;
32 | mod.carSpeedKph = carSpeedKph;
33 | mod.walkTimeFactor = walkTimeFactor;
34 | mod.bikeTimeFactor = bikeTimeFactor;
35 | mod.bikeLts = bikeLts;
36 | mod.linkable = linkable;
37 |
38 | return mod;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/AdjustDwellTime.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | /**
4 | * Created by matthewc on 3/3/16.
5 | */
6 | public class AdjustDwellTime extends Modification {
7 | @Override
8 | public String getType() {
9 | return "adjust-dwell-time";
10 | }
11 |
12 | public String feed;
13 |
14 | public String[] routes;
15 |
16 | public String[] trips;
17 |
18 | public String[] stops;
19 |
20 | /** are we scaling existing times (true) or replacing them with a brand new time (false) */
21 | public boolean scale;
22 |
23 | /** the factor by which to scale, OR the new time, depending on the value of above */
24 | public double value;
25 |
26 | public com.conveyal.r5.analyst.scenario.AdjustDwellTime toR5 () {
27 | com.conveyal.r5.analyst.scenario.AdjustDwellTime adt = new com.conveyal.r5.analyst.scenario.AdjustDwellTime();
28 | adt.comment = name;
29 |
30 | if (trips == null) {
31 | adt.routes = feedScopeIds(feed, routes);
32 | } else {
33 | adt.patterns = feedScopeIds(feed, trips);
34 | }
35 |
36 | adt.stops = feedScopeIds(feed, stops);
37 |
38 | if (scale) {
39 | adt.scale = value;
40 | } else {
41 | adt.dwellSecs = (int) value;
42 | }
43 |
44 | return adt;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/AdjustSpeed.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import java.util.Arrays;
4 | import java.util.stream.Collectors;
5 |
6 | /**
7 | * Adjust the speed of a route.
8 | */
9 | public class AdjustSpeed extends Modification {
10 | public String getType() {
11 | return "adjust-speed";
12 | }
13 |
14 | public String feed;
15 |
16 | public String[] routes;
17 |
18 | public String[] trips;
19 |
20 | /** array of [from stop, to stop] specifying single hops this should be applied to */
21 | public String[][] hops;
22 |
23 | /** the factor by which to scale speed. 1 means no change, 2 means faster. */
24 | public double scale;
25 |
26 | public com.conveyal.r5.analyst.scenario.AdjustSpeed toR5 () {
27 | com.conveyal.r5.analyst.scenario.AdjustSpeed as = new com.conveyal.r5.analyst.scenario.AdjustSpeed();
28 | as.comment = name;
29 |
30 | if (trips == null) {
31 | as.routes = feedScopeIds(feed, routes);
32 | } else {
33 | as.patterns = feedScopeIds(feed, trips);
34 | }
35 |
36 | if (hops != null) {
37 | as.hops = Arrays.stream(hops)
38 | .map(h -> feedScopeIds(feed, h))
39 | .map(s -> {
40 | Object[] oa = s.toArray();
41 | return Arrays.copyOf(oa, oa.length, String[].class);
42 | })
43 | .collect(Collectors.toList());
44 | }
45 |
46 | as.scale = scale;
47 |
48 | return as;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/AggregationArea.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnore;
4 |
5 | /**
6 | * An aggregation area defines a set of origin points to be averaged together to produce an aggregate accessibility figure.
7 | * It is defined by a geometry that is rasterized and stored as a grid, with pixels with values between 0 and 100,000
8 | * depending on how much of that pixel is overlapped by the mask.
9 | */
10 | public class AggregationArea extends Model {
11 | public String regionId;
12 |
13 | @JsonIgnore
14 | public String getS3Key () {
15 | return String.format("%s/mask/%s.grid", regionId, _id);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/BaseModel.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import org.bson.types.ObjectId;
4 |
5 | public class BaseModel {
6 | // Can retrieve `createdAt` from here
7 | public ObjectId _id;
8 |
9 | // For version management. ObjectId's contain a timestamp, so can retrieve `updatedAt` from here.
10 | public ObjectId nonce = new ObjectId();
11 |
12 | public String createdBy = null;
13 | public String updatedBy = null;
14 |
15 | // Who owns this?
16 | public String accessGroup = null;
17 |
18 | // Everything has a name
19 | public String name = null;
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/Bounds.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import org.locationtech.jts.geom.Envelope;
4 |
5 | /**
6 | * Represents a bounding box in degrees in the HTTP API.
7 | */
8 | public class Bounds {
9 |
10 | /** The latitude of the north edge and south edge, the longitude of the east edge and west edge of the box. */
11 | public double north, east, south, west;
12 |
13 | @Override
14 | public boolean equals (Object other) {
15 | return equals(other, 0D);
16 | }
17 |
18 | public boolean equals (Object other, double tolerance) {
19 | if (!Bounds.class.isInstance(other)) return false;
20 | Bounds o = (Bounds) other;
21 | return Math.abs(north - o.north) <= tolerance && Math.abs(east - o.east) <= tolerance &&
22 | Math.abs(south - o.south) <= tolerance && Math.abs(west - o.west) <= tolerance;
23 | }
24 |
25 | public Envelope envelope () {
26 | return new Envelope(this.west, this.east, this.south, this.north);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/CustomModificationHolder.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import com.fasterxml.jackson.annotation.JsonAnyGetter;
4 | import com.fasterxml.jackson.annotation.JsonAnySetter;
5 |
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | /**
10 | * This is the UI/Backend model for a freeform JSON modification.
11 | * It uses the JsonAnyGetter and JsonAnySetter annotations to handle all unrecognized properties, i.e. anything
12 | * that does not map to a field on the base class.
13 | */
14 | public class CustomModificationHolder extends Modification {
15 |
16 | public String getType() {
17 | return "custom";
18 | }
19 |
20 | private Map freeformProperties = new HashMap<>();
21 |
22 | @JsonAnyGetter
23 | public Map getFreeformProperties() {
24 | return freeformProperties;
25 | }
26 |
27 | @JsonAnySetter
28 | public void setFreeformProperties(String key, Object value) {
29 | this.freeformProperties.put(key, value);
30 | }
31 |
32 | public com.conveyal.r5.analyst.scenario.CustomModificationHolder toR5 () {
33 | com.conveyal.r5.analyst.scenario.CustomModificationHolder customR5 =
34 | new com.conveyal.r5.analyst.scenario.CustomModificationHolder(freeformProperties, name);
35 | return customR5;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/FileInfo.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import com.conveyal.file.FileStorageFormat;
4 | import com.conveyal.file.FileStorageKey;
5 | import com.fasterxml.jackson.annotation.JsonIgnore;
6 | import org.bson.types.ObjectId;
7 |
8 | public class FileInfo extends BaseModel {
9 | public String regionId = null;
10 |
11 | // What is the bucket or folder that this file is stored in?
12 | public String bucket = null;
13 |
14 | // The path to create a FileStorageKey
15 | public String path = null;
16 |
17 | // Has the file been uploaded and is ready to be used?
18 | public Boolean isReady = false;
19 |
20 | // Size (in bytes)
21 | public Integer size = 0;
22 |
23 | // Internal file format category. Corresponds to an extension and mime type.
24 | public FileStorageFormat format = null;
25 |
26 | // Get path
27 | @JsonIgnore
28 | public FileStorageKey getKey () {
29 | return new FileStorageKey(bucket, path);
30 | }
31 |
32 | /**
33 | * New objects will be stored using this path.
34 | * TODO clean path?
35 | * @param accessGroup
36 | * @param _id
37 | * @param filename
38 | * @return
39 | */
40 | public static String generatePath (String accessGroup, ObjectId _id, String filename) {
41 | String fileName = String.join("-", _id.toString(), filename);
42 | return String.join("/", accessGroup, fileName);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/JsonViews.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | /**
4 | * Created by matthewc on 7/20/16.
5 | */
6 | public class JsonViews {
7 | public static class Api { }
8 | public static class Db { }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/ModifyStreets.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import com.conveyal.r5.profile.StreetMode;
4 |
5 | import java.util.EnumSet;
6 |
7 | /**
8 | * Fields replicated from the R5 ModifyStreets modification.
9 | */
10 | public class ModifyStreets extends Modification {
11 |
12 | public double[][][] polygons;
13 | public EnumSet allowedModes;
14 | public Double carSpeedKph;
15 | public Double walkTimeFactor;
16 | public Double bikeTimeFactor;
17 | public Integer bikeLts;
18 |
19 | @Override
20 | public String getType() {
21 | return "modify-streets";
22 | }
23 |
24 | @Override
25 | public com.conveyal.r5.analyst.scenario.Modification toR5() {
26 | com.conveyal.r5.analyst.scenario.ModifyStreets mod = new com.conveyal.r5.analyst.scenario.ModifyStreets();
27 | mod.comment = name;
28 |
29 | mod.polygons = polygons;
30 | mod.allowedModes = allowedModes;
31 | mod.carSpeedKph = carSpeedKph;
32 | mod.walkTimeFactor = walkTimeFactor;
33 | mod.bikeTimeFactor = bikeTimeFactor;
34 | mod.bikeLts = bikeLts;
35 |
36 | return mod;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/Project.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import com.conveyal.analysis.AnalysisServerException;
4 |
5 | /**
6 | * Represents a TAUI project
7 | */
8 | public class Project extends Model implements Cloneable {
9 | /** Names of the variants of this project */
10 | public String[] variants;
11 |
12 | public String regionId;
13 |
14 | public String bundleId;
15 |
16 | public AnalysisRequest analysisRequestSettings;
17 |
18 | public Project clone () {
19 | try {
20 | return (Project) super.clone();
21 | } catch (CloneNotSupportedException e) {
22 | throw AnalysisServerException.unknown(e);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/Region.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import com.conveyal.analysis.AnalysisServerException;
4 |
5 | /**
6 | * Represents a region.
7 | */
8 | public class Region extends Model implements Cloneable {
9 | /** Region description */
10 | public String description;
11 |
12 | /** Bounds of this region */
13 | public Bounds bounds;
14 |
15 | public Region clone () {
16 | try {
17 | return (Region) super.clone();
18 | } catch (CloneNotSupportedException e) {
19 | // can't happen.
20 | throw AnalysisServerException.unknown(e);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/RemoveStops.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | /**
4 | * Created by matthewc on 3/2/16.
5 | */
6 | public class RemoveStops extends Modification {
7 | public String getType() {
8 | return "remove-stops";
9 | }
10 |
11 | public String feed;
12 |
13 | public String[] routes;
14 |
15 | public String[] trips;
16 |
17 | public String[] stops;
18 |
19 | public int secondsSavedAtEachStop = 0;
20 |
21 | public com.conveyal.r5.analyst.scenario.RemoveStops toR5 () {
22 | com.conveyal.r5.analyst.scenario.RemoveStops rs = new com.conveyal.r5.analyst.scenario.RemoveStops();
23 | rs.comment = name;
24 | rs.stops = feedScopeIds(feed, stops);
25 |
26 | if (trips == null) {
27 | rs.routes = feedScopeIds(feed, routes);
28 | } else {
29 | rs.patterns = feedScopeIds(feed, trips);
30 | }
31 |
32 | rs.secondsSavedAtEachStop = secondsSavedAtEachStop;
33 |
34 | return rs;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/RemoveTrips.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | /**
4 | * Remove trips from a graph.
5 | */
6 | public class RemoveTrips extends Modification {
7 | public String getType () {
8 | return "remove-trips";
9 | }
10 |
11 | public String feed;
12 |
13 | public String[] routes;
14 |
15 | public String[] patterns;
16 |
17 | public String[] trips;
18 |
19 | public com.conveyal.r5.analyst.scenario.RemoveTrips toR5 () {
20 | com.conveyal.r5.analyst.scenario.RemoveTrips rt = new com.conveyal.r5.analyst.scenario.RemoveTrips();
21 | rt.comment = name;
22 |
23 | if (trips == null) {
24 | rt.routes = feedScopeIds(feed, routes);
25 | } else {
26 | rt.patterns = feedScopeIds(feed, trips);
27 | }
28 |
29 | return rt;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/models/Segment.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.models;
2 |
3 | import com.conveyal.geojson.GeometryDeserializer;
4 | import com.conveyal.geojson.GeometrySerializer;
5 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
6 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
7 | import org.locationtech.jts.geom.Geometry;
8 |
9 | /**
10 | * Represents a single segment of an added trip pattern (between two user-specified points)
11 | */
12 | public class Segment {
13 | /** Is there a stop at the start of this segment */
14 | public boolean stopAtStart;
15 |
16 | /** Is there a stop at the end of this segment */
17 | public boolean stopAtEnd;
18 |
19 | /** If this segment starts at an existing stop, the feed-scoped stop ID (feed:stop_id). */
20 | public String fromStopId;
21 |
22 | /** If this segment ends at an existing stop, the feed-scoped stop ID (feed:stop_id). */
23 | public String toStopId;
24 |
25 | /** spacing between stops in this segment, meters */
26 | public int spacing;
27 |
28 | /**
29 | * Geometry of this segment
30 | * Generally speaking, this will be a LineString, but the first segment may be a Point
31 | * iff there are no more segments. This is used when someone first starts drawing a line and
32 | * they have only drawn one stop so far. Of course a transit line with only one stop would
33 | * not be particularly useful.
34 | */
35 | @JsonDeserialize(using= GeometryDeserializer.class)
36 | @JsonSerialize(using= GeometrySerializer.class)
37 | public Geometry geometry;
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/util/BsonObjectIdModule.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.util;
2 |
3 | import com.fasterxml.jackson.core.Version;
4 | import com.fasterxml.jackson.databind.DeserializationContext;
5 | import com.fasterxml.jackson.databind.deser.std.FromStringDeserializer;
6 | import com.fasterxml.jackson.databind.module.SimpleModule;
7 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
8 | import org.bson.types.ObjectId;
9 |
10 | /**
11 | * This provides JSON serialization and deserialization of BSON IDs.
12 | */
13 | public class BsonObjectIdModule extends SimpleModule {
14 |
15 | public BsonObjectIdModule () {
16 | super("BsonObjectId", new Version(1, 0, 0, null, "com.conveyal", "analysis"));
17 | this.addSerializer(ObjectId.class, new ToStringSerializer());
18 | this.addDeserializer(ObjectId.class, new FromStringDeserializer<>(ObjectId.class) {
19 | @Override
20 | protected ObjectId _deserialize(String s, DeserializationContext deserializationContext) {
21 | return new ObjectId(s);
22 | }
23 | });
24 |
25 |
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/util/HttpStatus.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.util;
2 |
3 | /**
4 | * It's kind of absurd to have our own set of HTTP status code constants, but I can't find any in the Spark project.
5 | */
6 | public class HttpStatus {
7 |
8 | public static final int OK_200 = 200;
9 | public static final int ACCEPTED_202 = 202;
10 | public static final int NO_CONTENT_204 = 204;
11 | public static final int BAD_REQUEST_400 = 400;
12 | public static final int SERVER_ERROR_500 = 500;
13 | public static final int SERVICE_UNAVAILABLE = 000;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/util/HttpUtils.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.util;
2 |
3 | import com.conveyal.analysis.AnalysisServerException;
4 | import com.conveyal.r5.util.ExceptionUtils;
5 | import org.apache.commons.fileupload.FileItem;
6 | import org.apache.commons.fileupload.FileItemFactory;
7 | import org.apache.commons.fileupload.disk.DiskFileItemFactory;
8 | import org.apache.commons.fileupload.servlet.ServletFileUpload;
9 |
10 | import javax.servlet.http.HttpServletRequest;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | public abstract class HttpUtils {
15 | /** Extract files from a Spark Request containing RFC 1867 multipart form-based file upload data. */
16 | public static Map> getRequestFiles (HttpServletRequest req) {
17 | // The Javadoc on this factory class doesn't say anything about thread safety. Looking at the source code it
18 | // all looks threadsafe. But also very lightweight to instantiate, so in this code run by multiple threads
19 | // we play it safe and always create a new factory.
20 | // Setting a size threshold of 0 causes all files to be written to disk, which allows processing them in a
21 | // uniform way in other threads, after the request handler has returned.
22 | FileItemFactory fileItemFactory = new DiskFileItemFactory(0, null);
23 | ServletFileUpload sfu = new ServletFileUpload(fileItemFactory);
24 | try {
25 | return sfu.parseParameterMap(req);
26 | } catch (Exception e) {
27 | throw AnalysisServerException.badRequest(ExceptionUtils.asString(e));
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/util/Jobs.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.util;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 |
6 | /**
7 | * Contains a shared ExecutorService.
8 | */
9 | public class Jobs {
10 | public static ExecutorService service = Executors.newCachedThreadPool();
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/analysis/util/JsonUtil.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.analysis.util;
2 |
3 | import com.conveyal.analysis.models.JsonViews;
4 | import com.conveyal.geojson.GeoJsonModule;
5 | import com.conveyal.r5.model.json_serialization.JavaLocalDateSerializer;
6 | import com.fasterxml.jackson.databind.DeserializationFeature;
7 | import com.fasterxml.jackson.databind.ObjectMapper;
8 | import org.mongojack.internal.MongoJackModule;
9 | import spark.ResponseTransformer;
10 |
11 | public abstract class JsonUtil {
12 |
13 | public static final ObjectMapper objectMapper = getObjectMapper(JsonViews.Api.class);
14 | public static final ResponseTransformer toJson = objectMapper::writeValueAsString;
15 |
16 | public static ObjectMapper getObjectMapper (Class view) {
17 | return getObjectMapper(view, false);
18 | }
19 |
20 | public static ObjectMapper getObjectMapper(Class view, boolean configureMongoJack) {
21 | ObjectMapper objectMapper = new ObjectMapper();
22 | objectMapper.registerModule(new GeoJsonModule());
23 | objectMapper.registerModule(JavaLocalDateSerializer.makeModule());
24 | objectMapper.registerModule(new BsonObjectIdModule());
25 |
26 | if (configureMongoJack) MongoJackModule.configure(objectMapper);
27 |
28 | // We removed a bunch of fields from ProfileRequests which are persisted to the database
29 | objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
30 |
31 | objectMapper.setConfig(objectMapper.getSerializationConfig().withView(view));
32 |
33 | return objectMapper;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/data/census/FileSeamlessSource.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.data.census;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 |
8 | /**
9 | * Seamless source for the file system.
10 | */
11 | public class FileSeamlessSource extends SeamlessSource {
12 | private File directory;
13 |
14 | public FileSeamlessSource(String path) {
15 | this.directory = new File(path);
16 | }
17 |
18 | @Override protected InputStream getInputStream(int x, int y) throws IOException {
19 | File dir = new File(directory, x + "");
20 | File file = new File(dir, y + ".pbf.gz");
21 |
22 | if (!file.exists())
23 | return null;
24 |
25 | return new FileInputStream(file);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/data/census/TigerLineSource.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.data.census;
2 |
3 | import com.conveyal.data.geobuf.GeobufFeature;
4 | import org.geotools.data.FileDataStore;
5 | import org.geotools.data.FileDataStoreFinder;
6 | import org.geotools.data.Query;
7 | import org.geotools.data.simple.SimpleFeatureCollection;
8 | import org.geotools.data.simple.SimpleFeatureIterator;
9 | import org.geotools.data.simple.SimpleFeatureSource;
10 | import org.geotools.referencing.CRS;
11 |
12 | import java.io.File;
13 | import java.util.HashMap;
14 |
15 | /**
16 | * Reads TIGER/Line data into a MapDB.
17 | */
18 | public class TigerLineSource {
19 | private File shapefile;
20 |
21 | public TigerLineSource (File shapefile) {
22 | this.shapefile = shapefile;
23 | }
24 |
25 | public void load (ShapeDataStore store) throws Exception {
26 | FileDataStore fds = FileDataStoreFinder.getDataStore(shapefile);
27 | SimpleFeatureSource src = fds.getFeatureSource();
28 |
29 | Query q = new Query();
30 | q.setCoordinateSystem(src.getInfo().getCRS());
31 | q.setCoordinateSystemReproject(CRS.decode("EPSG:4326", true));
32 | SimpleFeatureCollection sfc = src.getFeatures(q);
33 |
34 | for (SimpleFeatureIterator it = sfc.features(); it.hasNext();) {
35 | GeobufFeature feat = new GeobufFeature(it.next());
36 | feat.id = null;
37 | feat.numericId = Long.parseLong((String) feat.properties.get("GEOID10"));
38 | feat.properties = new HashMap<>();
39 | store.add(feat);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/data/geobuf/GeobufDecoder.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.data.geobuf;
2 |
3 | import geobuf.Geobuf;
4 |
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 | import java.util.Iterator;
8 | import java.util.List;
9 |
10 | /**
11 | * Decode a Geobuf.
12 | */
13 | public class GeobufDecoder implements Iterator {
14 | private int maxFeat, i = 0;
15 |
16 | private Geobuf.Data.FeatureCollection featureCollection;
17 |
18 | private List keys;
19 |
20 | private double precisionDivisor;
21 |
22 | /** Create a Geobuf decoder, optionally backed by high-performance on-disk storage */
23 | public GeobufDecoder (InputStream is) throws IOException {
24 | // read everything into memory
25 | Geobuf.Data data = Geobuf.Data.parseFrom(is);
26 | keys = data.getKeysList();
27 | featureCollection = data.getFeatureCollection();
28 |
29 | if (featureCollection == null)
30 | throw new UnsupportedOperationException("Geobuf is not a feature collection");
31 |
32 | maxFeat = featureCollection.getFeaturesCount();
33 |
34 | // calculate what to divide coords by; coords are stored as fixed-point longs
35 | precisionDivisor = Math.pow(10, data.getPrecision());
36 |
37 | is.close();
38 | }
39 |
40 | @Override public boolean hasNext() {
41 | return i < maxFeat;
42 | }
43 |
44 | @Override public GeobufFeature next() {
45 | return new GeobufFeature(featureCollection.getFeatures(i++), keys, precisionDivisor);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/data/geobuf/ShapefileToGeobuf.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.data.geobuf;
2 |
3 | import org.geotools.data.FileDataStore;
4 | import org.geotools.data.FileDataStoreFinder;
5 | import org.geotools.data.Query;
6 | import org.geotools.data.simple.SimpleFeatureCollection;
7 | import org.geotools.data.simple.SimpleFeatureIterator;
8 | import org.geotools.data.simple.SimpleFeatureSource;
9 | import org.geotools.referencing.CRS;
10 |
11 | import java.io.File;
12 | import java.io.FileOutputStream;
13 | import java.util.ArrayList;
14 | import java.util.Collection;
15 |
16 | /**
17 | * Convert a Shapefile to Geobuf format.
18 | */
19 | public class ShapefileToGeobuf {
20 | public static void main (String... args) throws Exception {
21 | File inShp = new File(args[0]);
22 | File outGb = new File(args[1]);
23 |
24 | GeobufEncoder encoder = new GeobufEncoder(new FileOutputStream(outGb), 5);
25 |
26 | FileDataStore store = FileDataStoreFinder.getDataStore(inShp);
27 | SimpleFeatureSource src = store.getFeatureSource();
28 |
29 | Query q = new Query();
30 | q.setCoordinateSystem(src.getInfo().getCRS());
31 | q.setCoordinateSystemReproject(CRS.decode("EPSG:4326", true));
32 | SimpleFeatureCollection sfc = src.getFeatures(q);
33 |
34 | Collection features = new ArrayList<>();
35 |
36 | for (SimpleFeatureIterator it = sfc.features(); it.hasNext();) {
37 | GeobufFeature feat = new GeobufFeature(it.next());
38 | features.add(feat);
39 | }
40 |
41 | encoder.writeFeatureCollection(features);
42 |
43 | encoder.close();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/file/FileStorageFormat.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.file;
2 |
3 | public enum FileStorageFormat {
4 | FREEFORM("pointset", "application/octet-stream"),
5 | GRID("grid", "application/octet-stream"),
6 | POINTSET("pointset", "application/octet-stream"),
7 | PNG("png", "image/png"),
8 | TIFF("tiff", "image/tiff");
9 |
10 | // These are not currently used but plan to be in the future. Exact types need to be determined
11 | // CSV("csv", "text/csv"),
12 | // GTFS("zip", "application/zip"),
13 | // PBF("pbf", "application/octet-stream"),
14 | // SHP("shp", "application/octet-stream") // This type does not work as is, it should be a zip?
15 |
16 | public final String extension;
17 | public final String mimeType;
18 |
19 | FileStorageFormat(String extension, String mimeType) {
20 | this.extension = extension;
21 | this.mimeType = mimeType;
22 | }
23 |
24 | public static FileStorageFormat fromFilename (String filename) {
25 | String extension = filename.substring(filename.lastIndexOf(".") + 1);
26 | return FileStorageFormat.valueOf(extension.toUpperCase());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/api/graphql/WrappedEntityFieldFetcher.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.api.graphql;
2 |
3 | import graphql.schema.DataFetcher;
4 | import graphql.schema.DataFetchingEnvironment;
5 |
6 | import java.lang.reflect.Field;
7 |
8 | /**
9 | * Fetch data from wrapped GTFS entities. Modeled after graphql-java FieldDataFetcher.
10 | */
11 | public class WrappedEntityFieldFetcher implements DataFetcher {
12 | private final String field;
13 |
14 | public WrappedEntityFieldFetcher (String field) {
15 | this.field = field;
16 | }
17 |
18 | @Override
19 | public Object get(DataFetchingEnvironment dataFetchingEnvironment) {
20 | Object source = dataFetchingEnvironment.getSource();
21 |
22 | if (source instanceof WrappedGTFSEntity) source = ((WrappedGTFSEntity) source).entity;
23 |
24 | Field field = null;
25 | try {
26 | field = source.getClass().getField(this.field);
27 | } catch (NoSuchFieldException e) {
28 | return null;
29 | }
30 |
31 | try {
32 | return field.get(source);
33 | } catch (IllegalAccessException e) {
34 | throw new RuntimeException(e);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/api/graphql/WrappedGTFSEntity.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.api.graphql;
2 |
3 | /**
4 | * Wraps a GTFS entity, whose own ID may only be unique within the feed, decorating it with the unique ID of the feed
5 | * it came from.
6 | */
7 | public class WrappedGTFSEntity {
8 | public T entity;
9 | public String feedUniqueId;
10 |
11 | /**
12 | * Wrap the given GTFS entity with the unique Feed ID specified (this is not generally a GTFS feed ID as they
13 | * are not unique between different versions of the same feed.
14 | */
15 | public WrappedGTFSEntity (String feedUniqueID, T entity) {
16 | this.feedUniqueId = feedUniqueID;
17 | this.entity = entity;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/api/graphql/types/StopTimeType.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.api.graphql.types;
2 |
3 | import com.conveyal.gtfs.api.graphql.fetchers.TripDataFetcher;
4 | import graphql.schema.GraphQLObjectType;
5 | import graphql.schema.GraphQLTypeReference;
6 |
7 | import static com.conveyal.gtfs.api.util.GraphQLUtil.*;
8 | import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
9 | import static graphql.schema.GraphQLObjectType.newObject;
10 |
11 | /**
12 | * Created by landon on 10/3/16.
13 | */
14 | public class StopTimeType {
15 | public static GraphQLObjectType build () {
16 | return newObject()
17 | .name("stopTime")
18 | .field(intt("arrival_time"))
19 | .field(intt("departure_time"))
20 | .field(intt("stop_sequence"))
21 | .field(string("stop_id"))
22 | .field(string("stop_headsign"))
23 | .field(doublee("shape_dist_traveled"))
24 | .field(feed())
25 | .field(newFieldDefinition()
26 | .name("trip")
27 | .type(new GraphQLTypeReference("trip"))
28 | .dataFetcher(TripDataFetcher::fromStopTime)
29 | .argument(stringArg("date"))
30 | .argument(longArg("from"))
31 | .argument(longArg("to"))
32 | .build()
33 | )
34 | .build();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/api/util/GeomUtil.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.api.util;
2 |
3 | import org.locationtech.jts.geom.Coordinate;
4 | import org.locationtech.jts.geom.CoordinateList;
5 | import org.locationtech.jts.geom.Envelope;
6 |
7 | /**
8 | * Created by landon on 2/8/16.
9 | */
10 | public class GeomUtil {
11 | public static Envelope getBoundingBox(Coordinate coordinate, Double radius){
12 | Envelope boundingBox;
13 |
14 | double R = 6371; // earth radius in km
15 |
16 | // radius argument is also in km
17 |
18 | double x1 = coordinate.x - Math.toDegrees(radius/R/Math.cos(Math.toRadians(coordinate.y)));
19 |
20 | double x2 = coordinate.x + Math.toDegrees(radius/R/Math.cos(Math.toRadians(coordinate.y)));
21 |
22 | double y1 = coordinate.y + Math.toDegrees(radius/R);
23 |
24 | double y2 = coordinate.y - Math.toDegrees(radius/R);
25 |
26 | boundingBox = new Envelope(x1, x2, y1, y2);
27 |
28 | return boundingBox;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/DateParseError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Represents a problem parsing a date field from a GTFS feed. */
6 | public class DateParseError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | public DateParseError(String file, long line, String field) {
10 | super(file, line, field);
11 | }
12 |
13 | @Override public String getMessage() {
14 | return "Could not parse date (format should be YYYYMMDD).";
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/DuplicateKeyError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Indicates that a GTFS entity was not added to a table because another object already exists with the same primary key. */
6 | public class DuplicateKeyError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | public DuplicateKeyError(String file, long line, String field) {
10 | super(file, line, field);
11 | }
12 |
13 | @Override public String getMessage() {
14 | return "Duplicate primary key.";
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/DuplicateStopError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.validator.model.DuplicateStops;
4 |
5 | import java.io.Serializable;
6 |
7 | /** Indicates that a stop exists more than once in the feed. */
8 | public class DuplicateStopError extends GTFSError implements Serializable {
9 | public static final long serialVersionUID = 1L;
10 |
11 | private final String message;
12 | public final DuplicateStops duplicateStop;
13 |
14 | public DuplicateStopError(DuplicateStops duplicateStop) {
15 | super("stop", duplicateStop.getDuplicatedStop().sourceFileLine, "stop_lat,stop_lon", duplicateStop.getDuplicatedStop().stop_id);
16 | this.message = duplicateStop.toString();
17 | this.duplicateStop = duplicateStop;
18 | }
19 |
20 | @Override public String getMessage() {
21 | return message;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/DuplicateTripError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.model.Trip;
4 | import com.conveyal.gtfs.validator.model.Priority;
5 |
6 | import java.io.Serializable;
7 |
8 | /**
9 | * Created by landon on 5/6/16.
10 | */
11 | public class DuplicateTripError extends GTFSError implements Serializable {
12 | public static final long serialVersionUID = 1L;
13 |
14 | public final Priority priority = Priority.LOW;
15 | public final String duplicateTripId;
16 | public final String patternName;
17 | public final String routeId;
18 | String serviceId;
19 | String blockId;
20 | String firstDeparture;
21 | String lastArrival;
22 |
23 | public DuplicateTripError(Trip trip, long line, String duplicateTripId, String patternName, String firstDeparture, String lastArrival) {
24 | super("trips", line, "trip_id", trip.trip_id);
25 | this.duplicateTripId = duplicateTripId;
26 | this.patternName = patternName;
27 | this.routeId = trip.route_id;
28 | this.blockId = trip.block_id;
29 | this.serviceId = trip.service_id;
30 | this.firstDeparture = firstDeparture;
31 | this.lastArrival = lastArrival;
32 | }
33 |
34 | @Override public String getMessage() {
35 | return String.format("Trip Ids %s & %s (route %s) are duplicates (pattern: %s, calendar: %s, from %s to %s)", duplicateTripId, affectedEntityId, routeId, patternName, serviceId, firstDeparture, lastArrival);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/EmptyFieldError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Indicates that a field marked as required is not present in a GTFS feed on a particular line. */
6 | public class EmptyFieldError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | public EmptyFieldError(String file, long line, String field) {
10 | super(file, line, field);
11 | }
12 |
13 | @Override public String getMessage() {
14 | return String.format("No value supplied for a required column.");
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/EmptyTableError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by landon on 4/5/17.
7 | */
8 | public class EmptyTableError extends GTFSError implements Serializable {
9 | public static final long serialVersionUID = 1L;
10 |
11 | public EmptyTableError(String file) {
12 | super(file, 0, null);
13 | }
14 |
15 | @Override public String getMessage() {
16 | return String.format("Table is present in zip file, but it has no entries.");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/GeneralError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Represents any GTFS loading problem that does not have its own class, with a free-text message. */
6 | public class GeneralError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | private String message;
10 |
11 | public GeneralError(String file, long line, String field, String message) {
12 | super(file, line, field);
13 | this.message = message;
14 | }
15 |
16 | @Override public String getMessage() {
17 | return message;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/MisplacedStopError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.model.Stop;
4 | import com.conveyal.gtfs.validator.model.Priority;
5 |
6 | import java.io.Serializable;
7 |
8 | /**
9 | * Created by landon on 5/11/16.
10 | */
11 | public class MisplacedStopError extends GTFSError implements Serializable {
12 | public static final long serialVersionUID = 1L;
13 |
14 | public final Priority priority;
15 | public final Stop stop;
16 |
17 | public MisplacedStopError(String affectedEntityId, long line, Stop stop) {
18 | super("stops", line, "stop_id", affectedEntityId);
19 | this.priority = Priority.HIGH;
20 | this.stop = stop;
21 | }
22 |
23 | @Override public String getMessage() {
24 | return String.format("Stop Id %s is misplaced.", affectedEntityId);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/MissingColumnError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Indicates that a column marked as required is entirely missing from a GTFS feed. */
6 | public class MissingColumnError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | public MissingColumnError(String file, String field) {
10 | super(file, 1, field);
11 | }
12 |
13 | @Override public String getMessage() {
14 | return String.format("Missing required column.");
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/MissingShapeError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.model.Trip;
4 | import com.conveyal.gtfs.validator.model.Priority;
5 |
6 | import java.io.Serializable;
7 |
8 | /**
9 | * Created by landon on 5/6/16.
10 | */
11 | public class MissingShapeError extends GTFSError implements Serializable {
12 | public static final long serialVersionUID = 1L;
13 |
14 | public final Priority priority = Priority.MEDIUM;
15 |
16 | public MissingShapeError(Trip trip) {
17 | super("trips", trip.sourceFileLine, "shape_id", trip.trip_id);
18 | }
19 |
20 | @Override public String getMessage() {
21 | return "Trip " + affectedEntityId + " is missing a shape";
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/MissingTableError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Indicates that a table marked as required is not present in a GTFS feed. */
6 | public class MissingTableError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | public MissingTableError(String file) {
10 | super(file, 0, null);
11 | }
12 |
13 | @Override public String getMessage() {
14 | return String.format("This table is required by the GTFS specification but is missing.");
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/NoAgencyInFeedError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.validator.model.Priority;
4 |
5 | /**
6 | * Created by landon on 5/2/17.
7 | */
8 | public class NoAgencyInFeedError extends GTFSError {
9 | public final Priority priority = Priority.HIGH;
10 |
11 | public NoAgencyInFeedError() {
12 | super("agency", 0, "agency_id");
13 | }
14 |
15 | @Override public String getMessage() {
16 | return String.format("No agency listed in feed (must have at least one).");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/NoTripsForRouteError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | /**
4 | * Created by landon on 5/26/16.
5 | */
6 | public class NoTripsForRouteError {
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/NumberParseError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Represents a problem parsing an integer field of GTFS feed. */
6 | public class NumberParseError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | public NumberParseError(String file, long line, String field) {
10 | super(file, line, field);
11 | }
12 |
13 | @Override public String getMessage() {
14 | return String.format("Error parsing a number from a string.");
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/OverlappingTripsInBlockError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.validator.model.Priority;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * Created by landon on 5/6/16.
9 | */
10 | public class OverlappingTripsInBlockError extends GTFSError implements Serializable {
11 | public static final long serialVersionUID = 1L;
12 |
13 | public final String[] tripIds;
14 | public final Priority priority = Priority.HIGH;
15 | public final String routeId;
16 |
17 | public OverlappingTripsInBlockError(long line, String field, String affectedEntityId, String routeId, String[] tripIds) {
18 | super("trips", line, field, affectedEntityId);
19 | this.tripIds = tripIds;
20 | this.routeId = routeId;
21 | }
22 |
23 | @Override public String getMessage() {
24 | return String.format("Trip Ids %s overlap (route: %s) and share block ID %s", String.join(" & ", tripIds), routeId, affectedEntityId);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/RangeError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Indicates that a number is out of the acceptable range. */
6 | public class RangeError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | final double min, max, actual;
10 |
11 | public RangeError(String file, long line, String field, double min, double max, double actual) {
12 | super(file, line, field);
13 | this.min = min;
14 | this.max = max;
15 | this.actual = actual;
16 | }
17 |
18 | @Override public String getMessage() {
19 | return String.format("Number %s outside of acceptable range [%s,%s].", actual, min, max);
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/ReferentialIntegrityError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Indicates that an entity referenced another entity that does not exist. */
6 | public class ReferentialIntegrityError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | // TODO: maybe also store the entity ID of the entity which contained the bad reference, in addition to the row number
10 | public final String badReference;
11 |
12 | public ReferentialIntegrityError(String tableName, long row, String field, String badReference) {
13 | super(tableName, row, field);
14 | this.badReference = badReference;
15 | }
16 |
17 | /** must be comparable to put into mapdb */
18 | @Override
19 | public int compareTo (GTFSError o) {
20 | int compare = super.compareTo(o);
21 | if (compare != 0) return compare;
22 | return this.badReference.compareTo((((ReferentialIntegrityError) o).badReference));
23 | }
24 |
25 | @Override public String getMessage() {
26 | return String.format(badReference);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/ReversedTripShapeError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.model.Trip;
4 | import com.conveyal.gtfs.validator.model.Priority;
5 |
6 | import java.io.Serializable;
7 |
8 | /**
9 | * Created by landon on 5/6/16.
10 | */
11 | public class ReversedTripShapeError extends GTFSError implements Serializable {
12 | public static final long serialVersionUID = 1L;
13 |
14 | public final Priority priority = Priority.HIGH;
15 | public final String shapeId;
16 |
17 | public ReversedTripShapeError(Trip trip) {
18 | super("trips", trip.sourceFileLine, "shape_id", trip.trip_id);
19 | this.shapeId = trip.shape_id;
20 | }
21 |
22 | @Override public String getMessage() {
23 | return "Trip " + affectedEntityId + " references reversed shape " + shapeId;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/ShapeMissingCoordinatesError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.model.ShapePoint;
4 | import com.conveyal.gtfs.validator.model.Priority;
5 |
6 | import java.io.Serializable;
7 |
8 | /**
9 | * Created by landon on 5/2/16.
10 | */
11 | public class ShapeMissingCoordinatesError extends GTFSError implements Serializable {
12 | public static final long serialVersionUID = 1L;
13 |
14 | public final Priority priority = Priority.MEDIUM;
15 | public final String[] tripIds;
16 |
17 | public ShapeMissingCoordinatesError(ShapePoint shapePoint, String[] tripIds) {
18 | super("shapes", shapePoint.sourceFileLine, "shape_id", shapePoint.shape_id);
19 | this.tripIds = tripIds;
20 | }
21 |
22 | @Override public String getMessage() {
23 | return "Shape " + affectedEntityId + " is missing coordinates (affects " + tripIds.length + " trips)";
24 | }
25 | }
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/TableInSubdirectoryError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.validator.model.Priority;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * Created by landon on 10/14/16.
9 | */
10 | public class TableInSubdirectoryError extends GTFSError implements Serializable {
11 | public static final long serialVersionUID = 1L;
12 |
13 | public final String directory;
14 | public final Priority priority = Priority.HIGH;
15 |
16 | public TableInSubdirectoryError(String file, String directory) {
17 | super(file, 0, null);
18 | this.directory = directory;
19 | }
20 |
21 | @Override public String getMessage() {
22 | return String.format("All GTFS files (including %s.txt) should be at root of zipfile, not nested in subdirectory (%s)", file, directory);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/TimeParseError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Represents a problem parsing a time of day field of GTFS feed. */
6 | public class TimeParseError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | public TimeParseError(String file, long line, String field) {
10 | super(file, line, field);
11 | }
12 |
13 | @Override public String getMessage() {
14 | return "Could not parse time (format should be HH:MM:SS).";
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/TimeZoneError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by landon on 5/11/16.
7 | */
8 |
9 | public class TimeZoneError extends GTFSError implements Serializable {
10 | public static final long serialVersionUID = 1L;
11 |
12 | public final String message;
13 |
14 | /**
15 | *
16 | * @param tableName name of table where error was found
17 | * @param line line of invalid timezone reference
18 | * @param field name of field for invalid timezone reference (agency_timezone or stop_timezone)
19 | * @param affectedEntityId stop or agency ID of the invalid timezone reference
20 | * @param message description of issue with timezone reference
21 | */
22 | public TimeZoneError(String tableName, long line, String field, String affectedEntityId, String message) {
23 | super(tableName, line, field, affectedEntityId);
24 | this.message = message;
25 | }
26 |
27 | @Override public String getMessage() {
28 | return message + ". (" + field + ": " + affectedEntityId + ")";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/URLParseError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import java.io.Serializable;
4 |
5 | /** Represents a problem parsing a URL field from a GTFS feed. */
6 | public class URLParseError extends GTFSError implements Serializable {
7 | public static final long serialVersionUID = 1L;
8 |
9 | public URLParseError(String file, long line, String field) {
10 | super(file, line, field);
11 | }
12 |
13 | @Override public String getMessage() {
14 | return "Could not parse URL (format should be ://?#).";
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/UnusedStopError.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.error;
2 |
3 | import com.conveyal.gtfs.model.Stop;
4 | import com.conveyal.gtfs.validator.model.Priority;
5 |
6 | import java.io.Serializable;
7 |
8 | /** Indicates that a stop exists more than once in the feed. */
9 | public class UnusedStopError extends GTFSError implements Serializable {
10 | public static final long serialVersionUID = 1L;
11 |
12 | public final Priority priority;
13 | public final Stop stop;
14 |
15 | public UnusedStopError(Stop stop) {
16 | super("stops", stop.sourceFileLine, "stop_id", stop.stop_id);
17 | this.priority = Priority.LOW;
18 | this.stop = stop;
19 | }
20 |
21 | @Override public String getMessage() {
22 | return String.format("Stop Id %s is not used in any trips.", affectedEntityId);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/error/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This package contains all the objects that represent errors encountered during GTFS loading.
3 | */
4 | package com.conveyal.gtfs.error;
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/loader/BooleanField.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.loader;
2 |
3 | import com.conveyal.gtfs.storage.StorageException;
4 |
5 | import java.sql.JDBCType;
6 | import java.sql.PreparedStatement;
7 | import java.sql.SQLType;
8 |
9 | /**
10 | * A GTFS boolean field, coded as a single character string 0 or 1.
11 | */
12 | public class BooleanField extends Field {
13 |
14 | public BooleanField (String name, Requirement requirement) {
15 | super(name, requirement);
16 | }
17 |
18 | private boolean validate (String string) {
19 | if ( ! ("0".equals(string) || "1".equals(string))) throw new StorageException("Field must be 0 or 1.");
20 | return "1".equals(string);
21 | }
22 |
23 | @Override
24 | public void setParameter (PreparedStatement preparedStatement, int oneBasedIndex, String string) {
25 | try {
26 | preparedStatement.setBoolean(oneBasedIndex, validate(string));
27 | } catch (Exception ex) {
28 | throw new StorageException(ex);
29 | }
30 | }
31 |
32 | /**
33 | * The 0 or 1 will be converted to the string "true" or "false" for SQL COPY.
34 | */
35 | @Override
36 | public String validateAndConvert (String string) {
37 | return Boolean.toString(validate(string));
38 | }
39 |
40 | @Override
41 | public SQLType getSqlType () {
42 | return JDBCType.BOOLEAN;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/loader/Requirement.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.loader;
2 |
3 | /**
4 | * Created by abyrd on 2017-03-30
5 | */
6 | public enum Requirement {
7 | REQUIRED, // Required by the GTFS spec
8 | OPTIONAL, // Optional according to the GTFS spec
9 | EXTENSION, // Extension proposed and documented on gtfs-changes
10 | PROPRIETARY, // Known proprietary extension that is not yet an official proposal
11 | UNKNOWN // Undocumented proprietary extension
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/loader/SQLEntityFetcher.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.loader;
2 |
3 | import java.sql.PreparedStatement;
4 |
5 | /**
6 | * Created by abyrd on 2017-04-04
7 | */
8 | public abstract class SQLEntityFetcher implements Iterable {
9 |
10 | EntityPopulator entityPopulator;
11 |
12 | public SQLEntityFetcher (PreparedStatement fetchAllStatement, EntityPopulator entityPopulator) {
13 | this.entityPopulator = entityPopulator;
14 | }
15 |
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/loader/ShortField.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.loader;
2 |
3 | import com.conveyal.gtfs.storage.StorageException;
4 |
5 | import java.sql.JDBCType;
6 | import java.sql.PreparedStatement;
7 | import java.sql.SQLType;
8 |
9 | /**
10 | * Created by abyrd on 2017-03-31
11 | */
12 | public class ShortField extends Field {
13 |
14 | private int maxValue; // can be shared with all numeric field types?
15 |
16 | public ShortField (String name, Requirement requirement, int maxValue) {
17 | super(name, requirement);
18 | this.maxValue = maxValue;
19 | }
20 |
21 | private short validate (String string) {
22 | if (string == null || string.isEmpty()) return 0; // Default numeric fields to zero.
23 | short s = Short.parseShort(string);
24 | if (s < 0) throw new StorageException("negative field in " + name );
25 | // TODO enforce
26 | // if (s > maxValue) throw new StorageException("excessively large short integer value in field " + name);
27 | return s;
28 | }
29 |
30 | @Override
31 | public void setParameter(PreparedStatement preparedStatement, int oneBasedIndex, String string) {
32 | try {
33 | preparedStatement.setShort(oneBasedIndex, validate(string));
34 | } catch (Exception ex) {
35 | throw new StorageException(ex);
36 | }
37 | }
38 |
39 | @Override
40 | public String validateAndConvert(String string) {
41 | validate(string);
42 | return string;
43 | }
44 |
45 | @Override
46 | public SQLType getSqlType () {
47 | return JDBCType.SMALLINT;
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/loader/StringField.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.loader;
2 |
3 | import com.conveyal.gtfs.storage.StorageException;
4 |
5 | import java.sql.JDBCType;
6 | import java.sql.PreparedStatement;
7 | import java.sql.SQLType;
8 |
9 | /**
10 | * Created by abyrd on 2017-03-31
11 | */
12 | public class StringField extends Field {
13 |
14 | public StringField (String name, Requirement requirement) {
15 | super(name, requirement);
16 | }
17 |
18 | /** Check that a string can be properly parsed and is in range. */
19 | public String validateAndConvert (String string) {
20 | return cleanString(string);
21 | }
22 |
23 | public void setParameter(PreparedStatement preparedStatement, int oneBasedIndex, String string) {
24 | try {
25 | preparedStatement.setString(oneBasedIndex, validateAndConvert(string));
26 | } catch (Exception ex) {
27 | throw new StorageException(ex);
28 | }
29 | }
30 |
31 | @Override
32 | public SQLType getSqlType() {
33 | return JDBCType.VARCHAR;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/loader/TableReader.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.loader;
2 |
3 | import com.conveyal.gtfs.model.Entity;
4 |
5 | /**
6 | * This is an interface for classes that can iterate over all entities in a single GTFS table, or fetch single entities
7 | * by ID, or fetch ordered groups of entities with the same ID (e.g. all stop times with the same trip_id).
8 | * Created by abyrd on 2017-04-06
9 | */
10 | public interface TableReader extends Iterable {
11 |
12 | public T get (String id);
13 |
14 | // public Iterable getAll ();
15 |
16 | // public Iterable getAllOrdered ();
17 |
18 | public Iterable getOrdered (String id);
19 |
20 | public void close ();
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/loader/TimeField.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.loader;
2 |
3 | import com.conveyal.gtfs.storage.StorageException;
4 |
5 | import java.sql.JDBCType;
6 | import java.sql.PreparedStatement;
7 | import java.sql.SQLType;
8 |
9 | /**
10 | * A field in the format HH:MM:SS, which will be stored as a number of seconds after midnight.
11 | */
12 | public class TimeField extends Field {
13 |
14 | public TimeField(String name, Requirement requirement) {
15 | super(name, requirement);
16 | }
17 |
18 | @Override
19 | public void setParameter(PreparedStatement preparedStatement, int oneBasedIndex, String string) {
20 | try {
21 | preparedStatement.setInt(oneBasedIndex, getSeconds(string));
22 | } catch (Exception ex) {
23 | throw new StorageException(ex);
24 | }
25 | }
26 |
27 | // Actually this is converting the string. Can we use some JDBC existing functions for this?
28 | @Override
29 | public String validateAndConvert(String hhmmss) {
30 | return Integer.toString(getSeconds(hhmmss));
31 | }
32 |
33 | private static int getSeconds (String hhmmss) {
34 | if (hhmmss.length() != 8) {
35 | throw new StorageException("Time field should be 8 characters long.");
36 | }
37 | String[] fields = hhmmss.split(":");
38 | int h = Integer.parseInt(fields[0]);
39 | int m = Integer.parseInt(fields[1]);
40 | int s = Integer.parseInt(fields[2]);
41 | return ((h * 60) + m) * 60 + s;
42 | }
43 |
44 | @Override
45 | public SQLType getSqlType () {
46 | return JDBCType.INTEGER;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/loader/URLField.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.loader;
2 |
3 | import com.conveyal.gtfs.storage.StorageException;
4 |
5 | import java.sql.JDBCType;
6 | import java.sql.PreparedStatement;
7 | import java.sql.SQLType;
8 |
9 | /**
10 | * Created by abyrd on 2017-03-31
11 | */
12 | public class URLField extends Field {
13 |
14 | public URLField(String name, Requirement requirement) {
15 | super(name, requirement);
16 | }
17 |
18 | /** Check that a string can be properly parsed and is in range. */
19 | public String validateAndConvert (String string) {
20 | try {
21 | string = cleanString(string);
22 | // new URL(cleanString); TODO call this to validate, but we can't default to zero
23 | return string;
24 | } catch (Exception ex) {
25 | throw new StorageException(ex);
26 | }
27 | }
28 |
29 | public void setParameter(PreparedStatement preparedStatement, int oneBasedIndex, String string) {
30 | try {
31 | preparedStatement.setString(oneBasedIndex, validateAndConvert(string));
32 | } catch (Exception ex) {
33 | throw new StorageException(ex);
34 | }
35 | }
36 |
37 | @Override
38 | public SQLType getSqlType() {
39 | return JDBCType.VARCHAR;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/model/Fare.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.model;
2 |
3 | import com.google.common.collect.Lists;
4 |
5 | import java.io.Serializable;
6 | import java.util.List;
7 |
8 | /**
9 | * This table does not exist in GTFS. It is a join of fare_attributes and fare_rules on fare_id.
10 | * There should only be one fare_attribute per fare_id, but there can be many fare_rules per fare_id.
11 | */
12 | public class Fare implements Serializable {
13 | public static final long serialVersionUID = 1L;
14 |
15 | public String fare_id;
16 | public FareAttribute fare_attribute;
17 | public List fare_rules = Lists.newArrayList();
18 |
19 | public Fare(String fare_id) {
20 | this.fare_id = fare_id;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/model/Shape.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.model;
2 |
3 | import com.conveyal.gtfs.GTFSFeed;
4 | import org.locationtech.jts.geom.Coordinate;
5 | import org.locationtech.jts.geom.LineString;
6 | import org.mapdb.Fun;
7 |
8 | import java.util.Map;
9 |
10 | import static com.conveyal.gtfs.util.GeometryUtil.geometryFactory;
11 |
12 | /**
13 | * Represents a collection of GTFS shape points. Never saved in MapDB but constructed on the fly.
14 | */
15 | public class Shape {
16 | /** The shape itself */
17 | public LineString geometry;
18 |
19 | /** shape_dist_traveled for each point in the geometry. TODO how to handle shape dist traveled not specified, or not specified on all stops? */
20 | public double[] shape_dist_traveled;
21 |
22 | public Shape (GTFSFeed feed, String shape_id) {
23 | Map, ShapePoint> points =
24 | feed.shape_points.subMap(new Fun.Tuple2(shape_id, null), new Fun.Tuple2(shape_id, Fun.HI));
25 |
26 | Coordinate[] coords = points.values().stream()
27 | .map(point -> new Coordinate(point.shape_pt_lon, point.shape_pt_lat))
28 | .toArray(i -> new Coordinate[i]);
29 | geometry = geometryFactory.createLineString(coords);
30 | shape_dist_traveled = points.values().stream().mapToDouble(point -> point.shape_dist_traveled).toArray();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/model/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This package contains an alternative to the GTFS loading classes we have been using from OBA.
3 | * It loads GTFS into a disk-backed map and attempts to be relatively efficient space-wise.
4 | * The intent is to eliminate the need for AgencyAndIds, using feed IDs and keeping each feed in its own
5 | * separate data structure.
6 | */
7 | package com.conveyal.gtfs.model;
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/storage/StorageException.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.storage;
2 |
3 | import com.conveyal.gtfs.error.NewGTFSErrorType;
4 |
5 | /**
6 | * Created by abyrd on 2017-03-25
7 | */
8 | public class StorageException extends RuntimeException {
9 |
10 | public NewGTFSErrorType errorType = NewGTFSErrorType.OTHER;
11 |
12 | public String badValue = null;
13 |
14 | public StorageException(NewGTFSErrorType errorType, String badValue) {
15 | super(errorType.englishMessage);
16 | this.errorType = errorType;
17 | this.badValue = badValue;
18 | }
19 |
20 | public StorageException(Exception ex) {
21 | super(ex);
22 | }
23 |
24 | public StorageException (String message) {
25 | super(message);
26 | }
27 |
28 | public StorageException(String message, Exception ex) {
29 | super(message, ex);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/util/Renamer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.util;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.UUID;
6 |
7 | /**
8 | * Creates new unique names to give things new IDs.
9 | */
10 | public class Renamer {
11 |
12 | private Map newNameForOldName = new HashMap<>();
13 | private Map oldNameForNewName = new HashMap<>();
14 |
15 | public String getNewName(String oldName) {
16 | String newName = newNameForOldName.get(oldName);
17 | if (newName == null) {
18 | while (newName == null || oldNameForNewName.containsKey(newName)) {
19 | newName = UUID.randomUUID().toString().substring(0, 6);
20 | }
21 | newNameForOldName.put(oldName, newName);
22 | oldNameForNewName.put(newName, oldName);
23 | System.out.println(oldName + " <--> " + newName);
24 | }
25 | return newName;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/util/json/Rectangle2DDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.util.json;
2 |
3 | import com.fasterxml.jackson.core.JsonParseException;
4 | import com.fasterxml.jackson.core.JsonParser;
5 | import com.fasterxml.jackson.databind.DeserializationContext;
6 | import com.fasterxml.jackson.databind.JsonDeserializer;
7 |
8 | import java.awt.geom.Rectangle2D;
9 | import java.io.IOException;
10 |
11 | public class Rectangle2DDeserializer extends JsonDeserializer {
12 |
13 | @Override
14 | public Rectangle2D deserialize(JsonParser jp, DeserializationContext arg1) throws IOException {
15 |
16 | IntermediateBoundingBox bbox = jp.readValueAs(IntermediateBoundingBox.class);
17 |
18 | if (bbox.north == null || bbox.south == null || bbox.east == null || bbox.west == null)
19 | throw new JsonParseException("Unable to deserialize bounding box; need north, south, east, and west.", jp.getCurrentLocation());
20 |
21 | Rectangle2D.Double ret = new Rectangle2D.Double(bbox.west, bbox.north, 0, 0);
22 | ret.add(bbox.east, bbox.south);
23 | return ret;
24 | }
25 |
26 | /**
27 | * A place to hold information from the JSON stream temporarily.
28 | */
29 | private static class IntermediateBoundingBox {
30 | public Double north;
31 | public Double south;
32 | public Double east;
33 | public Double west;
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/util/json/Rectangle2DMixIn.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.util.json;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFilter;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 |
6 | // ignore all by default
7 | @JsonFilter("bbox")
8 | public abstract class Rectangle2DMixIn {
9 | // stored as lon, lat
10 | @JsonProperty("west") public abstract double getMinX();
11 | @JsonProperty("east") public abstract double getMaxX();
12 | @JsonProperty("north") public abstract double getMaxY();
13 | @JsonProperty("south") public abstract double getMinY();
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/validator/model/DuplicateStops.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.validator.model;
2 |
3 | import com.conveyal.gtfs.model.Stop;
4 |
5 | import java.io.Serializable;
6 |
7 | public class DuplicateStops implements Serializable {
8 |
9 | public Stop stop1;
10 | public Stop stop2;
11 |
12 | public double distance;
13 |
14 | public DuplicateStops(Stop s1, Stop s2, double dist) {
15 | stop1 = s1;
16 | stop2 = s2;
17 | distance = dist;
18 | }
19 | public Stop getOriginalStop () { return stop1.sourceFileLine < stop2.sourceFileLine ? stop1 : stop2; }
20 |
21 | public Stop getDuplicatedStop () { return stop1.sourceFileLine > stop2.sourceFileLine ? stop1 : stop2; }
22 |
23 | public String getStop1Id() {
24 | return stop1.stop_id;
25 | }
26 |
27 | public String getStop2Id() {
28 | return stop2.stop_id;
29 | }
30 |
31 | public String getStopIds() {
32 | return this.getStop1Id() + "," + this.getStop2Id();
33 | }
34 |
35 | public String toString() {
36 | return "Stops " + this.getStop1Id() + " and " + this.getStop2Id() + " are within " + this.distance + " meters";
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/validator/model/Priority.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.validator.model;
2 |
3 | public enum Priority {
4 | /**
5 | * Something that is likely to break routing results,
6 | * e.g. stop times out of sequence or high-speed travel
7 | */
8 | HIGH,
9 |
10 | /**
11 | * Something that is likely to break display, but still give accurate routing results,
12 | * e.g. broken shapes or route long name containing route short name.
13 | */
14 | MEDIUM,
15 |
16 | /**
17 | * Something that will not affect user experience but should be corrected as time permits,
18 | * e.g. unused stops.
19 | */
20 | LOW,
21 |
22 | /**
23 | * An error for which we do not have a priority
24 | */
25 | UNKNOWN
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/gtfs/validator/service/ProjectedCoordinate.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.validator.service;
2 |
3 | import org.locationtech.jts.geom.Coordinate;
4 | import org.opengis.referencing.operation.MathTransform;
5 |
6 | public class ProjectedCoordinate extends Coordinate {
7 |
8 | private static final long serialVersionUID = 2905131060296578237L;
9 |
10 | final private MathTransform transform;
11 | final private Coordinate refLatLon;
12 |
13 | public ProjectedCoordinate(MathTransform mathTransform,
14 | Coordinate to, Coordinate refLatLon) {
15 | this.transform = mathTransform;
16 | this.x = to.x;
17 | this.y = to.y;
18 | this.refLatLon = refLatLon;
19 | }
20 |
21 | public String epsgCode() {
22 | final String epsgCode =
23 | "EPSG:" + GeoUtils.getEPSGCodefromUTS(refLatLon);
24 | return epsgCode;
25 | }
26 |
27 | public Coordinate getReferenceLatLon() {
28 | return refLatLon;
29 | }
30 |
31 | public MathTransform getTransform() {
32 | return transform;
33 | }
34 |
35 | public double getX()
36 | {
37 | return this.x;
38 | }
39 |
40 | public double getY()
41 | {
42 | return this.y;
43 | }
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/Node.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib;
2 |
3 | import java.io.Serializable;
4 |
5 | public class Node extends OSMEntity implements Serializable {
6 |
7 | private static final long serialVersionUID = 1L;
8 |
9 | // PBF uses 100 nanodegrees (1e7) by default. (180 * 10^7) / (2^31) ~= 0.84 so we should be fine.
10 | private static final double FIXED_PRECISION_FACTOR = 1e7;
11 |
12 | public Node () { }
13 |
14 | public Node (double lat, double lon) {
15 | setLatLon(lat, lon);
16 | }
17 |
18 | /* Angles are stored as fixed precision 32 bit integers because 32 bit floats are not sufficiently precise. */
19 | public int fixedLat;
20 | public int fixedLon;
21 |
22 | public double getLat() {return fixedLat / FIXED_PRECISION_FACTOR;}
23 |
24 | public double getLon() {return fixedLon / FIXED_PRECISION_FACTOR;}
25 |
26 | public void setLatLon (double lat, double lon) {
27 | this.fixedLat = (int)(lat * FIXED_PRECISION_FACTOR);
28 | this.fixedLon = (int)(lon * FIXED_PRECISION_FACTOR);
29 | }
30 |
31 | @Override
32 | public Type getType() {
33 | return Type.NODE;
34 | }
35 |
36 | public String toString() {
37 | return "[Node "+getLat()+" "+getLon()+"]";
38 | }
39 |
40 | @Override
41 | public boolean equals(Object other) {
42 | if ( ! (other instanceof Node)) return false;
43 | Node otherNode = (Node) other;
44 | return this.fixedLat == otherNode.fixedLat &&
45 | this.fixedLon == otherNode.fixedLon &&
46 | this.tagsEqual(otherNode);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/VexFormat.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib;
2 |
3 | public abstract class VexFormat {
4 |
5 | public static final byte[] HEADER = "VEXFMT".getBytes();
6 |
7 | // FIXME use OSMEntity.Type or Classes themselves
8 | public static final int VEX_NODE = 0;
9 | public static final int VEX_WAY = 1;
10 | public static final int VEX_RELATION = 2;
11 | public static final int VEX_NONE = 3;
12 |
13 | // TODO OSM layer support
14 | public static final int LAYER_ANY = 0;
15 | public static final int LAYER_STREET = 1;
16 | public static final int LAYER_LANDUSE = 2;
17 | public static final int LAYER_BUILDING = 3;
18 |
19 | // TODO helper methods that give etype for class, int for etype, etc.
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/Way.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib;
2 |
3 | import java.io.Serializable;
4 | import java.util.Arrays;
5 |
6 | public class Way extends OSMEntity implements Serializable {
7 |
8 | private static final long serialVersionUID = 1L;
9 |
10 | public long[] nodes;
11 |
12 | @Override
13 | public String toString() {
14 | return String.format("Way with %d tags and %d nodes", tags.size(), nodes.length);
15 | }
16 |
17 | @Override
18 | public Type getType() {
19 | return Type.WAY;
20 | }
21 |
22 | @Override
23 | public boolean equals(Object other) {
24 | if ( ! (other instanceof Way)) return false;
25 | Way otherWay = (Way) other;
26 | return Arrays.equals(this.nodes, otherWay.nodes) && this.tagsEqual(otherWay);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/WebMercatorTile.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib;
2 |
3 | /**
4 | *
5 | */
6 | public class WebMercatorTile {
7 |
8 | //http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
9 | public final int ZOOM = 12;
10 | public final int xtile, ytile;
11 |
12 | /**
13 | * Tile definition equations from: TODO URL
14 | */
15 | public WebMercatorTile(double lat, double lon) {
16 | xtile = (int) Math.floor((lon + 180) / 360 * (1 << ZOOM));
17 | ytile = (int) Math.floor((1 - Math.log(Math.tan(Math.toRadians(lat))
18 | + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1 << ZOOM));
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/display/GraphicsSink.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib.display;
2 |
3 | import com.conveyal.osmlib.Node;
4 | import com.conveyal.osmlib.OSMEntitySink;
5 | import com.conveyal.osmlib.Relation;
6 | import com.conveyal.osmlib.Way;
7 |
8 | import java.awt.*;
9 | import java.awt.geom.Line2D;
10 | import java.io.IOException;
11 | import java.time.Instant;
12 | import java.time.ZoneId;
13 |
14 | /**
15 | *
16 | */
17 | public class GraphicsSink implements OSMEntitySink {
18 |
19 | Graphics2D g2d;
20 |
21 | public GraphicsSink(Graphics2D g2d) {
22 | this.g2d = g2d;
23 | }
24 |
25 | @Override
26 | public void writeBegin() throws IOException {
27 |
28 | }
29 |
30 | @Override
31 | public void setReplicationTimestamp(long secondsSinceEpoch) {
32 | g2d.drawString(Instant.ofEpochSecond(secondsSinceEpoch).atZone(ZoneId.systemDefault()).toString(), 0, 0);
33 | }
34 |
35 | @Override
36 | public void writeNode(long id, Node node) throws IOException {
37 | Shape line = new Line2D.Double(node.getLon(), node.getLat(), node.getLon(), node.getLat());
38 | g2d.draw(line);
39 | }
40 |
41 | @Override
42 | public void writeWay(long id, Way way) throws IOException {
43 |
44 | }
45 |
46 | @Override
47 | public void writeRelation(long id, Relation relation) throws IOException {
48 |
49 | }
50 |
51 | @Override
52 | public void writeEnd() throws IOException {
53 |
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/main/Converter.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib.main;
2 |
3 | import com.conveyal.osmlib.OSMEntitySink;
4 | import com.conveyal.osmlib.OSMEntitySource;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.io.IOException;
9 |
10 | public class Converter {
11 |
12 | private static final Logger LOG = LoggerFactory.getLogger(Converter.class);
13 |
14 | /**
15 | * This main method will load a file into the osm-lib representation and write it back out as a stream,
16 | * without using an intermediate MapDB. File types are detected from the file name extensions.
17 | */
18 | public static void main(String[] args) {
19 |
20 | // Get input and output file names
21 | if (args.length < 2) {
22 | System.err.println("usage: Convert input.[pbf|vex] output.[pbf|vex|txt]");
23 | System.exit(0);
24 | }
25 | String inputPath = args[0];
26 | String outputPath = args[1];
27 |
28 | // Pump the entities from the input file directly to the output file.
29 | long startTime = System.currentTimeMillis();
30 | try {
31 | OSMEntitySource source = OSMEntitySource.forFile(inputPath);
32 | OSMEntitySink sink = OSMEntitySink.forFile(outputPath);
33 | source.copyTo(sink);
34 | } catch (IOException ex) {
35 | throw new RuntimeException(ex);
36 | }
37 | LOG.info("Total run time: {} sec", (System.currentTimeMillis() - startTime)/1000D);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/main/SpeedSetter.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib.main;
2 |
3 | import com.conveyal.osmlib.OSM;
4 | import com.conveyal.osmlib.Way;
5 |
6 | import java.io.BufferedReader;
7 | import java.io.File;
8 | import java.io.FileReader;
9 |
10 | /**
11 | * This is an example utility main method for setting speeds from a csv file.
12 | * It's meant to be run from an IDE as part of a data preparation pipeline.
13 | */
14 | public class SpeedSetter {
15 |
16 | public static void main (String[] args) throws Exception {
17 | OSM osm = new OSM(null);
18 | osm.readFromFile("/Users/abyrd/predicted_speeds_2015_for_conveyal.pbf");
19 |
20 | System.out.println("Setting maxspeed:motorcar tags...");
21 | File speedsFile = new File("/Users/abyrd/predicted_speeds_2015_for_conveyal.csv");
22 | try(BufferedReader br = new BufferedReader(new FileReader(speedsFile))) {
23 | br.readLine(); // skip headers
24 | for(String line; (line = br.readLine()) != null; ) {
25 | String[] fields = line.split(",");
26 | long osmWayId = Long.parseLong(fields[0]);
27 | double speedKph = Double.parseDouble(fields[1]);
28 | Way way = osm.ways.get(osmWayId);
29 | // R5 currently prioritizes maxspeed:motorcar above all other maxspeed tags
30 | way.addOrReplaceTag("maxspeed:motorcar", String.format("%1.1f kph", speedKph));
31 | osm.ways.put(osmWayId, way);
32 | }
33 | }
34 | osm.writeToFile("/Users/abyrd/predicted_speeds_output.pbf");
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This package duplicates functionality in the data model classes in org.otp.openstreetmap, but is designed for
3 | * loading OSM data into disk-backed maps in a more space efficient manner so that the OSM data can be retained for
4 | * later use. It is not yet used by OTP.
5 | */
6 | package com.conveyal.osmlib;
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/serializer/NodeSerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib.serializer;
2 |
3 | import com.conveyal.osmlib.Node;
4 | import org.mapdb.Serializer;
5 |
6 | import java.io.DataInput;
7 | import java.io.DataOutput;
8 | import java.io.IOException;
9 | import java.io.Serializable;
10 |
11 | public class NodeSerializer implements Serializer, Serializable {
12 |
13 | @Override
14 | public void serialize(DataOutput out, Node node) throws IOException {
15 | out.writeInt(node.fixedLat);
16 | out.writeInt(node.fixedLon);
17 | VarInt.writeTags(out, node);
18 | }
19 |
20 | @Override
21 | public Node deserialize(DataInput in, int available) throws IOException {
22 | Node node = new Node();
23 | node.fixedLat = in.readInt();
24 | node.fixedLon = in.readInt();
25 | VarInt.readTags(in, node);
26 | return node;
27 | }
28 |
29 | @Override
30 | public int fixedSize() {
31 | return -1;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/serializer/WaySerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib.serializer;
2 |
3 | import com.conveyal.osmlib.Way;
4 | import org.mapdb.Serializer;
5 |
6 | import java.io.DataInput;
7 | import java.io.DataOutput;
8 | import java.io.IOException;
9 | import java.io.Serializable;
10 |
11 | /** Ideally, these serializers would be the same ones used in the VEX binary exchange format. */
12 | public class WaySerializer implements Serializer, Serializable {
13 |
14 | /** Delta-code the series of node references, and write out all values as varints. */
15 | @Override
16 | public void serialize(DataOutput out, Way way) throws IOException {
17 | VarInt.writeRawVarint32(out, way.nodes.length);
18 | long lastNodeId = 0;
19 | for (int i = 0; i < way.nodes.length; i++) {
20 | long delta = way.nodes[i] - lastNodeId;
21 | VarInt.writeSInt64NoTag(out, delta);
22 | lastNodeId = way.nodes[i];
23 | }
24 | VarInt.writeTags(out, way);
25 | }
26 |
27 | @Override
28 | public Way deserialize(DataInput in, int available) throws IOException {
29 | Way way = new Way();
30 | int nNodes = VarInt.readRawVarint32(in);
31 | way.nodes = new long[nNodes];
32 | long lastNodeId = 0;
33 | for (int i = 0; i < nNodes; i++) {
34 | lastNodeId += VarInt.readSInt64(in);
35 | way.nodes[i] = lastNodeId;
36 | }
37 | VarInt.readTags(in, way);
38 | return way;
39 | }
40 |
41 | @Override
42 | public int fixedSize() { return -1; }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/osmlib/serializer/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This package contains custom MapDB serializers for OTP's OSM data model.
3 | * Without them, the 70MB DC PBF becomes a 248MB MapDB
4 | * With them, using compression and variable-byte encodings, it becomes a 158MB MapDB
5 | */
6 | package com.conveyal.osmlib.serializer;
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/OneOriginResult.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5;
2 |
3 | import com.conveyal.r5.analyst.AccessibilityResult;
4 | import com.conveyal.r5.analyst.cluster.TravelTimeResult;
5 |
6 | /**
7 | * This provides a single return type (for internal R5 use) for all the kinds of results we can get from a travel time
8 | * computer and reducer for a single origin point. Currently, these results include travel times to points in a
9 | * destination pointset, and accessibility indicator values for various travel time cutoffs and percentiles of travel
10 | * time.
11 | *
12 | * TODO add fields to record travel time breakdowns into wait and ride and walk time, and paths to destinations.
13 | */
14 | public class OneOriginResult {
15 |
16 | public final TravelTimeResult travelTimes;
17 |
18 | public final AccessibilityResult accessibility;
19 |
20 | public OneOriginResult(TravelTimeResult travelTimes, AccessibilityResult accessibility) {
21 | this.travelTimes = travelTimes;
22 | this.accessibility = accessibility;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/ByteArrayOutputInputStream.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.InputStream;
6 |
7 | /**
8 | * An OutputStream that buffers everything in memory, allowing the contents of that buffer to be read back out as an
9 | * InputStream. This works around the fact that ByteArrayOutputStream.toByteArray makes a copy of the backing byte
10 | * array, doubling memory consumption and wasting time.
11 | */
12 | public class ByteArrayOutputInputStream extends ByteArrayOutputStream {
13 |
14 | /**
15 | * @return an input stream wrapping the internal byte buffer. Further writes are not possible.
16 | */
17 | public InputStream getInputStream () {
18 | try {
19 | this.close();
20 | InputStream inputStream = new ByteArrayInputStream(buf);
21 | // Prevent additional writes to the internal buffer.
22 | buf = null;
23 | return inputStream;
24 | } catch (Exception e) {
25 | throw new RuntimeException(e);
26 | }
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/FileCategory.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst;
2 |
3 | /**
4 | * For use by FilePersistence. Avoids specifying bucket names or subfolders with Strings.
5 | */
6 | public enum FileCategory {
7 |
8 | POLYGON, // Only this one is currently used, others are examples
9 | GRID,
10 | BUNDLE;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/LittleEndianIntOutputStream.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst;
2 |
3 | import java.io.FilterOutputStream;
4 | import java.io.IOException;
5 | import java.io.OutputStream;
6 | import java.nio.charset.Charset;
7 |
8 | /**
9 | * Class to output ints. An order of magnitude faster than Guava LittleEndianDataOutputStream.
10 | */
11 | public class LittleEndianIntOutputStream extends FilterOutputStream {
12 | public LittleEndianIntOutputStream(OutputStream out) {
13 | super(out);
14 | }
15 |
16 | public void writeInt (int value) throws IOException {
17 | byte[] bytes = new byte[]{
18 | (byte) (value & 0xff),
19 | (byte) (value >> 8 & 0xff),
20 | (byte) (value >> 16 & 0xff),
21 | (byte) (value >> 24 & 0xff)
22 | };
23 |
24 | out.write(bytes);
25 | }
26 |
27 | /** Write an ASCII string as bytes, generally used as a header */
28 | public void writeAscii(String string) throws IOException {
29 | byte[] bytes = string.getBytes(Charset.forName("ASCII"));
30 | out.write(bytes);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/WorkerCategory.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst;
2 |
3 | import java.io.Serializable;
4 | import java.util.Objects;
5 |
6 | /**
7 | * This identifies a category of workers that are all running the same R5 commit and have the same graph loaded.
8 | * TODO perhaps this is a TaskCategory rather than a WorkerCategory.
9 | */
10 | public class WorkerCategory implements Comparable, Serializable {
11 |
12 | public final String graphId;
13 | public final String workerVersion;
14 |
15 | public WorkerCategory(String graphId, String workerCommit) {
16 | this.graphId = graphId;
17 | this.workerVersion = workerCommit;
18 | }
19 |
20 | @Override
21 | public String toString() {
22 | return "graph ID '" + graphId + '\'' + ", worker version '" + workerVersion + '\'';
23 | }
24 |
25 | @Override
26 | public boolean equals(Object o) {
27 | if (this == o) return true;
28 | if (o == null || getClass() != o.getClass()) return false;
29 | WorkerCategory that = (WorkerCategory) o;
30 | return Objects.equals(graphId, that.graphId) &&
31 | Objects.equals(workerVersion, that.workerVersion);
32 | }
33 |
34 | @Override
35 | public int hashCode() {
36 | return Objects.hash(graphId, workerVersion);
37 | }
38 |
39 | @Override
40 | public int compareTo (WorkerCategory other) {
41 | int result = this.graphId.compareTo(other.graphId);
42 | return result == 0 ? this.workerVersion.compareTo(other.workerVersion) : result;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/cluster/BundleManifest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.cluster;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Originally transportation data "bundles" were a zip file of GTFS files and OSM files.
7 | * OSM data is no longer specific to a GTFS feed, at least within our UI. OSM is now associated with a whole project.
8 | * So "new-style" bundles are no longer zip files of data, they are just references to OSM and GTFS files on S3.
9 | * The fields in this class do not contain filenames but IDs that will be sanitized and have file extensions added
10 | * before being looked up as S3 objects.
11 | */
12 | public class BundleManifest {
13 | /** ID of the OSM file, for use with OSMCache */
14 | public String osmId;
15 |
16 | /** IDs of the GTFS files, for use with GTFSCache */
17 | public List gtfsIds;
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/cluster/WorkerNotReadyException.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.cluster;
2 |
3 | import com.conveyal.r5.transit.TransportNetwork;
4 | import com.conveyal.r5.util.AsyncLoader;
5 |
6 | /**
7 | * This exception is thrown to indicate that a function cannot complete because it's still asynchronously loading
8 | * data it needs to perform its calculations. It implies that the thrower has already recorded the need for
9 | * those data and has begun an attempt to prepare them.
10 | *
11 | * Created by abyrd on 2018-10-30
12 | */
13 | public class WorkerNotReadyException extends Exception {
14 |
15 | public final AsyncLoader.LoaderState asyncLoaderState;
16 |
17 | public WorkerNotReadyException(AsyncLoader.LoaderState asyncLoaderState) {
18 | super(asyncLoaderState.toString());
19 | this.asyncLoaderState = asyncLoaderState;
20 | }
21 |
22 | public boolean isError() {
23 | return asyncLoaderState.status == AsyncLoader.Status.ERROR;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/decay/ExponentialDecayFunction.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.decay;
2 |
3 | import org.apache.commons.math3.util.FastMath;
4 |
5 | /**
6 | * This an exponential decay function where the cutoff parameter c is treated as the half-life.
7 | * So rather than working with the base e, we use: N(t) = 2^(-t/c) = 0.5^(t/c)
8 | * Exp() is usually faster than the more general pow().
9 | * Since pow(x,y) = exp(y*log(x)) and we generally hold c constant while varying t:
10 | * N(t) = exp(log(0.5) * t/c)
11 | * JIT may be smart enough to factor the (log(0.5)/cutoff) out of the series of method calls, without us needing to
12 | * create specific function instances with precomputed constants for each separate cutoff.
13 | */
14 | public class ExponentialDecayFunction extends DecayFunction {
15 |
16 | private static final double logOneHalf = FastMath.log(0.5);
17 |
18 | @Override
19 | public double computeWeight (int cutoffSeconds, int travelTimeSeconds) {
20 | if (travelTimeSeconds <= 0) {
21 | return 1;
22 | }
23 | if (travelTimeSeconds >= TWO_HOURS_IN_SECONDS) {
24 | return 0;
25 | }
26 | return FastMath.exp(logOneHalf / cutoffSeconds * travelTimeSeconds);
27 | }
28 |
29 | @Override
30 | public void prepare () { }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/decay/StepDecayFunction.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.decay;
2 |
3 | /**
4 | * Simple cliff-edge weight function. No parameters to set or validate.
5 | */
6 | public class StepDecayFunction extends DecayFunction {
7 |
8 | @Override
9 | public void prepare () {
10 | // Nothing to validate or prepare.
11 | }
12 |
13 | @Override
14 | public int reachesZeroAt (int cutoffSeconds) {
15 | return cutoffSeconds;
16 | }
17 |
18 | @Override
19 | public double computeWeight (int cutoffSeconds, int travelTimeSeconds) {
20 | if (travelTimeSeconds < cutoffSeconds) {
21 | return 1;
22 | } else {
23 | return 0;
24 | }
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/error/ScenarioApplicationException.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.error;
2 |
3 | import com.conveyal.r5.analyst.scenario.Modification;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * This Exception is thrown when a Scenario does not apply cleanly to a TransportNetwork.
10 | * We make an effort to recover from scenario application errors so that we can report as many errors as possible at once.
11 | * This Exception should contain one TaskError object for each Modification within the Scenario that failed to apply.
12 | */
13 | public class ScenarioApplicationException extends RuntimeException {
14 |
15 | /** The structured error reports that can be sent back to the client via the broker. */
16 | public final List taskErrors = new ArrayList<>();
17 |
18 | /**
19 | * Pass in all the modifications that failed.
20 | * The warning messages will be extracted and they will be converted to TaskErrors.
21 | * @param badModifications
22 | */
23 | public ScenarioApplicationException(List badModifications) {
24 | super("Errors occurred while applying a scenario to a network.");
25 | for (Modification modification : badModifications) {
26 | taskErrors.add(new TaskError(modification, modification.errors));
27 | }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/error/UnsupportedGeometryException.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.error;
2 |
3 | public class UnsupportedGeometryException extends Exception {
4 |
5 | public String message;
6 |
7 | public UnsupportedGeometryException(String message) {
8 | this.message = message;
9 | }
10 |
11 | }
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/fare/FareBounds.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.fare;
2 |
3 | /**
4 | * Used in InRoutingFareCalculator (and its extensions) to track how much has been paid to reach a state
5 | * (cumulativeFarePaid) and transfer privileges that may be redeemed at future boardings (transferAllowance). We need
6 | * to track the latter to protect certain states from premature pruning in Pareto search.
7 | */
8 |
9 | public class FareBounds {
10 | public int cumulativeFarePaid; // cash already paid, cumulatively for all previous journey stages
11 | public TransferAllowance transferAllowance; // possible remaining value; how much you stand to lose if you
12 | // throw your ticket on the ground
13 |
14 | public FareBounds(int cumulativeFarePaid, TransferAllowance transferAllowance){
15 | this.cumulativeFarePaid = cumulativeFarePaid;
16 | this.transferAllowance = transferAllowance;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/fare/SimpleInRoutingFareCalculator.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.fare;
2 |
3 | import com.conveyal.r5.profile.McRaptorSuboptimalPathProfileRouter;
4 |
5 | /**
6 | * A simple greedy fare calculator that simply applies a single fare at each boarding.
7 | */
8 | public class SimpleInRoutingFareCalculator extends InRoutingFareCalculator {
9 | public int fare;
10 |
11 | @Override
12 | public FareBounds calculateFare(McRaptorSuboptimalPathProfileRouter.McRaptorState state, int maxClockTime) {
13 | int fareForState = 0;
14 |
15 | while (state != null) {
16 | if (state.pattern != -1) fareForState += fare;
17 | state = state.back;
18 | }
19 |
20 | return new FareBounds(fareForState, new TransferAllowance());
21 | }
22 |
23 | @Override
24 | public String getType() {
25 | return "simple";
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/fare/ZoneBasedFareSystem.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.fare;
2 |
3 | import java.util.Map;
4 |
5 | /*
6 | Fares specified only by origin_id and destination_id.
7 | */
8 |
9 | public class ZoneBasedFareSystem {
10 | public Map fareByZonePair;
11 |
12 | public class Pair {
13 | String origin_id; // zone_id of stop at start of journey stage
14 | String destination_id; // zone_id of stop at end of journey stage
15 |
16 | public Pair(String origin_id, String destination_id){
17 | this.origin_id = origin_id;
18 | this.destination_id = destination_id;
19 | }
20 | }
21 |
22 | public void addZonePair(String origin_id, String destination_id, int price) {
23 | Pair pair = new Pair(origin_id, destination_id);
24 | fareByZonePair.put(pair, price);
25 | }
26 |
27 | public int getFare(String origin_id, String destination_id){
28 | Pair pair = new Pair(origin_id, destination_id);
29 | return fareByZonePair.get(pair);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/fare/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This contains fare calculation implementations that are used in accessibility analysis to apply cost limits while
3 | * a search is happening. This is a resource limiting problem and requires pareto-path routing. It's a distinct
4 | * problem from calculating fares for Modeify or normal point to point routing, where fares are not considered during
5 | * routing and are only calculated after the path is already found.
6 | */
7 | package com.conveyal.r5.analyst.fare;
8 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/progress/NoopProgressListener.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.progress;
2 |
3 | public class NoopProgressListener implements ProgressListener {
4 |
5 | @Override
6 | public void beginTask(String description, int totalElements) {
7 |
8 | }
9 |
10 | @Override
11 | public void increment() {
12 |
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/progress/ProgressListener.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.progress;
2 |
3 | /**
4 | * This interface provides simple callbacks to allow long running, asynchronous operations to report on their progress.
5 | */
6 | public interface ProgressListener {
7 |
8 | /**
9 | * Call this method once at the beginning of a new task, specifying how many sub-units of work will be performed.
10 | * This does not allow for subsequently starting sub-tasks that use the same ProgressListener while progress is
11 | * still being reported. Any recursion launching sub-tasks will need to be head- or tail-recursion, launched before
12 | * you call beginTask or after the last unit of work is complete.
13 | * Rather than implementing some kind of push/pop mechanism, we may eventually have some kind of nested task system,
14 | * where all tasks are retrieved in a hierarchy and progress on sub-tasks bubbles up to super-tasks.
15 | * Or alternatively, we may never recurse into lazy-loading code, which is probably a better long term goal.
16 | */
17 | void beginTask(String description, int totalElements);
18 |
19 | /**
20 | * Call this method to report that one unit of work has been performed.
21 | */
22 | void increment();
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/progress/TaskAction.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.progress;
2 |
3 | /**
4 | * This represents the work actually carried out by a Task.
5 | * It's a single-method interface so it can be defined with lambda functions, or other objects can implement it.
6 | * When the action is run, it will receive an object implementing an interface through which it can report progress
7 | * and errors.
8 | */
9 | public interface TaskAction {
10 |
11 | /**
12 | * This method will define an asynchronous action to take.
13 | * The parameter is a simpler interface of Task that only allows progress reporting, to encapsulate actions and
14 | * prevent them from seeing or modifying the task hierarchy that triggers and manages them.
15 | */
16 | public void action (ProgressListener progressListener);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/scenario/ModificationPolygon.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.scenario;
2 |
3 | import org.locationtech.jts.geom.Geometry;
4 | import org.locationtech.jts.geom.Polygonal;
5 |
6 | /**
7 | * This associates a single Polygonal Geometry with a name, numerical data, and a priority relative to other polygons
8 | * in the same set.
9 | */
10 | public class ModificationPolygon {
11 |
12 | public final Geometry polygonal;
13 | public final String id;
14 | public final String name;
15 | public final double data;
16 | public final double priority;
17 |
18 | public ModificationPolygon (
19 | Polygonal polygonal,
20 | String id,
21 | String name,
22 | double data,
23 | double priority
24 | ) {
25 | this.polygonal = (Geometry) polygonal;
26 | this.id = id;
27 | this.name = name;
28 | this.data = data;
29 | this.priority = priority;
30 | }
31 |
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/scenario/SetFareCalculator.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.scenario;
2 |
3 | import com.conveyal.r5.analyst.fare.InRoutingFareCalculator;
4 | import com.conveyal.r5.transit.TransportNetwork;
5 |
6 | /**
7 | * Set the fare calculator on a transport network.
8 | */
9 | public class SetFareCalculator extends Modification {
10 | public InRoutingFareCalculator fareCalculator;
11 |
12 | @Override
13 | public boolean apply(TransportNetwork network) {
14 | // NB will break if applied more than once, but don't think that should happen
15 | network.fareCalculator = this.fareCalculator;
16 | network.fareCalculator.transitLayer = network.transitLayer;
17 | return false;
18 | }
19 |
20 | @Override
21 | public int getSortOrder() {
22 | return 100;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/analyst/scenario/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This package contains classes for modeling transport scenarios as an ordered series of modifications to be applied
3 | * to an underlying baseline graph. It is used for impact analysis: the interactive creation and comparison of the
4 | * accessibility effects of modifications to a transport network.
5 | */
6 | package com.conveyal.r5.analyst.scenario;
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/GraphQlRequest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api;
2 |
3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4 |
5 | /**
6 | * Dummy request for GraphQL
7 | *
8 | * Since GraphQL request is in JSON Jackson needs this to parse it correctly.
9 | */
10 | @JsonIgnoreProperties(ignoreUnknown = true)
11 | public class GraphQlRequest {
12 | public String query;
13 | //FIXME: This should be Map and be serialized automatically with Jackson but it
14 | //doesn't seems to work.
15 | public String variables;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/AbsoluteDirection.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 |
4 | /**
5 | * An absolute cardinal or intermediate direction.
6 | */
7 | public enum AbsoluteDirection {
8 | NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST
9 | }
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/Alert.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | import java.time.ZonedDateTime;
4 |
5 | /**
6 | * Simple alert
7 | */
8 | public class Alert {
9 |
10 | //TODO: localization etc.
11 |
12 | //Header of alert if it exists
13 | public String alertHeaderText;
14 |
15 | /**
16 | * Long description of alert notnull
17 | */
18 | public String alertDescriptionText;
19 |
20 | //Url with more information
21 | public String alertUrl;
22 |
23 | //When this alerts comes into effect
24 | public ZonedDateTime effectiveStartDate;
25 | public ZonedDateTime effectiveEndDate;
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/BikeRentalStation.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | import java.io.Serializable;
4 | import java.util.Set;
5 |
6 | /**
7 | * Information about Bike rental station
8 | */
9 | public class BikeRentalStation implements Serializable {
10 |
11 | //@notnull
12 | public String id;
13 |
14 | public String name;
15 |
16 | //Coordinates @notnull
17 | public float lat, lon;
18 |
19 | public int bikesAvailable;
20 |
21 | public int spacesAvailable;
22 |
23 | public boolean allowDropoff = true;
24 |
25 | public Set networks;
26 |
27 | public boolean realTimeData = false;
28 |
29 | @Override
30 | public String toString() {
31 | String sb = "BikeRentalStation{" + "id='" + id + '\'' +
32 | ", name='" + name + '\'' +
33 | ", lat=" + lat +
34 | ", lon=" + lon +
35 | ", bikesAvailable=" + bikesAvailable +
36 | ", spacesAvailable=" + spacesAvailable +
37 | ", allowDropoff=" + allowDropoff +
38 | ", networks=" + networks +
39 | ", realTimeData=" + realTimeData +
40 | '}';
41 | return sb;
42 | }
43 | }
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/Coordinate.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | /**
4 | * Input type for profile
5 | */
6 | public class Coordinate {
7 | public float lat;
8 | public float lon;
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/Elevation.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | /**
4 | * TODO: this could also be copressed like Mapquest is doing
5 | */
6 | public class Elevation {
7 | //Distance from start of segment in meters @notnull
8 | public float distance;
9 | //Height in m at this distance @notnull
10 | public float elevation;
11 |
12 | public Elevation(float distance, float height) {
13 | this.distance = distance;
14 | this.elevation = height;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/ModeStopIndex.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | import java.util.Objects;
4 |
5 | /**
6 | * Used as a key so that access and egress paths are not duplicated and are each inserted only once in each profileOption
7 | *
8 | */
9 | public class ModeStopIndex {
10 | public LegMode mode;
11 | public int stopIndex;
12 |
13 | public ModeStopIndex(LegMode mode, int stopIndex) {
14 | this.mode = mode;
15 | this.stopIndex = stopIndex;
16 | }
17 |
18 | @Override
19 | public boolean equals(Object o) {
20 | if (this == o)
21 | return true;
22 | if (o == null || getClass() != o.getClass())
23 | return false;
24 | ModeStopIndex that = (ModeStopIndex) o;
25 | return stopIndex == that.stopIndex && mode == that.mode;
26 | }
27 |
28 | @Override
29 | public int hashCode() {
30 | return Objects.hash(mode, stopIndex);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/NonTransitMode.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | /**
4 | * Modes of transportation that aren't public transit
5 | */
6 | public enum NonTransitMode {
7 | WALK, BICYCLE, CAR
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/PointToPointConnection.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Object which pulls together specific access, transit and egress part of an option
7 | */
8 | public class PointToPointConnection {
9 | //Index of access part of this trip @notnull
10 | public int access;
11 | //Index of egress part of this trip
12 | public Integer egress;
13 | /*chooses which specific trip should be used
14 | Index in transit list specifies transit with same index
15 | Each TransitJourneyID has pattern in chosen index an time index in chosen pattern
16 |
17 | This can uniquly identify specific trip with transit */
18 | public List transit;
19 |
20 | //Connection for transit modes
21 | public PointToPointConnection(int accessIdx, int egressIdx,
22 | List transitJourneyIDs) {
23 | access = accessIdx;
24 | egress = egressIdx;
25 | transit = transitJourneyIDs;
26 | }
27 |
28 | //Connection for direct modes
29 | public PointToPointConnection(int accessIndex) {
30 | access = accessIndex;
31 | egress = null;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/PolylineGeometry.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | import com.conveyal.r5.model.json_serialization.LineStringDeserializer;
4 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
5 | import org.locationtech.jts.geom.LineString;
6 |
7 | /**
8 | * Created by mabu on 30.10.2015.
9 | */
10 | public class PolylineGeometry {
11 |
12 | /**
13 | * Polyline encoded geometry
14 | * @notnull
15 | */
16 | @JsonDeserialize(using = LineStringDeserializer.class)
17 | public LineString points;
18 |
19 | /**
20 | * Length of polyline encoded geometry
21 | * @notnull
22 | */
23 | public int length;
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/RelativeDirection.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | /**
4 | * Represents a turn direction, relative to the current heading.
5 | *
6 | * CIRCLE_CLOCKWISE and CIRCLE_CLOCKWISE are used to represent traffic circles.
7 | *
8 | */
9 | public enum RelativeDirection {
10 | DEPART, HARD_LEFT, LEFT, SLIGHTLY_LEFT, CONTINUE, SLIGHTLY_RIGHT, RIGHT, HARD_RIGHT,
11 | CIRCLE_CLOCKWISE, CIRCLE_COUNTERCLOCKWISE, ELEVATOR, UTURN_LEFT, UTURN_RIGHT;
12 |
13 | public static RelativeDirection setRelativeDirection(double lastAngle, double thisAngle, boolean roundabout) {
14 | double turn_degree = (((thisAngle - lastAngle) + 360) % 360);
15 |
16 | double ccw_turn_degree = 360 - turn_degree;
17 |
18 | if (roundabout) {
19 | if (turn_degree > ccw_turn_degree) {
20 | return CIRCLE_CLOCKWISE;
21 | } else {
22 | return CIRCLE_COUNTERCLOCKWISE;
23 | }
24 | }
25 |
26 | if (turn_degree < 17 || ccw_turn_degree < 17) {
27 | return CONTINUE;
28 | } else if (turn_degree < 40) {
29 | return SLIGHTLY_RIGHT;
30 | } else if (ccw_turn_degree < 40) {
31 | return SLIGHTLY_LEFT;
32 | } else if (turn_degree < 115) {
33 | return RIGHT;
34 | } else if (ccw_turn_degree < 115) {
35 | return LEFT;
36 | } else if (turn_degree < 180) {
37 | return HARD_RIGHT;
38 | } else {
39 | return HARD_LEFT;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/SearchType.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | /**
4 | * Type of plan search
5 | */
6 | public enum SearchType {
7 | //Search is made for trip that needs to arrive at specific time/date
8 | ARRIVE_BY,
9 | //Search is made for a trip that needs to depart at specific time/date
10 | DEPART_FROM
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/Stats.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | /**
4 | * num may be 0 if there are no observations.
5 | * num will become 1 when adding a scalar or another Stats.
6 | */
7 | public class Stats implements Cloneable {
8 |
9 | /**
10 | * Minimum travel time (seconds)
11 | * @notnull
12 | */
13 | public int min = Integer.MAX_VALUE;
14 |
15 | /**
16 | * Average travel time (including waiting) (seconds)
17 | * @notnull
18 | */
19 | public int avg = 0;
20 |
21 | /**
22 | * Maximum travel time (seconds)
23 | * @notnull
24 | */
25 | public int max = 0;
26 |
27 | /**
28 | * number of options
29 | * @notnull
30 | */
31 | public int num = 0;
32 |
33 | /** Construct a new empty Stats containing no values. */
34 | public Stats () { }
35 |
36 | @Override
37 | public String toString() {
38 | return String.format("min=%.1f avg=%.1f max=%.1f", min/60.0, avg/60.0, max/60.0);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/TransitJourneyID.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | /**
4 | * Tells which pattern and time in pattern to use for this specific transit
5 | *
6 | * Created by mabu on 21.12.2015.
7 | */
8 | public class TransitJourneyID {
9 | //Index of segment pattern @notnull
10 | public int pattern;
11 | //index of time in chosen pattern @notnull
12 | public int time;
13 |
14 | public TransitJourneyID(int patternIdx, int timeIdx) {
15 | pattern = patternIdx;
16 | time = timeIdx;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/TransitModes.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | /**
4 | * Types of transit mode transport from GTFS
5 | */
6 | public enum TransitModes {
7 | // Air
8 | AIR,
9 | // Tram, Streetcar, Light rail. Any light rail or street level system within a metropolitan area.
10 | TRAM,
11 | //Subway, Metro. Any underground rail system within a metropolitan area.
12 | SUBWAY,
13 | //Rail. Used for intercity or long-distance travel.
14 | RAIL,
15 | //Bus. Used for short- and long-distance bus routes.
16 | BUS,
17 | //Ferry. Used for short- and long-distance boat service.
18 | FERRY,
19 | //Cable car. Used for street-level cable cars where the cable runs beneath the car.
20 | CABLE_CAR,
21 | // Gondola, Suspended cable car. Typically used for aerial cable cars where the car is suspended from the cable.
22 | GONDOLA,
23 | //Funicular. Any rail system designed for steep inclines.
24 | FUNICULAR,
25 | //All modes
26 | TRANSIT
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/api/util/Trip.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.api.util;
2 |
3 | /**
4 | * One specific GTFS trip
5 | */
6 | public class Trip {
7 | /**
8 | * GTFS trip ID
9 | * @notnull
10 | */
11 | public String tripId;
12 |
13 | /**
14 | * Generated Service ID
15 | */
16 | public String serviceId;
17 |
18 |
19 | public Boolean wheelchairAccessible = false;
20 |
21 | public Boolean bikesAllowed = false;
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/common/GeoJsonFeature.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.common;
2 |
3 | import org.locationtech.jts.geom.Coordinate;
4 | import org.locationtech.jts.geom.Geometry;
5 |
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | /**
10 | * GeoJSON Feature class
11 | *
12 | * Written because GeoJSON Feature class from geojson-jackson has different type of Geometry
13 | * and needs a conversion
14 | *
15 | * Currently only used in TransportNetworkVisualizer
16 | */
17 | public class GeoJsonFeature {
18 | //for serialization
19 | private final String type = "Feature";
20 | private Map properties;
21 |
22 | private Geometry geometry;
23 |
24 | public GeoJsonFeature(Geometry geometry) {
25 | this.geometry = geometry;
26 | this.properties = new HashMap<>(5);
27 | }
28 |
29 | public GeoJsonFeature(double lon, double lat) {
30 | this(GeometryUtils.geometryFactory.createPoint(new Coordinate(lon, lat)));
31 | }
32 |
33 | public String getType() {
34 | return type;
35 | }
36 |
37 | public Map getProperties() {
38 | return properties;
39 | }
40 |
41 | public Geometry getGeometry() {
42 | return geometry;
43 | }
44 |
45 | public void addProperty(String propertyName, Object propertyValue) {
46 | properties.put(propertyName, propertyValue);
47 | }
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/labeling/RoadPermission.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.labeling;
2 |
3 | import com.conveyal.r5.streets.EdgeStore;
4 |
5 | import java.util.EnumSet;
6 |
7 | /**
8 | * Class providing a return type for functions in the TraversalPermissionLabeler, which need to return a set of
9 | * permissions in both the forward and backward direction on a single road segment.
10 | */
11 | public class RoadPermission {
12 | public final EnumSet forward;
13 | public final EnumSet backward;
14 |
15 | public RoadPermission(EnumSet forward,
16 | EnumSet backward) {
17 | this.forward = forward;
18 | this.backward = backward;
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/labeling/USTraversalPermissionLabeler.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.labeling;
2 |
3 |
4 | /**
5 | * Traversal permission labeler for the United States, adding things that differ from the base TraversalPermissionLabeler.
6 | * https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access-Restrictions#United_States_of_America
7 | */
8 | public class USTraversalPermissionLabeler extends TraversalPermissionLabeler {
9 | static {
10 | addPermissions("pedestrian", "bicycle=yes");
11 | addPermissions("bridleway", "bicycle=yes;foot=yes"); //horse=yes but we don't support horse
12 | addPermissions("cycleway", "bicycle=yes;foot=yes");
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/labeling/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Labelers set flags or characteristics of network links based on tags in the OSM data they are built from.
3 | */
4 | package com.conveyal.r5.labeling;
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/BitSetDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.fasterxml.jackson.core.JsonParser;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.core.JsonToken;
6 | import com.fasterxml.jackson.databind.DeserializationContext;
7 | import com.fasterxml.jackson.databind.JsonDeserializer;
8 |
9 | import java.io.IOException;
10 | import java.util.BitSet;
11 |
12 | /**
13 | * Deserialize an array [true, false, true . . .] to a bitset
14 | */
15 | public class BitSetDeserializer extends JsonDeserializer {
16 | @Override public BitSet deserialize(JsonParser jsonParser,
17 | DeserializationContext deserializationContext)
18 | throws IOException, JsonProcessingException {
19 | BitSet ret = new BitSet();
20 |
21 | int i = 0;
22 | JsonToken token;
23 | while (!JsonToken.END_ARRAY.equals(token = jsonParser.nextValue())) {
24 | if (JsonToken.VALUE_TRUE.equals(token))
25 | ret.set(i);
26 | i++;
27 | }
28 |
29 | return ret;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/BitSetSerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.core.Version;
6 | import com.fasterxml.jackson.databind.JsonSerializer;
7 | import com.fasterxml.jackson.databind.SerializerProvider;
8 | import com.fasterxml.jackson.databind.module.SimpleModule;
9 |
10 | import java.io.IOException;
11 | import java.util.BitSet;
12 |
13 | /**
14 | * Serialize a BitSet to an array [true, false . . .].
15 | */
16 | public class BitSetSerializer extends JsonSerializer {
17 |
18 | @Override public void serialize(BitSet bitSet, JsonGenerator jsonGenerator,
19 | SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
20 |
21 | jsonGenerator.writeStartArray();
22 |
23 | for (int i = 0; i < bitSet.length(); i++) {
24 | jsonGenerator.writeBoolean(bitSet.get(i));
25 | }
26 |
27 | jsonGenerator.writeEndArray();
28 | }
29 |
30 | public static SimpleModule makeModule () {
31 | Version moduleVersion = new Version(1, 0, 0, null, null, null);
32 | SimpleModule module = new SimpleModule("BitSet", moduleVersion);
33 | module.addSerializer(BitSet.class, new BitSetSerializer());
34 | module.addDeserializer(BitSet.class, new BitSetDeserializer());
35 | return module;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/JavaLocalDateDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.fasterxml.jackson.core.JsonParser;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.DeserializationContext;
6 | import com.fasterxml.jackson.databind.JsonDeserializer;
7 |
8 | import java.io.IOException;
9 | import java.time.LocalDate;
10 | import java.time.format.DateTimeFormatter;
11 |
12 | /** serializer/deserializer for LocalDates to ISO dates, YYYY-MM-DD */
13 | public class JavaLocalDateDeserializer extends JsonDeserializer {
14 |
15 | @Override public LocalDate deserialize(JsonParser jsonParser,
16 | DeserializationContext deserializationContext)
17 | throws IOException, JsonProcessingException {
18 | return LocalDate.parse(jsonParser.getValueAsString(), DateTimeFormatter.ISO_LOCAL_DATE);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/JavaLocalDateSerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.core.Version;
6 | import com.fasterxml.jackson.databind.JsonSerializer;
7 | import com.fasterxml.jackson.databind.SerializerProvider;
8 | import com.fasterxml.jackson.databind.module.SimpleModule;
9 |
10 | import java.io.IOException;
11 | import java.time.LocalDate;
12 | import java.time.format.DateTimeFormatter;
13 |
14 | /**
15 | * Serialize localDates to YYYY-MM-DD
16 | */
17 | public class JavaLocalDateSerializer extends JsonSerializer {
18 | /** Create a module including the serializer and deserializer for local dates */
19 | public static SimpleModule makeModule () {
20 | Version moduleVersion = new Version(1, 0, 0, null, null, null);
21 | SimpleModule module = new SimpleModule("LocalDate", moduleVersion);
22 | module.addSerializer(LocalDate.class, new JavaLocalDateSerializer());
23 | module.addDeserializer(LocalDate.class, new JavaLocalDateDeserializer());
24 | return module;
25 | }
26 |
27 | @Override public void serialize(LocalDate localDate, JsonGenerator jsonGenerator,
28 | SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
29 | jsonGenerator.writeString(localDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/LegModeSetDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.conveyal.r5.api.util.LegMode;
4 | import com.fasterxml.jackson.core.JsonParser;
5 | import com.fasterxml.jackson.core.JsonProcessingException;
6 | import com.fasterxml.jackson.databind.DeserializationContext;
7 | import com.fasterxml.jackson.databind.JsonDeserializer;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import java.io.IOException;
12 | import java.util.EnumSet;
13 | import java.util.stream.Stream;
14 |
15 | /**
16 | * Deserialize modesets in the form MODE,MODE,MODE
17 | */
18 | public class LegModeSetDeserializer extends JsonDeserializer> {
19 | private static final Logger LOG = LoggerFactory.getLogger(LegModeSetDeserializer.class);
20 |
21 | @Override
22 | public EnumSet deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
23 | String str = jsonParser.getValueAsString();
24 | EnumSet modes = EnumSet.noneOf(LegMode.class);
25 | Stream.of(str.split(",")).forEach(m -> {
26 | LegMode mode;
27 | try {
28 | mode = LegMode.valueOf(m.toUpperCase().trim());
29 | } catch (IllegalArgumentException e) {
30 | LOG.info("LegMode {} not found, ignoring (if this is an obscure transit mode, this message is safe to ignore)", m);
31 | return;
32 | }
33 |
34 | modes.add(mode);
35 | });
36 | return modes;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/LegModeSetSerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.conveyal.r5.api.util.LegMode;
4 | import com.fasterxml.jackson.core.JsonGenerator;
5 | import com.fasterxml.jackson.core.JsonProcessingException;
6 | import com.fasterxml.jackson.databind.JsonSerializer;
7 | import com.fasterxml.jackson.databind.SerializerProvider;
8 |
9 | import java.io.IOException;
10 | import java.util.EnumSet;
11 | import java.util.stream.Collectors;
12 |
13 | /**
14 | * Serialize a mode set as MODE,MODE,MODE
15 | */
16 | public class LegModeSetSerializer extends JsonSerializer> {
17 | @Override
18 | public void serialize(EnumSet modes, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
19 | String str = modes.stream().map(LegMode::toString).collect(Collectors.joining(","));
20 | jsonGenerator.writeString(str);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/LineStringDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.fasterxml.jackson.core.JsonParser;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.DeserializationContext;
6 | import com.fasterxml.jackson.databind.JsonDeserializer;
7 | import org.locationtech.jts.geom.GeometryFactory;
8 | import org.locationtech.jts.geom.LineString;
9 |
10 | import java.io.IOException;
11 |
12 | /**
13 | * A Jackson serializer module for reading Google encoded polylines into LineStrings.
14 | */
15 | public class LineStringDeserializer extends JsonDeserializer {
16 |
17 | private static GeometryFactory geometryFactory = new GeometryFactory();
18 |
19 | @Override
20 | public LineString deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
21 | throws IOException, JsonProcessingException {
22 | return geometryFactory.createLineString(PolyUtil.decode(jsonParser.getText()));
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/LineStringSerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.JsonSerializer;
6 | import com.fasterxml.jackson.databind.SerializerProvider;
7 | import org.locationtech.jts.geom.LineString;
8 |
9 | import java.io.IOException;
10 |
11 | /**
12 | * A Jackson serializer module for saving LineStrings as Google encoded polylines.
13 | */
14 | public class LineStringSerializer extends JsonSerializer {
15 |
16 | @Override
17 | public void serialize(LineString lineString, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
18 | throws IOException, JsonProcessingException {
19 | jsonGenerator.writeString(PolyUtil.encode(lineString));
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/ModeSetSerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.conveyal.r5.profile.StreetMode;
4 | import com.fasterxml.jackson.core.JsonGenerator;
5 | import com.fasterxml.jackson.core.JsonProcessingException;
6 | import com.fasterxml.jackson.databind.JsonSerializer;
7 | import com.fasterxml.jackson.databind.SerializerProvider;
8 |
9 | import java.io.IOException;
10 | import java.util.EnumSet;
11 | import java.util.stream.Collectors;
12 |
13 | /**
14 | * Serialize a mode set as MODE,MODE,MODE
15 | */
16 | public class ModeSetSerializer extends JsonSerializer> {
17 | @Override
18 | public void serialize(EnumSet streetModes, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
19 | String str = streetModes.stream().map(StreetMode::toString).collect(Collectors.joining(","));
20 | jsonGenerator.writeString(str);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/TransitModeSetSerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.conveyal.r5.api.util.TransitModes;
4 | import com.fasterxml.jackson.core.JsonGenerator;
5 | import com.fasterxml.jackson.core.JsonProcessingException;
6 | import com.fasterxml.jackson.databind.JsonSerializer;
7 | import com.fasterxml.jackson.databind.SerializerProvider;
8 |
9 | import java.io.IOException;
10 | import java.util.EnumSet;
11 | import java.util.stream.Collectors;
12 |
13 | /**
14 | * Serialize a mode set as MODE,MODE,MODE
15 | */
16 | public class TransitModeSetSerializer extends JsonSerializer> {
17 | @Override
18 | public void serialize(EnumSet modes, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
19 | String str = modes.stream().map(TransitModes::toString).collect(Collectors.joining(","));
20 | jsonGenerator.writeString(str);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/ZoneIdDeserializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.fasterxml.jackson.core.JsonParser;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.DeserializationContext;
6 | import com.fasterxml.jackson.databind.JsonDeserializer;
7 |
8 | import java.io.IOException;
9 | import java.time.ZoneId;
10 |
11 | /**
12 | * Deserialize a ZoneId from a string
13 | */
14 | public class ZoneIdDeserializer extends JsonDeserializer {
15 | @Override public ZoneId deserialize(JsonParser jsonParser,
16 | DeserializationContext deserializationContext)
17 | throws IOException, JsonProcessingException {
18 | return ZoneId.of(jsonParser.getValueAsString());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/model/json_serialization/ZoneIdSerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.model.json_serialization;
2 |
3 | import com.fasterxml.jackson.core.JsonGenerator;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.JsonSerializer;
6 | import com.fasterxml.jackson.databind.SerializerProvider;
7 |
8 | import java.io.IOException;
9 | import java.time.ZoneId;
10 |
11 | /**
12 | * Serialize a ZoneId to a string
13 | */
14 | public class ZoneIdSerializer extends JsonSerializer {
15 |
16 | @Override public void serialize(ZoneId zoneId, JsonGenerator jsonGenerator,
17 | SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
18 | jsonGenerator.writeString(zoneId.getId());
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/point_to_point/builder/RouterInfo.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.point_to_point.builder;
2 |
3 | import org.locationtech.jts.geom.Envelope;
4 |
5 | /**
6 | * Information about router
7 | *
8 | * Currently only envelope and name
9 | */
10 | public class RouterInfo {
11 |
12 | public String name = "default";
13 | public Envelope envelope;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/point_to_point/builder/SpeedUnit.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.point_to_point.builder;
2 |
3 | import com.fasterxml.jackson.annotation.JsonCreator;
4 | import com.fasterxml.jackson.annotation.JsonValue;
5 |
6 | /**
7 | * Speeds can be specified in different units
8 | */
9 | public enum SpeedUnit {
10 | KMH("kmh"),
11 | MPH("mph"),
12 | KNOTS("knots");
13 |
14 | private String shortUnit;
15 |
16 | SpeedUnit(String shortUnit) {
17 | this.shortUnit = shortUnit;
18 | }
19 |
20 | @JsonValue
21 | @Override
22 | public String toString() {
23 | return this.shortUnit;
24 | }
25 |
26 | @JsonCreator
27 | public static SpeedUnit fromString(String unit) {
28 | if (unit != null) {
29 | unit = unit.toLowerCase();
30 | switch (unit) {
31 | case "km/h":
32 | case "kmh":
33 | case "kmph":
34 | case "kph":
35 | return KMH;
36 | case "mph":
37 | return MPH;
38 | case "knots":
39 | return KNOTS;
40 | default:
41 | throw new IllegalArgumentException("Unknown unit:" + unit
42 | + " supported units are km/h|kmh|kmph|kph, mph and knots");
43 | }
44 | }
45 | return null;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/profile/DominatingList.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.profile;
2 |
3 | import java.util.Collection;
4 |
5 | /**
6 | * When performing a multi-criteria search that finds sets of pareto-optimal paths (which is essential for resource
7 | * constraint situations) we must allow for multiple search states at each vertex (in this case transit stops).
8 | * One state is said to dominate another when it is better than that other state in all ways, i.e. it provides a path
9 | * that is so much better that the other path can be pruned or abandoned.
10 | *
11 | * When you add states to this type of list, the state might not actually be added if another state in the list
12 | * dominates it. If the state is optimal and is added to the list, other states are automatically dropped if they
13 | * are no longer co-optimal given the existence of the new state.
14 | *
15 | * It is assumed that all states inserted are comparable, meaning that they are at the same location and part of the
16 | * same search when simultaneously conducting multiple searches e.g. for different access modes.
17 | *
18 | * We only do multi-criteria transit searches, we haven't implemented multi-criteria street searches.
19 | */
20 | public interface DominatingList {
21 | /** Attempt to add a state to this dominating list, and evict dominated states, returning true if this state is
22 | * undominated */
23 | boolean add (McRaptorSuboptimalPathProfileRouter.McRaptorState state);
24 |
25 | /** get non-dominated states at this location */
26 | Collection getNonDominatedStates ();
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/profile/HashPath.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.profile;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * A wrapper around a Path that redefines the hash code and equals functions.
7 | * The functions are changed to compare only the boardStops and alightStops of the Path.
8 | * This is used to group paths by their combination of boardStops and alightStops in the response.
9 | */
10 | public class HashPath {
11 |
12 | final public Path path;
13 |
14 | public HashPath(Path path) {
15 | this.path = path;
16 | }
17 |
18 | @Override
19 | public boolean equals(Object o) {
20 | if (this == o)
21 | return true;
22 | if (o == null || getClass() != o.getClass())
23 | return false;
24 | HashPath hashPath = (HashPath) o;
25 | return this == hashPath || Arrays.equals(path.boardStops, hashPath.path.boardStops)
26 | && Arrays.equals(path.alightStops, hashPath.path.alightStops);
27 | }
28 |
29 | @Override
30 | public int hashCode() {
31 | return Arrays.hashCode(path.boardStops) + 2 * Arrays.hashCode(path.alightStops);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/profile/PropagationTimer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.profile;
2 |
3 | /**
4 | * This groups together all the timers recording execution time of various steps of travel time propagation, which
5 | * is performed after the raptor search itself.
6 | *
7 | * TODO constructor that adds stop and target counts to top level message
8 | * LOG.info("Propagating {} iterations from {} stops to {} target points took {}s",
9 | * nIterations, nStops, endTarget - startTarget, (System.currentTimeMillis() - startTimeMillis) / 1000d
10 | * );
11 | */
12 | public class PropagationTimer {
13 |
14 | public final ExecutionTimer fullPropagation = new ExecutionTimer("Full travel time propagation");
15 |
16 | public final ExecutionTimer transposition = new ExecutionTimer(fullPropagation, "Travel time matrix transposition");
17 |
18 | public final ExecutionTimer propagation = new ExecutionTimer(fullPropagation, "Propagation");
19 |
20 | public final ExecutionTimer reducer = new ExecutionTimer(fullPropagation, "Travel time reducer");
21 |
22 | public void log () {
23 | fullPropagation.logWithChildren();
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/profile/RaptorTimer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.profile;
2 |
3 | /**
4 | * This groups together all the timers recording execution time of various steps of a range raptor search.
5 | */
6 | public class RaptorTimer {
7 |
8 | public final ExecutionTimer fullSearch = new ExecutionTimer("Full range-Raptor search");
9 |
10 | public final ExecutionTimer scheduledSearch = new ExecutionTimer(fullSearch, "Scheduled/bounds search");
11 |
12 | public final ExecutionTimer scheduledSearchTransit = new ExecutionTimer(scheduledSearch, "Scheduled search");
13 | public final ExecutionTimer scheduledSearchFrequencyBounds = new ExecutionTimer(scheduledSearch, "Frequency upper bounds");
14 | public final ExecutionTimer scheduledSearchTransfers = new ExecutionTimer(scheduledSearch, "Transfers");
15 |
16 | public final ExecutionTimer frequencySearch = new ExecutionTimer(fullSearch, "Frequency search");
17 |
18 | public final ExecutionTimer frequencySearchFrequency = new ExecutionTimer(frequencySearch, "Frequency component");
19 | public final ExecutionTimer frequencySearchScheduled = new ExecutionTimer(frequencySearch, "Resulting updates to scheduled component");
20 | public final ExecutionTimer frequencySearchTransfers = new ExecutionTimer(frequencySearch, "Transfers");
21 |
22 | public void log () {
23 | fullSearch.logWithChildren();
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/profile/StreetMode.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.profile;
2 |
3 | /**
4 | * Represents a travel mode used to traverse edges in the street graph.
5 | * Permissions on edges will allow or disallow traversal by these modes, and edges may be traversed at different
6 | * speeds depending on the selected mode.
7 | */
8 | public enum StreetMode {
9 | WALK,
10 | BICYCLE,
11 | CAR
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/streets/BikeRentalBuilder.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.streets;
2 |
3 | import com.conveyal.r5.api.util.BikeRentalStation;
4 |
5 | import java.io.File;
6 | import java.util.List;
7 |
8 | /**
9 | * This used to load capital bikeshare XML from a file.
10 | * TODO implement loading GBFS from a URL
11 | */
12 | public class BikeRentalBuilder {
13 |
14 | File file;
15 |
16 | public BikeRentalBuilder(File file) {
17 | this.file = file;
18 | }
19 |
20 | List getRentalStations() {
21 | throw new UnsupportedOperationException("IMPLEMENT GBFS!");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/streets/DebugRoutingVisitor.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.streets;
2 |
3 | import com.conveyal.r5.common.GeoJsonFeature;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | /**
9 | * Callbacks for debugging street routing.
10 | * It accumulates all the steps in routing as GeoJSON.
11 | * Created by mabu on 10.12.2015.
12 | */
13 | public class DebugRoutingVisitor implements RoutingVisitor {
14 |
15 | private List features;
16 | private final EdgeStore edgeStore;
17 |
18 | /**
19 | * Mode should be in the state itself
20 | * @param edgeStore streetLayer edgeStore
21 | *
22 | */
23 | public DebugRoutingVisitor(EdgeStore edgeStore) {
24 | this.features = new ArrayList<>();
25 | this.edgeStore = edgeStore;
26 | }
27 |
28 | /**
29 | * Saves current state geometry mode and weight as geoJSON feature properties
30 | *
31 | * in list of features. It is used in full state graph when debugging
32 | * @param state
33 | */
34 | @Override
35 | public void visitVertex(StreetRouter.State state) {
36 | Integer edgeIdx = state.backEdge;
37 | if (!(edgeIdx == null || edgeIdx == -1)) {
38 | EdgeStore.Edge edge = edgeStore.getCursor(edgeIdx);
39 | GeoJsonFeature feature = new GeoJsonFeature(edge.getGeometry());
40 | feature.addProperty("mode", state.streetMode);
41 | feature.addProperty("backEdge", state.backEdge);
42 | features.add(feature);
43 | }
44 | }
45 |
46 | public List getFeatures() {
47 | return features;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/streets/RoutingVisitor.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.streets;
2 |
3 | /**
4 | * A set of callbacks that the street router will invoke while it's routing, allowing you to observe its progress
5 | * and potentially stop the search.
6 | */
7 | public interface RoutingVisitor {
8 | /** Called after search algorithms dequeue a vertex */
9 | void visitVertex(StreetRouter.State state);
10 |
11 | /**
12 | * Called right after visitVertex
13 | * @return true if search should stop
14 | */
15 | default boolean shouldBreakSearch() {
16 | return false;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/streets/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This is a new replacement street layer implementation
3 | */
4 | package com.conveyal.r5.streets;
5 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transit/DuplicateFeedException.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.transit;
2 |
3 | /**
4 | * Thrown when a TransportNetwork is build with two feeds with the same feed ID.
5 | */
6 | public class DuplicateFeedException extends RuntimeException {
7 | private String feedId;
8 |
9 | public DuplicateFeedException(String feedId) {
10 | this.feedId = feedId;
11 | }
12 |
13 | @Override
14 | public String getMessage () {
15 | return String.format("Bundle contains duplicate feeds with feed ID %s", feedId);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transit/PickDropType.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.transit;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | /**
7 | *
8 | */
9 | public enum PickDropType {
10 |
11 | SCHEDULED(0),
12 | NONE(1),
13 | CALL_AGENCY(2),
14 | COORDINATE_WITH_DRIVER(3);
15 |
16 | private static final Logger LOG = LoggerFactory.getLogger(PickDropType.class);
17 |
18 | // Will be initialized after constructor is called on all enum values.
19 | private static PickDropType[] forGtfsCode;
20 |
21 | static {
22 | forGtfsCode = new PickDropType[4];
23 | for (PickDropType pdt : PickDropType.values()) {
24 | forGtfsCode[pdt.gtfsCode] = pdt;
25 | }
26 | }
27 |
28 | int gtfsCode;
29 |
30 | PickDropType(int gtfsCode) {
31 | this.gtfsCode = gtfsCode;
32 | }
33 |
34 | static PickDropType forGtfsCode (int gtfsCode) {
35 | if (gtfsCode >= forGtfsCode.length) {
36 | LOG.error("Pickup/dropoff code {} is invalid. Defaulting to 0 ('scheduled')", gtfsCode);
37 | gtfsCode = 0;
38 | }
39 | return forGtfsCode[gtfsCode];
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transit/RouteInfo.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.transit;
2 |
3 | import com.conveyal.gtfs.model.Agency;
4 | import com.conveyal.gtfs.model.Route;
5 |
6 | import java.io.Serializable;
7 | import java.net.URL;
8 |
9 | /**
10 | * Information about a route.
11 | * FIXME This was originally to copy GTFS Route to get rid of inter-object references. Eliminate it.
12 | */
13 | public class RouteInfo implements Serializable {
14 | public static final long serialVersionUID = 1L;
15 |
16 | public String agency_id;
17 | public String agency_name;
18 | public String route_id;
19 | public String route_short_name;
20 | public String route_long_name;
21 | public int route_type;
22 | public String color;
23 | public URL agency_url;
24 |
25 | public RouteInfo (Route route, Agency agency) {
26 | this.agency_id = route.agency_id;
27 | this.agency_name = agency.agency_name;
28 | this.route_id = route.route_id;
29 | this.route_short_name = route.route_short_name;
30 | this.route_long_name = route.route_long_name;
31 | this.route_type = route.route_type;
32 | this.color = route.route_color;
33 | this.agency_url = route.route_url;
34 | }
35 |
36 | public RouteInfo () { /* do nothing */ }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transit/TripFlag.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.transit;
2 |
3 | /**
4 | * Enums are inherently serializable.
5 | */
6 | public enum TripFlag {
7 |
8 | BICYCLE(0),
9 | WHEELCHAIR(1);
10 | int flag;
11 |
12 | TripFlag(int bitNumber) {
13 | flag = 1 << bitNumber;
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transit/fare/RideType.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.transit.fare;
2 |
3 | /**
4 | * Ride types for fares in DCDareCalculator
5 | */
6 | public enum RideType {
7 | METRO_RAIL,
8 | METRO_BUS_LOCAL,
9 | METRO_BUS_EXPRESS,
10 | METRO_BUS_AIRPORT,
11 | DC_CIRCULATOR_BUS,
12 | ART_BUS,
13 | DASH_BUS,
14 | MARC_RAIL,
15 | MTA_BUS_LOCAL,
16 | MTA_BUS_EXPRESS,
17 | MTA_BUS_COMMUTER,
18 | VRE_RAIL,
19 | MCRO_BUS_LOCAL,
20 | MCRO_BUS_EXPRESS,
21 | FAIRFAX_CONNECTOR_BUS,
22 | PRTC_BUS
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transit/fare/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * This package contains classes implementing fares for Modeify and point-to-point profile routing.
3 | */
4 | package com.conveyal.r5.transit.fare;
5 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transit/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Classes for the transit layer of an R5 TransportNetwork.
3 | */
4 | package com.conveyal.r5.transit;
5 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transitive/TransitivePattern.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.transitive;
2 |
3 | import com.conveyal.r5.util.EncodedPolylineSerializer;
4 | import com.fasterxml.jackson.databind.annotation.JsonSerialize;
5 | import org.locationtech.jts.geom.LineString;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * Represents a transitive pattern.
11 | */
12 | public class TransitivePattern {
13 | public String pattern_id;
14 | public String pattern_name;
15 | public String route_id;
16 | public List stops;
17 |
18 | // TODO is this level of indirection necessary?
19 | public static class StopIdRef {
20 | /** NB this is the stop index in the R5 graph, not the GTFS stop ID */
21 | public String stop_id;
22 |
23 | @JsonSerialize(using = EncodedPolylineSerializer.class)
24 | public LineString geometry;
25 |
26 | public StopIdRef (String stop_id, LineString geometry) {
27 | this.stop_id = stop_id;
28 | this.geometry = geometry;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transitive/TransitiveRoute.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.transitive;
2 |
3 | /**
4 | * Represents a Transitive route.
5 | */
6 | public class TransitiveRoute {
7 | public String agency_id;
8 | public String route_id;
9 | public String route_short_name;
10 | public String route_long_name;
11 | public int route_type;
12 | public String route_color;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transitive/TransitiveStop.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.transitive;
2 |
3 | /**
4 | * Represents a Transitive stop.
5 | * @author mattwigway
6 | */
7 | public class TransitiveStop {
8 | // TODO store stop ID as int?
9 | public String stop_id;
10 | public String stop_name;
11 | public double stop_lat;
12 | public double stop_lon;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/transitive/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Adapter classes to allow a TransitLayer to be represented as a Transitive network.
3 | */
4 | package com.conveyal.r5.transitive;
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/EncodedPolylineSerializer.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | import com.axiomalaska.polylineencoder.PolylineEncoder;
4 | import com.axiomalaska.polylineencoder.UnsupportedGeometryTypeException;
5 | import com.fasterxml.jackson.core.JsonGenerator;
6 | import com.fasterxml.jackson.core.JsonProcessingException;
7 | import com.fasterxml.jackson.databind.JsonSerializer;
8 | import com.fasterxml.jackson.databind.SerializerProvider;
9 | import org.locationtech.jts.geom.LineString;
10 |
11 | import java.io.IOException;
12 |
13 | /**
14 | * Serialize to Google encoded polyline.
15 | * Hopefully we can get rid of this - it's the only thing still using JTS objects under the vividsolutions package name
16 | * so is pulling in extra dependencies and requiring conversions (toLegacyLineString).
17 | */
18 | public class EncodedPolylineSerializer extends JsonSerializer {
19 |
20 | @Override
21 | public void serialize(LineString lineString, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
22 | try {
23 | String points = PolylineEncoder.encode(lineString).getPoints();
24 | jsonGenerator.writeString(points);
25 | } catch (UnsupportedGeometryTypeException e) {
26 | throw new RuntimeException(e);
27 | }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/ExceptionUtils.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | import java.io.PrintWriter;
4 | import java.io.StringWriter;
5 |
6 | /**
7 | * Convenience functions for working with exceptions (or more generally throwables).
8 | */
9 | public abstract class ExceptionUtils {
10 |
11 | public static String asString(Throwable throwable) {
12 | StringWriter sw = new StringWriter();
13 | sw.append(throwable.getMessage());
14 | sw.append("\n");
15 | throwable.printStackTrace(new PrintWriter(sw));
16 | return sw.toString();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/InputStreamProvider.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | /**
7 | * This interface is used in cases where we need to repeatedly request the same input stream, as when loading
8 | * from uploaded CSV files.
9 | */
10 | public interface InputStreamProvider {
11 |
12 | /**
13 | * @return a new input stream properly wrapped to buffer the input and remove UTF-8 BOM as needed.
14 | */
15 | InputStream getInputStream() throws IOException;
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/P2.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | /**
4 | * Tuple of two elements with same type
5 | */
6 | public class P2 {
7 | public final E a;
8 |
9 | public final E b;
10 |
11 | /**
12 | * Creates a new pair
13 | *
14 | * @param b The key for this pair
15 | * @param b The value to use for this pair
16 | */
17 | public P2(
18 | E a,
19 | E b) {
20 | this.a = a;
21 | this.b = b;
22 | }
23 |
24 | @Override
25 | public String toString() {
26 | return String.format("P2<%s %s>", a, b);
27 | }
28 |
29 | @Override
30 | public int hashCode() {
31 | return (a != null ? a.hashCode() : 0) +
32 | (b != null ? b.hashCode() * 31 : 0);
33 | }
34 |
35 | @Override
36 | public boolean equals(Object o) {
37 | if(!(o instanceof P2)) return false;
38 | P2 other = (P2) o;
39 | boolean aIsEqual = (a == null) ? other.a == null : a.equals(other.a);
40 | boolean bIsEqual = (b == null) ? other.b == null : b.equals(other.b);
41 | return aIsEqual && bIsEqual;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/ProgressListener.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | public interface ProgressListener {
4 |
5 | public void setTotalItems (int nTotal);
6 |
7 | public void setCompletedItems(int nComplete);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/S3Util.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | import com.amazonaws.services.s3.AmazonS3;
4 | import com.amazonaws.services.s3.AmazonS3ClientBuilder;
5 | import com.amazonaws.services.s3.model.ObjectMetadata;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.io.InputStream;
10 | import java.util.concurrent.ArrayBlockingQueue;
11 | import java.util.concurrent.ThreadPoolExecutor;
12 | import java.util.concurrent.TimeUnit;
13 |
14 | /**
15 | * Created by matthewc on 10/21/16.
16 | */
17 | public class S3Util {
18 | private static final Logger LOG = LoggerFactory.getLogger(S3Util.class);
19 | public static final AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
20 |
21 | private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 256, 60,TimeUnit.SECONDS, new ArrayBlockingQueue<>(255));
22 | // can't use CallerRunsPolicy as that would cause deadlocks, calling thread is writing to inputstream
23 | static {
24 | executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
25 | }
26 |
27 | public static void streamToS3 (String bucket, String key, InputStream is, ObjectMetadata metadata) {
28 | // write to S3 in a thread
29 | executor.execute(() -> {
30 | try {
31 | s3.putObject(bucket, key, is, metadata);
32 | is.close();
33 | } catch (Exception e) {
34 | LOG.error("Exception writing to S3", e);
35 | }
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/TIntIntHashMultimap.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | import gnu.trove.TIntCollection;
4 | import gnu.trove.list.TIntList;
5 | import gnu.trove.list.array.TIntArrayList;
6 | import gnu.trove.map.TIntObjectMap;
7 | import gnu.trove.map.hash.TIntObjectHashMap;
8 |
9 | import java.io.Serializable;
10 |
11 | /**
12 | * Created by matthewc on 2/19/16.
13 | */
14 | public class TIntIntHashMultimap implements TIntIntMultimap, Serializable {
15 | private long serialVersionUID = -1;
16 |
17 | private TIntObjectMap wrapped = new TIntObjectHashMap<>();
18 |
19 | @Override
20 | public boolean put(int key, int value) {
21 | if (!wrapped.containsKey(key)) wrapped.put(key, new TIntArrayList());
22 | return wrapped.get(key).add(value);
23 | }
24 |
25 | @Override
26 | public TIntCollection get(int key) {
27 | return wrapped.containsKey(key) ? wrapped.get(key) : EmptyTIntCollection.get();
28 | }
29 |
30 | @Override
31 | public boolean containsKey(int key) {
32 | return wrapped.containsKey(key);
33 | }
34 |
35 | @Override
36 | public TIntCollection removeAll(int key) {
37 | return wrapped.containsKey(key) ? wrapped.remove(key) : EmptyTIntCollection.get();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/TIntIntMultimap.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | import gnu.trove.TIntCollection;
4 |
5 | /**
6 | * Created by matthewc on 2/19/16.
7 | */
8 | public interface TIntIntMultimap {
9 | boolean put (int key, int value);
10 | TIntCollection get (int key);
11 | boolean containsKey (int key);
12 | TIntCollection removeAll (int key);
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/TIntObjectHashMultimap.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | import gnu.trove.map.TIntObjectMap;
4 | import gnu.trove.map.hash.TIntObjectHashMap;
5 | import gnu.trove.procedure.TIntObjectProcedure;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Collection;
9 | import java.util.Collections;
10 | import java.util.List;
11 |
12 | /**
13 | * Created by matthewc on 2/19/16.
14 | */
15 | public class TIntObjectHashMultimap implements TIntObjectMultimap {
16 | private TIntObjectMap> wrapped = new TIntObjectHashMap<>();
17 |
18 | @Override
19 | public boolean put(int key, V value) {
20 | if (!wrapped.containsKey(key)) wrapped.put(key, new ArrayList<>());
21 | return wrapped.get(key).add(value);
22 | }
23 |
24 | @Override
25 | public Collection get(int key) {
26 | return wrapped.containsKey(key) ? wrapped.get(key) : Collections.emptyList();
27 | }
28 |
29 | @Override
30 | public void clear() {
31 | wrapped.clear();
32 | }
33 |
34 | @Override
35 | public boolean containsKey(int key) {
36 | return wrapped.containsKey(key);
37 | }
38 |
39 | @Override
40 | public void forEachEntry(TIntObjectProcedure> procedure) {
41 | wrapped.forEachEntry(procedure);
42 | }
43 |
44 | @Override
45 | public int size() {
46 | return wrapped.size();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/conveyal/r5/util/TIntObjectMultimap.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.util;
2 |
3 | import gnu.trove.procedure.TIntObjectProcedure;
4 |
5 | import java.util.Collection;
6 |
7 | /**
8 | * A primitive multimap
9 | */
10 | public interface TIntObjectMultimap {
11 | boolean put (int key, V value);
12 | Collection get (int key);
13 | void clear();
14 | boolean containsKey (int key);
15 | void forEachEntry (TIntObjectProcedure> procedure);
16 |
17 | /** number of keys */
18 | int size();
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/resources/debug-plan/debug.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/main/resources/debug-plan/images/marker-flag-end-shadowed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/main/resources/debug-plan/images/marker-flag-end-shadowed.png
--------------------------------------------------------------------------------
/src/main/resources/debug-plan/images/marker-flag-start-shadowed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/main/resources/debug-plan/images/marker-flag-start-shadowed.png
--------------------------------------------------------------------------------
/src/main/resources/debug-plan/leaflet_context/leaflet.contextmenu.css:
--------------------------------------------------------------------------------
1 | .leaflet-contextmenu {
2 | display: none;
3 | box-shadow: 0 1px 7px rgba(0,0,0,0.4);
4 | -webkit-border-radius: 4px;
5 | border-radius: 4px;
6 | padding: 4px 0;
7 | background-color: #fff;
8 | cursor: default;
9 | -webkit-user-select: none;
10 | -moz-user-select: none;
11 | user-select: none;
12 | }
13 |
14 | .leaflet-contextmenu a.leaflet-contextmenu-item {
15 | display: block;
16 | color: #222;
17 | font-size: 12px;
18 | line-height: 20px;
19 | text-decoration: none;
20 | padding: 0 12px;
21 | border-top: 1px solid transparent;
22 | border-bottom: 1px solid transparent;
23 | cursor: default;
24 | outline: none;
25 | }
26 |
27 | .leaflet-contextmenu a.leaflet-contextmenu-item-disabled {
28 | opacity: 0.5;
29 | }
30 |
31 | .leaflet-contextmenu a.leaflet-contextmenu-item.over {
32 | background-color: #f4f4f4;
33 | border-top: 1px solid #f0f0f0;
34 | border-bottom: 1px solid #f0f0f0;
35 | }
36 |
37 | .leaflet-contextmenu a.leaflet-contextmenu-item-disabled.over {
38 | background-color: inherit;
39 | border-top: 1px solid transparent;
40 | border-bottom: 1px solid transparent;
41 | }
42 |
43 | .leaflet-contextmenu-icon {
44 | margin: 2px 8px 0 0;
45 | width: 16px;
46 | height: 16px;
47 | float: left;
48 | border: 0;
49 | }
50 |
51 | .leaflet-contextmenu-separator {
52 | border-bottom: 1px solid #ccc;
53 | margin: 5px 0;
54 | }
--------------------------------------------------------------------------------
/src/main/resources/debug-plan/oneway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/main/resources/debug-plan/oneway.png
--------------------------------------------------------------------------------
/src/main/resources/debug-plan/oneway@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/main/resources/debug-plan/oneway@2x.png
--------------------------------------------------------------------------------
/src/main/resources/fares/nyc/lirr/README.txt:
--------------------------------------------------------------------------------
1 | # LIRR Fares
2 |
3 | This directory contains fare information for the LIRR, used to construct LIRRTransferAllowances for the NYCInRoutingFareCalculator.
4 |
5 | - lirr_zonal_fares.csv contains the fares for zone-to-zone journeys that do not require a change in direction.
6 | - via_fares.csv contains the fares for station-to-station journeys that do require a change in direction, but where LIRR will sell you a special "via" ticket.
7 | - descendants.csv contains all the stations that can be reached from a given station using only inbound or outbound trains, and is used to determin transfer allowances since we assume that same-direction transfers are free.
8 |
--------------------------------------------------------------------------------
/src/main/resources/fares/nyc/mta/express_bus_routes.csv:
--------------------------------------------------------------------------------
1 | agency_id,route_id
2 | MTABC,BM1
3 | MTABC,BM2
4 | MTABC,BM3
5 | MTABC,BM4
6 | MTABC,BM5
7 | MTABC,BXM1
8 | MTABC,BXM10
9 | MTABC,BXM11
10 | MTABC,BXM18
11 | MTABC,BXM2
12 | MTABC,BXM3
13 | MTABC,BXM4
14 | MTABC,BXM6
15 | MTABC,BXM7
16 | MTABC,BXM8
17 | MTABC,BXM9
18 | MTA NYCT,SIM1
19 | MTA NYCT,SIM1C
20 | MTA NYCT,SIM2
21 | MTA NYCT,SIM3
22 | MTA NYCT,SIM3C
23 | MTA NYCT,SIM4
24 | MTA NYCT,SIM4X
25 | MTA NYCT,SIM4C
26 | MTA NYCT,SIM5
27 | MTA NYCT,SIM6
28 | MTA NYCT,SIM7
29 | MTA NYCT,SIM8
30 | MTA NYCT,SIM8X
31 | MTA NYCT,SIM9
32 | MTA NYCT,SIM10
33 | MTA NYCT,SIM11
34 | MTA NYCT,SIM15
35 | MTA NYCT,SIM22
36 | MTA NYCT,SIM23
37 | MTA NYCT,SIM24
38 | MTA NYCT,SIM25
39 | MTA NYCT,SIM26
40 | MTA NYCT,SIM30
41 | MTA NYCT,SIM31
42 | MTA NYCT,SIM32
43 | MTA NYCT,SIM33
44 | MTA NYCT,SIM33C
45 | MTA NYCT,SIM34
46 | MTA NYCT,SIM35
47 | MTA NYCT,X27
48 | MTA NYCT,X28
49 | MTA NYCT,X37
50 | MTA NYCT,X38
51 | MTA NYCT,X63
52 | MTA NYCT,X64
53 | MTA NYCT,X68
54 | MTABC,QM1
55 | MTABC,QM10
56 | MTABC,QM11
57 | MTABC,QM12
58 | MTABC,QM15
59 | MTABC,QM16
60 | MTABC,QM17
61 | MTABC,QM18
62 | MTABC,QM2
63 | MTABC,QM20
64 | MTABC,QM21
65 | MTABC,QM24
66 | MTABC,QM25
67 | MTABC,QM3
68 | MTABC,QM31
69 | MTABC,QM32
70 | MTABC,QM34
71 | MTABC,QM35
72 | MTABC,QM36
73 | MTABC,QM4
74 | MTABC,QM40
75 | MTABC,QM42
76 | MTABC,QM44
77 | MTABC,QM5
78 | MTABC,QM6
79 | MTABC,QM7
80 | MTABC,QM8
81 |
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/gtfs/GeometriesTest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs;
2 |
3 | import org.junit.Test;
4 | import org.locationtech.jts.geom.Coordinate;
5 | import org.locationtech.jts.geom.Geometry;
6 |
7 | import static com.conveyal.gtfs.Geometries.geometryFactory;
8 | import static com.conveyal.gtfs.Geometries.getNetherlandsWithoutTexel;
9 | import static org.hamcrest.CoreMatchers.equalTo;
10 | import static org.hamcrest.MatcherAssert.assertThat;
11 |
12 | /**
13 | * Makes tests for the Netherlands geometry utils.
14 | * I added tests here because it substantially increases the coverage of the library since the file it's testing is so big.
15 | */
16 | public class GeometriesTest {
17 |
18 | /**
19 | * Verify that a proper geometry is created using the getNetherlandsWithoutTexel method.
20 | * This method also calls the getNetherlands and getTexel methods, so we kill 3 birds with one stone here.
21 | */
22 | @Test
23 | public void canGetNetherlandsWithoutTexel() {
24 | Geometry geom = getNetherlandsWithoutTexel();
25 | assertThat(
26 | geom.contains(geometryFactory.createPoint(new Coordinate(4.907812, 52.317809))),
27 | equalTo(true)
28 | );
29 | assertThat(
30 | geom.contains(geometryFactory.createPoint(new Coordinate(4.816163, 53.099519))),
31 | equalTo(false)
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/gtfs/util/UtilTest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.gtfs.util;
2 |
3 | import org.junit.Test;
4 |
5 | import static com.conveyal.gtfs.util.Util.human;
6 | import static org.hamcrest.MatcherAssert.assertThat;
7 | import static org.hamcrest.Matchers.is;
8 |
9 | /**
10 | * A test suite to verify the functionality of methods in the Util class.
11 | */
12 | public class UtilTest {
13 |
14 | /**
15 | * Assert that the human function returns strings that are properly formatted.
16 | */
17 | @Test
18 | public void canHumanize() {
19 | assertThat(human(123), is("123"));
20 | assertThat(human(1234), is("1k"));
21 | assertThat(human(1234567), is("1.2M"));
22 | assertThat(human(1234567890), is("1.2G"));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/osmlib/NodeTest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib;
2 |
3 | import junit.framework.TestCase;
4 |
5 | public class NodeTest extends TestCase {
6 | public void testNode(){
7 | Node node = new Node();
8 | assertEquals( node.getLat(), 0.0 );
9 | assertEquals( node.getLon(), 0.0 );
10 |
11 | node.setLatLon( 47.1, -122.2 );
12 | assertEquals( node.getLat(), 47.1 );
13 | assertEquals( node.getLon(), -122.2 );
14 |
15 | Node node2 = new Node(-45.5, 122.2);
16 | assertEquals( node2.getLat(), -45.5 );
17 | assertEquals( node2.getLon(), 122.2 );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/osmlib/OSMEntityTest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib;
2 |
3 | import junit.framework.TestCase;
4 |
5 | public class OSMEntityTest extends TestCase{
6 | /**
7 | * Create the test case
8 | *
9 | * @param testName name of the test case
10 | */
11 | public OSMEntityTest( String testName )
12 | {
13 | super( testName );
14 | }
15 |
16 | public void testCreateTag()
17 | {
18 | OSMEntity.Tag tag = new OSMEntity.Tag("key","value");
19 | assertEquals( tag.key, "key" );
20 | assertEquals( tag.value, "value" );
21 | }
22 |
23 | public void testTagged(){
24 | class TaggedTester extends OSMEntity{
25 | private static final long serialVersionUID = 1L;
26 |
27 | @Override
28 | public Type getType() {
29 | // TODO Auto-generated method stub
30 | return null;
31 | }}
32 |
33 | TaggedTester tt = new TaggedTester();
34 | assertTrue( tt.hasNoTags() );
35 |
36 | tt.addTag("key", "value");
37 |
38 | assertFalse( tt.hasNoTags() );
39 | assertTrue( tt.hasTag("key") );
40 | assertTrue( tt.hasTag("key", "value") );
41 |
42 | tt.setTagsFromString("foo=true;bar=false");
43 |
44 | assertTrue( tt.hasTag("foo","true") );
45 | assertTrue( tt.tagIsTrue("foo" ) );
46 | assertTrue( tt.tagIsFalse("bar") );
47 |
48 | assertEquals( tt.getTag("key"), "value" );
49 | assertEquals( tt.getTag("foo"), "true" );
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/osmlib/OSMTest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib;
2 |
3 | import junit.framework.TestCase;
4 | import org.mapdb.Fun;
5 |
6 | import java.io.IOException;
7 | import java.nio.file.Files;
8 | import java.nio.file.Paths;
9 | import java.util.Map;
10 |
11 | public class OSMTest extends TestCase {
12 | public void testOSM(){
13 | OSM osm = new OSM("./src/test/resources/tmp");
14 | osm.readFromFile("./src/test/resources/bangor_maine.osm.pbf");
15 | assertEquals( osm.nodes.size(), 12030 );
16 | assertEquals( osm.ways.size(), 1828 );
17 | assertEquals( osm.relations.size(), 2 );
18 |
19 | // make sure the indices work
20 | for (Map.Entry e : osm.relations.entrySet()) {
21 | Relation relation = e.getValue();
22 | long id = e.getKey();
23 | // Tested: Bangor contains relations with way, node, and relation members
24 | for (Relation.Member member : relation.members) {
25 | if (member.type == OSMEntity.Type.NODE)
26 | assertTrue(osm.relationsByNode.contains(Fun.t2(member.id, id)));
27 | else if (member.type == OSMEntity.Type.WAY)
28 | assertTrue(osm.relationsByWay.contains(Fun.t2(member.id, id)));
29 | else if (member.type == OSMEntity.Type.RELATION)
30 | assertTrue(osm.relationsByRelation.contains(Fun.t2(member.id, id)));
31 | }
32 | }
33 | }
34 |
35 | public void tearDown() throws IOException{
36 | Files.delete( Paths.get("./src/test/resources/tmp") );
37 | Files.delete( Paths.get("./src/test/resources/tmp.p") );
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/osmlib/RelationTest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib;
2 |
3 | import junit.framework.TestCase;
4 |
5 | public class RelationTest extends TestCase {
6 | public void testRelation(){
7 | assertNotNull( new Relation() );
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/osmlib/WayTest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.osmlib;
2 |
3 | import junit.framework.TestCase;
4 |
5 | public class WayTest extends TestCase {
6 | public void testWay(){
7 | Way way = new Way();
8 | assertNotNull( way );
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/r5/analyst/core/LocalDateSerialization.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.analyst.core;
2 |
3 | import com.conveyal.r5.common.JsonUtilities;
4 | import org.junit.Test;
5 |
6 | import java.time.LocalDate;
7 |
8 | import static org.junit.Assert.assertEquals;
9 |
10 | /**
11 | * Tests correct LocalDate Serialization
12 | */
13 | public class LocalDateSerialization {
14 |
15 | @Test
16 | public void testSerializationDeserialization() throws Exception {
17 | LocalDate date = LocalDate.now();
18 |
19 | String jsonDate = JsonUtilities.objectMapper.writeValueAsString(date);
20 |
21 | LocalDate deserializedDate = JsonUtilities.objectMapper.readValue(jsonDate, LocalDate.class);
22 | assertEquals(date, deserializedDate);
23 |
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/r5/labeling/TestPermissionsLabeler.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.labeling;
2 |
3 | /**
4 | * This is used for tests. It adds new highway tag highway=nobikenoped which forbids cycling and walking. But allows other things.
5 | * Created by mabu on 27.11.2015.
6 | */
7 | public class TestPermissionsLabeler extends USTraversalPermissionLabeler {
8 | static {
9 | addPermissions("highway=nobikenoped", "access=yes;bicycle=no;foot=no");
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/test/java/com/conveyal/r5/profile/PropagatedTimesStoreTest.java:
--------------------------------------------------------------------------------
1 | package com.conveyal.r5.profile;
2 |
3 | import junit.framework.TestCase;
4 | import org.junit.Test;
5 |
6 | /**
7 | * Test the propagated times store.
8 | */
9 | public class PropagatedTimesStoreTest extends TestCase {
10 | /**
11 | * Test that changing the reachability threshold works (i.e. averages are computed properly when destinations are
12 | * only reachable part of the time).
13 | */
14 | @Test
15 | public static void testReachability () throws Exception {
16 | /*
17 | ProfileRequest pr = new ProfileRequest();
18 | // old default: no restrictions o
19 | pr.reachabilityThreshold = 0;
20 |
21 | PropagatedTimesStore pts = new PropagatedTimesStore(pr, 1);
22 | // accessible one-third of the time
23 | int[][] times = new int[][] {
24 | new int[] { 1 },
25 | new int[] { RaptorWorker.UNREACHED },
26 | new int[] { RaptorWorker.UNREACHED }
27 | };
28 |
29 | pts.setFromArray(times, PropagatedTimesStore.ConfidenceCalculationMethod.MIN_MAX);
30 |
31 | // it is reachable at least 0% of the time
32 | assertEquals(1, pts.avgs[0]);
33 |
34 | pr.reachabilityThreshold = 0.5f;
35 | pts = new PropagatedTimesStore(g, pr, 1);
36 | pts.setFromArray(times, PropagatedTimesStore.ConfidenceCalculationMethod.MIN_MAX);
37 |
38 | // it is not reachable 50% of the time
39 | assertEquals(RaptorWorker.UNREACHED, pts.avgs[0]);
40 | */
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/resources/bangor_maine.osm.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/bangor_maine.osm.pbf
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/data/census/integrationTest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/com/conveyal/data/census/integrationTest.zip
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/gtfs/null-island-ferry/agency.txt:
--------------------------------------------------------------------------------
1 | agency_id,agency_name,agency_url,agency_timezone,agency_lang
2 | NullFerry,Null Island Ferry Authority,"https://www.ndbc.noaa.gov/station_page.php?station=13010",Etc/UTC,en
3 |
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/gtfs/null-island-ferry/calendar.txt:
--------------------------------------------------------------------------------
1 | service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date
2 | all,1,1,1,1,1,1,1,20200901,20201231
3 |
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/gtfs/null-island-ferry/feed_info.txt:
--------------------------------------------------------------------------------
1 | feed_id,feed_publisher_name,feed_publisher_url,feed_lang,feed_start_date,feed_end_date,feed_version,feed_contact_email
2 | NIF,Conveyal LLC,http://conveyal.com,en,20200901,20201231,1,contact@conveyal.com
3 |
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/gtfs/null-island-ferry/routes.txt:
--------------------------------------------------------------------------------
1 | route_id,agency_id,route_short_name,route_long_name,route_desc,route_type
2 | NIF,NullFerry,NF1,Null Island Ferry,The Ferry operates between two PIRATA weather buoys,4
3 |
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/gtfs/null-island-ferry/stop_times.txt:
--------------------------------------------------------------------------------
1 | trip_id,arrival_time,departure_time,stop_id,stop_sequence
2 | out,00:00:00,00:00:00,0,1
3 | out,11:59:00,12:00:00,1,2
4 | back,11:59:00,12:00:00,1,1
5 | back,23:59:00,24:00:00,0,2
6 |
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/gtfs/null-island-ferry/stops.txt:
--------------------------------------------------------------------------------
1 | stop_id,stop_code,stop_name,stop_desc,stop_lat,stop_lon,location_type,stop_url
2 | 0,13010,Soul,Null Island,0,0,,https://www.ndbc.noaa.gov/station_page.php?station=13010
3 | 1,15002,Java,PIRATA Atlas Buoy,0,-10,,https://www.ndbc.noaa.gov/station_page.php?station=15002
4 |
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/gtfs/null-island-ferry/trips.txt:
--------------------------------------------------------------------------------
1 | route_id,service_id,trip_id,trip_headsign,direction_id
2 | NIF,all,out,Outbound,0
3 | NIF,all,back,Inbound,1
4 |
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/r5/analyst/scenario/columbus.osm.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/com/conveyal/r5/analyst/scenario/columbus.osm.pbf
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/r5/streets/cathedral-no-left.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/com/conveyal/r5/streets/cathedral-no-left.pbf
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/r5/streets/reisterstown-via-restriction.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/com/conveyal/r5/streets/reisterstown-via-restriction.pbf
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/r5/streets/snake-rd.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/com/conveyal/r5/streets/snake-rd.pbf
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/r5/streets/speedFlagsTest.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/com/conveyal/r5/streets/speedFlagsTest.pbf
--------------------------------------------------------------------------------
/src/test/resources/com/conveyal/r5/streets/subgraph.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/com/conveyal/r5/streets/subgraph.pbf
--------------------------------------------------------------------------------
/src/test/resources/fake-agency.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/fake-agency.zip
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/agency.txt:
--------------------------------------------------------------------------------
1 | agency_id,agency_name,agency_url,agency_lang,agency_phone,agency_email,agency_timezone,agency_fare_url,agency_branding_url
2 | 1,Fake Transit,,,,,America/Los_Angeles,,
3 |
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/calendar.txt:
--------------------------------------------------------------------------------
1 | service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date
2 | 04100312-8fe1-46a5-a9f2-556f39478f57,1,1,1,1,1,1,1,20170915,20170917
3 |
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/calendar_dates.txt:
--------------------------------------------------------------------------------
1 | service_id,date,exception_type
2 | 04100312-8fe1-46a5-a9f2-556f39478f57,20200220,2
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/fare_attributes.txt:
--------------------------------------------------------------------------------
1 | fare_id,price,currency_type,payment_method,transfers,transfer_duration
2 | route_based_fare,1.23,USD,0,0,0
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/fare_rules.txt:
--------------------------------------------------------------------------------
1 | fare_id,route_id,origin_id,destination_id,contains_id
2 | route_based_fare,1,,,
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/feed_info.txt:
--------------------------------------------------------------------------------
1 | feed_publisher_name,feed_publisher_url,feed_lang,feed_version
2 | Conveyal,http://www.conveyal.com,en,1.0
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/frequencies.txt:
--------------------------------------------------------------------------------
1 | trip_id,start_time,end_time,headway_secs,exact_times
2 | frequency-trip,08:00:00,09:00:00,1800,0
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/routes.txt:
--------------------------------------------------------------------------------
1 | agency_id,route_id,route_short_name,route_long_name,route_desc,route_type,route_url,route_color,route_text_color,route_branding_url
2 | 1,1,1,Route 1,,3,,7CE6E7,FFFFFF,
3 |
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/shapes.txt:
--------------------------------------------------------------------------------
1 | shape_id,shape_pt_lat,shape_pt_lon,shape_pt_sequence,shape_dist_traveled
2 | 5820f377-f947-4728-ac29-ac0102cbc34e,37.046495,-122.075212,1,0
3 | 5820f377-f947-4728-ac29-ac0102cbc34e,37.0611720,-122.0075000,2,400
4 | 5820f377-f947-4728-ac29-ac0102cbc34e,37.047819,-122.074137,3,730
5 |
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/stop_times.txt:
--------------------------------------------------------------------------------
1 | trip_id,arrival_time,departure_time,stop_id,stop_sequence,stop_headsign,pickup_type,drop_off_type,shape_dist_traveled,timepoint
2 | a30277f8-e50a-4a85-9141-b1e0da9d429d,07:00:00,07:00:00,4u6g,1,,0,0,0.0000000,
3 | a30277f8-e50a-4a85-9141-b1e0da9d429d,07:01:00,07:01:00,johv,2,,0,0,341.4491961,
4 | frequency-trip,08:00:00,08:00:00,4u6g,1,,0,0,0.0000000,
5 | frequency-trip,08:01:00,08:01:00,johv,2,,0,0,341.4491961,
6 |
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/stops.txt:
--------------------------------------------------------------------------------
1 | stop_id,stop_code,stop_name,stop_desc,stop_lat,stop_lon,zone_id,stop_url,location_type,parent_station,stop_timezone,wheelchair_boarding
2 | 4u6g,,Laurel Dr,,37.046495,-122.075212,,,0,,,
3 | johv,,Gushee St,,37.047819,-122.074137,,,0,,,
4 |
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/transfers.txt:
--------------------------------------------------------------------------------
1 | from_stop_id,to_stop_id,transfer_type,min_transfer_time
2 |
--------------------------------------------------------------------------------
/src/test/resources/fake-agency/trips.txt:
--------------------------------------------------------------------------------
1 | route_id,trip_id,trip_headsign,trip_short_name,direction_id,block_id,shape_id,bikes_allowed,wheelchair_accessible,service_id
2 | 1,a30277f8-e50a-4a85-9141-b1e0da9d429d,,,0,,5820f377-f947-4728-ac29-ac0102cbc34e,0,0,04100312-8fe1-46a5-a9f2-556f39478f57
3 | 1,frequency-trip,,,0,,5820f377-f947-4728-ac29-ac0102cbc34e,0,0,04100312-8fe1-46a5-a9f2-556f39478f57
--------------------------------------------------------------------------------
/src/test/resources/felton.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/felton.pbf
--------------------------------------------------------------------------------
/src/test/resources/logback-test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} %level \(%F:%L\) %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/test/resources/porto_portugal.osm.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/conveyal/analysis-backend/d14d1a2375f1596d29d6706b40bb02bd15a07614/src/test/resources/porto_portugal.osm.pbf
--------------------------------------------------------------------------------