A Kotlin library and associated applications for manipulating data from the USGS Earthquake Hazards Program data feeds.
This consists of three classes: Quake
, QuakeFeed
and QuakeDataset
.
You can run the tests for these classes with
./gradlew :lib:test
Quake
provides a significantly simplified representation of an earthquake
event, consisting solely of event time, longitude & latitude, depth and
magnitude. Other elements of the USGS data feeds are (for the moment)
ignored.
QuakeFeed
represents one of the available CSV-based feeds. A feed is
selected by specifying its severity level and time period. For example, a
severity level of "4.5"
will select a feed of events of magnitude 4.5
or higher, and a time period of "week"
will select a feed of events
for the past 7 days:
val feed = QuakeFeed("4.5", "week")
The sets of supported severity levels and time periods are accessible
in QuakeFeed
:
println(QuakeFeed.validLevels)
println(QuakeFeed.validPeriods)
QuakeDataset
represents a dataset collected from a feed. This starts
off empty and must be populated by calling the update()
method, with A
feed as an argument:
val dataset = QuakeDataset().apply { update(feed) }
update()
can be invoked repeatedly thereafter, but note that each
invocation will replace existing data with the latest contents of the
given feed.
A dataset is somewhat list-like: you can query its size, test whether it is empty or not, and access individual quake events by their position in the dataset. You can also iterate over the contents of the dataset using a for loop, or extract dataset contents to a regular Kotlin list:
println("${dataset.size} quakes acquired")
val first = dataset[0]
for (quake in dataset) {
println(quake)
}
val quakeList = dataset.toList()
You can query a dataset to find the shallowest and deepest quakes, the
weakest and strongest quakes, mean quake depth and mean quake magnitude.
All of these queries return null
if the dataset hasn't yet been populated
from a feed.
dataset.strongestQuake?.let {
println("Strongest quake has a magnitude of ${it.magnitude}")
}
You can display the contents of a dataset in a plain text tabular format like so:
println(dataset.asTable())
println(dataset.asTable(compareBy { it.depth }))
println(dataset.asTable(compareByDescending { it.magnitude }))
The first of these examples displays quakes sorted by ascending event time,
via a default Comparator
object. You can easily plug in a different
comparator, using Kotlin's compareBy
& compareByDescending
functions,
as shown in the second and third examples.
Quake details can be formatted as an HTML table if you prefer:
val table = dataset.asHtmlTable(id="quakes")
The optional id
argument allows you to specify the id
attribute of
the generated table, thereby allowing targeting with specific CSS rules.
Just as with asTable()
, you can provide a Comparator
object if
the default sort order is not to your liking.
This terminal-based application extracts information from a USGS data feed. It can print summary statistics for the captured data, print a table of quake details, or write the captured data to a CSV file (or any combination of those three operations). The application has a command line UI, implemented with Clikt.
For testing purposes, you can run the application from Gradle:
./gradlew :quakeinfo:run
This will supply a fixed set of command line arguments. You can specify your own arguments like so:
./gradlew :quakeinfo:run --args="--summary 4.5 week"
A standalone distribution of the application can be created with
./gradlew :quakeinfo:distZip
This JavaFX application plots quake event locations on a background image showing a relief map of the world, allowing you to see the close correspondence between seismic events and tectonic plate boundaries. A tooltip is created for each plotted point, containing details of the associated quake.
For testing purposes, you can run the application from Gradle:
./gradlew :quakemap:run
This will supply a fixed values for severity level and period as command line arguments. You can specify your own arguments like so:
./gradlew :quakemap:run --args="4.5 week"