Data Querying
Query AIS data loaded with AISdb using DBQuery and TrackGen, with practical examples for time range, bounding box, and MMSI filters.
Data querying with AISdb involves setting up a connection to the database, defining query parameters, creating and executing the query, and processing the results. Following the previous tutorial, Database Loading, we set up a database connection and made simple queries and visualizations. This tutorial will dig into data query functions and parameters and show you the queries you can make with AISdb.
Query functions
Data querying with AISdb involves two components, DBQuery and TrackGen. In this section, we will introduce each component with examples. Before starting data querying, please ensure you have connected to the database. If you have not done so, please follow the instructions and examples in Database Loading or Quick Start.
Query database
The DBQuery class is used to create a query object that specifies the parameters for data retrieval, including the time range, spatial domain, and any filtering callbacks. Here is an example of creating a DBQuery object and using parameters to specify the time range and geographical locations:
import aisdb
# Specify database path
dbpath = 'YOUR_DATABASE.db'
# Specify constraints (optional)
start_time = ...
end_time = ...
domain = ...
with aisdb.SQLiteDBConn(dbpath=dbpath) as dbconn:
# Create a query object to fetch data within time and geographical range
qry = aisdb.DBQuery(
dbconn=dbconn, # Database connection object
start=start_time, # Start time for the query
end=end_time, # End time for the query
xmin=domain.boundary['xmin'], # Minimum longitude of the domain
xmax=domain.boundary['xmax'], # Maximum longitude of the domain
ymin=domain.boundary['ymin'], # Minimum latitude of the domain
ymax=domain.boundary['ymax'], # Maximum latitude of the domain
callback=aisdb.database.sqlfcn_callbacks.in_time_bbox_validmmsi, # Callback function to filter data
)Callback functions
Callback functions are used in the DBQuery class to filter data based on specific criteria. Some common callbacks include in_validmmsi_bbox, in_time_bbox, in_timerange_validmmsi, and in_time_bbox_validmmsi. These callbacks ensure that the data retrieved matches the specific criteria defined in the query. Please find examples of using different callbacks with other parameters in Query types with practical examples.
For more callback functions, refer to the API documentation here: API-Doc
Method gen_qry
The method gen_qry of the DBQuery class runs the query and streams back the matching data. It does not yield one AIS record at a time. Instead, it is a generator that yields a batch of rows for each unique MMSI, sorted by MMSI first and then by time within each batch, fetching results in chunks under the hood so large queries stay memory-efficient. That grouping is exactly what TrackGen expects downstream, since a "track" is just a time-ordered run of positions for one vessel.
The SQL-generating function used internally is controlled by the fcn argument. AISdb ships two of them in aisdb.database.sqlfcn.
crawl_dynamiciterates only over the position reports table. This is the default.crawl_dynamic_staticiterates over both the position reports and static message tables, so each row also carries fields such as vessel name and ship type.
After creating the DBQuery object, generate the grouped rows with gen_qry.
Each element of mmsi_rows is a sqlite3.Row (or a dict-like row when querying PostgreSQL) representing one position report. In practice you will rarely iterate gen_qry directly. Pass it straight to TrackGen, which does this grouping work for you and returns ready-to-use track dictionaries.
Generate trajectories
The TrackGen class converts the generated rows from gen_qry into tracks (trajectories). It takes the row generator and, optionally, a decimate parameter to control point reduction. This conversion is essential for analyzing vessel movements, identifying patterns, and visualizing trajectories in later steps.
Following the generated rows above, here is how to use the TrackGen class:
The TrackGen class returns a generator object that yields "tracks." While iterating over the tracks, each item is a dictionary representing the track of a specific vessel:
This is the output with our sample data:
Query types with practical examples
In this section, we will provide practical examples of the most common query types you can make using the DBQuery class, including querying within a time range, querying within a geographical area, and tracking vessels by MMSI. Different queries can be achieved by changing the callbacks parameter and other parameters defined in the DBQuery class. Then, we will use TrackGen to convert these query results into structured tracks for further analysis and visualization.
First, we need to import the necessary packages and prepare data:
Within time range
Querying data within a specified time range can be done by using the in_timerange_validmmsi callback in the DBQuery class:
This will display the queried vessel tracks (within a time range, with a valid MMSI) on the map:

You may find noise in some of the track data. In Data Cleaning, we introduced the de-noising methods in AISdb that can effectively remove unreasonable or erroneous data points, ensuring more accurate and reliable vessel trajectories.
Within bounding box
In practical scenarios, people may have specific points/areas of interest. DBQuery includes parameters to define a bounding box and has relevant callbacks. Let's look at an example:
This will show all the vessel tracks with valid MMSI in the defined bounding box:

Combination of multiple conditions
In the above examples, we queried data in a time range and a geographical area. If you want to combine multiple query criteria, please check out available types of callbacks in the API Docs. In the last example above, we can simply modify the callback type to obtain vessel tracks within both the time range and geographical area:
The displayed vessel tracks:

Filtering MMSI
In addition to time and location range, you can track one or more vessels of interest by specifying their MMSIs in the query. Here is an example of tracking several vessels within a time range:

Where to go next
The tracks pulled here still carry the noise inherent to raw AIS, duplicate points, GPS jumps, and implausible speeds among them. See data-cleaning.md for denoising them before further analysis. Once a track is clean, data-visualization.md covers plotting it on a map alongside other vessels and points of interest.
Last updated