Skip to content
Live monitoring of AIS vessel targets
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
ais-track-common Errorneous timestamps in lastReport #4 Jul 12, 2016
.gitignore Added aisbus.xml and boilerplate Apr 24, 2015
Jenkinsfile test if java problem is fixed Dec 14, 2018
LICENSE Initial commit Nov 21, 2014


AisTrack receives continuous input of AIS data streams from different sources and maintains a collection of 'targets' (aka tracks) with the most recent and consolidated information from each source.

AisTrack can be queried for track information by source and selected target attributes using a Java API or a RESTful interface returning JSON.


  • Java 8
  • Maven 3
  • (Docker)


mvn clean install


Before launch an aisbus.xml file must be prepared (example).

Aisbus.xml configures the AIS sources and input filtering in front of the tracker.


Directly from the command line:

  1. Go to a working directory where ais-track-rest-0.1-SNAPSHOT.jar resides; e.g.:

     $ cd ais-track-rest/target/
  2. Make sure that aisbus.xml is located in data/aisbus.xml:

     $ ls -l data/
     total 8
     -rwxr-xr-x+ 1 tbsalling  staff  1317 27 Apr 09:00 aisbus.xml
  3. Launch the tracker:

     $ java -jar ais-track-rest-0.1-SNAPSHOT.jar

Using Docker:

  1. Pull the latest Docker image:

     $ sudo docker pull dmadk/ais-track:latest
  2. Make sure that aisbus.xml is located in some directory, say ~/tmp:

     $ ls -l ~/tmp/
     total 8
     -rwxr-xr-x+ 1 tbsalling  staff  1317 27 Apr 09:00 aisbus.xml
  3. Run the docker image - with ~/tmp mounted as /data:

     $ sudo docker run -v ~/tmp:/data dmadk/ais-track:latest


Query status information

Query for status information from the tracker: http://localhost:8080/ (currently response is text format; not JSON)

Query all targets

Return the most recent information known about any target regardless which source the information is received from:


Beware, that if tens or hundreds of thousands of targets are tracked, then this response can be quite large.

The set of returned targets can be limited through filtering. E.g. filtering to include only given MMSI numbers:


Or including only targets inside a given geographical area (here a bounding box):


Or including only targets inside any of a set of geographical areas (here bounding boxes):


Or including only targets inside any of a set of geographical areas but in all cases limited to a base area. This case is useful when baseArea is configured in the calling system, where as areas are decided by users.


Or including only targets matching given MMSI numbers OR given geographical areas:


Geographical areas are either bounding boxes or circles. They are written using the syntax:

bounding box: <latitude left side>|<longitude bottom>|<latitude right side>|<longitude top>
circle: circle(<latitude center>,<longitude center>,<radius in meters>)

Query all targets limited by source

The queries shown above all return the most recent information known about the matching targets - regardless which source provided the information.

It is possible to take into considetaration only certain sources, by supplying a source filter expression to limit the source taken into account (Read more about the source filter expressions).

http://localhost:8080/tracks?   -- use only Danish sources
http://localhost:8080/tracks?sourceFilter%3Ds.region%20%3D%20819  -- use only source region 819
http://localhost:8080/tracks?          -- use only basestation 002190047

E.g. return latest information about MMSI 244820404 and MMSI 345070335 using only Danish sources:


Query a specific target by source

As a supplement to quering all targets and filtering them by MMSI, it is also possible to query the service for a single specific target using its MMSI no. as key:


This can also be combined with limiting the set of contributing sources:



The returned target information is in JSON format and complies with this format:

  "source" : {
    "country" : "DK",
    "bs" : 2190077
  "target" : {
    "mmsi" : 219007235,
    "country" : "DK",
    "lastReport" : "2015-04-27T08:23:13.707Z",
    "created" : "2015-04-24T14:26:36.667Z",
    "vesselStatic" : {
      "mmsi" : 219007235,
      "received" : "2015-04-24T14:26:36.670Z",
      "sourceTimestamp" : "2015-04-27T08:23:13.707Z",
      "created" : "2015-04-24T14:26:36.667Z",
      "name" : "R67 KIKI LOUISE",
      "callsign" : "XP5636",
      "shipType" : 30,
      "shipTypeCargo" : {
        "shipType" : "FISHING",
        "shipCargo" : "UNDEFINED"
      "dimensions" : {
        "dimBow" : 5,
        "dimStern" : 7,
        "dimPort" : 3,
        "dimStarboard" : 1
    "vesselPosition" : {
      "mmsi" : 219007235,
      "received" : "2015-04-24T14:26:36.670Z",
      "sourceTimestamp" : "2015-04-27T08:23:32.613Z",
      "created" : "2015-04-24T14:26:36.670Z",
      "sog" : 0.3,
      "cog" : 187.9,
      "pos" : {
        "lat" : 54.8387,
        "lon" : 15.093032
      "posAcc" : 0,
      "utcSec" : 32,
      "raim" : 1
    "targetType" : "B"
You can’t perform that action at this time.