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 @ 40435

History | View | Annotate | Download (26.9 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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 2
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
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2009 {Iver T.I.}   {Task}
26
 */
27

    
28
package org.gvsig.fmap.geom.impl;
29

    
30
import java.awt.geom.PathIterator;
31
import java.util.ArrayList;
32
import java.util.HashMap;
33
import java.util.Iterator;
34
import java.util.List;
35
import java.util.Map;
36

    
37
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39

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

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

    
79
public class DefaultGeometryManager implements GeometryManager {
80

    
81
    private static final Logger logger = LoggerFactory
82
    .getLogger(GeometryManager.class);
83
    private double flatness = 0.8;
84

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

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

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

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

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

    
120
    public DefaultGeometryManager() {
121
        this(DEFAULT_TYPES_SIZE, DEFAULT_SUBTYPES_SIZE);
122
    }
123

    
124
    public DefaultGeometryManager(int initialTypesSize, int initialSubtypesSize) {
125
        geometryTypes = new GeometryType[initialTypesSize][initialSubtypesSize];
126
    }
127

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

    
137
        int index = getGeometryOperationCode(geomOpName);
138

    
139
        geomType.setGeometryOperation(index, geomOp);
140

    
141
        return index;
142
    }
143

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

    
153
        int index = getGeometryOperationCode(geomOpName);
154

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

    
161
        return index;
162

    
163
    }
164

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

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

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

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

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

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

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

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

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

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

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

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

    
317
        logger.debug("Class {} registered with name {}", geomClass,
318
            geomType.getName());
319

    
320
        return geomType;
321
    }
322

    
323
    public void registerGeometryType(GeometryType geometryType) {
324
        if (geometryType.getType() >= geometryTypes.length
325
            || geometryType.getSubType() >= geometryTypes[0].length) {
326

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

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

    
345
        geometryTypes[geometryType.getType()][geometryType.getSubType()] =
346
            geometryType;
347
        geometryTypeName.put(geometryType.getName(), geometryType);
348
    }
349

    
350
    public GeometryType registerGeometryType(Class geomClass, int type,
351
        int subType) {
352
        return registerGeometryType(geomClass, null, type, subType);
353
    }
354

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

    
362
        gType = geometryTypes[type][subType];
363

    
364
        if (gType == null) {
365
            throw new GeometryTypeNotSupportedException(type, subType);
366
        }
367

    
368
        return gType;
369
    }
370

    
371
    public Geometry create(GeometryType geomType)
372
    throws CreateGeometryException {
373
        return geomType.create();
374
    }
375

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

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

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

    
400
    public NullGeometry createNullGeometry(int subType)
401
    throws CreateGeometryException {
402
        NullGeometry nullGeom = (NullGeometry) create(TYPES.NULL, subType);
403
        return nullGeom;
404
    }
405

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

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

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

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

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

    
449
        if (geomOp != null) {
450
            return geomOp.invoke(geom, ctx);
451
        }
452

    
453
        throw new GeometryOperationNotSupportedException(opCode,
454
            geom.getGeometryType());
455
    }
456

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

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

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

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

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

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

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

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

    
565
            case PathIterator.SEG_CLOSE:
566
                tmpPath.lineTo(first[0], first[1]);
567
                break;
568

    
569
            } // end switch
570

    
571
            piter.next();
572

    
573
        }
574
        if (tmpPath != null) {
575
            tmpCurve = createCurve(tmpPath, subType);
576
            multiCurve.addCurve(tmpCurve);
577
        }
578

    
579
        return multiCurve;
580

    
581
    }
582

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

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

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

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

    
634
            case PathIterator.SEG_CLOSE:
635
                tmpPath.lineTo(first[0], first[1]);
636
                break;
637
            } // end switch
638

    
639
            piter.next();
640

    
641
        }
642
        if (tmpPath != null) {
643
            tmpSurface = createSurface(tmpPath, subType);
644
            multiSurface.addSurface(tmpSurface);
645
        }
646

    
647
        return multiSurface;
648

    
649
    }
650

    
651
    public int getGeometryOperationCode(String geomOpName) {
652
        if (geomOpName == null) {
653
            throw new IllegalArgumentException("geomOpName cannot be null.");
654
        }
655

    
656
        int index = geometryOperations.indexOf(geomOpName);
657
        if (index == -1) {
658
            geometryOperations.add(geomOpName);
659
            index = geometryOperations.indexOf(geomOpName);
660
        }
661
        return index;
662
    }
663

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

    
672
    public double getFlatness() {
673
        return flatness;
674
    }
675

    
676
    public void setFlatness(double flatness) {
677
        this.flatness = flatness;
678
    }
679

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

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

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

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

    
720
        public SpatialIndex createDefaultMemorySpatialIndex() throws GeometryException {
721
                return new SpatialIndexJTS();
722
        }
723

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