Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.geometry / org.gvsig.fmap.geometry.impl / src / main / java / org / gvsig / fmap / geom / impl / DefaultGeometryManager.java @ 40767

History | View | Annotate | Download (26.9 KB)

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.impl;
26

    
27
import java.awt.geom.PathIterator;
28
import java.util.ArrayList;
29
import java.util.HashMap;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.Map;
33

    
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36

    
37
import org.gvsig.fmap.geom.Geometry;
38
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
39
import org.gvsig.fmap.geom.Geometry.TYPES;
40
import org.gvsig.fmap.geom.GeometryException;
41
import org.gvsig.fmap.geom.GeometryLocator;
42
import org.gvsig.fmap.geom.GeometryManager;
43
import org.gvsig.fmap.geom.SpatialIndex;
44
import org.gvsig.fmap.geom.aggregate.MultiCurve;
45
import org.gvsig.fmap.geom.aggregate.MultiSurface;
46
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
47
import org.gvsig.fmap.geom.exception.CreateGeometryException;
48
import org.gvsig.fmap.geom.operation.GeometryOperation;
49
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
50
import org.gvsig.fmap.geom.operation.GeometryOperationException;
51
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
52
import org.gvsig.fmap.geom.primitive.Curve;
53
import org.gvsig.fmap.geom.primitive.DefaultGeneralPathX;
54
import org.gvsig.fmap.geom.primitive.Envelope;
55
import org.gvsig.fmap.geom.primitive.GeneralPathX;
56
import org.gvsig.fmap.geom.primitive.NullGeometry;
57
import org.gvsig.fmap.geom.primitive.Point;
58
import org.gvsig.fmap.geom.primitive.PointGeometryType;
59
import org.gvsig.fmap.geom.primitive.Surface;
60
import org.gvsig.fmap.geom.primitive.impl.DefaultNullGeometry;
61
import org.gvsig.fmap.geom.primitive.impl.Envelope2D;
62
import org.gvsig.fmap.geom.primitive.impl.Envelope3D;
63
import org.gvsig.fmap.geom.type.GeometryType;
64
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
65
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
66
import org.gvsig.fmap.geom.type.impl.DefaultGeometryType;
67

    
68
/**
69
 * Default implementation for the {@link GeometryManager}. When the
70
 * application starts, this class is registered in the {@link GeometryLocator}
71
 * using the {@link DefaultGeometryLibrary}.
72
 * 
73
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
74
 */
75

    
76
public class DefaultGeometryManager implements GeometryManager {
77

    
78
    private static final Logger logger = LoggerFactory
79
    .getLogger(GeometryManager.class);
80
    private double flatness = 0.8;
81

    
82
    /**
83
     * This list holds the unique name of all registered geometry operations.
84
     * The index in which they are stored is also the operation code used to
85
     * invoke each one of them
86
     */
87
    private List geometryOperations = new ArrayList();
88

    
89
    /**
90
     * Common operations are registered here. Type specific operations are
91
     * registered in the corresponding GeometryType instance
92
     */
93
    // private List commonOperations = new ArrayList();
94

    
95
    /**
96
     * This map holds the instances of all registered GeometryType. The key is
97
     * the name of the specific Geometry subclass.
98
     * In other words, the string "org.gvsig.fmap.geom.primitive.Point2D" is the
99
     * hash key to obtain an instance of GeometryType holding the
100
     * operations associated to the class org.gvsig.fmap.geom.primitive.Point2D.
101
     */
102
    private Map geometryTypeName = new HashMap();
103

    
104
    /**
105
     * Matrix of geometry types by type (row) and subtype (column). This matrix
106
     * will contain null values in the cells where a GeometryType hasn't been
107
     * registered.
108
     */
109
    private GeometryType[][] geometryTypes;
110

    
111
    // Initially create a matrix of 17 x 6, which are the current default
112
    // types and subtypes. If another type or subtype is registered, the
113
    // matrix will grow as needed
114
    private static final int DEFAULT_TYPES_SIZE = 17;
115
    private static final int DEFAULT_SUBTYPES_SIZE = 6;
116

    
117
    public DefaultGeometryManager() {
118
        this(DEFAULT_TYPES_SIZE, DEFAULT_SUBTYPES_SIZE);
119
    }
120

    
121
    public DefaultGeometryManager(int initialTypesSize, int initialSubtypesSize) {
122
        geometryTypes = new GeometryType[initialTypesSize][initialSubtypesSize];
123
    }
124

    
125
    public int registerGeometryOperation(String geomOpName,
126
        GeometryOperation geomOp, GeometryType geomType) {
127
        if (geomOp == null) {
128
            throw new IllegalArgumentException("geomOp cannot be null.");
129
        }
130
        if (geomType == null) {
131
            throw new IllegalArgumentException("geomType cannot be null.");
132
        }
133

    
134
        int index = getGeometryOperationCode(geomOpName);
135

    
136
        geomType.setGeometryOperation(index, geomOp);
137

    
138
        return index;
139
    }
140

    
141
    public int registerGeometryOperation(String geomOpName,
142
        GeometryOperation geomOp) {
143
        if (geomOpName == null) {
144
            throw new IllegalArgumentException("geomOpName cannot be null.");
145
        }
146
        if (geomOp == null) {
147
            throw new IllegalArgumentException("geomOp cannot be null.");
148
        }
149

    
150
        int index = getGeometryOperationCode(geomOpName);
151

    
152
        Iterator it = geometryTypeName.values().iterator();
153
        while (it.hasNext()) {
154
            GeometryType geometryType = (GeometryType) it.next();
155
            registerGeometryOperation(geomOpName, geomOp, geometryType);
156
        }
157

    
158
        return index;
159

    
160
    }
161

    
162
    public int registerGeometryOperation(String geomOpName,
163
        GeometryOperation geomOp, int type, int subType)
164
    throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
165
        GeometryType geometryType = getGeometryType(type, subType);
166
        return registerGeometryOperation(geomOpName, geomOp, geometryType);
167
    }
168

    
169
    public int registerGeometryOperation(String geomOpName,
170
        GeometryOperation geomOp, int type) {
171
        int code = -1;
172
        Iterator it = geometryTypeName.values().iterator();
173
        while (it.hasNext()) {
174
            GeometryType geometryType = (GeometryType) it.next();
175
            if ((type == geometryType.getType())) {
176
                code =
177
                    registerGeometryOperation(geomOpName, geomOp, geometryType);
178
            }
179
        }
180
        return code;
181
    }
182

    
183
    public int registerGeometryOperationBySubtype(String geomOpName,
184
        GeometryOperation geomOp, int subType) {
185
        int code = -1;
186
        Iterator it = geometryTypeName.values().iterator();
187
        while (it.hasNext()) {
188
            GeometryType geometryType = (GeometryType) it.next();
189
            if ((subType == geometryType.getSubType())) {
190
                code =
191
                    registerGeometryOperation(geomOpName, geomOp, geometryType);
192
            }
193
        }
194
        return code;
195
    }    
196

    
197
    public int registerGeometryOperationBySuperType(String geomOpName,
198
        GeometryOperation geomOp, int superType) {       
199
        int code = -1;
200
        Iterator it = geometryTypeName.values().iterator();
201
        while (it.hasNext()) {
202
            GeometryType geometryType = (GeometryType) it.next();
203
            if (geometryType.isTypeOf(superType)) {
204
                code =
205
                    registerGeometryOperation(geomOpName, geomOp, geometryType);
206
            }
207
        }
208
        return code;
209
    }
210

    
211
    public int registerGeometryOperationBySuperSubType(String geomOpName,
212
        GeometryOperation geomOp, int superSubType) {       
213
        int code = -1;
214
        Iterator it = geometryTypeName.values().iterator();
215
        while (it.hasNext()) {
216
            GeometryType geometryType = (GeometryType) it.next();
217
            if (geometryType.isSubTypeOf(superSubType)) {
218
                code =
219
                    registerGeometryOperation(geomOpName, geomOp, geometryType);
220
            }
221
        }
222
        return code;
223
    }
224

    
225
    public GeometryType registerGeometryType(Class geomClass, String name,
226
        int type, int subType) {
227
        return registerGeometryType(geomClass, name, type, subType,
228
            new int[0], new int[0]);
229
    }    
230

    
231
    public GeometryType registerGeometryType(Class geomClass, String name,
232
        int type, int subType, int superType, int superSubType) {
233
        return registerGeometryType(geomClass, name, type, subType,
234
            new int[]{superType}, new int[]{superSubType});
235
    }
236

    
237
    public GeometryType registerGeometryType(Class geomClass, String name,
238
        int type, int subType, int superType) {
239
        return registerGeometryType(geomClass, name, type, subType,
240
            new int[]{superType}, new int[0]);
241
    }
242

    
243
    public GeometryType registerGeometryType(Class geomClass, String name,
244
        int type, int subType, int[] superTypes) {
245
        return registerGeometryType(geomClass, name, type, subType,
246
            superTypes, new int[0]);
247
    }
248

    
249
    /**
250
     * Registers a Geometry implementation class with a predefined geometry type
251
     * and returns the
252
     * associated GeometryType instance. Available predefined types are defined
253
     * in {@link Geometry.TYPES} If the class is already registered then this
254
     * method throws an IllegalArgumentException.<br>
255
     * 
256
     * How to register a geometry class with a predefined type:
257
     * 
258
     * <pre>
259
     * 
260
     * public class Point2D implements Point {
261
     *   private static final GeometryType geomType = GeometryManager.getInstance()
262
     *    .registerBasicGeometryType(Point2D.class, "Point2D", Geometry.TYPES.POINT);
263
     * 
264
     * ...
265
     *   public int getType() {
266
     *      return geomType.getType();
267
     *   }
268
     * }
269
     * </pre>
270
     * 
271
     * @param geomClass
272
     *            Geometry subclass. It must not be null and must implement
273
     *            Geometry, otherwise an exception
274
     *            is raised.
275
     * @param name
276
     *            Symbolic name for the geometry type, it can be null. If it is
277
     *            null then the symbolic name
278
     *            will be the simple class name.
279
     * @param id
280
     *            Geometry identifier.
281
     * @param type
282
     *            Type of geometry. Must be a value defined in
283
     *            {@link Geometry.TYPES}
284
     * @param subType
285
     *            SubType of geometry. Must be a value defined in
286
     *            {@link Geometry.SUBTYPES}
287
     * @return Instance of GeometryType associated to the Geometry
288
     *         implementation class
289
     *         geomClass
290
     * @throws IllegalArgumentException
291
     *             If geomClass is null or does not implement Geometry
292
     */
293
    public GeometryType registerGeometryType(Class geomClass, String name,
294
        int type, int subType, int[] superTypes, int superSubTypes[]) {
295
        if (geomClass == null) {
296
            throw new IllegalArgumentException("geomClass cannot be null.");
297
        }
298

    
299
        if (!Geometry.class.isAssignableFrom(geomClass)) {
300
            throw new IllegalArgumentException(geomClass.getName()
301
                + " must implement the Geometry interface");
302
        }
303

    
304
        // Check if it is registered
305
        GeometryType geomType = null;
306
        if (type >= geometryTypes.length || subType >= geometryTypes[0].length
307
            || (geomType = geometryTypes[type][subType]) == null) {
308
            geomType =
309
                new DefaultGeometryType(geomClass, name, type, subType,
310
                    superTypes, superSubTypes);
311
            registerGeometryType(geomType);
312
        }
313

    
314
        logger.debug("Class {} registered with name {}", geomClass,
315
            geomType.getName());
316

    
317
        return geomType;
318
    }
319

    
320
    public void registerGeometryType(GeometryType geometryType) {
321
        if (geometryType.getType() >= geometryTypes.length
322
            || geometryType.getSubType() >= geometryTypes[0].length) {
323

    
324
            // Recreate the geometry type matrix if the types
325
            // or subtypes don't fit
326
            int newTypesSize =
327
                geometryType.getType() < geometryTypes.length
328
                ? geometryTypes.length : geometryType.getType() + 1;
329
            int newSubTypesSize =
330
                geometryType.getSubType() < geometryTypes[0].length
331
                ? geometryTypes[0].length : geometryType.getSubType() + 1;
332
                GeometryType[][] newMatrix =
333
                    new GeometryType[newTypesSize][newSubTypesSize];
334

    
335
                for (int i = 0; i < geometryTypes.length; i++) {
336
                    System.arraycopy(geometryTypes[i], 0, newMatrix[i], 0,
337
                        geometryTypes[i].length);
338
                }
339
                geometryTypes = newMatrix;
340
        }
341

    
342
        geometryTypes[geometryType.getType()][geometryType.getSubType()] =
343
            geometryType;
344
        geometryTypeName.put(geometryType.getName(), geometryType);
345
    }
346

    
347
    public GeometryType registerGeometryType(Class geomClass, int type,
348
        int subType) {
349
        return registerGeometryType(geomClass, null, type, subType);
350
    }
351

    
352
    public GeometryType getGeometryType(int type, int subType)
353
    throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
354
        GeometryType gType = null;
355
        if (type >= geometryTypes.length || subType >= geometryTypes[0].length) {
356
            throw new GeometryTypeNotValidException(type, subType);
357
        }
358

    
359
        gType = geometryTypes[type][subType];
360

    
361
        if (gType == null) {
362
            throw new GeometryTypeNotSupportedException(type, subType);
363
        }
364

    
365
        return gType;
366
    }
367

    
368
    public Geometry create(GeometryType geomType)
369
    throws CreateGeometryException {
370
        return geomType.create();
371
    }
372

    
373
    public Geometry create(String name) throws CreateGeometryException {
374
        if (!geometryTypeName.containsKey(name)) {
375
            throw new IllegalArgumentException(name
376
                + " has not been registered yet.");
377
        }
378
        return ((GeometryType) geometryTypeName.get(name)).create();
379
    }
380

    
381
    public Geometry create(int type, int subType)
382
    throws CreateGeometryException {
383
        try {
384
            return getGeometryType(type, subType).create();
385
        } catch (GeometryException e) {
386
            throw new CreateGeometryException(type, subType, e);
387
        }
388
    }
389

    
390
    public Curve createCurve(GeneralPathX generalPathX, int subType)
391
    throws CreateGeometryException {
392
        Curve curve = (Curve) create(TYPES.CURVE, subType);
393
        curve.setGeneralPath(generalPathX);
394
        return curve;
395
    }
396

    
397
    public NullGeometry createNullGeometry(int subType)
398
    throws CreateGeometryException {
399
        NullGeometry nullGeom = (NullGeometry) create(TYPES.NULL, subType);
400
        return nullGeom;
401
    }
402

    
403
    public Point createPoint(double x, double y, int subType)
404
    throws CreateGeometryException {
405
        Point point = (Point) create(TYPES.POINT, subType);
406
        point.setX(x);
407
        point.setY(y);
408
        return point;
409
    }
410

    
411
    public Surface createSurface(GeneralPathX generalPathX, int subType)
412
    throws CreateGeometryException {
413
        Surface surface = (Surface) create(TYPES.SURFACE, subType);
414
        surface.setGeneralPath(generalPathX);
415
        return surface;
416
    }
417

    
418
    public GeometryOperation getGeometryOperation(int opCode, int type,
419
        int subType) throws GeometryTypeNotSupportedException,
420
        GeometryOperationNotSupportedException, GeometryTypeNotValidException {
421
        GeometryType geometryType = getGeometryType(type, subType);
422
        return geometryType.getGeometryOperation(opCode);
423
    }
424

    
425
    public GeometryOperation getGeometryOperation(int opCode)
426
        throws GeometryOperationNotSupportedException {
427
        if (opCode < 0) {
428
            throw new GeometryOperationNotSupportedException(opCode);
429
        }
430
        GeometryType type =
431
            (GeometryType) geometryTypeName.get(DefaultNullGeometry.class
432
                .getName());
433
        if (type == null) {
434
            throw new GeometryOperationNotSupportedException(opCode);
435
        }
436
        return type.getGeometryOperation(opCode);
437
    }
438

    
439
    public Object invokeOperation(int opCode, Geometry geom,
440
        GeometryOperationContext ctx)
441
    throws GeometryOperationNotSupportedException,
442
    GeometryOperationException {
443
        GeometryOperation geomOp =
444
            geom.getGeometryType().getGeometryOperation(opCode);
445

    
446
        if (geomOp != null) {
447
            return geomOp.invoke(geom, ctx);
448
        }
449

    
450
        throw new GeometryOperationNotSupportedException(opCode,
451
            geom.getGeometryType());
452
    }
453

    
454
    public Object invokeOperation(String geomOpName, Geometry geom,
455
        GeometryOperationContext ctx)
456
    throws GeometryOperationNotSupportedException,
457
    GeometryOperationException {
458
        int index = geometryOperations.indexOf(geomOpName);
459
        if (index == -1) {
460
            throw new GeometryOperationNotSupportedException(-1);
461
        }
462
        return invokeOperation(index, geom, ctx);
463
    }
464

    
465
    public Object invokeOperation(String geomOpName,
466
        GeometryOperationContext ctx)
467
        throws GeometryOperationNotSupportedException,
468
        GeometryOperationException {
469
        int index = geometryOperations.indexOf(geomOpName);
470
        GeometryOperation geomOp = getGeometryOperation(index);
471
        return geomOp.invoke(null, ctx);
472
    }
473

    
474
    public Envelope createEnvelope(int subType) {
475
        // TODO: register the envelopes!!!
476
        switch (subType) {
477
        case SUBTYPES.GEOM3D:
478
            return new Envelope3D();
479
        default:
480
            return new Envelope2D();
481
        }
482
    }
483

    
484
    public Envelope createEnvelope(double minX, double minY, double maxX,
485
        double maxY, int subType) throws CreateEnvelopeException {
486
        org.gvsig.fmap.geom.primitive.Point min = null;
487
        org.gvsig.fmap.geom.primitive.Point max = null;
488
        try {
489
            PointGeometryType gType = (PointGeometryType) getGeometryType(TYPES.POINT, subType);
490
            min = gType.createPoint(minX, minY);
491
            max = gType.createPoint(maxX, maxY);
492
        } catch (GeometryTypeNotSupportedException e) {
493
            throw new CreateEnvelopeException(subType, e);
494
        } catch (GeometryTypeNotValidException e) {
495
            throw new CreateEnvelopeException(subType, e);
496
        }
497
        switch (subType) {
498
        case SUBTYPES.GEOM2D:
499
        case SUBTYPES.GEOM2DM:
500
            // Small optimization to directly create an Envelope2D
501
            // return new Envelope2D(minX, minY, maxX, maxY);
502
            return new Envelope2D(min, max);
503
        default:
504
            Envelope envelope = createEnvelope(subType);
505
            envelope.setLowerCorner(min);
506
            envelope.setUpperCorner(max);
507
            return envelope;
508
        }
509
    }
510

    
511
    public MultiCurve createMultiCurve(GeneralPathX generalPathX, int subType)
512
    throws CreateGeometryException {
513
        if (subType != SUBTYPES.GEOM2D) {
514
            // FIXME Exception
515
            throw new UnsupportedOperationException();
516
        }
517
        MultiCurve multiCurve = (MultiCurve) create(TYPES.MULTICURVE, subType);
518
        PathIterator piter = generalPathX.getPathIterator(null);
519
        GeneralPathX tmpPath = null;
520
        Curve tmpCurve = null;
521
        double[] coords = new double[6];
522
        double[] first = new double[6];
523
        int type;
524
        while (!piter.isDone()) {
525
            type = piter.currentSegment(coords);
526
            switch (type) {
527
            case PathIterator.SEG_MOVETO:
528
                if (tmpPath != null) {
529
                    tmpCurve = createCurve(tmpPath, subType);
530
                    multiCurve.addCurve(tmpCurve);
531
                }
532
                System.arraycopy(coords, 0, first, 0, 2);
533
                tmpPath = new GeneralPathX(piter.getWindingRule());
534
                tmpPath.moveTo(coords[0], coords[1]);
535
                break;
536

    
537
            case PathIterator.SEG_LINETO:
538
                if (tmpPath == null) {
539
                    System.arraycopy(coords, 0, first, 0, 2);
540
                    tmpPath = new GeneralPathX(piter.getWindingRule());
541
                }
542
                tmpPath.lineTo(coords[0], coords[1]);
543
                break;
544

    
545
            case PathIterator.SEG_QUADTO:
546
                if (tmpPath == null) {
547
                    System.arraycopy(coords, 0, first, 0, 2);
548
                    tmpPath = new GeneralPathX(piter.getWindingRule());
549
                }
550
                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
551
                break;
552

    
553
            case PathIterator.SEG_CUBICTO:
554
                if (tmpPath == null) {
555
                    System.arraycopy(coords, 0, first, 0, 2);
556
                    tmpPath = new GeneralPathX(piter.getWindingRule());
557
                }
558
                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
559
                    coords[4], coords[5]);
560
                break;
561

    
562
            case PathIterator.SEG_CLOSE:
563
                tmpPath.lineTo(first[0], first[1]);
564
                break;
565

    
566
            } // end switch
567

    
568
            piter.next();
569

    
570
        }
571
        if (tmpPath != null) {
572
            tmpCurve = createCurve(tmpPath, subType);
573
            multiCurve.addCurve(tmpCurve);
574
        }
575

    
576
        return multiCurve;
577

    
578
    }
579

    
580
    public MultiSurface createMultiSurface(GeneralPathX generalPathX,
581
        int subType) throws CreateGeometryException {
582
        if (subType != SUBTYPES.GEOM2D) {
583
            // FIXME Exception
584
            throw new UnsupportedOperationException();
585
        }
586
        MultiSurface multiSurface =
587
            (MultiSurface) create(TYPES.MULTISURFACE, subType);
588
        PathIterator piter = generalPathX.getPathIterator(null);
589
        GeneralPathX tmpPath = null;
590
        Surface tmpSurface = null;
591
        double[] coords = new double[6];
592
        double[] first = new double[6];
593
        int type;
594
        while (!piter.isDone()) {
595
            type = piter.currentSegment(coords);
596
            switch (type) {
597
            case PathIterator.SEG_MOVETO:
598
                if (tmpPath != null) {
599
                    tmpSurface = createSurface(tmpPath, subType);
600
                    multiSurface.addSurface(tmpSurface);
601
                }
602
                System.arraycopy(coords, 0, first, 0, 2);
603
                tmpPath = new GeneralPathX(piter.getWindingRule());
604
                tmpPath.moveTo(coords[0], coords[1]);
605

    
606
            case PathIterator.SEG_LINETO:
607
                if (tmpPath == null) {
608
                    System.arraycopy(coords, 0, first, 0, 2);
609
                    tmpPath = new GeneralPathX(piter.getWindingRule());
610
                }
611
                tmpPath.lineTo(coords[0], coords[1]);
612
                break;
613

    
614
            case PathIterator.SEG_QUADTO:
615
                if (tmpPath == null) {
616
                    System.arraycopy(coords, 0, first, 0, 2);
617
                    tmpPath = new GeneralPathX(piter.getWindingRule());
618
                }
619
                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
620
                break;
621

    
622
            case PathIterator.SEG_CUBICTO:
623
                if (tmpPath == null) {
624
                    System.arraycopy(coords, 0, first, 0, 2);
625
                    tmpPath = new GeneralPathX(piter.getWindingRule());
626
                }
627
                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
628
                    coords[4], coords[5]);
629
                break;
630

    
631
            case PathIterator.SEG_CLOSE:
632
                tmpPath.lineTo(first[0], first[1]);
633
                break;
634
            } // end switch
635

    
636
            piter.next();
637

    
638
        }
639
        if (tmpPath != null) {
640
            tmpSurface = createSurface(tmpPath, subType);
641
            multiSurface.addSurface(tmpSurface);
642
        }
643

    
644
        return multiSurface;
645

    
646
    }
647

    
648
    public int getGeometryOperationCode(String geomOpName) {
649
        if (geomOpName == null) {
650
            throw new IllegalArgumentException("geomOpName cannot be null.");
651
        }
652

    
653
        int index = geometryOperations.indexOf(geomOpName);
654
        if (index == -1) {
655
            geometryOperations.add(geomOpName);
656
            index = geometryOperations.indexOf(geomOpName);
657
        }
658
        return index;
659
    }
660

    
661
    public List getGeometryOperationNames() {
662
        List operations = new ArrayList();
663
        for (int i = 0; i < operations.size(); i++) {
664
            operations.add(geometryOperations.get(i));
665
        }
666
        return operations;
667
    }
668

    
669
    public double getFlatness() {
670
        return flatness;
671
    }
672

    
673
    public void setFlatness(double flatness) {
674
        this.flatness = flatness;
675
    }
676

    
677
    public Geometry createFrom(String wkt, String srs) throws GeometryException {
678
        GeometryOperationContext context = new GeometryOperationContext();
679
        context.setAttribute("text", wkt);
680
        context.setAttribute("srs", srs);
681
        
682
        try {
683
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
684
        } catch (GeometryOperationNotSupportedException e) {
685
            throw new GeometryException(e);
686
        } catch (GeometryOperationException e) {
687
            throw new GeometryException(e);
688
        }
689
    }
690

    
691
    public Geometry createFrom(String wkt) throws GeometryException {
692
        GeometryOperationContext context = new GeometryOperationContext();
693
        context.setAttribute("text", wkt);
694
        context.setAttribute("srs", null);
695

    
696
        try {
697
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
698
        } catch (GeometryOperationNotSupportedException e) {
699
            throw new GeometryException(e);
700
        } catch (GeometryOperationException e) {
701
            throw new GeometryException(e);
702
        }
703
    }
704

    
705
    public Geometry createFrom(byte[] wkb) throws GeometryException {
706
        GeometryOperationContext context = new GeometryOperationContext();
707
        context.setAttribute("data", wkb);
708
        try {
709
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKB, context);
710
        } catch (GeometryOperationNotSupportedException e) {
711
            throw new GeometryException(e);
712
        } catch (GeometryOperationException e) {
713
            throw new GeometryException(e);
714
        }
715
    }
716

    
717
        public SpatialIndex createDefaultMemorySpatialIndex() throws GeometryException {
718
                return new SpatialIndexJTS();
719
        }
720

    
721
        public GeneralPathX createGeneralPath(int rule, PathIterator pathIterator) {
722
                if( pathIterator == null ) {
723
                        return new DefaultGeneralPathX(rule);
724
                }
725
                return  new DefaultGeneralPathX(pathIterator);
726
        }
727
        public Curve createCurve(int subType) throws CreateGeometryException {
728
                return (Curve) create(TYPES.CURVE, subType);
729
        }
730
        
731
        public MultiCurve createMultiCurve(int subType)
732
                        throws CreateGeometryException {
733
                return (MultiCurve) create(TYPES.MULTICURVE, subType);
734
        }
735
        
736
        public MultiSurface createMultiSurface(int subType)
737
                        throws CreateGeometryException {
738
                return (MultiSurface) create(TYPES.MULTISURFACE, subType);
739
        }
740
        
741
        public Surface createSurface(int subType) throws CreateGeometryException {
742
                return (Surface) create(TYPES.SURFACE, subType);
743
        }
744
}