View Javadoc
1   package au.gov.amsa.ais.message;
2   
3   import au.gov.amsa.ais.AisExtractor;
4   import au.gov.amsa.ais.AisExtractorFactory;
5   import au.gov.amsa.ais.AisParseException;
6   import au.gov.amsa.ais.Util;
7   
8   import static au.gov.amsa.ais.AisMessageType.POSITION_GPS;
9   
10  /**
11   * Decoder for AIS message type 27 (AIS Satelitte).
12   *
13   * @author dcuenot
14   *
15   */
16  public class AisPositionGPS implements AisPosition {
17  
18      private static final Integer COG_NOT_AVAILABLE = 511;
19      private static final Integer SOG_NOT_AVAILABLE = 63;
20      private static final Integer LONGITUDE_NOT_AVAILABLE = 181 * 600; // 108600;
21      private static final Integer LATITUDE_NOT_AVAILABLE = 91 * 600; // 54600;
22      private final AisExtractor extractor;
23      private final String source;
24      private final int messageId;
25      private final int mmsi;
26      private final Double longitude;
27      private final Double latitude;
28  
29      public AisPositionGPS(String message, String source, int padBits) {
30          this(Util.getAisExtractorFactory(), message, source, padBits);
31      }
32      
33      public AisPositionGPS(String message, int padBits) {
34          this(message, null, padBits);
35      }
36  
37      public AisPositionGPS(AisExtractorFactory factory, String message, String source, int padBits) {
38          this.source = source;
39          this.extractor = factory.create(message, 96, padBits);
40          messageId = extractor.getMessageId();
41          Util.checkMessageId(messageId, POSITION_GPS);
42          mmsi = extractor.getValue(8, 38);
43          longitude = extractLongitude(extractor);
44          latitude = extractLatitude(extractor);
45      }
46  
47  
48      static Double extractCourseOverGround(AisExtractor extractor) {
49          try {
50              int val = extractor.getValue(85, 94);
51              if (val == COG_NOT_AVAILABLE || val >= 360)
52                  return null;
53              else
54                  return val * 1.0;
55          } catch (AisParseException e) {
56              return null;
57          }
58      }
59  
60      static Double extractSpeedOverGround(AisExtractor extractor) {
61          try {
62              int val = extractor.getValue(79, 85);
63              if (val == SOG_NOT_AVAILABLE)
64                  return null;
65              else
66                  return val * 1.0;
67          } catch (AisParseException e) {
68              return null;
69          }
70      }
71  
72      static Double extractLongitude(AisExtractor extractor) {
73          try {
74              int val = extractor.getSignedValue(44, 62);
75              if (val == LONGITUDE_NOT_AVAILABLE) {
76                  return null;
77              } else {
78                  Util.checkLong(val / 600.0);
79                  return val / 600.0;
80              }
81          } catch (AisParseException e) {
82              return null;
83          }
84      }
85  
86      static Double extractLatitude(AisExtractor extractor) {
87  
88          try {
89              int val = extractor.getSignedValue(62, 79);
90              if (val == LATITUDE_NOT_AVAILABLE) {
91                  return null;
92              } else {
93                  Util.checkLat(val / 600.0);
94                  return val / 600.0;
95              }
96          } catch (AisParseException e) {
97              return null;
98          }
99      }
100 
101     @Override
102     public int getMessageId() {
103         return messageId;
104     }
105 
106     @Override
107     public int getRepeatIndicator() {
108         return extractor.getValue(6, 8);
109     }
110 
111     @Override
112     public int getMmsi() {
113         return mmsi;
114     }
115 
116     public NavigationalStatus getNavigationalStatus() { return NavigationalStatus.values()[extractor.getValue(40, 44)]; }
117 
118     @Override
119     public Double getSpeedOverGroundKnots() {
120         return extractSpeedOverGround(extractor);
121     }
122 
123     @Override
124     public boolean isHighAccuracyPosition() {
125         return Util.areEqual(extractor.getValue(38, 39), 1);
126     }
127 
128     @Override
129     public Double getLongitude() {
130         return longitude;
131     }
132 
133     @Override
134     public Double getLatitude() {
135         return latitude;
136     }
137 
138     @Override
139     public Double getCourseOverGround() {
140         return extractCourseOverGround(extractor);
141     }
142 
143     @Override
144     public Integer getTrueHeading() {
145         return null;
146     }
147 
148     @Override
149     public int getTimeSecondsOnly() {
150         return 0;
151     }
152 
153     public int getSpare() {
154         return extractor.getValue(95, 96);
155     }
156 
157     @Override
158     public boolean isUsingRAIM() {
159         return Util.areEqual(extractor.getValue(39, 40), 1);
160     }
161 
162     @Override
163     public String getSource() {
164         return source;
165     }
166 
167     @Override
168     public String toString() {
169         StringBuilder builder = new StringBuilder();
170         builder.append("AisPositionGPS [source=");
171         builder.append(source);
172         builder.append(", messageId=");
173         builder.append(messageId);
174         builder.append(", repeatIndicator=");
175         builder.append(getRepeatIndicator());
176         builder.append(", mmsi=");
177         builder.append(mmsi);
178         builder.append(", navigationalStatus=");
179         builder.append(getNavigationalStatus());
180         builder.append(", speedOverGroundKnots=");
181         builder.append(getSpeedOverGroundKnots());
182         builder.append(", isHighAccuracyPosition=");
183         builder.append(isHighAccuracyPosition());
184         builder.append(", longitude=");
185         builder.append(longitude);
186         builder.append(", latitude=");
187         builder.append(latitude);
188         builder.append(", courseOverGround=");
189         builder.append(getCourseOverGround());
190         builder.append(", trueHeading=");
191         builder.append(getTrueHeading());
192         builder.append(", timeSecondsOnly=");
193         builder.append(getTimeSecondsOnly());
194         builder.append(", spare=");
195         builder.append(getSpare());
196         builder.append(", isUsingRAIM=");
197         builder.append(isUsingRAIM());
198         builder.append("]");
199         return builder.toString();
200     }
201 
202 }