-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MetroGTFS Package: MetroRail GTFS Static data in a new wrapper (#57)
Create a new package, MetroGTFS, for handling GTFS Static data
- Loading branch information
1 parent
883b7e8
commit 74dcbb0
Showing
22 changed files
with
968 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,41 @@ | ||
{ | ||
"object": { | ||
"pins": [ | ||
{ | ||
"package": "DVR", | ||
"repositoryURL": "https://github.com/venmo/DVR.git", | ||
"state": { | ||
"branch": null, | ||
"revision": "d13f7135d1993053580efe13c9ecc43200852d09", | ||
"version": "2.1.0" | ||
} | ||
}, | ||
{ | ||
"package": "SwiftDocCPlugin", | ||
"repositoryURL": "https://github.com/apple/swift-docc-plugin", | ||
"state": { | ||
"branch": null, | ||
"revision": "3303b164430d9a7055ba484c8ead67a52f7b74f6", | ||
"version": "1.0.0" | ||
} | ||
}, | ||
{ | ||
"package": "SwiftProtobuf", | ||
"repositoryURL": "https://github.com/apple/swift-protobuf.git", | ||
"state": { | ||
"branch": null, | ||
"revision": "7e2c5f3cbbeea68e004915e3a8961e20bd11d824", | ||
"version": "1.18.0" | ||
} | ||
"pins" : [ | ||
{ | ||
"identity" : "dvr", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/venmo/DVR.git", | ||
"state" : { | ||
"revision" : "d13f7135d1993053580efe13c9ecc43200852d09", | ||
"version" : "2.1.0" | ||
} | ||
] | ||
}, | ||
"version": 1 | ||
}, | ||
{ | ||
"identity" : "sqlite.swift", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/stephencelis/SQLite.swift.git", | ||
"state" : { | ||
"revision" : "7a2e3cd27de56f6d396e84f63beefd0267b55ccb", | ||
"version" : "0.14.1" | ||
} | ||
}, | ||
{ | ||
"identity" : "swift-docc-plugin", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/apple/swift-docc-plugin", | ||
"state" : { | ||
"revision" : "3303b164430d9a7055ba484c8ead67a52f7b74f6", | ||
"version" : "1.0.0" | ||
} | ||
}, | ||
{ | ||
"identity" : "swift-protobuf", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/apple/swift-protobuf.git", | ||
"state" : { | ||
"revision" : "7e2c5f3cbbeea68e004915e3a8961e20bd11d824", | ||
"version" : "1.18.0" | ||
} | ||
} | ||
], | ||
"version" : 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,22 +2,12 @@ | |
|
||
WMATA.swift is a Swift interface to the [Washington Metropolitan Area Transit Authority API](https://developer.wmata.com). | ||
|
||
## Contents | ||
|
||
- [Requirements](#requirements) | ||
- [Installation](#installation) | ||
- [Documentation](#documentation) | ||
- [Dependencies](#dependencies) | ||
- [Contact](#contact) | ||
- [Contributing](#contributing) | ||
- [License](#license) | ||
|
||
## Installation | ||
## Install | ||
|
||
### Requirements | ||
|
||
- Swift 5.6 | ||
- Xcode 13.2 | ||
- Swift 5.9 | ||
- Xcode 15 | ||
|
||
### Swift Package Manager | ||
|
||
|
@@ -31,11 +21,47 @@ dependencies: [ | |
] | ||
``` | ||
|
||
## Usage | ||
|
||
### Standard API | ||
|
||
To work with WMATA's Standard API use the `WMATA` package. | ||
|
||
```swift | ||
import WMATA | ||
|
||
let nextTrains = Rail.NextRails( | ||
key: YOUR_API_KEY, | ||
station: .waterfront | ||
) | ||
|
||
nextTrains.request { result in | ||
switch result { | ||
case let .success(response): | ||
print(response.trains) | ||
case let .failure(error): | ||
print(error) | ||
} | ||
} | ||
``` | ||
|
||
### GTFS Static | ||
|
||
To work with GTFS Static data use the `MetroGTFS` package. | ||
|
||
```swift | ||
import MetroGTFS | ||
|
||
let ashburn = try GTFSStop("STN_N12") | ||
|
||
print(ashburn.name) // "ASHBURN METRORAIL STATION" | ||
``` | ||
|
||
## OS Support | ||
|
||
WMATA.swift commits to supporting current minus 2 OS versions. | ||
|
||
Currently, WMATA.swift is compatible with macOS 10.15, iOS 13, tvOS 13, watchOS 6 or higher. | ||
Currently, WMATA.swift is compatible with macOS 12, iOS 15, tvOS 15, watchOS 8 or higher. | ||
|
||
## Documentation | ||
|
||
|
@@ -47,6 +73,7 @@ To view documentation within Xcode, within the menu navigate to `Product > Build | |
|
||
- [swift-protobuf](https://github.com/apple/swift-protobuf), for GTFS-RT feeds. | ||
- [DVR](https://github.com/venmo/DVR), for testing. | ||
- [SQLite.swift](https://github.com/stephencelis/SQLite.swift), for GTFS Static data. Only used in `MetroGTFS` package. | ||
|
||
## Contact | ||
|
||
|
@@ -56,9 +83,8 @@ Feel free to email questions and comments to [[email protected]](mailto:[email protected]) | |
|
||
Todo: | ||
|
||
- [ ] Build out more DVR tests. | ||
- [ ] Automated builds. | ||
- [ ] Convert async functions from a `Result` to `return` or `throw` behavior, the dominant async pattern in Swift. | ||
- [ ] Support all GTFS Static data in `MetroGTFS` | ||
- [ ] Convert async functions from a `Result` to `return` or `throw` behavior, the dominant async pattern in Swift | ||
|
||
## Developer | ||
|
||
|
@@ -67,3 +93,5 @@ To generate documentation for deploying to Github Pages, run `./docs.sh`. | |
## License | ||
|
||
WMATA.swift is released under the MIT license. [See LICENSE](https://github.com/emma-k-alexandra/WMATA.swift/blob/main/LICENSE) for details. | ||
|
||
This package is not distributed by or affiliated with WMATA. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
gtfs-files/*.txt | ||
gtfs-files/swift-files/*.swift |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// | ||
// GTFSCoordinates.swift | ||
// | ||
// | ||
// Created by Emma on 11/25/23. | ||
// | ||
|
||
import Foundation | ||
|
||
/// Location with latitude and longitude coordinates | ||
public struct GTFSCoordinates: Equatable, Hashable, Codable { | ||
/// Latitude in degrees, for the DMV this value is positive. | ||
public var latitude: Double | ||
|
||
/// Longitude in degrees, For the DMV this value is negative. | ||
public var longitude: Double | ||
|
||
/// Create a new location | ||
/// | ||
/// - Parameters: | ||
/// - latitude: Latitude of location in degrees, positive for the DMV. | ||
/// - longitude: Longitude of location in degrees, negative for the DMV. | ||
public init(latitude: Double, longitude: Double) { | ||
self.latitude = latitude | ||
self.longitude = longitude | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// | ||
// Database.swift | ||
// | ||
// | ||
// Created by Emma on 11/26/23. | ||
// | ||
|
||
import Foundation | ||
import SQLite | ||
|
||
/// The GTFS Static Database. Used to perform queries on the GTFS Static Database. | ||
struct GTFSDatabase { | ||
private let connection: Connection | ||
|
||
/// Create a new GTFS Database. If there is not currently an open connection to the database, create one. | ||
init() throws { | ||
if let connection = GTFSDatabase.shared { | ||
self.connection = connection | ||
|
||
return | ||
} | ||
|
||
let connection: Connection | ||
|
||
do { | ||
connection = try GTFSDatabase.connection() | ||
} catch { | ||
throw GTFSDatabaseError.unableToConnectToDatabase | ||
} | ||
|
||
GTFSDatabase.shared = connection | ||
|
||
self.connection = connection | ||
} | ||
|
||
/// Run a database query that only returns one row | ||
func run(query: SQLite.Table) throws -> Row? { | ||
do { | ||
return try connection.pluck(query) | ||
} catch { | ||
throw GTFSDatabaseError.unableToPerformQuery(query) | ||
} | ||
} | ||
|
||
/// Run a database query that returns multiple rows | ||
func run(query: SQLite.Table) throws -> AnySequence<Row> { | ||
do { | ||
return try connection.prepare(query) | ||
} catch { | ||
throw GTFSDatabaseError.unableToPerformQuery(query) | ||
} | ||
} | ||
} | ||
|
||
extension GTFSDatabase { | ||
/// Get all GTFS Structures of the given type from the GTFS Database | ||
func all<Structure: Queryable>(_ structure: Structure.Type) throws -> AnySequence<Row> { | ||
return try run(query: structure.databaseTable.sqlTable) | ||
} | ||
|
||
/// Get all GTFS Structures of the given type with the given `id` in the given `column`. Defaults to using the primary key column. | ||
func all<Structure: Queryable>( | ||
_ structure: Structure.Type, | ||
with id: GTFSIdentifier<Structure>, | ||
in column: SQLite.Expression<String> = Structure.databaseTable.primaryKeyColumn | ||
) throws -> AnySequence<Row> { | ||
return try run(query: structure.databaseTable.sqlTable.where(column == id.rawValue)) | ||
} | ||
|
||
/// Get all GTFS Structures of the given type with the given `id` in the given `column`. | ||
func all<Structure: Queryable>( | ||
_ structure: Structure.Type, | ||
with id: GTFSIdentifier<Structure>, | ||
in column: SQLite.Expression<String?> | ||
) throws -> AnySequence<Row> { | ||
return try run(query: structure.databaseTable.sqlTable.where(column == id.rawValue)) | ||
} | ||
|
||
|
||
/// Get a single structure of the given type with the given `id` in the given `column`. Defaults to using the primary key column. | ||
func one<Structure: Queryable>( | ||
_ structure: Structure.Type, | ||
with id: GTFSIdentifier<Structure>, | ||
in column: SQLite.Expression<String> = Structure.databaseTable.primaryKeyColumn | ||
) throws -> Row? { | ||
return try run(query: structure.databaseTable.sqlTable.where(column == id.rawValue)) | ||
} | ||
} | ||
|
||
extension GTFSDatabase { | ||
/// The global shares connection to the GTFS database | ||
private static var shared: Connection? | ||
|
||
/// Create a new connection to the MetroGTFS SQLite database | ||
private static func connection() throws -> Connection { | ||
let path = Bundle.module.path(forResource: "MetroGTFS", ofType: "sqlite3") | ||
|
||
guard let path else { | ||
throw GTFSDatabaseError.failedToLoadDatabase | ||
} | ||
|
||
let connection = try Connection(path, readonly: true) | ||
|
||
return connection | ||
} | ||
} | ||
|
||
extension GTFSDatabase { | ||
/// A SQLite database table and the column it's primary key is in | ||
struct Table { | ||
let sqlTable: SQLite.Table | ||
let primaryKeyColumn: SQLite.Expression<String> | ||
} | ||
} | ||
|
||
/// If a data type can be loaded from a SQLite database | ||
protocol Queryable { | ||
/// The actual table in SQLite to pull the data type from | ||
static var databaseTable: GTFSDatabase.Table { get } | ||
} | ||
|
Oops, something went wrong.