001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data.vpf.io;
017:
018: import org.geotools.data.vpf.exc.VPFDataFormatException;
019:
020: /**
021: * Class TripletId.java is responsible for
022: *
023: * @author <a href="mailto:kobit@users.sourceforge.net">Artur Hefczyc</a>
024: * @author <a href="mailto:knuterik@onemap.org">Knut-Erik Johnsen</a>, Project
025: * OneMap
026: * @version 1.0.0
027: * @author <a href="mailto:jeff@ionicenterprise.com">Jeff Yutzler</a>
028: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/vpf/src/main/java/org/geotools/data/vpf/io/TripletId.java $
029: */
030: public class TripletId extends Number {
031: /**
032: * The raw data that can be decomposed into as many as three separate
033: * numbers
034: */
035: private byte[] rawData = null;
036:
037: /**
038: * Creates a new <code>TripletId</code> instance.
039: *
040: * @param data a <code>byte[]</code> value
041: */
042: public TripletId(byte[] data) {
043: rawData = data;
044: }
045:
046: /*
047: * (non-Javadoc)
048: * @see java.lang.Object#toString()
049: */
050: public String toString() {
051: String result = new String();
052:
053: try {
054: if (getIdLength() > 0) {
055: result = new Integer(getId()).toString();
056: }
057:
058: if (getTileIdLength() > 0) {
059: result = result.concat("%").concat(
060: new Integer(getTileId()).toString()).trim();
061: }
062:
063: if (getNextIdLength() > 0) {
064: result = result.concat("%").concat(
065: new Integer(getNextId()).toString()).trim();
066: }
067: } catch (RuntimeException exp) {
068: throw new VPFDataFormatException(
069: "This triplet is invalid.", exp);
070: }
071:
072: return result;
073: }
074:
075: /**
076: * Returns the length in bytes of the ID
077: *
078: * @return an <code>int</code> value
079: */
080: private int getIdLength() {
081: return (rawData[0] >> 6) & 3;
082: }
083:
084: /**
085: * Returns the length in bytes of the Tile ID
086: *
087: * @return an <code>int</code> value
088: */
089: private int getTileIdLength() {
090: return (rawData[0] >> 4) & 3;
091: }
092:
093: /**
094: * Returns the length in bytes of the Next ID
095: *
096: * @return an <code>int</code> value
097: */
098: private int getNextIdLength() {
099: return (rawData[0] >> 2) & 3;
100: }
101:
102: /**
103: * Returns the ID value
104: *
105: * @return Returns the ID, the first number of the triplet
106: */
107: public int getId() {
108: int result = 0;
109: int length = getIdLength();
110: int piece;
111:
112: if (length > 0) {
113: try {
114: for (int inx = 0; inx < length; inx++) {
115: piece = rawData[inx + 1];
116:
117: // Convert bytes from signed to unsigned
118: if (piece < 0) {
119: piece += (-2 * (Byte.MIN_VALUE));
120: }
121:
122: result += (piece << (8 * inx));
123: }
124: } catch (RuntimeException exp) {
125: exp.printStackTrace();
126: result = 0;
127: }
128: }
129:
130: return result;
131: }
132:
133: /**
134: * Returns the Tile ID
135: * @return Returns the Tile ID, the second number of the triplet
136: */
137: public int getTileId() {
138: int result = 0;
139: int length = getTileIdLength();
140: int piece;
141:
142: if (length > 0) {
143: int rowIdLength = getIdLength();
144:
145: try {
146: for (int inx = 0; inx < length; inx++) {
147: piece = rawData[inx + rowIdLength + 1];
148:
149: if (piece < 0) {
150: piece += (2 * Byte.MAX_VALUE);
151: }
152:
153: result += (piece << (8 * inx));
154: }
155: } catch (RuntimeException exp) {
156: exp.printStackTrace();
157: result = 0;
158: }
159: }
160:
161: return result;
162: }
163:
164: /**
165: * Returns the Next ID
166: * @return Returns the Next ID, the third number of the triplet
167: */
168: public int getNextId() {
169: int result = 0;
170: int length = getTileIdLength();
171: int piece;
172:
173: if (length > 0) {
174: int prevLength = getIdLength() + getTileIdLength();
175:
176: try {
177: for (int inx = 0; inx < length; inx++) {
178: piece = rawData[inx + prevLength + 1];
179:
180: if (piece < 0) {
181: piece += (2 * Byte.MAX_VALUE);
182: }
183:
184: result += (piece << (8 * inx));
185: }
186: } catch (RuntimeException exp) {
187: exp.printStackTrace();
188: result = 0;
189: }
190: }
191:
192: return result;
193: }
194:
195: /**
196: * Describe <code>calculateDataSize</code> method here.
197: *
198: * @param definition a <code>byte</code> value indicating the details of the bytes
199: *
200: * @return an <code>int</code> value
201: */
202: public static int calculateDataSize(byte definition) {
203: int[] pieces = new int[3];
204: pieces[0] = (definition >> 2) & 3;
205: pieces[1] = (definition >> 4) & 3;
206: pieces[2] = (definition >> 6) & 3;
207:
208: int size = 0;
209:
210: for (int i = 0; i < pieces.length; i++) {
211: switch (pieces[i]) {
212: case 0:
213: break;
214:
215: case 1:
216: size++;
217:
218: break;
219:
220: case 2:
221: size += 2;
222:
223: break;
224:
225: case 3:
226: size += 4;
227:
228: break;
229:
230: default:
231: System.out.println("Tripled id size decoding error");
232: System.out.println("tripled definition: " + definition);
233: System.out.println("piece 0: " + pieces[0]);
234: System.out.println("piece 1: " + pieces[1]);
235: System.out.println("piece 2: " + pieces[2]);
236:
237: break;
238: }
239: }
240:
241: return size;
242: }
243:
244: /* (non-Javadoc)
245: * @see java.lang.Number#doubleValue()
246: */
247: public double doubleValue() {
248: return new Integer(getId()).doubleValue();
249: }
250:
251: /* (non-Javadoc)
252: * @see java.lang.Number#floatValue()
253: */
254: public float floatValue() {
255: return new Integer(getId()).floatValue();
256: }
257:
258: /* (non-Javadoc)
259: * @see java.lang.Number#intValue()
260: */
261: public int intValue() {
262: return getId();
263: }
264:
265: /* (non-Javadoc)
266: * @see java.lang.Number#longValue()
267: */
268: public long longValue() {
269: return new Integer(getId()).longValue();
270: }
271:
272: /* (non-Javadoc)
273: * @see java.lang.Number#byteValue()
274: */
275: public byte byteValue() {
276: return new Integer(getId()).byteValue();
277: }
278:
279: /* (non-Javadoc)
280: * @see java.lang.Number#shortValue()
281: */
282: public short shortValue() {
283: return new Integer(getId()).shortValue();
284: }
285: }
|