Revision 47432 trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.geometry/org.gvsig.fmap.geometry.jts/src/main/java/org/gvsig/fmap/geom/jts/operation/towkb/OGCWKBEncoder.java

View differences:

OGCWKBEncoder.java
21 21
 * For any additional information, do not hesitate to contact us
22 22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 23
 */
24

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

  
27
import java.awt.geom.PathIterator;
28 26
import java.io.ByteArrayOutputStream;
29 27
import java.io.DataOutputStream;
30 28
import java.io.IOException;
31
import java.util.ArrayList;
32
import java.util.List;
33 29
import org.apache.commons.io.EndianUtils;
34

  
35 30
import org.gvsig.fmap.geom.Geometry;
36 31
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
37 32
import org.gvsig.fmap.geom.Geometry.TYPES;
33
import org.gvsig.fmap.geom.GeometryException;
38 34
import org.gvsig.fmap.geom.aggregate.Aggregate;
39
import org.gvsig.fmap.geom.aggregate.MultiCurve;
35
import org.gvsig.fmap.geom.aggregate.MultiLine;
40 36
import org.gvsig.fmap.geom.aggregate.MultiPoint;
41
import org.gvsig.fmap.geom.aggregate.MultiSurface;
42
import org.gvsig.fmap.geom.primitive.Curve;
37
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
38
import org.gvsig.fmap.geom.primitive.Line;
43 39
import org.gvsig.fmap.geom.primitive.Point;
44
import org.gvsig.fmap.geom.primitive.Surface;
40
import org.gvsig.fmap.geom.primitive.Polygon;
41
import org.gvsig.fmap.geom.primitive.Ring;
45 42
import org.gvsig.fmap.geom.type.GeometryType;
46 43
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
47 44

  
45
public class OGCWKBEncoder {
48 46

  
47
    public interface wkbGeometryType {
49 48

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

  
52
	public interface wkbGeometryType {
53
		public final static int wkbPoint = 1;
54
		public final static int wkbLineString = 2;
55
		public final static int wkbPolygon = 3;
56
		public final static int wkbTriangle = 17;
57
		public final static int wkbMultiPoint = 4;
58
		public final static int wkbMultiLineString = 5;
59
		public final static int wkbMultiPolygon = 6;
60
		public final static int wkbGeometryCollection = 7;
61
		public final static int wkbPolyhedralSurface = 15;
62
		public final static int wkbTIN = 16;
60
        public final static int wkbPointZ = 1001;
61
        public final static int wkbLineStringZ = 1002;
62
        public final static int wkbPolygonZ = 1003;
63
        public final static int wkbTrianglez = 1017;
64
        public final static int wkbMultiPointZ = 1004;
65
        public final static int wkbMultiLineStringZ = 1005;
66
        public final static int wkbMultiPolygonZ = 1006;
67
        public final static int wkbGeometryCollectionZ = 1007;
68
        public final static int wkbPolyhedralSurfaceZ = 1015;
69
        public final static int wkbTINZ = 1016;
63 70

  
64
		public final static int wkbPointZ = 1001;
65
		public final static int wkbLineStringZ = 1002;
66
		public final static int wkbPolygonZ = 1003;
67
		public final static int wkbTrianglez = 1017;
68
		public final static int wkbMultiPointZ = 1004;
69
		public final static int wkbMultiLineStringZ = 1005;
70
		public final static int wkbMultiPolygonZ = 1006;
71
		public final static int wkbGeometryCollectionZ = 1007;
72
		public final static int wkbPolyhedralSurfaceZ = 1015;
73
		public final static int wkbTINZ = 1016;
71
        public final static int wkbPointM = 2001;
72
        public final static int wkbLineStringM = 2002;
73
        public final static int wkbPolygonM = 2003;
74
        public final static int wkbTriangleM = 2017;
75
        public final static int wkbMultiPointM = 2004;
76
        public final static int wkbMultiLineStringM = 2005;
77
        public final static int wkbMultiPolygonM = 2006;
78
        public final static int wkbGeometryCollectionM = 2007;
79
        public final static int wkbPolyhedralSurfaceM = 2015;
80
        public final static int wkbTINM = 2016;
74 81

  
75
		public final static int wkbPointM = 2001;
76
		public final static int wkbLineStringM = 2002;
77
		public final static int wkbPolygonM = 2003;
78
		public final static int wkbTriangleM = 2017;
79
		public final static int wkbMultiPointM = 2004;
80
		public final static int wkbMultiLineStringM = 2005;
81
		public final static int wkbMultiPolygonM = 2006;
82
		public final static int wkbGeometryCollectionM = 2007;
83
		public final static int wkbPolyhedralSurfaceM = 2015;
84
		public final static int wkbTINM = 2016;
82
        public final static int wkbPointZM = 3001;
83
        public final static int wkbLineStringZM = 3002;
84
        public final static int wkbPolygonZM = 3003;
85
        public final static int wkbTriangleZM = 3017;
86
        public final static int wkbMultiPointZM = 3004;
87
        public final static int wkbMultiLineStringZM = 3005;
88
        public final static int wkbMultiPolygonZM = 3006;
89
        public final static int wkbGeometryCollectionZM = 3007;
90
        public final static int wkbPolyhedralSurfaceZM = 3015;
91
        public final static int wkbTinZM = 3016;
85 92

  
86
		public final static int wkbPointZM = 3001;
87
		public final static int wkbLineStringZM = 3002;
88
		public final static int wkbPolygonZM = 3003;
89
		public final static int wkbTriangleZM = 3017;
90
		public final static int wkbMultiPointZM = 3004;
91
		public final static int wkbMultiLineStringZM = 3005;
92
		public final static int wkbMultiPolygonZM = 3006;
93
		public final static int wkbGeometryCollectionZM = 3007;
94
		public final static int wkbPolyhedralSurfaceZM = 3015;
95
		public final static int wkbTinZM = 3016;
93
        public final static int wkb_baseToZ = wkbPointZ - wkbPoint;
94
        public final static int wkb_baseToM = wkbPointM - wkbPoint;
95
        public final static int wkb_baseToZM = wkbPointZM - wkbPoint;
96
    }
96 97

  
97
		public final static int wkb_baseToZ = wkbPointZ - wkbPoint;
98
		public final static int wkb_baseToM = wkbPointM - wkbPoint;
99
		public final static int wkb_baseToZM = wkbPointZM - wkbPoint;
100
	}
98
    public interface wkbByteOrder {
101 99

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

  
107
        private int byteOrder;
108
        
109
        public OGCWKBEncoder() {
110
            this(wkbByteOrder.wkbXDR);
111
        }
112
        
113
        public OGCWKBEncoder(int byteOrder) {
114
            this.byteOrder = byteOrder;
115
        }
116
        
117
	public byte[] encode(Geometry geometry)
118
			throws GeometryTypeNotSupportedException,
119
			WKBEncodingException,
120
			IOException {
121
		ByteArrayOutputStream stream;
104
    private int byteOrder;
122 105

  
123
		if (geometry.getType() == TYPES.POINT) {
124
			stream = new ByteArrayOutputStream(50);
125
		} else {
126
			stream = new ByteArrayOutputStream(512);
127
		}
106
    public OGCWKBEncoder() {
107
        this(wkbByteOrder.wkbXDR);
108
    }
128 109

  
129
		encode(geometry, stream);
130
		return stream.toByteArray();
110
    public OGCWKBEncoder(int byteOrder) {
111
        this.byteOrder = byteOrder;
112
    }
131 113

  
132
	}
133
	public void encode(Geometry geometry, ByteArrayOutputStream stream)
134
			throws GeometryTypeNotSupportedException, WKBEncodingException,
135
			IOException {
136
		encode(geometry, new DataOutputStream(stream));
137
	}
114
    public byte[] encode(Geometry geometry)
115
            throws GeometryTypeNotSupportedException,
116
            WKBEncodingException,
117
            IOException {
118
        ByteArrayOutputStream stream;
138 119

  
139
	public void encode(Geometry geometry, DataOutputStream stream)
140
			throws GeometryTypeNotSupportedException,
141
			WKBEncodingException,
142
			IOException {
143
            if (geometry.getGeometryType().isTypeOf(TYPES.POINT)) {
144
                encodePoint(geometry, stream);
120
        if (geometry.getType() == TYPES.POINT) {
121
            stream = new ByteArrayOutputStream(50);
122
        } else {
123
            stream = new ByteArrayOutputStream(512);
124
        }
145 125

  
146
            } else if (geometry.getGeometryType().isTypeOf(TYPES.CURVE)) {
147
                encodeLineString(geometry, stream);
126
        encode(geometry, stream);
127
        return stream.toByteArray();
148 128

  
149
            } else if (geometry.getGeometryType().isTypeOf(TYPES.SURFACE)) {
150
                encodePolygon(geometry, stream);
129
    }
151 130

  
152
            } else if (geometry.getGeometryType().isTypeOf(TYPES.AGGREGATE)) {
153
                switch (geometry.getType()) {
154
                    case TYPES.MULTIPOINT:
155
                        encodeMultiPoint(geometry, stream);
156
                        break;
157
                    case TYPES.MULTICURVE:
158
                    case TYPES.MULTILINE:
159
                        encodeMultiLineString(geometry, stream);
160
                        break;
131
    public void encode(Geometry geometry, ByteArrayOutputStream stream)
132
            throws GeometryTypeNotSupportedException, WKBEncodingException,
133
            IOException {
134
        encode(geometry, new DataOutputStream(stream));
135
    }
161 136

  
162
                    case TYPES.MULTISURFACE:
163
                    case TYPES.MULTIPOLYGON:
164
                        encodeMultiPolygon(geometry, stream);
165
                        break;
137
    public void encode(Geometry geometry, DataOutputStream stream)
138
            throws GeometryTypeNotSupportedException,
139
            WKBEncodingException,
140
            IOException {
141
        if (geometry.getGeometryType().isTypeOf(TYPES.POINT)) {
142
            encodePoint(geometry, stream);
166 143

  
167
                    case TYPES.AGGREGATE:
168
                        encodeCollection(geometry, stream);
169
                        break;
144
        } else if (geometry.getGeometryType().isTypeOf(TYPES.LINE)) {
145
            encodeLineString((Line)geometry, stream);
146
        } else if (geometry.getGeometryType().isTypeOf(TYPES.CURVE)) {
147
            try {
148
                MultiLine lines = geometry.toLines();
149
                if(lines.getPrimitivesNumber() == 1){
150
                    encodeLineString((Line) lines.getPrimitiveAt(0), stream);
151
                } else {
152
                    encodeMultiLineString(lines, stream);
170 153
                }
154
            } catch (GeometryException ex) {
155
                throw new WKBEncodingException(ex);
156
            }
171 157

  
172
            } else {
173
                throw new GeometryTypeNotSupportedException(geometry.getType(),
174
                        geometry.getGeometryType().getSubType());
158
        } else if (geometry.getGeometryType().isTypeOf(TYPES.POLYGON)) {
159
            encodePolygon((Polygon) geometry, stream);
160
        } else if (geometry.getGeometryType().isTypeOf(TYPES.SURFACE)) {
161
            try {
162
                MultiPolygon pols = geometry.toPolygons();
163
                if(pols.getPrimitivesNumber() == 1){
164
                    encodePolygon((Polygon) pols.getPrimitiveAt(0), stream);
165
                } else {
166
                    encodeMultiPolygon(pols, stream);
167
                }
168
            } catch (GeometryException ex) {
169
                throw new WKBEncodingException(ex);
175 170
            }
171

  
172
        } else if (geometry.getGeometryType().isTypeOf(TYPES.AGGREGATE)) {
173
            switch (geometry.getType()) {
174
                case TYPES.MULTIPOINT:
175
                    encodeMultiPoint(geometry, stream);
176
                    break;
177
                case TYPES.MULTICURVE:
178
                    try {
179
                        encodeMultiLineString(geometry.toLines(), stream);
180
                    } catch (GeometryException ex) {
181
                        throw new WKBEncodingException(ex);
182
                    }
183
                    break;
184
                case TYPES.MULTILINE:
185
                    encodeMultiLineString((MultiLine) geometry, stream);
186
                    break;
187

  
188
                case TYPES.MULTISURFACE:
189
                    try {
190
                        encodeMultiPolygon(geometry.toPolygons(), stream);
191
                    } catch (GeometryException ex) {
192
                        throw new WKBEncodingException(ex);
193
                    }
194
                    break;
195
                case TYPES.MULTIPOLYGON:
196
                    encodeMultiPolygon((MultiPolygon) geometry, stream);
197
                    break;
198

  
199
                case TYPES.AGGREGATE:
200
                    encodeCollection(geometry, stream);
201
                    break;
202
            }
203

  
204
        } else {
205
            throw new GeometryTypeNotSupportedException(geometry.getType(),
206
                    geometry.getGeometryType().getSubType());
207
        }
176 208
//
177 209
//            // FIXME geom.subtype != SUBTYPES.GEOM2D NOT SUPPORTED !!!!
178 210
//            if (geometry.getGeometryType().getSubType() != SUBTYPES.GEOM2D) {
179 211
//                throw new GeometryTypeNotSupportedException(geometry.getType(),
180 212
//                        geometry.getGeometryType().getSubType());
181 213
//            }
182
	}
214
    }
183 215

  
216
    private void encodeCollection(Geometry geometry, DataOutputStream stream)
217
            throws GeometryTypeNotSupportedException,
218
            WKBEncodingException,
219
            IOException {
220
        GeometryType geometryType = geometry.getGeometryType();
221
        encodeWKBGeomHead(wkbGeometryType.wkbGeometryCollection, geometryType,
222
                stream);
184 223

  
185
	private void encodeCollection(Geometry geometry, DataOutputStream stream)
186
			throws GeometryTypeNotSupportedException,
187
			WKBEncodingException,
188
			IOException {
189
		GeometryType geometryType = geometry.getGeometryType();
190
		encodeWKBGeomHead(wkbGeometryType.wkbGeometryCollection, geometryType,
191
				stream);
224
        Aggregate collection = (Aggregate) geometry;
192 225

  
193
		Aggregate collection = (Aggregate) geometry;
226
        int nGeometries = collection.getPrimitivesNumber();
227
        encodeInteger(nGeometries, stream);
228
        for (int i = 0; i < nGeometries; i++) {
229
            encode(collection.getPrimitiveAt(i), stream);
230
        }
231
    }
194 232

  
195
		int nGeometries = collection.getPrimitivesNumber();
196
                encodeInteger(nGeometries, stream);
197
		for (int i = 0; i < nGeometries; i++) {
198
			encode(collection.getPrimitiveAt(i), stream);
199
		}
200
	}
233
    private void encodeMultiPolygon(MultiPolygon geometry, DataOutputStream stream)
234
            throws GeometryTypeNotSupportedException,
235
            WKBPolygonNotClosedException, IOException {
236
        GeometryType geometryType = geometry.getGeometryType();
237
        encodeWKBGeomHead(wkbGeometryType.wkbMultiPolygon, geometryType, stream);
201 238

  
202
	private void encodeMultiPolygon(Geometry geometry, DataOutputStream stream)
203
			throws GeometryTypeNotSupportedException,
204
			WKBPolygonNotClosedException, IOException {
205
		GeometryType geometryType = geometry.getGeometryType();
206
		encodeWKBGeomHead(wkbGeometryType.wkbMultiPolygon, geometryType, stream);
239
        int nGeometries = geometry.getPrimitivesNumber();
240
        encodeInteger(nGeometries, stream);
241
        for (int i = 0; i < nGeometries; i++) {
242
            encodePolygon((Polygon) geometry.getPrimitiveAt(i), stream);
243
        }
244
    }
207 245

  
208
		MultiSurface surfaces = (MultiSurface) geometry;
246
    private void encodePolygon(Polygon geometry, DataOutputStream stream)
247
            throws GeometryTypeNotSupportedException,
248
            WKBPolygonNotClosedException, IOException {
249
        GeometryType geometryType = geometry.getGeometryType();
250
        encodeWKBGeomHead(wkbGeometryType.wkbPolygon, geometryType, stream);
209 251

  
210
		int nGeometries = surfaces.getPrimitivesNumber();
211
                encodeInteger(nGeometries, stream);
212
		for (int i = 0; i < nGeometries; i++) {
213
			encodePolygon(surfaces.getPrimitiveAt(i), stream);
214
		}
215
	}
252
        encodeInteger(1 + geometry.getNumInteriorRings(), stream);
253
        encodeLinearRing(geometry, stream);
254
        for (int i = 0; i < geometry.getNumInteriorRings(); i++) {
255
            Ring ring = geometry.getInteriorRing(i);
256
            encodeLinearRing(ring, stream);
216 257

  
217
	private void checkLinearRingIsClosed(Geometry geom, List linearRing)
218
			throws WKBPolygonNotClosedException {
219
		double[] first = (double[]) linearRing.get(0);
220
		double[] last = (double[]) linearRing.get(linearRing.size() - 1);
258
        }
259
    }
221 260

  
222
		for (int i = 0; i < first.length; i++) {
223
			if (Math.abs(first[i] - last[i]) > 0.000001) {
224
				throw new WKBPolygonNotClosedException(geom);
225
			}
226
		}
261
    private void encodeLinearRing(Ring geom, DataOutputStream stream)
262
            throws IOException {
263
        encodeInteger(geom.getNumVertices(), stream);
264
        for (Point point : geom) {
265
            encodeCoordinates(point.getCoordinates(), stream);
266
        }
267
    }
227 268

  
228
	}
269
    private void encodeMultiLineString(MultiLine geometry, DataOutputStream stream)
270
            throws GeometryTypeNotSupportedException,
271
            WKBPolygonNotClosedException, IOException {
272
        GeometryType geometryType = geometry.getGeometryType();
273
        encodeWKBGeomHead(wkbGeometryType.wkbMultiLineString, geometryType, stream);
229 274

  
230
	private List getLinearRings(Surface surface)
231
			throws WKBPolygonNotClosedException {
232
		PathIterator theIterator = surface.getPathIterator(null);
233
		List linearRings = new ArrayList();
234
		List curlinearRing = new ArrayList();
235
		int theType;
236
		double[] theData = new double[6];
275
        int nGeometries = geometry.getPrimitivesNumber();
276
        encodeInteger(nGeometries, stream);
277
        for (int i = 0; i < nGeometries; i++) {
278
            encodeLineString((Line) geometry.getPrimitiveAt(i), stream);
279
        }
280
    }
237 281

  
238
		while (!theIterator.isDone()) {
239
			// while not done
240
			theType = theIterator.currentSegment(theData);
282
        private void encodeLineString(Line geometry, DataOutputStream stream)
283
            throws GeometryTypeNotSupportedException,
284
            WKBPolygonNotClosedException, IOException {
285
        GeometryType geometryType = geometry.getGeometryType();
286
        encodeWKBGeomHead(wkbGeometryType.wkbLineString, geometryType, stream);
287
        
288
        int nVertices = geometry.getNumVertices();
289
        encodeInteger(nVertices, stream);
290
        
291
        for (Point point : geometry) {
292
            encodeCoordinates(point.getCoordinates(), stream);
293
        }
294
    }
241 295

  
242
			// Populate a segment of the new
243
			// GeneralPathX object.
244
			// Process the current segment to populate a new
245
			// segment of the new GeneralPathX object.
246
			switch (theType) {
247
			case PathIterator.SEG_MOVETO:
248
				if (curlinearRing.size() != 0) {
249
					if (curlinearRing.size() < 4) {
250
						// FIXME exception
251
						throw new WKBPolygonNotClosedException(surface);
252
					}
253
					checkLinearRingIsClosed(surface, curlinearRing);
254
					linearRings.add(curlinearRing);
255
					curlinearRing = new ArrayList();
256 296

  
257
				}
258
				curlinearRing.add(new double[] { theData[0], theData[1] });
259
				break;
297
    private void encodeDouble(double data, DataOutputStream stream)
298
            throws IOException {
299
        if (this.byteOrder == wkbByteOrder.wkbXDR) {
300
            stream.writeDouble(data);
301
        } else {
302
            EndianUtils.writeSwappedDouble(stream, data);
303
        }
304
    }
260 305

  
261
			case PathIterator.SEG_LINETO:
262
				curlinearRing.add(new double[] { theData[0], theData[1] });
263
				break;
264

  
265
			case PathIterator.SEG_QUADTO:
266
				// TODO transform to linear segments
267
				throw new IllegalArgumentException("SEG_QUADTO unsupported");
268

  
269
				// shape.quadTo(theData[0], theData[1], theData[2], theData[3]);
270

  
271
				// break;
272

  
273
			case PathIterator.SEG_CUBICTO:
274
				// TODO transform to linear segments
275
				throw new IllegalArgumentException("SEG_QUADTO unsupported");
276
				// shape.curveTo(theData[0], theData[1], theData[2], theData[3],
277
				// theData[4], theData[5]);
278

  
279
				// break;
280

  
281
			case PathIterator.SEG_CLOSE:
282
				curlinearRing.add(curlinearRing.get(0));
283
				linearRings.add(curlinearRing);
284
				curlinearRing = new ArrayList();
285
				break;
286
			} // end switch
287

  
288
			theIterator.next();
289
		}
290

  
291
		if (curlinearRing.size() != 0) {
292
			if (curlinearRing.size() < 4) {
293
				// FIXME exception
294
				throw new WKBPolygonNotClosedException(surface);
295
			}
296
			checkLinearRingIsClosed(surface, curlinearRing);
297
			linearRings.add(curlinearRing);
298
		}
299
		return linearRings;
300
	}
301

  
302
	private List getLines(Curve curve) throws WKBEncodingException {
303
		List lines = new ArrayList();
304
		PathIterator theIterator = curve.getPathIterator(null);
305
		List curlinearRing = new ArrayList();
306
		int theType;
307
		double[] theData = new double[6];
308

  
309
		while (!theIterator.isDone()) {
310
			// while not done
311
			theType = theIterator.currentSegment(theData);
312

  
313
			// Populate a segment of the new
314
			// GeneralPathX object.
315
			// Process the current segment to populate a new
316
			// segment of the new GeneralPathX object.
317
			switch (theType) {
318
			case PathIterator.SEG_MOVETO:
319
				if (curlinearRing.size() != 0) {
320
					if (curlinearRing.size() < 2) {
321
						throw new WKBOnePointLineException(curve);
322
					}
323
					lines.add(curlinearRing);
324
					curlinearRing = new ArrayList();
325
				}
326
				curlinearRing.add(new double[] { theData[0], theData[1] });
327

  
328
				break;
329

  
330
			case PathIterator.SEG_LINETO:
331
				curlinearRing.add(new double[] { theData[0], theData[1] });
332
				break;
333

  
334
			case PathIterator.SEG_QUADTO:
335
				// TODO transform to linear segments
336
				throw new IllegalArgumentException("SEG_QUADTO unsupported");
337

  
338
				// shape.quadTo(theData[0], theData[1], theData[2], theData[3]);
339

  
340
				// break;
341

  
342
			case PathIterator.SEG_CUBICTO:
343
				// TODO transform to linear segments
344
				throw new IllegalArgumentException("SEG_QUADTO unsupported");
345
				// shape.curveTo(theData[0], theData[1], theData[2], theData[3],
346
				// theData[4], theData[5]);
347

  
348
				// break;
349

  
350
			case PathIterator.SEG_CLOSE:
351
				curlinearRing.add(curlinearRing.get(0));
352
				break;
353
			} // end switch
354

  
355
			theIterator.next();
356
		}
357

  
358
		if (curlinearRing.size() != 0) {
359
			if (curlinearRing.size() < 2) {
360
				throw new WKBOnePointLineException(curve);
361
			}
362
			lines.add(curlinearRing);
363
		}
364
		return lines;
365
	}
366

  
367

  
368
	private void encodePolygon(Geometry geometry, DataOutputStream stream)
369
			throws GeometryTypeNotSupportedException,
370
			WKBPolygonNotClosedException, IOException {
371
		GeometryType geometryType = geometry.getGeometryType();
372
		encodeWKBGeomHead(wkbGeometryType.wkbPolygon, geometryType, stream);
373

  
374
		Surface surface = (Surface) geometry;
375

  
376
		List linearRings = getLinearRings(surface);
377
                encodeInteger(linearRings.size(), stream);
378
		for (int i = 0; i < linearRings.size(); i++) {
379
			encodeLinearRing((List) linearRings.get(i), stream);
380
		}
381

  
382
	}
383

  
384
	private void encodeLinearRing(List linearRing, DataOutputStream stream)
385
			throws IOException {
386
                encodeInteger(linearRing.size(), stream);
387
		for (int i = 0; i < linearRing.size(); i++) {
388
			encodeCoordinates((double[]) linearRing.get(i), stream);
389
		}
390
	}
391

  
392
	private void encodeMultiLineString(Geometry geometry,
393
			DataOutputStream stream)
394
			throws GeometryTypeNotSupportedException,
395
			WKBEncodingException, IOException {
396
		GeometryType geometryType = geometry.getGeometryType();
397
		encodeWKBGeomHead(wkbGeometryType.wkbMultiLineString, geometryType,
398
				stream);
399

  
400
		MultiCurve curves = (MultiCurve) geometry;
401

  
402
		int nGeometries = curves.getPrimitivesNumber();
403
                encodeInteger(nGeometries, stream);
404
		for (int i = 0; i < nGeometries; i++) {
405
			encodeLineString(curves.getPrimitiveAt(i), stream);
406
		}
407
	}
408

  
409
	private void encodeLineString(Geometry geometry, DataOutputStream stream)
410
			throws GeometryTypeNotSupportedException, WKBEncodingException,
411
			IOException {
412
		GeometryType geometryType = geometry.getGeometryType();
413
		encodeWKBGeomHead(wkbGeometryType.wkbLineString, geometryType,
414
				 stream);
415

  
416
		Curve curve = (Curve) geometry;
417

  
418
		List lines = getLines(curve);
419
		if (lines.size() != 1) {
420
			throw new WKBMultyLineInLineDefinitionException(curve);
421
		}
422

  
423
		List line = (List) lines.get(0);
424
		int nVertices = line.size();
425
                encodeInteger(nVertices, stream);
426
		for (int i = 0; i < nVertices; i++) {
427
			encodeCoordinates((double[]) line.get(i), stream);
428
		}
429

  
430
	}
431

  
432
        private void encodeDouble(double data, DataOutputStream stream)
433
			throws IOException {
434
            if( this.byteOrder == wkbByteOrder.wkbXDR ) {
435
                stream.writeDouble(data);
436
            } else {
437
                EndianUtils.writeSwappedDouble(stream, data);
438
            }
306
    private void encodeInteger(int data, DataOutputStream stream)
307
            throws IOException {
308
        if (this.byteOrder == wkbByteOrder.wkbXDR) {
309
            stream.writeInt(data);
310
        } else {
311
            EndianUtils.writeSwappedInteger(stream, data);
439 312
        }
313
    }
440 314

  
441
        private void encodeInteger(int data, DataOutputStream stream)
442
			throws IOException {
443
            if( this.byteOrder == wkbByteOrder.wkbXDR ) {
444
                stream.writeInt(data);
445
            } else {
446
                EndianUtils.writeSwappedInteger(stream, data);
447
            }
315
    private void encodeCoordinates(double[] coordinates, DataOutputStream stream)
316
            throws IOException {
317
        for (int i = 0; i < coordinates.length; i++) {
318
            encodeDouble(coordinates[i], stream);
448 319
        }
320
    }
449 321

  
450
	private void encodeCoordinates(double[] coordinates, DataOutputStream stream)
451
			throws IOException {
452
		for (int i = 0; i < coordinates.length; i++) {
453
			encodeDouble(coordinates[i],stream);
454
		}
455
	}
322
    private void encodeWKBGeomHead(int wkbBaseType, GeometryType geometryType,
323
            DataOutputStream stream) throws GeometryTypeNotSupportedException,
324
            IOException {
456 325

  
457
	private void encodeWKBGeomHead(int wkbBaseType, GeometryType geometryType,
458
			DataOutputStream stream) throws GeometryTypeNotSupportedException,
459
			IOException {
326
        stream.writeByte(this.byteOrder);
460 327

  
461
		stream.writeByte(this.byteOrder);
328
        int finalType = wkbBaseType % wkbGeometryType.wkb_baseToZ;
462 329

  
463
		int finalType = wkbBaseType % wkbGeometryType.wkb_baseToZ;
330
        switch (geometryType.getSubType()) {
331
            case SUBTYPES.GEOM2D:
332
                break;
333
            case SUBTYPES.GEOM2DM:
334
                finalType = finalType + wkbGeometryType.wkb_baseToM;
335
                break;
464 336

  
465
		switch (geometryType.getSubType()) {
466
		case SUBTYPES.GEOM2D:
467
			break;
468
		case SUBTYPES.GEOM2DM:
469
			finalType = finalType + wkbGeometryType.wkb_baseToM;
470
			break;
471
		
472
		case SUBTYPES.GEOM3D:
473
			finalType = finalType + wkbGeometryType.wkb_baseToZ;
474
			break;
337
            case SUBTYPES.GEOM3D:
338
                finalType = finalType + wkbGeometryType.wkb_baseToZ;
339
                break;
475 340

  
476
		case SUBTYPES.GEOM3DM:
477
			finalType = finalType + wkbGeometryType.wkb_baseToZM;
478
			break;
341
            case SUBTYPES.GEOM3DM:
342
                finalType = finalType + wkbGeometryType.wkb_baseToZM;
343
                break;
479 344

  
345
            default:
346
                throw new GeometryTypeNotSupportedException(geometryType.getType(),
347
                        geometryType.getSubType());
480 348

  
481
		default:
482
			throw new GeometryTypeNotSupportedException(geometryType.getType(),
483
					geometryType.getSubType());
349
        }
350
        encodeInteger(finalType, stream);
351
    }
484 352

  
485
		}
486
                encodeInteger(finalType, stream);
487
	}
353
    private void encodePoint(Geometry geometry, DataOutputStream stream)
354
            throws GeometryTypeNotSupportedException, IOException {
355
        GeometryType geometryType = geometry.getGeometryType();
356
        encodeWKBGeomHead(wkbGeometryType.wkbPoint, geometryType,
357
                stream);
488 358

  
359
        Point point = (Point) geometry;
360
        encodeCoordinates(point.getCoordinates(), stream);
361
    }
489 362

  
490
	private void encodePoint(Geometry geometry, DataOutputStream stream)
491
			throws GeometryTypeNotSupportedException, IOException {
492
		GeometryType geometryType = geometry.getGeometryType();
493
		encodeWKBGeomHead(wkbGeometryType.wkbPoint, geometryType,
494
				stream);
363
    private void encodeMultiPoint(Geometry geometry, DataOutputStream stream)
364
            throws GeometryTypeNotSupportedException, IOException {
365
        GeometryType geometryType = geometry.getGeometryType();
366
        encodeWKBGeomHead(wkbGeometryType.wkbMultiPoint, geometryType, stream);
495 367

  
496
		Point point = (Point) geometry;
497
                encodeCoordinates(point.getCoordinates(), stream);
498
	}
368
        MultiPoint points = (MultiPoint) geometry;
499 369

  
500
	private void encodeMultiPoint(Geometry geometry, DataOutputStream stream)
501
			throws GeometryTypeNotSupportedException, IOException {
502
		GeometryType geometryType = geometry.getGeometryType();
503
		encodeWKBGeomHead(wkbGeometryType.wkbMultiPoint, geometryType, stream);
370
        int nGeometries = points.getPrimitivesNumber();
371
        encodeInteger(nGeometries, stream);
372
        for (int i = 0; i < nGeometries; i++) {
373
            encodePoint(points.getPrimitiveAt(i), stream);
374
        }
375
    }
504 376

  
505
		MultiPoint points = (MultiPoint) geometry;
506

  
507
		int nGeometries = points.getPrimitivesNumber();
508
                encodeInteger(nGeometries, stream);
509
		for (int i=0;i<nGeometries;i++) {
510
			encodePoint(points.getPrimitiveAt(i), stream);
511
		}
512
	}
513

  
514

  
515

  
516 377
}

Also available in: Unified diff