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.oracle.sdo;
017:
018: import java.text.DecimalFormat;
019: import java.text.DecimalFormatSymbols;
020: import java.text.NumberFormat;
021: import java.util.Collections;
022: import java.util.Iterator;
023: import java.util.List;
024:
025: import com.vividsolutions.jts.geom.Coordinate;
026: import com.vividsolutions.jts.geom.CoordinateList;
027: import com.vividsolutions.jts.geom.CoordinateSequence;
028: import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
029: import com.vividsolutions.jts.geom.PrecisionModel;
030:
031: /**
032: * HelperClass for dealing with JTS14 CoordianteSequences.
033: *
034: * <p>
035: * JTS14 does not supply suffiecnt API to allow the modification of
036: * CoordinateSequence in a lossless manner. To make full use of this class
037: * your CoordianteSequence will need to support the additional methods
038: * outlined in CoordinateAccess.
039: * </p>
040: *
041: * @author bowens , Refractions Research, Inc.
042: * @author $Author: jgarnett $ (last modification)
043: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/oracle-spatial/src/main/java/org/geotools/data/oracle/sdo/Coordinates.java $
044: * @version $Id: Coordinates.java 23604 2006-12-27 09:53:19Z aaime $
045: */
046: public class Coordinates {
047: private Coordinates() {
048: // utility class do not inaniate
049: }
050:
051: /**
052: * Sublist opperation for CoordinateSequence.
053: *
054: * <p>
055: * Opperates in the same manner as corrasponding java util List method.
056: * </p>
057: *
058: * @param factory factory used to manage sequence
059: * @param sequence coordinate sequence
060: * @param fromIndex - low endpoint (inclusive) of the subList.
061: * @param toIndex - high endpoint (exclusive) of the subList.
062: *
063: * @return sublist of sequence (start,end] as provided by factory
064: */
065: public static CoordinateSequence subList(
066: CoordinateSequenceFactory factory,
067: CoordinateSequence sequence, int fromIndex, int toIndex) {
068: if ((fromIndex == 0) && (toIndex == sequence.size())) {
069: return sequence; // same list so just return it
070: }
071:
072: if (sequence instanceof List) {
073: List sublist = ((List) sequence)
074: .subList(fromIndex, toIndex);
075:
076: if (sublist instanceof CoordinateSequence) {
077: return (CoordinateSequence) sublist;
078: }
079: }
080:
081: if (sequence instanceof CoordinateAccess) {
082: CoordinateAccess access = (CoordinateAccess) sequence;
083: double[][] coordArray = access.toOrdinateArrays();
084: Object[] attributeArray = access.toAttributeArrays();
085:
086: double[][] subCoordArray = new double[access.getDimension()][];
087: Object[][] subAttributeArray = new Object[access
088: .getNumAttributes()][];
089:
090: // System.out.println("Dimension = " + access.getDimension());
091: // System.out.println("coordArray.length = " + coordArray.length);
092: // System.out.println("fromIndex= " + fromIndex + ", toIndex= " + toIndex);
093: // System.out.println("coordArray: ");
094: // System.out.print("X ");
095: // for (int p=0; p<coordArray[0].length; p++)
096: // System.out.print(coordArray[0][p] + " ");
097: // System.out.print("\nY ");
098: // for (int p=0; p<coordArray[1].length; p++)
099: // System.out.print(coordArray[1][p] + " ");
100: // System.out.println("");
101: //
102: // System.out.println("Num attributes = " + access.getNumAttributes());
103: // System.out.println("attributeArray.length = " + attributeArray.length);
104: // System.out.println("attributeArray: ");
105: // System.out.print("Z ");
106: // for (int p=0; p<attributeArray[0].length; p++)
107: // System.out.print(attributeArray[0][p] + " ");
108: // System.out.print("\nT ");
109: // for (int p=0; p<attributeArray[1].length; p++)
110: // System.out.print(attributeArray[1][p] + " ");
111: // System.out.println("");
112: // try
113: // {
114: for (int i = 0; i < access.getDimension(); i++) {
115: subCoordArray[i] = new OrdinateList(coordArray[i], 0,
116: 1, fromIndex, toIndex).toDoubleArray();
117: }
118:
119: // }
120: // catch (ArrayIndexOutOfBoundsException e)
121: // {
122: // e.printStackTrace();
123: // System.out.println("Dimension = " + access.getDimension());
124: // System.out.println("coordArray.length = " + coordArray.length);
125: // System.out.println("fromIndex= " + fromIndex + ", toIndex= " + toIndex);
126: // System.out.println("coordArray: ");
127: // System.out.print("X ");
128: // for (int p=0; p<coordArray[0].length; p++)
129: // System.out.print(coordArray[0][p] + " ");
130: // System.out.print("\nY ");
131: // for (int p=0; p<coordArray[1].length; p++)
132: // System.out.print(coordArray[1][p] + " ");
133: // System.out.println("");
134: // }
135: for (int i = 0; i < access.getNumAttributes(); i++) {
136: subAttributeArray[i] = new AttributeList(
137: attributeArray[i], 0, 1, fromIndex, toIndex)
138: .toObjectArray();
139: }
140:
141: System.out.println("subCoordArray.length = "
142: + subCoordArray.length);
143: System.out.println("subCoordArray: ");
144: System.out.print("X ");
145:
146: for (int p = 0; p < subCoordArray[0].length; p++)
147: System.out.print(subCoordArray[0][p] + " ");
148:
149: System.out.print("\nY ");
150:
151: for (int p = 0; p < subCoordArray[1].length; p++)
152: System.out.print(subCoordArray[1][p] + " ");
153:
154: System.out.println("");
155:
156: System.out.println("subAttributeArray.length = "
157: + subAttributeArray.length);
158: System.out.println("subAttributeArray: ");
159: System.out.print("Z ");
160:
161: for (int p = 0; p < subAttributeArray[0].length; p++)
162: System.out.print(subAttributeArray[0][p] + " ");
163:
164: System.out.print("\nT ");
165:
166: for (int p = 0; p < subAttributeArray[1].length; p++)
167: System.out.print(subAttributeArray[1][p] + " ");
168:
169: System.out.println("");
170:
171: CoordinateAccess c = (CoordinateAccess) ((CoordinateAccessFactory) factory)
172: .create(subCoordArray, subAttributeArray);
173:
174: return c;
175: }
176:
177: Coordinate[] array = new Coordinate[toIndex - fromIndex];
178: int index = 0;
179: for (int i = fromIndex; i < toIndex; i++, index++) {
180: array[index] = sequence.getCoordinate(i);
181: }
182:
183: return factory.create(array);
184: }
185:
186: /**
187: * DOCUMENT ME!
188: *
189: * @param factory
190: * @param sequence
191: *
192: */
193: public static CoordinateSequence reverse(
194: CoordinateSequenceFactory factory,
195: CoordinateSequence sequence) {
196: if (sequence instanceof CoordinateAccess) {
197: CoordinateAccess access = (CoordinateAccess) sequence;
198: double[][] coordArray = access.toOrdinateArrays();
199: Object[] attributeArray = access.toAttributeArrays();
200:
201: double[][] subCoordArray = new double[access.getDimension()][];
202: Object[][] subAttributeArray = new Object[access
203: .getNumAttributes()][];
204:
205: for (int i = 0; i < access.getDimension(); i++) {
206: subCoordArray[i] = new OrdinateList(coordArray[i], 0,
207: 1, access.size() - 1, -1).toDoubleArray();
208: }
209:
210: for (int i = 0; i < access.getNumAttributes(); i++) {
211: subAttributeArray[i] = new AttributeList(
212: attributeArray[i], 0, 1, access.size() - 1, -1)
213: .toObjectArray();
214: }
215:
216: CoordinateAccess c = (CoordinateAccess) ((CoordinateAccessFactory) factory)
217: .create(subCoordArray, subAttributeArray);
218:
219: return c;
220: } else // else CoordinateSequence
221: {
222: CoordinateList list = new CoordinateList(sequence
223: .toCoordinateArray());
224: Collections.reverse(list);
225:
226: return factory.create(list.toCoordinateArray());
227: }
228: }
229:
230: public static String toString(CoordinateSequence cs,
231: int coordinate, NumberFormat nf) {
232: StringBuffer buf = new StringBuffer();
233: append(buf, cs, coordinate, nf);
234:
235: return buf.toString();
236: }
237:
238: public static void append(StringBuffer buf, CoordinateSequence cs,
239: int coordinate, NumberFormat nf) {
240: if (cs instanceof CoordinateAccess) {
241: CoordinateAccess ca = (CoordinateAccess) cs;
242: append(buf, ca, coordinate, LEN(ca), nf);
243: } else {
244: append(buf, cs, coordinate, LEN(cs), nf);
245: }
246: }
247:
248: public static void append(StringBuffer buf, CoordinateSequence cs,
249: int coordinate, int LEN, NumberFormat nf) {
250: Coordinate c = cs.getCoordinate(coordinate);
251: buf.append(nf.format(c.x));
252: buf.append(" ");
253: buf.append(nf.format(c.y));
254:
255: if (LEN == 3) {
256: buf.append(" ");
257: buf.append(nf.format(c.z));
258: }
259: }
260:
261: public static void append(StringBuffer buf, CoordinateAccess ca,
262: int coordinate, int LEN, NumberFormat nf) {
263: buf.append(nf.format(ca.getOrdinate(coordinate, 0)));
264:
265: for (int i = 1; i < LEN; i++) {
266: buf.append(" ");
267: buf.append(nf.format(ca.getOrdinate(coordinate, i)));
268: }
269: }
270:
271: public static int LEN(CoordinateSequence cs) {
272: return D(cs) + L(cs);
273: }
274:
275: public static int D(CoordinateSequence cs) {
276: if (cs instanceof CoordinateAccess) {
277: return ((CoordinateAccess) cs).getDimension();
278: }
279:
280: if (cs.size() > 0) {
281: return Double.isNaN(cs.getCoordinate(0).z) ? 2 : 3;
282: }
283:
284: return 3;
285: }
286:
287: public static int L(CoordinateSequence cs) {
288: if (cs instanceof CoordinateAccess) {
289: return ((CoordinateAccess) cs).getNumAttributes();
290: }
291:
292: return 0;
293: }
294:
295: public static NumberFormat format(PrecisionModel pm) {
296: DecimalFormatSymbols symbols = new DecimalFormatSymbols();
297: symbols.setNaN("NaN");
298:
299: DecimalFormat f = new DecimalFormat();
300: f.setDecimalFormatSymbols(symbols);
301:
302: if (pm == null) {
303: f.setMaximumFractionDigits(0);
304:
305: return f;
306: }
307:
308: f.setMinimumFractionDigits(0);
309: f.setMaximumFractionDigits(pm.getMaximumSignificantDigits());
310:
311: return f;
312: }
313:
314: public static String toString(CoordinateSequence cs,
315: PrecisionModel pm) {
316: StringBuffer buf = new StringBuffer();
317: append(buf, cs, format(pm));
318:
319: return buf.toString();
320: }
321:
322: public static void append(StringBuffer buf, CoordinateSequence cs,
323: NumberFormat nf) {
324: if (cs instanceof CoordinateAccess) {
325: append(buf, (CoordinateAccess) cs, nf);
326: } else {
327: int LEN = LEN(cs); // 2 or 3
328:
329: if (cs.size() == 0) {
330: return;
331: }
332:
333: append(buf, cs, 0, LEN, nf);
334:
335: if (cs.size() == 1) {
336: return;
337: }
338:
339: for (int i = 1; i < cs.size(); i++) {
340: buf.append(", ");
341: append(buf, cs, i, LEN, nf);
342: }
343: }
344: }
345:
346: public static void append(StringBuffer buf, CoordinateAccess ca,
347: NumberFormat nf) {
348: int LEN = LEN(ca);
349:
350: if (ca.size() == 0) {
351: return;
352: }
353:
354: append(buf, ca, 0, LEN, nf);
355:
356: if (ca.size() == 1) {
357: return;
358: }
359:
360: for (int i = 1; i < ca.size(); i++) {
361: buf.append(", ");
362: append(buf, ca, i, LEN, nf);
363: }
364: }
365: }
|