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

History | View | Annotate | Download (27 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
 * AUTHORS (In addition to CIT):
26
 * 2009 {Iver T.I.}   {Task}
27
 */
28

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

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

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

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

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

    
80
public class DefaultGeometryManager implements GeometryManager {
81

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

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

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

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

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

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

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

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

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

    
138
        int index = getGeometryOperationCode(geomOpName);
139

    
140
        geomType.setGeometryOperation(index, geomOp);
141

    
142
        return index;
143
    }
144

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

    
154
        int index = getGeometryOperationCode(geomOpName);
155

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

    
162
        return index;
163

    
164
    }
165

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

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

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

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

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

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

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

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

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

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

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

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

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

    
321
        return geomType;
322
    }
323

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

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

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

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

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

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

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

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

    
369
        return gType;
370
    }
371

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
570
            } // end switch
571

    
572
            piter.next();
573

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

    
580
        return multiCurve;
581

    
582
    }
583

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

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

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

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

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

    
640
            piter.next();
641

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

    
648
        return multiSurface;
649

    
650
    }
651

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

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

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

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

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

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

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

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

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

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

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