Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] AIS message type 8 #84

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/main/java/net/sf/marineapi/ais/message/AISMessage08.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* AISMessage08.java
* Copyright (C) 2018 Paweł Kozioł
*
* This file is part of Java Marine API.
* <http://ktuukkan.github.io/marine-api/>
*
* Java Marine API is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Java Marine API is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Java Marine API. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.marineapi.ais.message;

import net.sf.marineapi.ais.util.BitVector;

/**
* Binary Broadcast Message.
*
* @author Paweł Kozioł
*/
public interface AISMessage08 extends AISMessage {

/**
* Returns Designated Area Code used with FID to determine message subtype.
*
* @return Designated Area Code
*/
int getDAC();

/**
* Returns Functional ID used with DAC to determine message subtype.
*
* @return Functional ID
*/
int getFID();

/**
* Returns message binary data.
* Useful for debugging when there are no specific implementations
* for given combination of DAC and FID.
*
* @return Binary data with maximum 952 bits.
*/
BitVector getData();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* AISMessage08DAC200FID10.java
* Copyright (C) 2018 Paweł Kozioł
*
* This file is part of Java Marine API.
* <http://ktuukkan.github.io/marine-api/>
*
* Java Marine API is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Java Marine API is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Java Marine API. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.marineapi.ais.message;

/**
* Inland ship static and voyage related data (Inland AIS).
*
* @author Paweł Kozioł
*/
public interface AISMessage08DAC200FID10 extends AISMessage08 {

/**
* Returns European Number of Identification a.k.a. European Vessel Identification Number.
* @return European Number of Identification (8 six-bit characters)
*/
String getENI();

/**
* Returns length of the ship in meters with 0.1m precision.
* @return Length of the ship in meters with 0.1m precision
*/
double getShipLength();

/**
* Returns beam of the ship in meters with 0.1m precision.
* @return Beam of the ship in meters with 0.1m precision
*/
double getShipBeam();

/**
* Returns ship/combination type as full ERI codes with range 8000-8370
* or ERI SOLAS codes in the range 1-99.
*
* @return Ship/combination type
*/
int getShipType();

/**
* Returns hazardous cargo code.
* @return Hazardous cargo code
*/
int getHazardCode();

/**
* Returns draught in meters with 0.01m precision.
* @return Draught in meters with 0.01m precision
*/
double getDraught();

/**
* Returns load status. 0 = N/A, 1 = Unloaded, 2 = Loaded.
* @return Load status
*/
int getLoadStatus();

/**
* Returns speed inf. quality. 0 = low/GNSS (default) 1 = high
* @return Speed inf. quality
*/
boolean getSpeedQuality();

/**
* Returns course inf. quality. 0 = low/GNSS (default) 1 = high
* @return Course inf. quality
*/
boolean getCourseQuality();

/**
* Returns heading inf. quality. 0 = low/GNSS (default) 1 = high
* @return Heading inf. quality
*/
boolean getHeadingQuality();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/*
* AISMessage08DAC200FID10Parser.java
* Copyright (C) 2018 Paweł Kozioł
*
* This file is part of Java Marine API.
* <http://ktuukkan.github.io/marine-api/>
*
* Java Marine API is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Java Marine API is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Java Marine API. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.marineapi.ais.parser;

import net.sf.marineapi.ais.message.AISMessage08DAC200FID10;
import net.sf.marineapi.ais.util.Sixbit;

/**
* AIS Message 8 subtype, DAC = 200, FID = 10:
* Inland ship static and voyage related data (Inland AIS).
*
* <pre>
* Field Name Bits (from, to )
* -------------------------------------------------------------------------
* 1 messageID 6 ( 1, 6)
* 2 repeatIndicator 2 ( 7, 8)
* 3 userID 30 ( 9, 38)
* 4 spare 2 ( 39, 40)
* 5 designatedAreaCode 10 ( 41, 50)
* 6 functionalID 6 ( 51, 56)
* 7 European Vessel ID 48 ( 57, 104)
* 7 Length of ship 13 ( 58, 117)
* 7 Beam of ship 10 ( 118, 127)
* 7 Ship/combination type 14 ( 128, 141)
* 7 Hazardous cargo 3 ( 142, 144)
* 7 Draught 11 ( 145, 155)
* 7 Loaded/Unloaded 2 ( 156, 157)
* 7 Speed inf. quality 1 ( 158, 158)
* 7 Course inf. quality 1 ( 159, 159)
* 7 Heading inf. quality 1 ( 160, 160)
* 7 spare2 8 ( 161, 168)
* ---- +
* sum 168
* </pre>
*
* @author Paweł Kozioł
*/
class AISMessage08DAC200FID10Parser extends AISMessage08Parser implements AISMessage08DAC200FID10 {

private final static int MSG_TYPE = 8;
private final static int MSG_DAC = 200;
private final static int MSG_FID = 10;
private final static int MSG_LEN = 168;

private final static String SEPARATOR = "\n\t";
private final static int VIN = 0;
private final static int SHIP_LENGTH = 1;
private final static int SHIP_BEAM = 2;
private final static int SHIP_TYPE = 3;
private final static int HAZARD_CODE = 4;
private final static int DRAUGHT = 5;
private final static int LOAD_STATUS = 6;
private final static int SPEED_QUALITY = 7;
private final static int COURSE_QUALITY = 8;
private final static int HEADING_QUALITY = 9;
private final static int[] FROM = {
56, 104, 117, 127, 141, 144, 155, 157, 158, 159};
private final static int[] TO = {
104, 117, 127, 141, 144, 155, 157, 158, 159, 160};

public static class Factory extends AISMessage08Parser.Factory {

@Override
public boolean canCreate(AISMessageParser parser) {
return parser.getMessageType() == MSG_TYPE
&& parser.getSixbit().length() == MSG_LEN
&& getDAC(parser.getSixbit()) == MSG_DAC
&& getFID(parser.getSixbit()) == MSG_FID;
}

@Override
public AISMessage08DAC200FID10Parser create(AISMessageParser parser) {
return new AISMessage08DAC200FID10Parser(parser.getSixbit());
}
}

private String vin;
private double shipLength;
private double shipBeam;
private int shipType;
private int hazardCode;
private double draught;
private int loadStatus;
private boolean speedQuality;
private boolean courseQuality;
private boolean headingQuality;

public AISMessage08DAC200FID10Parser(Sixbit content) {
super(content);
if (content.length() != 168)
throw new IllegalArgumentException("Wrong message length");

vin = content.getString(FROM[VIN], TO[VIN]);
shipLength = 0.1 * content.getInt(FROM[SHIP_LENGTH], TO[SHIP_LENGTH]);
shipBeam = 0.1 * content.getInt(FROM[SHIP_BEAM], TO[SHIP_BEAM]);
shipType = content.getInt(FROM[SHIP_TYPE], TO[SHIP_TYPE]);
hazardCode = content.getInt(FROM[HAZARD_CODE], TO[HAZARD_CODE]);
draught = 0.01 * content.getInt(FROM[DRAUGHT], TO[DRAUGHT]);
loadStatus = content.getInt(FROM[LOAD_STATUS], TO[LOAD_STATUS]);
speedQuality = content.getBoolean(FROM[SPEED_QUALITY]);
courseQuality = content.getBoolean(FROM[COURSE_QUALITY]);
headingQuality = content.getBoolean(FROM[HEADING_QUALITY]);
}

@Override
public String getENI() {
return vin;
}

@Override
public double getShipLength() {
return shipLength;
}

@Override
public double getShipBeam() {
return shipBeam;
}

@Override
public int getShipType() {
return shipType;
}

@Override
public int getHazardCode() {
return hazardCode;
}

@Override
public double getDraught() {
return draught;
}

@Override
public int getLoadStatus() {
return loadStatus;
}

@Override
public boolean getSpeedQuality() {
return speedQuality;
}

@Override
public boolean getCourseQuality() {
return courseQuality;
}

@Override
public boolean getHeadingQuality() {
return headingQuality;
}

public String toString() {
String result = "\tDAC: " + getDAC();
result += SEPARATOR + "FID: " + getFID();
result += SEPARATOR + "VIN: " + getENI();
result += SEPARATOR + "Ship length: " + getShipLength();
result += SEPARATOR + "Ship beam: " + getShipBeam();
result += SEPARATOR + "Ship type: " + getShipType();
result += SEPARATOR + "Hazard code: " + getHazardCode();
result += SEPARATOR + "Draught: " + getDraught();
result += SEPARATOR + "Load status: " + getLoadStatus();
result += SEPARATOR + "Speed quality: " + (speedQuality ? "high" : "low");
result += SEPARATOR + "Course quality: " + (courseQuality ? "high" : "low");
result += SEPARATOR + "Heading quality: " + (headingQuality ? "high" : "low");
return result;
}
}
Loading