001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-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;
009: * version 2.1 of the License.
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.geometry.jts;
017:
018: import com.vividsolutions.jts.geom.Coordinate;
019: import com.vividsolutions.jts.geom.Envelope;
020: import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence;
021:
022: /**
023: * @TODO class description
024: *
025: * @author jeichar
026: * @since 2.1.x
027: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/geometry/jts/LiteCoordinateSequence.java $
028: */
029: public class LiteCoordinateSequence extends PackedCoordinateSequence {
030:
031: /**
032: * The packed coordinate array
033: */
034: private double[] coords;
035:
036: /**
037: * Cached size, getSize() gets called an incredible number of times during rendering
038: * (a profile shows 2 million calls when rendering 90.000 linear features)
039: */
040: private int size;
041:
042: /**
043: * Builds a new packed coordinate sequence
044: *
045: * @param coords
046: *
047: */
048: public LiteCoordinateSequence(double[] coords) {
049: this .dimension = 2;
050: if (coords.length % dimension != 0) {
051: throw new IllegalArgumentException(
052: "Packed array does not contain "
053: + "an integral number of coordinates");
054: }
055: this .coords = coords;
056: this .size = coords.length / dimension;
057: }
058:
059: /**
060: * Builds a new packed coordinate sequence out of a float coordinate array
061: *
062: * @param coordinates
063: */
064: public LiteCoordinateSequence(float[] coordinates) {
065: this .coords = new double[coordinates.length];
066: this .dimension = 2;
067: this .size = coords.length / dimension;
068: for (int i = 0; i < coordinates.length; i++) {
069: this .coords[i] = coordinates[i];
070: }
071: }
072:
073: /**
074: * Builds a new packed coordinate sequence out of a coordinate array
075: *
076: * @param coordinates
077: */
078: public LiteCoordinateSequence(Coordinate[] coordinates) {
079: if (coordinates == null)
080: coordinates = new Coordinate[0];
081: this .dimension = 2;
082:
083: coords = new double[coordinates.length * this .dimension];
084: for (int i = 0; i < coordinates.length; i++) {
085: coords[i * this .dimension] = coordinates[i].x;
086: if (this .dimension >= 2)
087: coords[i * this .dimension + 1] = coordinates[i].y;
088: }
089: this .size = coordinates.length;
090: }
091:
092: /**
093: * Builds a new empty packed coordinate sequence of a given size and dimension
094: *
095: * @param size
096: * @param dimension
097: *
098: */
099: public LiteCoordinateSequence(int size, int dimension) {
100: if (dimension != 2)
101: throw new IllegalArgumentException(
102: "This type of sequence is always 2 dimensional");
103: this .dimension = 2;
104: coords = new double[size * this .dimension];
105: this .size = coords.length / dimension;
106:
107: }
108:
109: /**
110: * Copy constructor
111: * @param seq
112: */
113: public LiteCoordinateSequence(LiteCoordinateSequence seq) {
114: // a trivial benchmark can show that cloning arrays like this is actually faster
115: // than calling clone on the array.
116: this .dimension = seq.dimension;
117: this .size = seq.size;
118: double[] orig = seq.getArray();
119: this .coords = new double[orig.length];
120: System.arraycopy(orig, 0, coords, 0, coords.length);
121:
122: }
123:
124: /**
125: * @see com.vividsolutions.jts.geom.CoordinateSequence#getCoordinate(int)
126: */
127: public Coordinate getCoordinateInternal(int i) {
128: double x = coords[i * dimension];
129: double y = coords[i * dimension + 1];
130: double z = dimension == 2 ? java.lang.Double.NaN : coords[i
131: * dimension + 2];
132: return new Coordinate(x, y, z);
133: }
134:
135: /**
136: * @see com.vividsolutions.jts.geom.CoordinateSequence#size()
137: */
138: public int size() {
139: return size;
140: }
141:
142: /**
143: * @see java.lang.Object#clone()
144: */
145: public Object clone() {
146: double[] clone = new double[coords.length];
147: System.arraycopy(coords, 0, clone, 0, coords.length);
148: return new LiteCoordinateSequence(clone);
149: }
150:
151: /**
152: * @see com.vividsolutions.jts.geom.CoordinateSequence#getOrdinate(int, int)
153: * Beware, for performace reasons the ordinate index is not checked, if
154: * it's over dimensions you may not get an exception but a meaningless
155: * value.
156: */
157: public double getOrdinate(int index, int ordinate) {
158: return coords[index * dimension + ordinate];
159: }
160:
161: /**
162: * @see com.vividsolutions.jts.geom.CoordinateSequence#getX(int)
163: */
164: public double getX(int index) {
165: return coords[index * dimension];
166: }
167:
168: /**
169: * @see com.vividsolutions.jts.geom.CoordinateSequence#getY(int)
170: */
171: public double getY(int index) {
172: return coords[index * dimension + 1];
173: }
174:
175: /**
176: * @see com.vividsolutions.jts.geom.PackedCoordinateSequence#setOrdinate(int,
177: * int, double)
178: */
179: public void setOrdinate(int index, int ordinate, double value) {
180: coordRef = null;
181: coords[index * dimension + ordinate] = value;
182: }
183:
184: public Envelope expandEnvelope(Envelope env) {
185: for (int i = 0; i < coords.length; i += dimension) {
186: env.expandToInclude(coords[i], coords[i + 1]);
187: }
188: return env;
189: }
190:
191: /**
192: */
193: public double[] getArray() {
194: return coords;
195: }
196:
197: /**
198: * @param coords2
199: */
200: public void setArray(double[] coords2) {
201: coords = coords2;
202: size = coords.length / dimension;
203: coordRef = null;
204: }
205:
206: /**
207: * if this is a dimension=2 seq, then this is the same as getArray().
208: * If its >2 dims this will make a new array with dim=2
209: */
210: public double[] getXYArray() {
211: if (dimension == 2) //this is always true
212: return coords;
213: // this should never run, but its here for the future...
214: int n = size();
215: double[] result = new double[n * 2];
216: for (int t = 0; t < n; t++) {
217: result[t * 2] = getOrdinate(t, 0);
218: result[t * 2 + 1] = getOrdinate(t, 1);
219: }
220: return result;
221: }
222:
223: }
|