View Javadoc
1   package au.gov.amsa.ais.message;
2   
3   import static au.gov.amsa.ais.Util.areEqual;
4   
5   import au.gov.amsa.ais.AisExtractor;
6   import au.gov.amsa.ais.AisExtractorFactory;
7   import au.gov.amsa.ais.AisMessage;
8   import au.gov.amsa.ais.AisMessageType;
9   import au.gov.amsa.ais.HasMmsi;
10  import au.gov.amsa.ais.Util;
11  
12  /**
13   * Decoder for AIS Aid to Navigation data (message type 21).
14   * 
15   * @author pxg
16   * 
17   */
18  public class AisAidToNavigation implements AisMessage, HasMmsi {
19  
20      private static final Integer LONGITUDE_NOT_AVAILABLE = 181 * 600000; // 108600000;
21      private static final Integer LATITUDE_NOT_AVAILABLE = 91 * 600000; // 54600000;
22      private final AisExtractor extractor;
23      private final String source;
24      private final int messageId;
25      private final int repeatIndicator;
26      private final int mmsi;
27      private final String name;
28      private final int dimensionA;
29      private final int dimensionB;
30      private final int dimensionC;
31      private final int dimensionD;
32      private final int typeOfElectronicPositionFixingDevice;
33      private final boolean isHighAccuracyPosition;
34      private final boolean isVirtualAtoN;
35      private final boolean isAtonOff;
36      private final boolean isAtonInAssignedMode;
37      private final Double longitude;
38      private final Double latitude;
39      private final int timeSecondsOnly;
40      private final String atonStatus;
41      private final int atonType;
42      private final boolean isUsingRAIM;
43  
44      public AisAidToNavigation(String message, String source, int padBits) {
45          this(Util.getAisExtractorFactory(), message, source, padBits);
46      }
47  
48      private AisAidToNavigation(AisExtractorFactory factory, String message, String source,
49              int padBits) {
50          this.source = source;
51          extractor = factory.create(message, 172, padBits);
52          messageId = extractor.getValue(0, 6);
53          Util.checkMessageId(getMessageId(), AisMessageType.ATON_REPORT);
54          repeatIndicator = extractor.getValue(6, 8);
55          mmsi = extractor.getValue(8, 38);
56          atonType = extractor.getValue(38, 43);
57          name = extractor.getString(43, 163);
58          isHighAccuracyPosition = areEqual(extractor.getValue(163, 164), 1);
59          longitude = extractLongitude(extractor);
60          latitude = extractLatitude(extractor);
61          dimensionA = extractor.getValue(219, 228);
62          dimensionB = extractor.getValue(228, 237);
63          dimensionC = extractor.getValue(237, 243);
64          dimensionD = extractor.getValue(243, 249);
65          typeOfElectronicPositionFixingDevice = extractor.getValue(249, 253);
66          timeSecondsOnly = extractor.getValue(253, 259);
67          isAtonOff = areEqual(extractor.getValue(259, 260), 1);
68          atonStatus = extractor.getString(260, 268);
69          isUsingRAIM = Util.areEqual(extractor.getValue(268, 269), 1);
70          isVirtualAtoN = areEqual(extractor.getValue(269, 270), 1);
71          isAtonInAssignedMode = areEqual(extractor.getValue(270, 271), 1);
72      }
73  
74      @Override
75      public int getMessageId() {
76          return messageId;
77      }
78  
79      public int getRepeatIndicator() {
80          return repeatIndicator;
81      }
82  
83      @Override
84      public int getMmsi() {
85          return mmsi;
86      }
87  
88      public boolean isHighAccuracyPosition() {
89          return isHighAccuracyPosition;
90      }
91  
92      public boolean isVirtualAtoN() {
93          return isVirtualAtoN;
94      }
95  
96      public boolean isAtonOff() {
97          return isAtonOff;
98      }
99  
100     public boolean isAtonInAssignedMode() {
101         return isAtonInAssignedMode;
102     }
103 
104     public String getAtonStatus() {
105         return atonStatus;
106     }
107 
108     public String getName() {
109         return name;
110     }
111 
112     public int getAtoNType() {
113         return atonType;
114     }
115 
116     public int getDimensionA() {
117         return dimensionA;
118     }
119 
120     public int getDimensionB() {
121         return dimensionB;
122     }
123 
124     public int getDimensionC() {
125         return dimensionC;
126     }
127 
128     public int getDimensionD() {
129         return dimensionD;
130     }
131 
132     public int getLengthMetres() {
133         return getDimensionA() + getDimensionB();
134     }
135 
136     public int getWidthMetres() {
137         return getDimensionC() + getDimensionD();
138     }
139 
140     public int getTypeOfElectronicPositionFixingDevice() {
141         return typeOfElectronicPositionFixingDevice;
142     }
143 
144     @Override
145     public String getSource() {
146         return source;
147     }
148 
149     static Double extractLongitude(AisExtractor extractor) {
150         int val = extractor.getSignedValue(164, 192);
151         if (val == LONGITUDE_NOT_AVAILABLE) {
152             return null;
153         } else {
154             Util.checkLong(val / 600000.0);
155             return val / 600000.0;
156         }
157 
158     }
159 
160     static Double extractLatitude(AisExtractor extractor) {
161         int val = extractor.getSignedValue(192, 219);
162         if (val == LATITUDE_NOT_AVAILABLE) {
163             return null;
164         } else {
165             Util.checkLat(val / 600000.0);
166             return val / 600000.0;
167         }
168     }
169 
170     public Double getLongitude() {
171         return longitude;
172     }
173 
174     public Double getLatitude() {
175         return latitude;
176     }
177 
178     public int getTimeSecondsOnly() {
179         return timeSecondsOnly;
180     }
181 
182     public boolean isUsingRAIM() {
183         return isUsingRAIM;
184     }
185 
186     @Override
187     public String toString() {
188         StringBuilder builder = new StringBuilder();
189         builder.append("AisAidToNavigation [source=");
190         builder.append(source);
191         builder.append(", messageId=");
192         builder.append(messageId);
193         builder.append(", repeatIndicator=");
194         builder.append(repeatIndicator);
195         builder.append(", mmsi=");
196         builder.append(mmsi);
197         builder.append(", atonType=");
198         builder.append(atonType);
199         builder.append(", atonStatus=");
200         builder.append(atonStatus);
201         builder.append(", name=");
202         builder.append(name);
203         builder.append(", isHighAccuracyPosition=");
204         builder.append(isHighAccuracyPosition);
205         builder.append(", longitude=");
206         builder.append(longitude);
207         builder.append(", latitude=");
208         builder.append(latitude);
209         builder.append(", dimensionA=");
210         builder.append(dimensionA);
211         builder.append(", dimensionB=");
212         builder.append(dimensionB);
213         builder.append(", dimensionC=");
214         builder.append(dimensionC);
215         builder.append(", dimensionD=");
216         builder.append(dimensionD);
217         builder.append(", typeOfElectronicPositionFixingDevice=");
218         builder.append(typeOfElectronicPositionFixingDevice);
219         builder.append(", timeSecondsOnly=");
220         builder.append(timeSecondsOnly);
221         builder.append(", isAtonOff=");
222         builder.append(isAtonOff);
223         builder.append(", isUsingRAIM=");
224         builder.append(isUsingRAIM);
225         builder.append(", isVirtualAtoN=");
226         builder.append(isVirtualAtoN);
227         builder.append(", isAtonInAssignedMode=");
228         builder.append(isAtonInAssignedMode);
229         builder.append("]");
230         return builder.toString();
231     }
232 
233 }