/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2003-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.data.oracle.sdo;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Collections;
import java.util.List;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateList;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
import com.vividsolutions.jts.geom.PrecisionModel;
/**
* HelperClass for dealing with JTS14 CoordianteSequences.
*
* <p>
* JTS14 does not supply suffiecnt API to allow the modification of
* CoordinateSequence in a lossless manner. To make full use of this class
* your CoordianteSequence will need to support the additional methods
* outlined in CoordinateAccess.
* </p>
*
* @author bowens , Refractions Research, Inc.
* @author $Author: jgarnett $ (last modification)
* @source $URL$
* @version $Id$
*/
public class Coordinates {
private Coordinates() {
// utility class do not inaniate
}
/**
* Sublist opperation for CoordinateSequence.
*
* <p>
* Opperates in the same manner as corrasponding java util List method.
* </p>
*
* @param factory factory used to manage sequence
* @param sequence coordinate sequence
* @param fromIndex - low endpoint (inclusive) of the subList.
* @param toIndex - high endpoint (exclusive) of the subList.
*
* @return sublist of sequence (start,end] as provided by factory
*/
public static CoordinateSequence subList(
CoordinateSequenceFactory factory, CoordinateSequence sequence,
int fromIndex, int toIndex) {
if ((fromIndex == 0) && (toIndex == sequence.size())) {
return sequence; // same list so just return it
}
if (sequence instanceof List) {
List sublist = ((List) sequence).subList(fromIndex, toIndex);
if (sublist instanceof CoordinateSequence) {
return (CoordinateSequence) sublist;
}
}
if (sequence instanceof CoordinateAccess) {
CoordinateAccess access = (CoordinateAccess) sequence;
double[][] coordArray = access.toOrdinateArrays();
Object[] attributeArray = access.toAttributeArrays();
double[][] subCoordArray = new double[access.getDimension()][];
Object[][] subAttributeArray = new Object[access.getNumAttributes()][];
// System.out.println("Dimension = " + access.getDimension());
// System.out.println("coordArray.length = " + coordArray.length);
// System.out.println("fromIndex= " + fromIndex + ", toIndex= " + toIndex);
// System.out.println("coordArray: ");
// System.out.print("X ");
// for (int p=0; p<coordArray[0].length; p++)
// System.out.print(coordArray[0][p] + " ");
// System.out.print("\nY ");
// for (int p=0; p<coordArray[1].length; p++)
// System.out.print(coordArray[1][p] + " ");
// System.out.println("");
//
// System.out.println("Num attributes = " + access.getNumAttributes());
// System.out.println("attributeArray.length = " + attributeArray.length);
// System.out.println("attributeArray: ");
// System.out.print("Z ");
// for (int p=0; p<attributeArray[0].length; p++)
// System.out.print(attributeArray[0][p] + " ");
// System.out.print("\nT ");
// for (int p=0; p<attributeArray[1].length; p++)
// System.out.print(attributeArray[1][p] + " ");
// System.out.println("");
// try
// {
for (int i = 0; i < access.getDimension(); i++) {
subCoordArray[i] = new OrdinateList(coordArray[i], 0, 1,
fromIndex, toIndex).toDoubleArray();
}
// }
// catch (ArrayIndexOutOfBoundsException e)
// {
// e.printStackTrace();
// System.out.println("Dimension = " + access.getDimension());
// System.out.println("coordArray.length = " + coordArray.length);
// System.out.println("fromIndex= " + fromIndex + ", toIndex= " + toIndex);
// System.out.println("coordArray: ");
// System.out.print("X ");
// for (int p=0; p<coordArray[0].length; p++)
// System.out.print(coordArray[0][p] + " ");
// System.out.print("\nY ");
// for (int p=0; p<coordArray[1].length; p++)
// System.out.print(coordArray[1][p] + " ");
// System.out.println("");
// }
for (int i = 0; i < access.getNumAttributes(); i++) {
subAttributeArray[i] = new AttributeList(attributeArray[i], 0,
1, fromIndex, toIndex).toObjectArray();
}
System.out.println("subCoordArray.length = " + subCoordArray.length);
System.out.println("subCoordArray: ");
System.out.print("X ");
for (int p = 0; p < subCoordArray[0].length; p++)
System.out.print(subCoordArray[0][p] + " ");
System.out.print("\nY ");
for (int p = 0; p < subCoordArray[1].length; p++)
System.out.print(subCoordArray[1][p] + " ");
System.out.println("");
System.out.println("subAttributeArray.length = "
+ subAttributeArray.length);
System.out.println("subAttributeArray: ");
System.out.print("Z ");
for (int p = 0; p < subAttributeArray[0].length; p++)
System.out.print(subAttributeArray[0][p] + " ");
System.out.print("\nT ");
for (int p = 0; p < subAttributeArray[1].length; p++)
System.out.print(subAttributeArray[1][p] + " ");
System.out.println("");
CoordinateAccess c = (CoordinateAccess) ((CoordinateAccessFactory) factory)
.create(subCoordArray, subAttributeArray);
return c;
}
Coordinate[] array = new Coordinate[toIndex - fromIndex];
int index = 0;
for(int i = fromIndex; i < toIndex; i++, index++) {
array[index] = sequence.getCoordinate(i);
}
return factory.create(array);
}
/**
* DOCUMENT ME!
*
* @param factory
* @param sequence
*
*/
public static CoordinateSequence reverse(
CoordinateSequenceFactory factory, CoordinateSequence sequence) {
if (sequence instanceof CoordinateAccess) {
CoordinateAccess access = (CoordinateAccess) sequence;
double[][] coordArray = access.toOrdinateArrays();
Object[] attributeArray = access.toAttributeArrays();
double[][] subCoordArray = new double[access.getDimension()][];
Object[][] subAttributeArray = new Object[access.getNumAttributes()][];
for (int i = 0; i < access.getDimension(); i++) {
subCoordArray[i] = new OrdinateList(coordArray[i], 0, 1,
access.size() - 1, -1).toDoubleArray();
}
for (int i = 0; i < access.getNumAttributes(); i++) {
subAttributeArray[i] = new AttributeList(attributeArray[i], 0,
1, access.size() - 1, -1).toObjectArray();
}
CoordinateAccess c = (CoordinateAccess) ((CoordinateAccessFactory) factory)
.create(subCoordArray, subAttributeArray);
return c;
} else // else CoordinateSequence
{
CoordinateList list = new CoordinateList(sequence.toCoordinateArray());
Collections.reverse(list);
return factory.create(list.toCoordinateArray());
}
}
public static String toString(CoordinateSequence cs, int coordinate,
NumberFormat nf) {
StringBuffer buf = new StringBuffer();
append(buf, cs, coordinate, nf);
return buf.toString();
}
public static void append(StringBuffer buf, CoordinateSequence cs,
int coordinate, NumberFormat nf) {
if (cs instanceof CoordinateAccess) {
CoordinateAccess ca = (CoordinateAccess) cs;
append(buf, ca, coordinate, LEN(ca), nf);
} else {
append(buf, cs, coordinate, LEN(cs), nf);
}
}
public static void append(StringBuffer buf, CoordinateSequence cs,
int coordinate, int LEN, NumberFormat nf) {
Coordinate c = cs.getCoordinate(coordinate);
buf.append(nf.format(c.x));
buf.append(" ");
buf.append(nf.format(c.y));
if (LEN == 3) {
buf.append(" ");
buf.append(nf.format(c.z));
}
}
public static void append(StringBuffer buf, CoordinateAccess ca,
int coordinate, int LEN, NumberFormat nf) {
buf.append(nf.format(ca.getOrdinate(coordinate, 0)));
for (int i = 1; i < LEN; i++) {
buf.append(" ");
buf.append(nf.format(ca.getOrdinate(coordinate, i)));
}
}
public static int LEN(CoordinateSequence cs) {
return D(cs) + L(cs);
}
public static int D(CoordinateSequence cs) {
if (cs instanceof CoordinateAccess) {
return ((CoordinateAccess) cs).getDimension();
}
if (cs.size() > 0) {
return Double.isNaN(cs.getCoordinate(0).z) ? 2 : 3;
}
return 3;
}
public static int L(CoordinateSequence cs) {
if (cs instanceof CoordinateAccess) {
return ((CoordinateAccess) cs).getNumAttributes();
}
return 0;
}
public static NumberFormat format(PrecisionModel pm) {
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setNaN("NaN");
DecimalFormat f = new DecimalFormat();
f.setDecimalFormatSymbols(symbols);
if (pm == null) {
f.setMaximumFractionDigits(0);
return f;
}
f.setMinimumFractionDigits(0);
f.setMaximumFractionDigits(pm.getMaximumSignificantDigits());
return f;
}
public static String toString(CoordinateSequence cs, PrecisionModel pm) {
StringBuffer buf = new StringBuffer();
append(buf, cs, format(pm));
return buf.toString();
}
public static void append(StringBuffer buf, CoordinateSequence cs,
NumberFormat nf) {
if (cs instanceof CoordinateAccess) {
append(buf, (CoordinateAccess) cs, nf);
} else {
int LEN = LEN(cs); // 2 or 3
if (cs.size() == 0) {
return;
}
append(buf, cs, 0, LEN, nf);
if (cs.size() == 1) {
return;
}
for (int i = 1; i < cs.size(); i++) {
buf.append(", ");
append(buf, cs, i, LEN, nf);
}
}
}
public static void append(StringBuffer buf, CoordinateAccess ca,
NumberFormat nf) {
int LEN = LEN(ca);
if (ca.size() == 0) {
return;
}
append(buf, ca, 0, LEN, nf);
if (ca.size() == 1) {
return;
}
for (int i = 1; i < ca.size(); i++) {
buf.append(", ");
append(buf, ca, i, LEN, nf);
}
}
}