/* Copyright (c) 2011 Danish Maritime Authority. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package dk.dma.ais.message.binary; import java.util.ArrayList; import java.util.List; import dk.dma.ais.binary.BinArray; import dk.dma.ais.binary.SixbitEncoder; import dk.dma.ais.binary.SixbitException; //import java.math.BigInteger; /** * Abstract base class for area notice ASM's */ public abstract class AreaNotice extends AisApplicationMessage { public enum SubAreaType { CIRCLE_OR_POINT(0), RECTANGLE(1), SECTOR(2), POLYLINE(3), POLYGON(4), TEXT(5), RESERVED(6), RESERVED2(7); private int astype; private SubAreaType(int astype) { this.astype = astype; } public int getType() { return astype; } } private int msgLinkId; // 10 bits: Source specific running number linking // birary messages private int notice; // 7 bits: Notice description private int startMonth; // 4 bits private int startDay; // 5 bits private int startHour; // 5 bits private int startMin; // 6 bits private int duration; // 18 bits: Minutes until end of validity 0=cancel // route // /--------------- private int subareasCount; private List<SubArea> subareas; // = null; // 55 bits each longitude 28 bit, // latitude 27 bit // TODO the rest from SN Circ 289 public AreaNotice(int fi) { super(1, fi); this.subareas = new ArrayList<>(); } public AreaNotice(int fi, BinArray binArray) throws SixbitException { super(1, fi, binArray); } @Override public SixbitEncoder getEncoded() { SixbitEncoder encoder = new SixbitEncoder(); encoder.addVal(msgLinkId, 10); encoder.addVal(notice, 7); encoder.addVal(startMonth, 4); encoder.addVal(startDay, 5); encoder.addVal(startHour, 5); encoder.addVal(startMin, 6); encoder.addVal(duration, 18); for (SubArea subarea : subareas) { encoder.addVal(subarea.getRawAreaShape(), 3); switch (subarea.getRawAreaShape()) { case 0: encoder.addVal(subarea.getRawScaleFactor(), 2); encoder.addVal(subarea.getRawLongitude(), 25); encoder.addVal(subarea.getRawLatitude(), 24); encoder.addVal(subarea.getRawPrecision(), 3); encoder.addVal(subarea.getRawRadius(), 12); encoder.addVal(subarea.getSpare(), 18); break; case 1: encoder.addVal(subarea.getRawScaleFactor(), 2); encoder.addVal(subarea.getRawLongitude(), 25); encoder.addVal(subarea.getRawLatitude(), 24); encoder.addVal(subarea.getRawPrecision(), 3); encoder.addVal(subarea.getRawEDim(), 8); encoder.addVal(subarea.getRawNDim(), 8); encoder.addVal(subarea.getRawOrient(), 9); encoder.addVal(subarea.getSpare(), 5); break; case 2: encoder.addVal(subarea.getRawScaleFactor(), 2); encoder.addVal(subarea.getRawLongitude(), 25); encoder.addVal(subarea.getRawLatitude(), 24); encoder.addVal(subarea.getRawPrecision(), 3); encoder.addVal(subarea.getRawRadius(), 12); encoder.addVal(subarea.getRawLeftBound(), 9); encoder.addVal(subarea.getRawRightBound(), 9); encoder.addVal(subarea.getSpare(), 0); break; case 3: encoder.addVal(subarea.getRawScaleFactor(), 2); encoder.addVal(subarea.getRawP1Angle(), 10); encoder.addVal(subarea.getRawP1Dist(), 10); encoder.addVal(subarea.getRawP2Angle(), 10); encoder.addVal(subarea.getRawP2Dist(), 10); encoder.addVal(subarea.getRawP3Angle(), 10); encoder.addVal(subarea.getRawP3Dist(), 10); encoder.addVal(subarea.getRawP4Angle(), 10); encoder.addVal(subarea.getRawP4Dist(), 10); encoder.addVal(subarea.getSpare(), 2); break; case 4: encoder.addVal(subarea.getRawScaleFactor(), 2); encoder.addVal(subarea.getRawP1Angle(), 10); encoder.addVal(subarea.getRawP1Dist(), 10); encoder.addVal(subarea.getRawP2Angle(), 10); encoder.addVal(subarea.getRawP2Dist(), 10); encoder.addVal(subarea.getRawP3Angle(), 10); encoder.addVal(subarea.getRawP3Dist(), 10); encoder.addVal(subarea.getRawP4Angle(), 10); encoder.addVal(subarea.getRawP4Dist(), 10); encoder.addVal(subarea.getSpare(), 2); break; case 5: encoder.addVal(subarea.getText(), 32); encoder.addVal(subarea.getText1(), 32); encoder.addVal(subarea.getText2(), 20); break; default: // reserved break; } } // TODO rest of the fields (as in RouteInformation) return encoder; } @Override public void parse(BinArray binArray) throws SixbitException { this.subareas = new ArrayList<>(); this.msgLinkId = (int) binArray.getVal(10); this.notice = (int) binArray.getVal(7); this.startMonth = (int) binArray.getVal(4); this.startDay = (int) binArray.getVal(5); this.startHour = (int) binArray.getVal(5); this.startMin = (int) binArray.getVal(6); this.duration = (int) binArray.getVal(18); subareasCount = (binArray.getLength() - 111) / 87; for (int i = 0; i < subareasCount; i++) { SubArea subarea = new SubArea(); subarea.setRawAreaShape((int) binArray.getVal(3)); switch (subarea.getRawAreaShape()) { case 0: subarea.setRawScaleFactor((int) binArray.getVal(2)); subarea.setRawLongitude((int) binArray.getVal(25)); subarea.setRawLatitude((int) binArray.getVal(24)); subarea.setRawPrecision((int) binArray.getVal(3)); subarea.setRawRadius((int) binArray.getVal(12)); subarea.setSpare((int) binArray.getVal(18)); break; case 1: subarea.setRawScaleFactor((int) binArray.getVal(2)); subarea.setRawLongitude((int) binArray.getVal(25)); subarea.setRawLatitude((int) binArray.getVal(24)); subarea.setRawPrecision((int) binArray.getVal(3)); subarea.setRawEDim((int) binArray.getVal(8)); subarea.setRawNDim((int) binArray.getVal(8)); subarea.setRawOrient((int) binArray.getVal(9)); subarea.setSpare((int) binArray.getVal(5)); break; case 2: subarea.setRawScaleFactor((int) binArray.getVal(2)); subarea.setRawLongitude((int) binArray.getVal(25)); subarea.setRawLatitude((int) binArray.getVal(24)); subarea.setRawPrecision((int) binArray.getVal(3)); subarea.setRawRadius((int) binArray.getVal(12)); subarea.setRawLeftBound((int) binArray.getVal(9)); subarea.setRawRightBound((int) binArray.getVal(9)); subarea.setSpare((int) binArray.getVal(0)); break; case 3: subarea.setRawScaleFactor((int) binArray.getVal(2)); subarea.setRawP1Angle((int) binArray.getVal(10)); subarea.setRawP1Dist((int) binArray.getVal(10)); subarea.setRawP2Angle((int) binArray.getVal(10)); subarea.setRawP2Dist((int) binArray.getVal(10)); subarea.setRawP3Angle((int) binArray.getVal(10)); subarea.setRawP3Dist((int) binArray.getVal(10)); subarea.setRawP4Angle((int) binArray.getVal(10)); subarea.setRawP4Dist((int) binArray.getVal(10)); subarea.setSpare((int) binArray.getVal(2)); break; case 4: subarea.setRawScaleFactor((int) binArray.getVal(2)); subarea.setRawP1Angle((int) binArray.getVal(10)); subarea.setRawP1Dist((int) binArray.getVal(10)); subarea.setRawP2Angle((int) binArray.getVal(10)); subarea.setRawP2Dist((int) binArray.getVal(10)); subarea.setRawP3Angle((int) binArray.getVal(10)); subarea.setRawP3Dist((int) binArray.getVal(10)); subarea.setRawP4Angle((int) binArray.getVal(10)); subarea.setRawP4Dist((int) binArray.getVal(10)); subarea.setSpare((int) binArray.getVal(2)); break; case 5: subarea.setText((int) binArray.getVal(32)); subarea.setText1((int) binArray.getVal(32)); subarea.setText2((int) binArray.getVal(20)); break; default: // reserved break; } this.subareas.add(subarea); // addSubArea(subarea); } // TODO rest of the fields (as in RouteInformation) } public int getMsgLinkId() { return msgLinkId; } public void setMsgLinkId(int msgLinkId) { this.msgLinkId = msgLinkId; } public int getNotice() { return notice; } public void setNotice(int notice) { this.notice = notice; } public int getStartMonth() { return startMonth; } public void setStartMonth(int startMonth) { this.startMonth = startMonth; } public int getStartDay() { return startDay; } public void setStartDay(int startDay) { this.startDay = startDay; } public int getStartHour() { return startHour; } public void setStartHour(int startHour) { this.startHour = startHour; } public int getStartMin() { return startMin; } public void setStartMin(int startMin) { this.startMin = startMin; } public int getDuration() { return duration; } public void setDuration(int duration) { this.duration = duration; } public void setSubAreas(List<SubArea> subareas) { this.subareas = subareas; } public void addSubArea(SubArea subarea) { subareas.add(subarea); subareasCount = subareas.size(); } public List<SubArea> getSubAreas() { return subareas; } // TODO rest of getters and setters @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append(super.toString()); builder.append(", msgLinkId="); builder.append(msgLinkId); builder.append(", notice="); builder.append(notice); builder.append(", startDay="); builder.append(startDay); builder.append(", startHour="); builder.append(startHour); builder.append(", startMin="); builder.append(startMin); builder.append(", startMonth="); builder.append(startMonth); builder.append(", duration="); builder.append(duration); builder.append(", subareas="); builder.append(subareas); // builder.append(this.getLength()); // TODO add rest of the fields builder.append("]"); return builder.toString(); } }