001: /*
002: * The JTS Topology Suite is a collection of Java classes that
003: * implement the fundamental operations required to validate a given
004: * geo-spatial data set to a known topological specification.
005: *
006: * Copyright (C) 2001 Vivid Solutions
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public
010: * License as published by the Free Software Foundation; either
011: * version 2.1 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public
019: * License along with this library; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021: *
022: * For more information, contact:
023: *
024: * Vivid Solutions
025: * Suite #1A
026: * 2328 Government Street
027: * Victoria BC V8T 5G5
028: * Canada
029: *
030: * (250)385-6040
031: * www.vividsolutions.com
032: */
033: package com.vividsolutions.jts.generator;
034:
035: import java.util.NoSuchElementException;
036:
037: import com.vividsolutions.jts.geom.Envelope;
038: import com.vividsolutions.jts.geom.Geometry;
039:
040: /**
041: * This class should be used to generate a grid of bounding boxes,
042: * most useful when creating multiple geometries.
043: *
044: * Successive calls to create() will walk the user though the grid.
045: * Use canCreate() and reset() to control the walk through the grid.
046: *
047: * @see #canCreate()
048: * @see #reset()
049: *
050: * @author David Zwiers, Vivid Solutions.
051: */
052: public class GridGenerator extends GeometryGenerator {
053:
054: protected int numberColumns = 1;
055: protected int numberRows = 1;
056: protected int index = 0;
057:
058: /**
059: * Sets some default values.
060: */
061: public GridGenerator() {
062: dimensions = 2;
063: }
064:
065: /**
066: *
067: * @see com.vividsolutions.jts.generator.GeometryGenerator#create()
068: *
069: * @throws NoSuchElementException when all the grids have been created (@see #create())
070: * @throws NullPointerException when either the Geometry Factory, or the Bounding Box are undefined.
071: */
072: public Geometry create() {
073: return geometryFactory.toGeometry(createEnv());
074: }
075:
076: /**
077: *
078: * @return Envelope
079: *
080: * @see com.vividsolutions.jts.generator.GeometryGenerator#create()
081: *
082: * @throws NoSuchElementException when all the grids have been created (@see #create())
083: * @throws NullPointerException when either the Geometry Factory, or the Bounding Box are undefined.
084: */
085: public Envelope createEnv() {
086: if (!canCreate()) {
087: throw new NoSuchElementException(
088: "There are not any grids left to create.");
089: }
090: if (geometryFactory == null) {
091: throw new NullPointerException(
092: "GeometryFactory is not declared");
093: }
094: if (boundingBox == null || boundingBox.isNull()) {
095: throw new NullPointerException(
096: "Bounding Box is not declared");
097: }
098:
099: double x = boundingBox.getMinX(); // base x
100: double dx = boundingBox.getMaxX() - x;
101:
102: double y = boundingBox.getMinY(); // base y
103: double dy = boundingBox.getMaxY() - y;
104:
105: int row = numberRows == 1 ? 0 : index / numberRows;
106: int col = numberColumns == 1 ? 0 : index % numberColumns;
107:
108: double sx, sy; // size of a step
109: sx = dx / numberColumns;
110: sy = dy / numberRows;
111:
112: double minx, miny;
113: minx = x + col * sx;
114: miny = y + row * sy;
115:
116: Envelope box = new Envelope(geometryFactory.getPrecisionModel()
117: .makePrecise(minx), geometryFactory.getPrecisionModel()
118: .makePrecise(minx + sx), geometryFactory
119: .getPrecisionModel().makePrecise(miny), geometryFactory
120: .getPrecisionModel().makePrecise(miny + sy));
121:
122: index++;
123: return box;
124: }
125:
126: /**
127: * @return true when more grids exist
128: */
129: public boolean canCreate() {
130: return (numberColumns * numberRows) > index;
131: }
132:
133: /**
134: * Resets the grid counter
135: */
136: public void reset() {
137: index = 0;
138: }
139:
140: /**
141: * @see com.vividsolutions.jts.generator.GeometryGenerator#setDimensions(int)
142: */
143: public void setDimensions(int dimensions) {
144: if (dimensions != 2)
145: throw new IllegalStateException(
146: "MAY NOT CHANGE GridGenerator's Dimensions");
147: }
148:
149: /**
150: * @return Returns the numberColumns.
151: */
152: public int getNumberColumns() {
153: return numberColumns;
154: }
155:
156: /**
157: * @param numberColumns The numberColumns to set.
158: */
159: public void setNumberColumns(int numberColumns) {
160: if (numberColumns <= 0)
161: throw new IndexOutOfBoundsException(
162: "Index sizes must be positive, non zero");
163: this .numberColumns = numberColumns;
164: }
165:
166: /**
167: * @return Returns the numberRows.
168: */
169: public int getNumberRows() {
170: return numberRows;
171: }
172:
173: /**
174: * @param numberRows The numberRows to set.
175: */
176: public void setNumberRows(int numberRows) {
177: if (numberRows <= 0)
178: throw new IndexOutOfBoundsException(
179: "Index sizes must be positive, non zero");
180: this.numberRows = numberRows;
181: }
182:
183: }
|