Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / impl / DefaultGeometryManager.java @ 38596

History | View | Annotate | Download (26.8 KB)

1 26788 jpiera
/* gvSIG. Geographic Information System of the Valencian Government
2 27019 jpiera
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5 29105 jmvivo
 *
6 27019 jpiera
 * 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 2
9
 * of the License, or (at your option) any later version.
10 29105 jmvivo
 *
11 27019 jpiera
 * 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 29105 jmvivo
 *
16 27019 jpiera
 * 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 29105 jmvivo
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 27019 jpiera
 * MA  02110-1301, USA.
20 29105 jmvivo
 *
21 27019 jpiera
 */
22 26788 jpiera
23
/*
24 27019 jpiera
 * AUTHORS (In addition to CIT):
25
 * 2009 {Iver T.I.}   {Task}
26
 */
27
28 27029 jpiera
package org.gvsig.fmap.geom.impl;
29 26788 jpiera
30 29105 jmvivo
import java.awt.geom.PathIterator;
31 26788 jpiera
import java.util.ArrayList;
32
import java.util.HashMap;
33 27229 jpiera
import java.util.Iterator;
34 26788 jpiera
import java.util.List;
35
import java.util.Map;
36
37 34140 jpiera
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39
40 27029 jpiera
import org.gvsig.fmap.geom.Geometry;
41 34140 jpiera
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
42
import org.gvsig.fmap.geom.Geometry.TYPES;
43 31020 cordinyana
import org.gvsig.fmap.geom.GeometryException;
44 27029 jpiera
import org.gvsig.fmap.geom.GeometryLocator;
45
import org.gvsig.fmap.geom.GeometryManager;
46 29105 jmvivo
import org.gvsig.fmap.geom.aggregate.MultiCurve;
47
import org.gvsig.fmap.geom.aggregate.MultiSurface;
48 27397 jpiera
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
49
import org.gvsig.fmap.geom.exception.CreateGeometryException;
50 26788 jpiera
import org.gvsig.fmap.geom.operation.GeometryOperation;
51
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
52
import org.gvsig.fmap.geom.operation.GeometryOperationException;
53
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
54 32924 jjdelcerro
import org.gvsig.fmap.geom.operation.fromwkt.FromWKTGeometryOperationContext;
55 27397 jpiera
import org.gvsig.fmap.geom.primitive.Curve;
56 27019 jpiera
import org.gvsig.fmap.geom.primitive.Envelope;
57 27397 jpiera
import org.gvsig.fmap.geom.primitive.GeneralPathX;
58
import org.gvsig.fmap.geom.primitive.NullGeometry;
59
import org.gvsig.fmap.geom.primitive.Point;
60 38596 cordinyana
import org.gvsig.fmap.geom.primitive.PointGeometryType;
61 27397 jpiera
import org.gvsig.fmap.geom.primitive.Surface;
62 32387 nbrodin
import org.gvsig.fmap.geom.primitive.impl.DefaultNullGeometry;
63 27029 jpiera
import org.gvsig.fmap.geom.primitive.impl.Envelope2D;
64
import org.gvsig.fmap.geom.primitive.impl.Envelope3D;
65 26788 jpiera
import org.gvsig.fmap.geom.type.GeometryType;
66
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
67 28085 jpiera
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
68 27029 jpiera
import org.gvsig.fmap.geom.type.impl.DefaultGeometryType;
69 26788 jpiera
70
/**
71 26809 jpiera
 * Default implementation for the {@link GeometryManager}. When the
72 34708 jjdelcerro
 * application starts, this class is registered in the {@link GeometryLocator}
73
 * using the {@link DefaultGeometryLibrary}.
74
 *
75 26788 jpiera
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
76
 */
77
78 31020 cordinyana
public class DefaultGeometryManager implements GeometryManager {
79 26788 jpiera
80 34708 jjdelcerro
    private static final Logger logger = LoggerFactory
81 35185 jpiera
    .getLogger(GeometryManager.class);
82 34708 jjdelcerro
    private double flatness = 0.8;
83 26788 jpiera
84 34708 jjdelcerro
    /**
85
     * This list holds the unique name of all registered geometry operations.
86
     * The index in which they are stored is also the operation code used to
87
     * invoke each one of them
88
     */
89
    private List geometryOperations = new ArrayList();
90 26788 jpiera
91 34708 jjdelcerro
    /**
92
     * Common operations are registered here. Type specific operations are
93
     * registered in the corresponding GeometryType instance
94
     */
95
    // private List commonOperations = new ArrayList();
96 27019 jpiera
97 34708 jjdelcerro
    /**
98
     * This map holds the instances of all registered GeometryType. The key is
99
     * the name of the specific Geometry subclass.
100
     * In other words, the string "org.gvsig.fmap.geom.primitive.Point2D" is the
101
     * hash key to obtain an instance of GeometryType holding the
102
     * operations associated to the class org.gvsig.fmap.geom.primitive.Point2D.
103
     */
104
    private Map geometryTypeName = new HashMap();
105 26788 jpiera
106 34708 jjdelcerro
    /**
107
     * Matrix of geometry types by type (row) and subtype (column). This matrix
108
     * will contain null values in the cells where a GeometryType hasn't been
109
     * registered.
110
     */
111
    private GeometryType[][] geometryTypes;
112 26788 jpiera
113 34708 jjdelcerro
    // Initially create a matrix of 17 x 6, which are the current default
114
    // types and subtypes. If another type or subtype is registered, the
115
    // matrix will grow as needed
116
    private static final int DEFAULT_TYPES_SIZE = 17;
117
    private static final int DEFAULT_SUBTYPES_SIZE = 6;
118 26788 jpiera
119 34708 jjdelcerro
    public DefaultGeometryManager() {
120
        this(DEFAULT_TYPES_SIZE, DEFAULT_SUBTYPES_SIZE);
121
    }
122 26788 jpiera
123 34708 jjdelcerro
    public DefaultGeometryManager(int initialTypesSize, int initialSubtypesSize) {
124
        geometryTypes = new GeometryType[initialTypesSize][initialSubtypesSize];
125
    }
126 26788 jpiera
127 34708 jjdelcerro
    public int registerGeometryOperation(String geomOpName,
128
        GeometryOperation geomOp, GeometryType geomType) {
129
        if (geomOp == null) {
130
            throw new IllegalArgumentException("geomOp cannot be null.");
131
        }
132
        if (geomType == null) {
133
            throw new IllegalArgumentException("geomType cannot be null.");
134
        }
135 26788 jpiera
136 34708 jjdelcerro
        int index = getGeometryOperationCode(geomOpName);
137 26788 jpiera
138 34708 jjdelcerro
        geomType.setGeometryOperation(index, geomOp);
139 26788 jpiera
140 34708 jjdelcerro
        return index;
141
    }
142 26788 jpiera
143 34708 jjdelcerro
    public int registerGeometryOperation(String geomOpName,
144
        GeometryOperation geomOp) {
145
        if (geomOpName == null) {
146
            throw new IllegalArgumentException("geomOpName cannot be null.");
147
        }
148
        if (geomOp == null) {
149
            throw new IllegalArgumentException("geomOp cannot be null.");
150
        }
151 26788 jpiera
152 34708 jjdelcerro
        int index = getGeometryOperationCode(geomOpName);
153 26788 jpiera
154 34708 jjdelcerro
        Iterator it = geometryTypeName.keySet().iterator();
155
        while (it.hasNext()) {
156
            String className = (String) it.next();
157
            GeometryType geometryType =
158
                (GeometryType) geometryTypeName.get(className);
159
            registerGeometryOperation(geomOpName, geomOp, geometryType);
160
        }
161 26788 jpiera
162 34708 jjdelcerro
        return index;
163 26788 jpiera
164 34708 jjdelcerro
    }
165 26788 jpiera
166 34708 jjdelcerro
    public int registerGeometryOperation(String geomOpName,
167
        GeometryOperation geomOp, int type, int subType)
168 35185 jpiera
    throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
169 34708 jjdelcerro
        GeometryType geometryType = getGeometryType(type, subType);
170
        return registerGeometryOperation(geomOpName, geomOp, geometryType);
171
    }
172 27397 jpiera
173 34708 jjdelcerro
    public int registerGeometryOperation(String geomOpName,
174
        GeometryOperation geomOp, int type) {
175
        Iterator it = geometryTypeName.keySet().iterator();
176
        int code = -1;
177
        while (it.hasNext()) {
178
            String className = (String) it.next();
179
            GeometryType geometryType =
180
                (GeometryType) geometryTypeName.get(className);
181
            if ((type == geometryType.getType())) {
182
                code =
183
                    registerGeometryOperation(geomOpName, geomOp, geometryType);
184
            }
185
        }
186
        return code;
187
    }
188 27229 jpiera
189 34708 jjdelcerro
    public int registerGeometryOperationBySubtype(String geomOpName,
190
        GeometryOperation geomOp, int subType) {
191
        Iterator it = geometryTypeName.keySet().iterator();
192
        int code = -1;
193
        while (it.hasNext()) {
194
            String className = (String) it.next();
195
            GeometryType geometryType =
196
                (GeometryType) geometryTypeName.get(className);
197
            if ((subType == geometryType.getSubType())) {
198
                code =
199
                    registerGeometryOperation(geomOpName, geomOp, geometryType);
200
            }
201
        }
202
        return code;
203 35185 jpiera
    }
204
205
    public int registerGeometryOperationBySuperType(String geomOpName,
206
        GeometryOperation geomOp, int superType) {
207
        Iterator it = geometryTypeName.keySet().iterator();
208
        int code = -1;
209
        while (it.hasNext()) {
210
            String className = (String) it.next();
211
            GeometryType geometryType =
212
                (GeometryType) geometryTypeName.get(className);
213
            if (geometryType.isTypeOf(superType)) {
214
                code =
215
                    registerGeometryOperation(geomOpName, geomOp, geometryType);
216
            }
217
        }
218
        return code;
219 34708 jjdelcerro
    }
220 26788 jpiera
221 35185 jpiera
    public int registerGeometryOperationBySuperSubType(String geomOpName,
222
        GeometryOperation geomOp, int superSubType) {
223
        Iterator it = geometryTypeName.keySet().iterator();
224
        int code = -1;
225
        while (it.hasNext()) {
226
            String className = (String) it.next();
227
            GeometryType geometryType =
228
                (GeometryType) geometryTypeName.get(className);
229
            if (geometryType.isSubTypeOf(superSubType)) {
230
                code =
231
                    registerGeometryOperation(geomOpName, geomOp, geometryType);
232
            }
233
        }
234
        return code;
235
    }
236
237 34708 jjdelcerro
    public GeometryType registerGeometryType(Class geomClass, String name,
238
        int type, int subType) {
239 35185 jpiera
        return registerGeometryType(geomClass, name, type, subType,
240
            new int[0], new int[0]);
241
    }
242
243
    public GeometryType registerGeometryType(Class geomClass, String name,
244
        int type, int subType, int superType, int superSubType) {
245
        return registerGeometryType(geomClass, name, type, subType,
246
            new int[]{superType}, new int[]{superSubType});
247 34708 jjdelcerro
    }
248 26788 jpiera
249 35185 jpiera
    public GeometryType registerGeometryType(Class geomClass, String name,
250
        int type, int subType, int superType) {
251
        return registerGeometryType(geomClass, name, type, subType,
252
            new int[]{superType}, new int[0]);
253
    }
254
255
    public GeometryType registerGeometryType(Class geomClass, String name,
256
        int type, int subType, int[] superTypes) {
257
        return registerGeometryType(geomClass, name, type, subType,
258
            superTypes, new int[0]);
259
    }
260
261 34708 jjdelcerro
    /**
262
     * Registers a Geometry implementation class with a predefined geometry type
263
     * and returns the
264
     * associated GeometryType instance. Available predefined types are defined
265
     * in {@link Geometry.TYPES} If the class is already registered then this
266
     * method throws an IllegalArgumentException.<br>
267
     *
268
     * How to register a geometry class with a predefined type:
269
     *
270
     * <pre>
271
     *
272
     * public class Point2D implements Point {
273
     *   private static final GeometryType geomType = GeometryManager.getInstance()
274
     *    .registerBasicGeometryType(Point2D.class, "Point2D", Geometry.TYPES.POINT);
275
     *
276
     * ...
277
     *   public int getType() {
278
     *      return geomType.getType();
279
     *   }
280
     * }
281
     * </pre>
282
     *
283
     * @param geomClass
284
     *            Geometry subclass. It must not be null and must implement
285
     *            Geometry, otherwise an exception
286
     *            is raised.
287
     * @param name
288
     *            Symbolic name for the geometry type, it can be null. If it is
289
     *            null then the symbolic name
290
     *            will be the simple class name.
291
     * @param id
292
     *            Geometry identifier.
293
     * @param type
294
     *            Type of geometry. Must be a value defined in
295
     *            {@link Geometry.TYPES}
296
     * @param subType
297
     *            SubType of geometry. Must be a value defined in
298
     *            {@link Geometry.SUBTYPES}
299
     * @return Instance of GeometryType associated to the Geometry
300
     *         implementation class
301
     *         geomClass
302
     * @throws IllegalArgumentException
303
     *             If geomClass is null or does not implement Geometry
304
     */
305 38596 cordinyana
    public GeometryType registerGeometryType(Class geomClass, String name,
306
        int type, int subType, int[] superTypes, int superSubTypes[]) {
307 34708 jjdelcerro
        if (geomClass == null) {
308
            throw new IllegalArgumentException("geomClass cannot be null.");
309
        }
310 26788 jpiera
311 34708 jjdelcerro
        if (!Geometry.class.isAssignableFrom(geomClass)) {
312
            throw new IllegalArgumentException(geomClass.getName()
313
                + " must implement the Geometry interface");
314
        }
315 26788 jpiera
316 34708 jjdelcerro
        // Check if it is registered
317
        GeometryType geomType = null;
318
        if (type >= geometryTypes.length || subType >= geometryTypes[0].length
319
            || (geomType = geometryTypes[type][subType]) == null) {
320
            geomType =
321 38596 cordinyana
                new DefaultGeometryType(geomClass, name, type, subType,
322 35185 jpiera
                    superTypes, superSubTypes);
323 34708 jjdelcerro
            registerGeometryType(geomType);
324
            geometryTypeName.put(geomClass.getName(), geomType);
325
        }
326 31020 cordinyana
327 34708 jjdelcerro
        logger.debug("Class {} registered with name {}", geomClass,
328
            geomType.getName());
329 26788 jpiera
330 34708 jjdelcerro
        return geomType;
331
    }
332 31020 cordinyana
333 38596 cordinyana
    public void registerGeometryType(GeometryType geometryType) {
334 34708 jjdelcerro
        if (geometryType.getType() >= geometryTypes.length
335
            || geometryType.getSubType() >= geometryTypes[0].length) {
336 31020 cordinyana
337 34708 jjdelcerro
            // Recreate the geometry type matrix if the types
338
            // or subtypes don't fit
339
            int newTypesSize =
340
                geometryType.getType() < geometryTypes.length
341 35185 jpiera
                ? geometryTypes.length : geometryType.getType() + 1;
342 34708 jjdelcerro
            int newSubTypesSize =
343
                geometryType.getSubType() < geometryTypes[0].length
344 35185 jpiera
                ? geometryTypes[0].length : geometryType.getSubType() + 1;
345
                GeometryType[][] newMatrix =
346
                    new GeometryType[newTypesSize][newSubTypesSize];
347 31020 cordinyana
348 35185 jpiera
                for (int i = 0; i < geometryTypes.length; i++) {
349
                    System.arraycopy(geometryTypes[i], 0, newMatrix[i], 0,
350
                        geometryTypes[i].length);
351
                }
352
                geometryTypes = newMatrix;
353 34708 jjdelcerro
        }
354 31020 cordinyana
355 34708 jjdelcerro
        geometryTypes[geometryType.getType()][geometryType.getSubType()] =
356
            geometryType;
357
    }
358 26788 jpiera
359 34708 jjdelcerro
    public GeometryType registerGeometryType(Class geomClass, int type,
360
        int subType) {
361
        return registerGeometryType(geomClass, null, type, subType);
362
    }
363 26788 jpiera
364 34708 jjdelcerro
    public GeometryType getGeometryType(String className)
365 35185 jpiera
    throws GeometryTypeNotSupportedException {
366 34708 jjdelcerro
        if (!geometryTypeName.containsKey(className)) {
367
            throw new GeometryTypeNotSupportedException(className);
368
        }
369
        return (GeometryType) geometryTypeName.get(className);
370
    }
371 31020 cordinyana
372 34708 jjdelcerro
    public GeometryType getGeometryType(int type, int subType)
373 35185 jpiera
    throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
374 34708 jjdelcerro
        GeometryType gType = null;
375
        if (type >= geometryTypes.length || subType >= geometryTypes[0].length) {
376
            throw new GeometryTypeNotValidException(type, subType);
377
        }
378 31020 cordinyana
379 34708 jjdelcerro
        gType = geometryTypes[type][subType];
380 31020 cordinyana
381 34708 jjdelcerro
        if (gType == null) {
382
            throw new GeometryTypeNotSupportedException(type, subType);
383
        }
384 31020 cordinyana
385 34708 jjdelcerro
        return gType;
386
    }
387 26788 jpiera
388 34708 jjdelcerro
    public Geometry create(GeometryType geomType)
389 35185 jpiera
    throws CreateGeometryException {
390 34708 jjdelcerro
        return geomType.create();
391
    }
392 26788 jpiera
393 34708 jjdelcerro
    public Geometry create(String name) throws CreateGeometryException {
394
        if (!geometryTypeName.containsKey(name)) {
395
            throw new IllegalArgumentException(name
396
                + " has not been registered yet.");
397
        }
398
        return ((GeometryType) geometryTypeName.get(name)).create();
399
    }
400 26788 jpiera
401 34708 jjdelcerro
    public Geometry create(int type, int subType)
402 35185 jpiera
    throws CreateGeometryException {
403 34708 jjdelcerro
        try {
404
            return getGeometryType(type, subType).create();
405
        } catch (GeometryException e) {
406
            throw new CreateGeometryException(type, subType, e);
407
        }
408
    }
409 27397 jpiera
410 34708 jjdelcerro
    public Curve createCurve(GeneralPathX generalPathX, int subType)
411 35185 jpiera
    throws CreateGeometryException {
412 34708 jjdelcerro
        Curve curve = (Curve) create(TYPES.CURVE, subType);
413
        curve.setGeneralPath(generalPathX);
414
        return curve;
415
    }
416 27397 jpiera
417 34708 jjdelcerro
    public NullGeometry createNullGeometry(int subType)
418 35185 jpiera
    throws CreateGeometryException {
419 34708 jjdelcerro
        NullGeometry nullGeom = (NullGeometry) create(TYPES.NULL, subType);
420
        return nullGeom;
421
    }
422 27397 jpiera
423 34708 jjdelcerro
    public Point createPoint(double x, double y, int subType)
424 35185 jpiera
    throws CreateGeometryException {
425 34708 jjdelcerro
        Point point = (Point) create(TYPES.POINT, subType);
426
        point.setX(x);
427
        point.setY(y);
428
        return point;
429
    }
430 27397 jpiera
431 34708 jjdelcerro
    public Surface createSurface(GeneralPathX generalPathX, int subType)
432 35185 jpiera
    throws CreateGeometryException {
433 34708 jjdelcerro
        Surface surface = (Surface) create(TYPES.SURFACE, subType);
434
        surface.setGeneralPath(generalPathX);
435
        return surface;
436
    }
437 27397 jpiera
438 34708 jjdelcerro
    public GeometryOperation getGeometryOperation(int opCode, int type,
439
        int subType) throws GeometryTypeNotSupportedException,
440
        GeometryOperationNotSupportedException, GeometryTypeNotValidException {
441
        GeometryType geometryType = getGeometryType(type, subType);
442
        return geometryType.getGeometryOperation(opCode);
443
    }
444 26788 jpiera
445 37331 cordinyana
    public GeometryOperation getGeometryOperation(int opCode)
446
        throws GeometryOperationNotSupportedException {
447
        if (opCode < 0) {
448
            throw new GeometryOperationNotSupportedException(opCode);
449
        }
450
        GeometryType type =
451
            (GeometryType) geometryTypeName.get(DefaultNullGeometry.class
452
                .getName());
453
        if (type == null) {
454
            throw new GeometryOperationNotSupportedException(opCode);
455
        }
456
        return type.getGeometryOperation(opCode);
457
    }
458
459 34708 jjdelcerro
    public Object invokeOperation(int opCode, Geometry geom,
460
        GeometryOperationContext ctx)
461 35185 jpiera
    throws GeometryOperationNotSupportedException,
462
    GeometryOperationException {
463 34708 jjdelcerro
        GeometryOperation geomOp =
464
            geom.getGeometryType().getGeometryOperation(opCode);
465 26788 jpiera
466 34708 jjdelcerro
        if (geomOp != null) {
467
            return geomOp.invoke(geom, ctx);
468
        }
469 26788 jpiera
470 34708 jjdelcerro
        throw new GeometryOperationNotSupportedException(opCode,
471
            geom.getGeometryType());
472
    }
473 27019 jpiera
474 34708 jjdelcerro
    public Object invokeOperation(String geomOpName, Geometry geom,
475
        GeometryOperationContext ctx)
476 35185 jpiera
    throws GeometryOperationNotSupportedException,
477
    GeometryOperationException {
478 34708 jjdelcerro
        int index = geometryOperations.indexOf(geomOpName);
479
        if (index == -1) {
480
            throw new GeometryOperationNotSupportedException(-1);
481
        }
482
        return invokeOperation(index, geom, ctx);
483
    }
484 26788 jpiera
485 34708 jjdelcerro
    public Object invokeOperation(String geomOpName,
486
        GeometryOperationContext ctx)
487 37331 cordinyana
        throws GeometryOperationNotSupportedException,
488
        GeometryOperationException {
489 34708 jjdelcerro
        int index = geometryOperations.indexOf(geomOpName);
490 37331 cordinyana
        GeometryOperation geomOp = getGeometryOperation(index);
491
        return geomOp.invoke(null, ctx);
492 34708 jjdelcerro
    }
493 27019 jpiera
494 34708 jjdelcerro
    public GeometryType unregisterGeometryType(Class geomClass) {
495
        return (GeometryType) geometryTypeName.remove(geomClass.getName());
496
    }
497 27397 jpiera
498 34708 jjdelcerro
    public Envelope createEnvelope(int subType) {
499
        // TODO: register the envelopes!!!
500
        switch (subType) {
501
        case SUBTYPES.GEOM3D:
502
            return new Envelope3D();
503
        default:
504
            return new Envelope2D();
505
        }
506
    }
507 27397 jpiera
508 34708 jjdelcerro
    public Envelope createEnvelope(double minX, double minY, double maxX,
509
        double maxY, int subType) throws CreateEnvelopeException {
510
        org.gvsig.fmap.geom.primitive.Point min = null;
511
        org.gvsig.fmap.geom.primitive.Point max = null;
512
        try {
513 38596 cordinyana
            PointGeometryType gType = (PointGeometryType) getGeometryType(TYPES.POINT, subType);
514
            min = gType.createPoint(minX, minY);
515
            max = gType.createPoint(maxX, maxY);
516 34708 jjdelcerro
        } catch (GeometryTypeNotSupportedException e) {
517
            throw new CreateEnvelopeException(subType, e);
518
        } catch (GeometryTypeNotValidException e) {
519
            throw new CreateEnvelopeException(subType, e);
520
        }
521
        switch (subType) {
522
        case SUBTYPES.GEOM2D:
523
        case SUBTYPES.GEOM2DM:
524
            // Small optimization to directly create an Envelope2D
525
            // return new Envelope2D(minX, minY, maxX, maxY);
526
            return new Envelope2D(min, max);
527
        default:
528
            Envelope envelope = createEnvelope(subType);
529
            envelope.setLowerCorner(min);
530
            envelope.setUpperCorner(max);
531
            return envelope;
532
        }
533
    }
534 29105 jmvivo
535 34708 jjdelcerro
    public MultiCurve createMultiCurve(GeneralPathX generalPathX, int subType)
536 35185 jpiera
    throws CreateGeometryException {
537 34708 jjdelcerro
        if (subType != SUBTYPES.GEOM2D) {
538
            // FIXME Exception
539
            throw new UnsupportedOperationException();
540
        }
541
        MultiCurve multiCurve = (MultiCurve) create(TYPES.MULTICURVE, subType);
542
        PathIterator piter = generalPathX.getPathIterator(null);
543
        GeneralPathX tmpPath = null;
544
        Curve tmpCurve = null;
545
        double[] coords = new double[6];
546
        double[] first = new double[6];
547
        int type;
548
        while (!piter.isDone()) {
549
            type = piter.currentSegment(coords);
550
            switch (type) {
551
            case PathIterator.SEG_MOVETO:
552
                if (tmpPath != null) {
553
                    tmpCurve = createCurve(tmpPath, subType);
554
                    multiCurve.addCurve(tmpCurve);
555
                }
556
                System.arraycopy(coords, 0, first, 0, 2);
557
                tmpPath = new GeneralPathX(piter.getWindingRule());
558
                tmpPath.moveTo(coords[0], coords[1]);
559
                break;
560 29105 jmvivo
561 34708 jjdelcerro
            case PathIterator.SEG_LINETO:
562
                if (tmpPath == null) {
563
                    System.arraycopy(coords, 0, first, 0, 2);
564
                    tmpPath = new GeneralPathX(piter.getWindingRule());
565
                }
566
                tmpPath.lineTo(coords[0], coords[1]);
567
                break;
568 29113 jmvivo
569 34708 jjdelcerro
            case PathIterator.SEG_QUADTO:
570
                if (tmpPath == null) {
571
                    System.arraycopy(coords, 0, first, 0, 2);
572
                    tmpPath = new GeneralPathX(piter.getWindingRule());
573
                }
574
                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
575
                break;
576 29105 jmvivo
577 34708 jjdelcerro
            case PathIterator.SEG_CUBICTO:
578
                if (tmpPath == null) {
579
                    System.arraycopy(coords, 0, first, 0, 2);
580
                    tmpPath = new GeneralPathX(piter.getWindingRule());
581
                }
582
                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
583
                    coords[4], coords[5]);
584
                break;
585 29105 jmvivo
586 34708 jjdelcerro
            case PathIterator.SEG_CLOSE:
587
                tmpPath.lineTo(first[0], first[1]);
588
                break;
589 29105 jmvivo
590 34708 jjdelcerro
            } // end switch
591 29105 jmvivo
592 34708 jjdelcerro
            piter.next();
593 29113 jmvivo
594 34708 jjdelcerro
        }
595
        if (tmpPath != null) {
596
            tmpCurve = createCurve(tmpPath, subType);
597
            multiCurve.addCurve(tmpCurve);
598
        }
599 29105 jmvivo
600 34708 jjdelcerro
        return multiCurve;
601 29105 jmvivo
602 34708 jjdelcerro
    }
603 29105 jmvivo
604 34708 jjdelcerro
    public MultiSurface createMultiSurface(GeneralPathX generalPathX,
605
        int subType) throws CreateGeometryException {
606
        if (subType != SUBTYPES.GEOM2D) {
607
            // FIXME Exception
608
            throw new UnsupportedOperationException();
609
        }
610
        MultiSurface multiSurface =
611
            (MultiSurface) create(TYPES.MULTISURFACE, subType);
612
        PathIterator piter = generalPathX.getPathIterator(null);
613
        GeneralPathX tmpPath = null;
614
        Surface tmpSurface = null;
615
        double[] coords = new double[6];
616
        double[] first = new double[6];
617
        int type;
618
        while (!piter.isDone()) {
619
            type = piter.currentSegment(coords);
620
            switch (type) {
621
            case PathIterator.SEG_MOVETO:
622
                if (tmpPath != null) {
623
                    tmpSurface = createSurface(tmpPath, subType);
624
                    multiSurface.addSurface(tmpSurface);
625
                }
626
                System.arraycopy(coords, 0, first, 0, 2);
627
                tmpPath = new GeneralPathX(piter.getWindingRule());
628
                tmpPath.moveTo(coords[0], coords[1]);
629 29105 jmvivo
630 34708 jjdelcerro
            case PathIterator.SEG_LINETO:
631
                if (tmpPath == null) {
632
                    System.arraycopy(coords, 0, first, 0, 2);
633
                    tmpPath = new GeneralPathX(piter.getWindingRule());
634
                }
635
                tmpPath.lineTo(coords[0], coords[1]);
636
                break;
637 29105 jmvivo
638 34708 jjdelcerro
            case PathIterator.SEG_QUADTO:
639
                if (tmpPath == null) {
640
                    System.arraycopy(coords, 0, first, 0, 2);
641
                    tmpPath = new GeneralPathX(piter.getWindingRule());
642
                }
643
                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
644
                break;
645 29105 jmvivo
646 34708 jjdelcerro
            case PathIterator.SEG_CUBICTO:
647
                if (tmpPath == null) {
648
                    System.arraycopy(coords, 0, first, 0, 2);
649
                    tmpPath = new GeneralPathX(piter.getWindingRule());
650
                }
651
                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
652
                    coords[4], coords[5]);
653
                break;
654 29105 jmvivo
655 34708 jjdelcerro
            case PathIterator.SEG_CLOSE:
656
                tmpPath.lineTo(first[0], first[1]);
657
                break;
658
            } // end switch
659 29113 jmvivo
660 34708 jjdelcerro
            piter.next();
661 29105 jmvivo
662 34708 jjdelcerro
        }
663
        if (tmpPath != null) {
664
            tmpSurface = createSurface(tmpPath, subType);
665
            multiSurface.addSurface(tmpSurface);
666
        }
667 29105 jmvivo
668 34708 jjdelcerro
        return multiSurface;
669 29105 jmvivo
670 34708 jjdelcerro
    }
671 29105 jmvivo
672 34708 jjdelcerro
    public int getGeometryOperationCode(String geomOpName) {
673
        if (geomOpName == null) {
674
            throw new IllegalArgumentException("geomOpName cannot be null.");
675
        }
676 29105 jmvivo
677 34708 jjdelcerro
        int index = geometryOperations.indexOf(geomOpName);
678
        if (index == -1) {
679
            geometryOperations.add(geomOpName);
680
            index = geometryOperations.indexOf(geomOpName);
681
        }
682
        return index;
683
    }
684 29105 jmvivo
685 34708 jjdelcerro
    public List getGeometryOperationNames() {
686
        List operations = new ArrayList();
687
        for (int i = 0; i < operations.size(); i++) {
688
            operations.add(geometryOperations.get(i));
689
        }
690
        return operations;
691
    }
692 29798 jpiera
693 34708 jjdelcerro
    public double getFlatness() {
694
        return flatness;
695
    }
696 29798 jpiera
697 34708 jjdelcerro
    public void setFlatness(double flatness) {
698
        this.flatness = flatness;
699
    }
700 29798 jpiera
701 34708 jjdelcerro
    public Geometry createFrom(String wkt, String srs) throws GeometryException {
702
        FromWKTGeometryOperationContext context =
703
            new FromWKTGeometryOperationContext(wkt, srs);
704
        try {
705
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
706
        } catch (GeometryOperationNotSupportedException e) {
707
            throw new GeometryException(e);
708
        } catch (GeometryOperationException e) {
709
            throw new GeometryException(e);
710
        }
711
    }
712 30323 jpiera
713 34708 jjdelcerro
    public Geometry createFrom(String wkt) throws GeometryException {
714
        FromWKTGeometryOperationContext context =
715
            new FromWKTGeometryOperationContext(wkt, null);
716
        try {
717
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
718
        } catch (GeometryOperationNotSupportedException e) {
719
            throw new GeometryException(e);
720
        } catch (GeometryOperationException e) {
721
            throw new GeometryException(e);
722
        }
723
    }
724 30323 jpiera
725 34708 jjdelcerro
    public Geometry createFrom(byte[] wkb) throws GeometryException {
726
        GeometryOperationContext context = new GeometryOperationContext();
727
        context.setAttribute("data", wkb);
728
        try {
729
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKB, context);
730
        } catch (GeometryOperationNotSupportedException e) {
731
            throw new GeometryException(e);
732
        } catch (GeometryOperationException e) {
733
            throw new GeometryException(e);
734
        }
735
    }
736
}