Revision 41275

View differences:

tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/fromjts/FromJTS.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.geom.operation.fromjts;
25

  
26
import org.gvsig.fmap.geom.Geometry;
27
import org.gvsig.fmap.geom.GeometryLocator;
28
import org.gvsig.fmap.geom.GeometryManager;
29
import org.gvsig.fmap.geom.exception.CreateGeometryException;
30
import org.gvsig.fmap.geom.operation.GeometryOperation;
31
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
32
import org.gvsig.fmap.geom.operation.GeometryOperationException;
33
import org.gvsig.fmap.geom.util.Converter;
34

  
35
/**
36
 * <p>
37
 * Converts a geometry from JTS to DAL format. This is a special geometry operation
38
 * because don't use the Geometry parameter and returns a JTS geometry. This kind
39
 * of operation can be called from the {@link GeometryManager} using invokeOperation.
40
 * </p>
41
 * <p>
42
 * This operation needs a JTS geometry loaded in the context. The only attribute
43
 * of the {@link GeometryOperation} have to be a geometry of this type and the ID 
44
 * of this attribute will be JTSGeometry.
45
 * </p>
46
 * 
47
 * @author Nacho Brodin (nachobrodin@gmail.com)
48
 *
49
 */
50
public class FromJTS extends GeometryOperation {
51
    public static final String NAME  = "fromJTS";
52
    public static final String PARAM = "JTSGeometry";
53
	protected static GeometryManager geomManager = GeometryLocator.getGeometryManager();
54
    public static final int CODE = geomManager.getGeometryOperationCode(NAME);	
55
	protected final static com.vividsolutions.jts.geom.GeometryFactory geomFactory = new com.vividsolutions.jts.geom.GeometryFactory();
56

  
57
	public int getOperationIndex() {
58
		return CODE;
59
	}
60
	
61
	/*
62
	 * (non-Javadoc)
63
	 * @see org.gvsig.fmap.geom.operation.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.geom.operation.GeometryOperationContext)
64
	 */
65
	public Object invoke(Geometry geom, GeometryOperationContext ctx)
66
			throws GeometryOperationException {
67
		Object obj = ctx.getAttribute("JTSGeometry");
68
		if(obj instanceof com.vividsolutions.jts.geom.Geometry) {
69
			try {
70
				return Converter.jtsToGeometry((com.vividsolutions.jts.geom.Geometry)obj);
71
			} catch (CreateGeometryException e) {
72
				throw new GeometryOperationException(e); 
73
			}
74
		}
75
		return null;
76
	}
77

  
78
}
0 79

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/towkb/WKBEncodingException.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.geom.operation.towkb;
25

  
26
import java.util.HashMap;
27
import java.util.Map;
28

  
29
import org.gvsig.tools.exception.BaseException;
30

  
31
public abstract class WKBEncodingException extends BaseException {
32

  
33
	/**
34
	 *
35
	 */
36
	private static final long serialVersionUID = -7340057779411755446L;
37

  
38
	protected Map values = new HashMap();
39

  
40
	public WKBEncodingException(String messageFormat, Throwable cause,
41
			String messageKey, long code) {
42
		super(messageFormat, cause, messageKey, code);
43
	}
44

  
45
	public WKBEncodingException(String messageFormat, String messageKey, long code) {
46
		super(messageFormat, messageKey, code);
47
	}
48

  
49
	protected void setValue(String name, String value) {
50
		this.values.put(name, value);
51
	}
52

  
53
	protected Map values() {
54
		return this.values;
55
	}
56
}
0 57

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/towkb/ToWKBOperationContext.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.geom.operation.towkb;
25

  
26
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
27

  
28
/**
29
 * @author jmvivo
30
 *
31
 */
32
public class ToWKBOperationContext extends GeometryOperationContext {
33
	public static final String SRS = "srs";
34

  
35
	/**
36
	 * Set the srID to use in the WKB geometry
37
	 * 
38
	 * @param srID
39
	 */
40
	public void setSrID(int srID) {
41
		this.setAttribute(SRS, new Integer(srID));
42
	}
43

  
44
	/**
45
	 * Get the srId to use in the WKB geometry
46
	 * 
47
	 * @return
48
	 */
49
	public int getSrID() {
50
		Integer srs = (Integer) this.getAttribute(SRS);
51
		if( srs == null ) {
52
			return -1;
53
		}
54
		return srs.intValue();
55
	}
56

  
57

  
58
}
0 59

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/towkb/ToWKBNative.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.geom.operation.towkb;
25

  
26
import org.gvsig.fmap.geom.Geometry;
27
import org.gvsig.fmap.geom.GeometryLocator;
28
import org.gvsig.fmap.geom.operation.GeometryOperation;
29
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
30
import org.gvsig.fmap.geom.operation.GeometryOperationException;
31

  
32
public class ToWKBNative extends GeometryOperation {
33
    public static final String NAME = "toWKBNative";
34
	public static final int CODE = GeometryLocator.getGeometryManager().
35
    	getGeometryOperationCode(NAME);
36
	
37
	private static WKBEncoder encoder = new WKBEncoder();
38

  
39
	public Object invoke(Geometry geom, GeometryOperationContext ctx)
40
			throws GeometryOperationException {
41
		try {
42
			return encoder.encode(geom);
43
		} catch (Exception e) {
44
			throw new GeometryOperationException(e);
45
		}
46
	}
47

  
48
	public int getOperationIndex() {
49
		return CODE;
50
	}
51

  
52
}
0 53

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/towkb/WKBMultyLineInLineDefinitionException.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

  
25
package org.gvsig.fmap.geom.operation.towkb;
26

  
27
import org.gvsig.fmap.geom.Geometry;
28

  
29
public class WKBMultyLineInLineDefinitionException extends WKBEncodingException {
30

  
31
	/**
32
	 * Generated serial version UID
33
	 */
34
	private static final long serialVersionUID = -4562404266549127771L;
35

  
36
	/**
37
	 * Key to retrieve this exception's message
38
	 */
39
	private static final String MESSAGE_KEY = "wkb_move_in_middle_of_line_exception";
40
	private static final String FORMAT_STRING =
41
		"MoveTo segment in middle of a single line";
42

  
43
	/**
44
	 * Class name of the geometry type. Should never be null in this exception
45
	 */
46
	public Geometry geometry = null;
47

  
48

  
49
	public WKBMultyLineInLineDefinitionException(Geometry geom) {
50
		super(FORMAT_STRING, MESSAGE_KEY, serialVersionUID);
51
		this.geometry = geom;
52
	}
53

  
54
}
0 55

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/towkb/WKBEncoder.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

  
25
package org.gvsig.fmap.geom.operation.towkb;
26

  
27
import java.awt.geom.PathIterator;
28
import java.io.ByteArrayOutputStream;
29
import java.io.DataOutputStream;
30
import java.io.IOException;
31
import java.util.ArrayList;
32
import java.util.List;
33

  
34
import org.gvsig.fmap.geom.Geometry;
35
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
36
import org.gvsig.fmap.geom.Geometry.TYPES;
37
import org.gvsig.fmap.geom.aggregate.Aggregate;
38
import org.gvsig.fmap.geom.aggregate.MultiCurve;
39
import org.gvsig.fmap.geom.aggregate.MultiPoint;
40
import org.gvsig.fmap.geom.aggregate.MultiSurface;
41
import org.gvsig.fmap.geom.primitive.Curve;
42
import org.gvsig.fmap.geom.primitive.Point;
43
import org.gvsig.fmap.geom.primitive.Surface;
44
import org.gvsig.fmap.geom.type.GeometryType;
45
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
46

  
47

  
48

  
49
public class WKBEncoder {
50

  
51
	public interface wkbGeometryType {
52
		public final static int wkbPoint = 1;
53
		public final static int wkbLineString = 2;
54
		public final static int wkbPolygon = 3;
55
		public final static int wkbTriangle = 17;
56
		public final static int wkbMultiPoint = 4;
57
		public final static int wkbMultiLineString = 5;
58
		public final static int wkbMultiPolygon = 6;
59
		public final static int wkbGeometryCollection = 7;
60
		public final static int wkbPolyhedralSurface = 15;
61
		public final static int wkbTIN = 16;
62

  
63
		public final static int wkbPointZ = 1001;
64
		public final static int wkbLineStringZ = 1002;
65
		public final static int wkbPolygonZ = 1003;
66
		public final static int wkbTrianglez = 1017;
67
		public final static int wkbMultiPointZ = 1004;
68
		public final static int wkbMultiLineStringZ = 1005;
69
		public final static int wkbMultiPolygonZ = 1006;
70
		public final static int wkbGeometryCollectionZ = 1007;
71
		public final static int wkbPolyhedralSurfaceZ = 1015;
72
		public final static int wkbTINZ = 1016;
73

  
74
		public final static int wkbPointM = 2001;
75
		public final static int wkbLineStringM = 2002;
76
		public final static int wkbPolygonM = 2003;
77
		public final static int wkbTriangleM = 2017;
78
		public final static int wkbMultiPointM = 2004;
79
		public final static int wkbMultiLineStringM = 2005;
80
		public final static int wkbMultiPolygonM = 2006;
81
		public final static int wkbGeometryCollectionM = 2007;
82
		public final static int wkbPolyhedralSurfaceM = 2015;
83
		public final static int wkbTINM = 2016;
84

  
85
		public final static int wkbPointZM = 3001;
86
		public final static int wkbLineStringZM = 3002;
87
		public final static int wkbPolygonZM = 3003;
88
		public final static int wkbTriangleZM = 3017;
89
		public final static int wkbMultiPointZM = 3004;
90
		public final static int wkbMultiLineStringZM = 3005;
91
		public final static int wkbMultiPolygonZM = 3006;
92
		public final static int wkbGeometryCollectionZM = 3007;
93
		public final static int wkbPolyhedralSurfaceZM = 3015;
94
		public final static int wkbTinZM = 3016;
95

  
96
		public final static int wkb_baseToZ = wkbPointZ - wkbPoint;
97
		public final static int wkb_baseToM = wkbPointM - wkbPoint;
98
		public final static int wkb_baseToZM = wkbPointZM - wkbPoint;
99
	}
100

  
101
	public interface wkbByteOrder {
102
		public final static byte wkbXDR = 0;                // Big Endian
103
		public final static byte wkbNDR = 1;                // Little Endian
104
	}
105

  
106

  
107
	public byte[] encode(Geometry geometry)
108
			throws GeometryTypeNotSupportedException,
109
			WKBEncodingException,
110
			IOException {
111
		ByteArrayOutputStream stream;
112

  
113
		if (geometry.getType() == TYPES.POINT) {
114
			stream = new ByteArrayOutputStream(50);
115
		} else {
116
			stream = new ByteArrayOutputStream(512);
117
		}
118

  
119
		encode(geometry, stream);
120
		return stream.toByteArray();
121

  
122
	}
123
	public void encode(Geometry geometry, ByteArrayOutputStream stream)
124
			throws GeometryTypeNotSupportedException, WKBEncodingException,
125
			IOException {
126
		encode(geometry, new DataOutputStream(stream));
127
	}
128

  
129
	public void encode(Geometry geometry, DataOutputStream stream)
130
			throws GeometryTypeNotSupportedException,
131
			WKBEncodingException,
132
			IOException {
133
		switch (geometry.getType()) {
134
			case TYPES.POINT:
135
				encodePoint(geometry, stream);
136
				break;
137
			case TYPES.MULTIPOINT:
138
				encodeMultiPoint(geometry, stream);
139
				break;
140

  
141
			case TYPES.ARC:
142
			case TYPES.CURVE:
143
			case TYPES.CIRCLE:
144
			case TYPES.ELLIPSE:
145
			case TYPES.ELLIPTICARC:
146
				encodeLineString(geometry, stream);
147
				break;
148

  
149
			case TYPES.MULTICURVE:
150
				encodeMultiLineString(geometry, stream);
151
				break;
152

  
153
			case TYPES.SURFACE:
154
				encodePolygon(geometry, stream);
155
				break;
156

  
157
			case TYPES.MULTISURFACE:
158
				encodeMultiPolygon(geometry, stream);
159
				break;
160

  
161
			case TYPES.AGGREGATE:
162
				encodeCollection(geometry, stream);
163
				break;
164

  
165
			default:
166
				throw new GeometryTypeNotSupportedException(geometry.getType(),
167
					geometry.getGeometryType().getSubType());
168
		}
169

  
170
		// FIXME geom.subtype != SUBTYPES.GEOM2D NOT SUPPORTED !!!!
171
		if (geometry.getGeometryType().getSubType() != SUBTYPES.GEOM2D) {
172
			throw new GeometryTypeNotSupportedException(geometry.getType(),
173
					geometry.getGeometryType().getSubType());
174
		}
175
	}
176

  
177

  
178
	private void encodeCollection(Geometry geometry, DataOutputStream stream)
179
			throws GeometryTypeNotSupportedException,
180
			WKBEncodingException,
181
			IOException {
182
		GeometryType geometryType = geometry.getGeometryType();
183
		encodeWKBGeomHead(wkbGeometryType.wkbGeometryCollection, geometryType,
184
				stream);
185

  
186
		Aggregate collection = (Aggregate) geometry;
187

  
188
		int nGeometries = collection.getPrimitivesNumber();
189
		stream.writeInt(nGeometries);
190
		for (int i = 0; i < nGeometries; i++) {
191
			encode(collection.getPrimitiveAt(i), stream);
192
		}
193
	}
194

  
195
	private void encodeMultiPolygon(Geometry geometry, DataOutputStream stream)
196
			throws GeometryTypeNotSupportedException,
197
			WKBPolygonNotClosedException, IOException {
198
		GeometryType geometryType = geometry.getGeometryType();
199
		encodeWKBGeomHead(wkbGeometryType.wkbMultiPolygon, geometryType, stream);
200

  
201
		MultiSurface surfaces = (MultiSurface) geometry;
202

  
203
		int nGeometries = surfaces.getPrimitivesNumber();
204
		stream.writeInt(nGeometries);
205
		for (int i = 0; i < nGeometries; i++) {
206
			encodePolygon(surfaces.getPrimitiveAt(i), stream);
207
		}
208
	}
209

  
210
	private void checkLinearRingIsClosed(Geometry geom, List linearRing)
211
			throws WKBPolygonNotClosedException {
212
		double[] first = (double[]) linearRing.get(0);
213
		double[] last = (double[]) linearRing.get(linearRing.size() - 1);
214

  
215
		for (int i = 0; i < first.length; i++) {
216
			if (Math.abs(first[i] - last[i]) > 0.000001) {
217
				throw new WKBPolygonNotClosedException(geom);
218
			}
219
		}
220

  
221
	}
222

  
223
	private List getLinearRings(Surface surface)
224
			throws WKBPolygonNotClosedException {
225
		PathIterator theIterator = surface.getPathIterator(null);
226
		List linearRings = new ArrayList();
227
		List curlinearRing = new ArrayList();
228
		int theType;
229
		double[] theData = new double[6];
230

  
231
		while (!theIterator.isDone()) {
232
			// while not done
233
			theType = theIterator.currentSegment(theData);
234

  
235
			// Populate a segment of the new
236
			// GeneralPathX object.
237
			// Process the current segment to populate a new
238
			// segment of the new GeneralPathX object.
239
			switch (theType) {
240
			case PathIterator.SEG_MOVETO:
241
				if (curlinearRing.size() != 0) {
242
					if (curlinearRing.size() < 4) {
243
						// FIXME exception
244
						throw new WKBPolygonNotClosedException(surface);
245
					}
246
					checkLinearRingIsClosed(surface, curlinearRing);
247
					linearRings.add(curlinearRing);
248
					curlinearRing = new ArrayList();
249

  
250
				}
251
				curlinearRing.add(new double[] { theData[0], theData[1] });
252
				break;
253

  
254
			case PathIterator.SEG_LINETO:
255
				curlinearRing.add(new double[] { theData[0], theData[1] });
256
				break;
257

  
258
			case PathIterator.SEG_QUADTO:
259
				// TODO transform to linear segments
260
				throw new IllegalArgumentException("SEG_QUADTO unsupported");
261

  
262
				// shape.quadTo(theData[0], theData[1], theData[2], theData[3]);
263

  
264
				// break;
265

  
266
			case PathIterator.SEG_CUBICTO:
267
				// TODO transform to linear segments
268
				throw new IllegalArgumentException("SEG_QUADTO unsupported");
269
				// shape.curveTo(theData[0], theData[1], theData[2], theData[3],
270
				// theData[4], theData[5]);
271

  
272
				// break;
273

  
274
			case PathIterator.SEG_CLOSE:
275
				curlinearRing.add(curlinearRing.get(0));
276
				linearRings.add(curlinearRing);
277
				curlinearRing = new ArrayList();
278
				break;
279
			} // end switch
280

  
281
			theIterator.next();
282
		}
283

  
284
		if (curlinearRing.size() != 0) {
285
			if (curlinearRing.size() < 4) {
286
				// FIXME exception
287
				throw new WKBPolygonNotClosedException(surface);
288
			}
289
			checkLinearRingIsClosed(surface, curlinearRing);
290
			linearRings.add(curlinearRing);
291
		}
292
		return linearRings;
293
	}
294

  
295
	private List getLines(Curve curve) throws WKBEncodingException {
296
		List lines = new ArrayList();
297
		PathIterator theIterator = curve.getPathIterator(null);
298
		List curlinearRing = new ArrayList();
299
		int theType;
300
		double[] theData = new double[6];
301

  
302
		while (!theIterator.isDone()) {
303
			// while not done
304
			theType = theIterator.currentSegment(theData);
305

  
306
			// Populate a segment of the new
307
			// GeneralPathX object.
308
			// Process the current segment to populate a new
309
			// segment of the new GeneralPathX object.
310
			switch (theType) {
311
			case PathIterator.SEG_MOVETO:
312
				if (curlinearRing.size() != 0) {
313
					if (curlinearRing.size() < 2) {
314
						throw new WKBOnePointLineException(curve);
315
					}
316
					lines.add(curlinearRing);
317
					curlinearRing = new ArrayList();
318
				}
319
				curlinearRing.add(new double[] { theData[0], theData[1] });
320

  
321
				break;
322

  
323
			case PathIterator.SEG_LINETO:
324
				curlinearRing.add(new double[] { theData[0], theData[1] });
325
				break;
326

  
327
			case PathIterator.SEG_QUADTO:
328
				// TODO transform to linear segments
329
				throw new IllegalArgumentException("SEG_QUADTO unsupported");
330

  
331
				// shape.quadTo(theData[0], theData[1], theData[2], theData[3]);
332

  
333
				// break;
334

  
335
			case PathIterator.SEG_CUBICTO:
336
				// TODO transform to linear segments
337
				throw new IllegalArgumentException("SEG_QUADTO unsupported");
338
				// shape.curveTo(theData[0], theData[1], theData[2], theData[3],
339
				// theData[4], theData[5]);
340

  
341
				// break;
342

  
343
			case PathIterator.SEG_CLOSE:
344
				curlinearRing.add(curlinearRing.get(0));
345
				break;
346
			} // end switch
347

  
348
			theIterator.next();
349
		}
350

  
351
		if (curlinearRing.size() != 0) {
352
			if (curlinearRing.size() < 2) {
353
				throw new WKBOnePointLineException(curve);
354
			}
355
			lines.add(curlinearRing);
356
		}
357
		return lines;
358
	}
359

  
360

  
361
	private void encodePolygon(Geometry geometry, DataOutputStream stream)
362
			throws GeometryTypeNotSupportedException,
363
			WKBPolygonNotClosedException, IOException {
364
		GeometryType geometryType = geometry.getGeometryType();
365
		encodeWKBGeomHead(wkbGeometryType.wkbPolygon, geometryType, stream);
366

  
367
		Surface surface = (Surface) geometry;
368

  
369
		List linearRings = getLinearRings(surface);
370
		stream.writeInt(linearRings.size());
371
		for (int i = 0; i < linearRings.size(); i++) {
372
			encodeLinearRing((List) linearRings.get(i), stream);
373
		}
374

  
375
	}
376

  
377
	private void encodeLinearRing(List linearRing, DataOutputStream stream)
378
			throws IOException {
379
		stream.writeInt(linearRing.size());
380
		for (int i = 0; i < linearRing.size(); i++) {
381
			encodeCoordinates((double[]) linearRing.get(i), stream);
382
		}
383
	}
384

  
385
	private void encodeMultiLineString(Geometry geometry,
386
			DataOutputStream stream)
387
			throws GeometryTypeNotSupportedException,
388
			WKBEncodingException, IOException {
389
		GeometryType geometryType = geometry.getGeometryType();
390
		encodeWKBGeomHead(wkbGeometryType.wkbMultiLineString, geometryType,
391
				stream);
392

  
393
		MultiCurve curves = (MultiCurve) geometry;
394

  
395
		int nGeometries = curves.getPrimitivesNumber();
396
		stream.writeInt(nGeometries);
397
		for (int i = 0; i < nGeometries; i++) {
398
			encodeLineString(curves.getPrimitiveAt(i), stream);
399
		}
400
	}
401

  
402
	private void encodeLineString(Geometry geometry, DataOutputStream stream)
403
			throws GeometryTypeNotSupportedException, WKBEncodingException,
404
			IOException {
405
		GeometryType geometryType = geometry.getGeometryType();
406
		encodeWKBGeomHead(wkbGeometryType.wkbLineString, geometryType,
407
				 stream);
408

  
409
		Curve curve = (Curve) geometry;
410

  
411
		List lines = getLines(curve);
412
		if (lines.size() != 1) {
413
			throw new WKBMultyLineInLineDefinitionException(curve);
414
		}
415

  
416
		List line = (List) lines.get(0);
417
		int nVertices = line.size();
418
		stream.writeInt(nVertices);
419
		for (int i = 0; i < nVertices; i++) {
420
			encodeCoordinates((double[]) line.get(i), stream);
421
		}
422

  
423
	}
424

  
425

  
426
	private void encodeCoordinates(double[] coordinates, DataOutputStream stream)
427
			throws IOException {
428
		for (int i = 0; i < coordinates.length; i++) {
429
			stream.writeDouble(coordinates[i]);
430
		}
431
	}
432

  
433
	private void encodeWKBGeomHead(int wkbBaseType, GeometryType geometryType,
434
			DataOutputStream stream) throws GeometryTypeNotSupportedException,
435
			IOException {
436

  
437
		stream.writeByte(wkbByteOrder.wkbXDR);
438

  
439
		int finalType = wkbBaseType % wkbGeometryType.wkb_baseToZ;
440

  
441
		switch (geometryType.getSubType()) {
442
		case SUBTYPES.GEOM2D:
443
			break;
444
		case SUBTYPES.GEOM2DM:
445
			finalType = finalType + wkbGeometryType.wkb_baseToM;
446
			break;
447
		
448
		case SUBTYPES.GEOM3D:
449
			finalType = finalType + wkbGeometryType.wkb_baseToZ;
450
			break;
451

  
452
		case SUBTYPES.GEOM3DM:
453
			finalType = finalType + wkbGeometryType.wkb_baseToZM;
454
			break;
455

  
456

  
457
		default:
458
			throw new GeometryTypeNotSupportedException(geometryType.getType(),
459
					geometryType.getSubType());
460

  
461
		}
462

  
463
		stream.writeInt(finalType);
464

  
465

  
466
	}
467

  
468

  
469
	private void encodePoint(Geometry geometry, DataOutputStream stream)
470
			throws GeometryTypeNotSupportedException, IOException {
471
		GeometryType geometryType = geometry.getGeometryType();
472
		encodeWKBGeomHead(wkbGeometryType.wkbPoint, geometryType,
473
				stream);
474

  
475
		Point point = (Point) geometry;
476
		double[] coords = point.getCoordinates();
477
		for (int i = 0; i < coords.length; i++) {
478
			stream.writeDouble(coords[i]);
479
		}
480

  
481
	}
482

  
483
	private void encodeMultiPoint(Geometry geometry, DataOutputStream stream)
484
			throws GeometryTypeNotSupportedException, IOException {
485
		GeometryType geometryType = geometry.getGeometryType();
486
		encodeWKBGeomHead(wkbGeometryType.wkbMultiPoint, geometryType, stream);
487

  
488
		MultiPoint points = (MultiPoint) geometry;
489

  
490
		int nGeometries = points.getPrimitivesNumber();
491
		stream.writeInt(nGeometries);
492
		for (int i=0;i<nGeometries;i++) {
493
			encodePoint(points.getPrimitiveAt(i), stream);
494
		}
495
	}
496

  
497

  
498

  
499
}
0 500

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/towkb/WKBPolygonNotClosedException.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

  
25
package org.gvsig.fmap.geom.operation.towkb;
26

  
27
import org.gvsig.fmap.geom.Geometry;
28

  
29
public class WKBPolygonNotClosedException extends WKBEncodingException {
30

  
31
	/**
32
	 * Generated serial version UID
33
	 */
34
	private static final long serialVersionUID = 2345762531238114238L;
35

  
36
	/**
37
	 * Key to retrieve this exception's message
38
	 */
39
	private static final String MESSAGE_KEY = "wkb_polygon_not_closed_exception";
40
	private static final String FORMAT_STRING =
41
		"Polygon not closed found";
42

  
43
	/**
44
	 * Class name of the geometry type. Should never be null in this exception
45
	 */
46
	public Geometry geometry = null;
47

  
48

  
49
	public WKBPolygonNotClosedException(Geometry geom) {
50
		super(FORMAT_STRING, MESSAGE_KEY, serialVersionUID);
51
		this.geometry = geom;
52
	}
53

  
54
}
0 55

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/towkb/ToWKB.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.geom.operation.towkb;
25

  
26
import org.gvsig.fmap.geom.Geometry;
27
import org.gvsig.fmap.geom.GeometryLocator;
28
import org.gvsig.fmap.geom.operation.GeometryOperation;
29
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
30
import org.gvsig.fmap.geom.util.Converter;
31

  
32
import com.vividsolutions.jts.io.WKBWriter;
33

  
34
public class ToWKB extends GeometryOperation {
35
    public static final String NAME       = "toWKB";
36
	public static final int    CODE       =  GeometryLocator.getGeometryManager().getGeometryOperationCode(NAME);
37
	private static WKBWriter   writer     = null;
38
	private static int         dimension  = 2;
39

  
40
	public Object invoke(Geometry geom, GeometryOperationContext ctx) {
41
		int subType = geom.getGeometryType().getSubType();
42
		boolean is3D = subType == 1 || subType == 3;
43
		
44
		if(writer == null) {
45
			if(is3D) {
46
				dimension = 3;
47
				writer = new WKBWriter(3);
48
			} else {
49
				dimension = 2;
50
				writer = new WKBWriter();
51
			}
52
		} else {
53
			if(is3D && dimension == 2) {
54
				dimension = 3;
55
				writer = new WKBWriter(3);
56
			}
57
			if(!is3D && dimension == 3) {
58
				dimension = 2;
59
				writer = new WKBWriter();
60
			}
61
		}
62
		
63
		if (ctx == null) {
64
			return writer.write(Converter.geometryToJts(geom));
65
		}
66
		return writer.write(Converter.geometryToJtsWithSRID(geom,
67
				((ToWKBOperationContext) ctx).getSrID()));
68
	}
69

  
70
	public int getOperationIndex() {
71
		return CODE;
72
	}
73

  
74
}
0 75

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/towkb/WKBOnePointLineException.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

  
25
package org.gvsig.fmap.geom.operation.towkb;
26

  
27
import org.gvsig.fmap.geom.Geometry;
28

  
29
public class WKBOnePointLineException extends WKBEncodingException {
30

  
31
	/**
32
	 * Generated serial version UID
33
	 */
34
	private static final long serialVersionUID = 1810408131264048570L;
35

  
36
	/**
37
	 * Key to retrieve this exception's message
38
	 */
39
	private static final String MESSAGE_KEY = "wkb_one_point_line_exception";
40
	private static final String FORMAT_STRING =
41
		"Single point line definition";
42

  
43
	/**
44
	 * Class name of the geometry type. Should never be null in this exception
45
	 */
46
	public Geometry geometry = null;
47

  
48

  
49
	public WKBOnePointLineException(Geometry geom) {
50
		super(FORMAT_STRING, MESSAGE_KEY, serialVersionUID);
51
		this.geometry = geom;
52
	}
53

  
54
}
0 55

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/fromwkt/FromWKTGeometryOperationContext.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.geom.operation.fromwkt;
25

  
26
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
27

  
28
/**
29
 * @author jmvivo
30
 * 
31
 */
32
public class FromWKTGeometryOperationContext extends GeometryOperationContext {
33

  
34
	public static final String SRS = "srs";
35
	public static final String TEXT = "text";
36
	
37
	
38
	public FromWKTGeometryOperationContext(String text,String srs) {
39
		this.setText(text);
40
		this.setSrs(srs);
41
	}
42

  
43
	public void setText(String text) {
44
		this.setAttribute(TEXT, text);
45
	}
46

  
47
	public String getText() {
48
		return (String) this.getAttribute(TEXT);
49
	}
50

  
51
	protected String getSrs() {
52
		return (String) this.getAttribute(SRS);
53
	}
54

  
55
	protected void setSrs(String srs) {
56
		this.setAttribute(SRS, srs);
57
	}
58
}
59

  
60

  
0 61

  
tags/org.gvsig.desktop-2.0.29/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.operation/src/main/java/org/gvsig/fmap/geom/operation/fromwkt/WKTParser.java
1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.geom.operation.fromwkt;
25

  
26
import java.io.IOException;
27
import java.io.Reader;
28
import java.io.StreamTokenizer;
29
import java.io.StringReader;
30
import java.util.ArrayList;
31

  
32
import org.gvsig.fmap.geom.Geometry;
33
import org.gvsig.fmap.geom.GeometryException;
34
import org.gvsig.fmap.geom.GeometryLocator;
35
import org.gvsig.fmap.geom.GeometryManager;
36
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
37
import org.gvsig.fmap.geom.Geometry.TYPES;
38
import org.gvsig.fmap.geom.aggregate.MultiCurve;
39
import org.gvsig.fmap.geom.aggregate.MultiPoint;
40
import org.gvsig.fmap.geom.aggregate.MultiSurface;
41
import org.gvsig.fmap.geom.exception.CreateGeometryException;
42
import org.gvsig.fmap.geom.operation.GeometryOperationException;
43
import org.gvsig.fmap.geom.primitive.Curve;
44
import org.gvsig.fmap.geom.primitive.GeneralPathX;
45
import org.gvsig.fmap.geom.primitive.Point;
46
import org.gvsig.fmap.geom.primitive.Surface;
47
import org.gvsig.tools.exception.BaseException;
48

  
49
import com.vividsolutions.jts.geom.Coordinate;
50
import com.vividsolutions.jts.io.ParseException;
51

  
52
/**
53
 *  Converts a Well-Known Text string to a <code>Geometry</code>.
54
 * <p>
55
 *  The <code>WKTReader</code> allows
56
 *  extracting <code>Geometry</code> objects from either input streams or
57
 *  internal strings. This allows it to function as a parser to read <code>Geometry</code>
58
 *  objects from text blocks embedded in other data formats (e.g. XML). <P>
59
 * <p>
60
 * The Well-known
61
 *  Text format is defined in the <A HREF="http://www.opengis.org/techno/specs.htm">
62
 *  OpenGIS Simple Features Specification for SQL</A> . <P>
63
 * <p>
64
 *  <B>Note: </B> There is an inconsistency in the SFS. The WKT grammar states
65
 *  that <code>MultiPoints</code> are represented by <code>MULTIPOINT ( ( x y), (x y) )</code>
66
 *  , but the examples show <code>MultiPoint</code>s as <code>MULTIPOINT ( x y, x y )</code>
67
 *  . Other implementations follow the latter syntax, so JTS will adopt it as
68
 *  well.
69
 *
70
 *  A <code>WKTReader</code> is parameterized by a <code>GeometryFactory</code>
71
 *  , to allow it to create <code>Geometry</code> objects of the appropriate
72
 *  implementation. In particular, the <code>GeometryFactory</code> will
73
 *  determine the <code>PrecisionModel</code> and <code>SRID</code> that is
74
 *  used. <P>
75
 *
76
 *  The <code>WKTReader</code> will convert the input numbers to the precise
77
 *  internal representation.
78
 *
79
 *  Reads non-standard "LINEARRING" tags.
80
 *
81
 *@version 1.5
82
 */
83
public class WKTParser {
84

  
85
	private GeometryManager manager = GeometryLocator.getGeometryManager();
86
	/**
87
	 * Creates a WKTReader that creates objects using a basic GeometryFactory.
88
	 */
89
	public WKTParser() {
90
	}
91

  
92

  
93

  
94
	/**
95
	 * Converts a Well-known Text representation to a <code>Geometry</code>.
96
	 * 
97
	 * @param wellKnownText
98
	 *            one or more <Geometry Tagged Text>strings (see the OpenGIS
99
	 *            Simple Features Specification) separated by whitespace
100
	 * @return a <code>Geometry</code> specified by <code>wellKnownText</code>
101
	 * @throws ParseException
102
	 *             if a parsing problem occurs
103
	 */
104
	public Geometry read(String wellKnownText) throws ParseException {
105
		StringReader reader = new StringReader(wellKnownText);
106
		try {
107
			return read(reader);
108
		}
109
		finally {
110
			reader.close();
111
		}
112
	}
113

  
114
	/**
115
	 *  Converts a Well-known Text representation to a <code>Geometry</code>.
116
	 *
117
	 *@param  reader           a Reader which will return a <Geometry Tagged Text>
118
	 *      string (see the OpenGIS Simple Features Specification)
119
	 *@return                  a <code>Geometry</code> read from <code>reader</code>
120
	 *@throws  ParseException  if a parsing problem occurs
121
	 */
122
	public Geometry read(Reader reader) throws ParseException {
123
		StreamTokenizer tokenizer = new StreamTokenizer(reader);
124
		try {
125
			return readGeometryTaggedText(tokenizer);
126
		}
127
		catch (IOException e) {
128
			throw new ParseException(e.toString());
129
		} catch (CreateGeometryException e) {
130
			throw new ParseException(e.toString());
131
		}
132
	}
133

  
134
	/**
135
	 *  Returns the next array of <code>Coordinate</code>s in the stream.
136
	 *
137
	 *@param  tokenizer        tokenizer over a stream of text in Well-known Text
138
	 *      format. The next element returned by the stream should be "(" (the
139
	 *      beginning of "(x1 y1, x2 y2, ..., xn yn)") or "EMPTY".
140
	 *@return                  the next array of <code>Coordinate</code>s in the
141
	 *      stream, or an empty array if "EMPTY" is the next element returned by
142
	 *      the stream.
143
	 *@throws  IOException     if an I/O error occurs
144
	 *@throws  ParseException  if an unexpected token was encountered
145
	 */
146
	private Coordinate[] getCoordinates(StreamTokenizer tokenizer)
147
	throws IOException, ParseException
148
	{
149
		String nextToken = getNextEmptyOrOpener(tokenizer);
150
		if (nextToken.equals("EMPTY")) {
151
			return new Coordinate[]{};
152
		}
153
		ArrayList coordinates = new ArrayList();
154
		coordinates.add(getPreciseCoordinate(tokenizer));
155
		nextToken = getNextCloserOrComma(tokenizer);
156
		while (nextToken.equals(",")) {
157
			coordinates.add(getPreciseCoordinate(tokenizer));
158
			nextToken = getNextCloserOrComma(tokenizer);
159
		}
160
		Coordinate[] array = new Coordinate[coordinates.size()];
161
		return (Coordinate[]) coordinates.toArray(array);
162
	}
163

  
164
	private Coordinate getPreciseCoordinate(StreamTokenizer tokenizer)
165
	throws IOException, ParseException
166
	{
167
		Coordinate coord = new Coordinate();
168
		coord.x = getNextNumber(tokenizer);
169
		coord.y = getNextNumber(tokenizer);
170
		if (isNumberNext(tokenizer)) {
171
			coord.z = getNextNumber(tokenizer);
172
		}
173
		return coord;
174
	}
175
	private boolean isNumberNext(StreamTokenizer tokenizer) throws IOException {
176
		try {
177
			return tokenizer.nextToken() == StreamTokenizer.TT_NUMBER;
178
		}
179
		finally {
180
			tokenizer.pushBack();
181
		}
182
	}
183
	/**
184
	 *  Returns the next number in the stream.
185
	 *
186
	 *@param  tokenizer        tokenizer over a stream of text in Well-known Text
187
	 *      format. The next token must be a number.
188
	 *@return                  the next number in the stream
189
	 *@throws  ParseException  if the next token is not a number
190
	 *@throws  IOException     if an I/O error occurs
191
	 */
192
	private double getNextNumber(StreamTokenizer tokenizer) throws IOException,
193
	ParseException {
194
		int type = tokenizer.nextToken();
195
		switch (type) {
196
		case StreamTokenizer.TT_EOF:
197
			throw new ParseException("Expected number but encountered end of stream");
198
		case StreamTokenizer.TT_EOL:
199
			throw new ParseException("Expected number but encountered end of line");
200
		case StreamTokenizer.TT_NUMBER:
201
			return tokenizer.nval;
202
		case StreamTokenizer.TT_WORD:
203
			throw new ParseException("Expected number but encountered word: " +
204
					tokenizer.sval);
205
		case '(':
206
			throw new ParseException("Expected number but encountered '('");
207
		case ')':
208
			throw new ParseException("Expected number but encountered ')'");
209
		case ',':
210
			throw new ParseException("Expected number but encountered ','");
211
		}
212
		return 0;
213
	}
214

  
215
	/**
216
	 *  Returns the next "EMPTY" or "(" in the stream as uppercase text.
217
	 *
218
	 *@param  tokenizer        tokenizer over a stream of text in Well-known Text
219
	 *      format. The next token must be "EMPTY" or "(".
220
	 *@return                  the next "EMPTY" or "(" in the stream as uppercase
221
	 *      text.
222
	 *@throws  ParseException  if the next token is not "EMPTY" or "("
223
	 *@throws  IOException     if an I/O error occurs
224
	 */
225
	private String getNextEmptyOrOpener(StreamTokenizer tokenizer) throws IOException, ParseException {
226
		String nextWord = getNextWord(tokenizer);
227
		if (nextWord.equals("EMPTY") || nextWord.equals("(")) {
228
			return nextWord;
229
		}
230
		throw new ParseException("Expected 'EMPTY' or '(' but encountered '" +
231
				nextWord + "'");
232
	}
233

  
234
	/**
235
	 *  Returns the next ")" or "," in the stream.
236
	 *
237
	 *@param  tokenizer        tokenizer over a stream of text in Well-known Text
238
	 *      format. The next token must be ")" or ",".
239
	 *@return                  the next ")" or "," in the stream
240
	 *@throws  ParseException  if the next token is not ")" or ","
241
	 *@throws  IOException     if an I/O error occurs
242
	 */
243
	private String getNextCloserOrComma(StreamTokenizer tokenizer) throws IOException, ParseException {
244
		String nextWord = getNextWord(tokenizer);
245
		if (nextWord.equals(",") || nextWord.equals(")")) {
246
			return nextWord;
247
		}
248
		throw new ParseException("Expected ')' or ',' but encountered '" + nextWord
249
				+ "'");
250
	}
251

  
252
	/**
253
	 *  Returns the next ")" in the stream.
254
	 *
255
	 *@param  tokenizer        tokenizer over a stream of text in Well-known Text
256
	 *      format. The next token must be ")".
257
	 *@return                  the next ")" in the stream
258
	 *@throws  ParseException  if the next token is not ")"
259
	 *@throws  IOException     if an I/O error occurs
260
	 */
261
	private String getNextCloser(StreamTokenizer tokenizer) throws IOException, ParseException {
262
		String nextWord = getNextWord(tokenizer);
263
		if (nextWord.equals(")")) {
264
			return nextWord;
265
		}
266
		throw new ParseException("Expected ')' but encountered '" + nextWord + "'");
267
	}
268

  
269
	/**
270
	 *  Returns the next word in the stream as uppercase text.
271
	 *
272
	 *@param  tokenizer        tokenizer over a stream of text in Well-known Text
273
	 *      format. The next token must be a word.
274
	 *@return                  the next word in the stream as uppercase text
275
	 *@throws  ParseException  if the next token is not a word
276
	 *@throws  IOException     if an I/O error occurs
277
	 */
278
	private String getNextWord(StreamTokenizer tokenizer) throws IOException, ParseException {
279
		int type = tokenizer.nextToken();
280
		switch (type) {
281
		case StreamTokenizer.TT_EOF:
282
			throw new ParseException("Expected word but encountered end of stream");
283
		case StreamTokenizer.TT_EOL:
284
			throw new ParseException("Expected word but encountered end of line");
285
		case StreamTokenizer.TT_NUMBER:
286
			throw new ParseException("Expected word but encountered number: " +
287
					tokenizer.nval);
288
		case StreamTokenizer.TT_WORD:
289
			return tokenizer.sval.toUpperCase();
290
		case '(':
291
			return "(";
292
		case ')':
293
			return ")";
294
		case ',':
295
			return ",";
296
		}
297
		// Assert.shouldNeverReachHere("Encountered unexpected StreamTokenizer type: " + type);
298
		return null;
299
	}
300

  
301
	/**
302
	 *  Creates a <code>Geometry</code> using the next token in the stream.
303
	 *
304
	 *@param  tokenizer        tokenizer over a stream of text in Well-known Text
305
	 *      format. The next tokens must form a &lt;Geometry Tagged Text&gt;.
306
	 *@return                  a <code>Geometry</code> specified by the next token
307
	 *      in the stream
308
	 *@throws  ParseException  if the coordinates used to create a <code>Polygon</code>
309
	 *      shell and holes do not form closed linestrings, or if an unexpected
310
	 *      token was encountered
311
	 *@throws  IOException     if an I/O error occurs
312
	 * @throws CreateGeometryException 
313
	 */
314
	private Geometry readGeometryTaggedText(StreamTokenizer tokenizer) throws IOException, ParseException, CreateGeometryException{
315
		String type = getNextWord(tokenizer);
316
		if (type.equals("POINT")) {
317
			return readPointText(tokenizer);
318
		}
319
		else if (type.equals("LINESTRING")) {
320
			return readLineStringText(tokenizer);
321
		}
322
		else if (type.equals("LINEARRING")) {
323
			return readLinearRingText(tokenizer);
324
		}
325
		else if (type.equals("POLYGON")) {
326
			return readPolygonText(tokenizer);
327
		}
328
		else if (type.equals("MULTIPOINT")) {
329
			return readMultiPointText(tokenizer);
330
		}
331
		else if (type.equals("MULTILINESTRING")) {
332
			return readMultiLineStringText(tokenizer);
333
		}
334
		else if (type.equals("MULTIPOLYGON")) {
335
			return readMultiPolygonText(tokenizer);
336
		}
337
		/* else if (type.equals("GEOMETRYCOLLECTION")) {
338
      return readGeometryCollectionText(tokenizer);
339
    } */
340
		System.err.println("Unknown type: " + type);
341
		throw new ParseException("Unknown type: " + type);
342
	}
343

  
344
	/**
345
	 *  Creates a <code>Point</code> using the next token in the stream.
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff