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

History | View | Annotate | Download (29.4 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 org.gvsig.fmap.geom.impl.spatialIndex.SpatialIndexFactoryJTS;
28
import java.awt.geom.PathIterator;
29
import java.util.ArrayList;
30
import java.util.HashMap;
31
import java.util.Iterator;
32
import java.util.List;
33
import java.util.Map;
34

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

    
38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
40
import org.gvsig.fmap.geom.Geometry.TYPES;
41
import org.gvsig.fmap.geom.GeometryException;
42
import org.gvsig.fmap.geom.GeometryLocator;
43
import org.gvsig.fmap.geom.GeometryManager;
44
import org.gvsig.fmap.geom.SpatialIndex;
45
import org.gvsig.fmap.geom.SpatialIndexFactory;
46
import org.gvsig.fmap.geom.aggregate.MultiCurve;
47
import org.gvsig.fmap.geom.aggregate.MultiPoint;
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.impl.spatialIndex.SpatialIndexFactoryJSI;
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
import org.gvsig.tools.dynobject.DynObject;
72
import org.gvsig.tools.service.Service;
73
import org.gvsig.tools.service.ServiceException;
74
import org.gvsig.tools.service.spi.ServiceFactory;
75

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

    
84
public class DefaultGeometryManager implements GeometryManager {
85

    
86
    private static final Logger logger = LoggerFactory
87
    .getLogger(GeometryManager.class);
88
    private double flatness = 0.8;
89

    
90
    private Map spatialIndexFactories = new HashMap();
91
    
92
    /**
93
     * This list holds the unique name of all registered geometry operations.
94
     * The index in which they are stored is also the operation code used to
95
     * invoke each one of them
96
     */
97
    private List geometryOperations = new ArrayList();
98

    
99
    /**
100
     * Common operations are registered here. Type specific operations are
101
     * registered in the corresponding GeometryType instance
102
     */
103
    // private List commonOperations = new ArrayList();
104

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

    
114
    /**
115
     * Matrix of geometry types by type (row) and subtype (column). This matrix
116
     * will contain null values in the cells where a GeometryType hasn't been
117
     * registered.
118
     */
119
    private GeometryType[][] geometryTypes;
120

    
121
    // Initially create a matrix of 17 x 6, which are the current default
122
    // types and subtypes. If another type or subtype is registered, the
123
    // matrix will grow as needed
124
    private static final int DEFAULT_TYPES_SIZE = 17;
125
    private static final int DEFAULT_SUBTYPES_SIZE = 6;
126

    
127
    public DefaultGeometryManager() throws GeometryException {
128
        this(DEFAULT_TYPES_SIZE, DEFAULT_SUBTYPES_SIZE);
129
    }
130

    
131
    public DefaultGeometryManager(int initialTypesSize, int initialSubtypesSize) throws GeometryException {
132
        geometryTypes = new GeometryType[initialTypesSize][initialSubtypesSize];
133
        this.addServiceFactory(new SpatialIndexFactoryJTS());
134
        this.addServiceFactory(new SpatialIndexFactoryJSI());
135
    }
136

    
137
    public int registerGeometryOperation(String geomOpName,
138
        GeometryOperation geomOp, GeometryType geomType) {
139
        if (geomOp == null) {
140
            throw new IllegalArgumentException("geomOp cannot be null.");
141
        }
142
        if (geomType == null) {
143
            throw new IllegalArgumentException("geomType cannot be null.");
144
        }
145

    
146
        int index = getGeometryOperationCode(geomOpName);
147

    
148
        geomType.setGeometryOperation(index, geomOp);
149

    
150
        return index;
151
    }
152

    
153
    public int registerGeometryOperation(String geomOpName,
154
        GeometryOperation geomOp) {
155
        if (geomOpName == null) {
156
            throw new IllegalArgumentException("geomOpName cannot be null.");
157
        }
158
        if (geomOp == null) {
159
            throw new IllegalArgumentException("geomOp cannot be null.");
160
        }
161

    
162
        int index = getGeometryOperationCode(geomOpName);
163

    
164
        Iterator it = geometryTypeName.values().iterator();
165
        while (it.hasNext()) {
166
            GeometryType geometryType = (GeometryType) it.next();
167
            registerGeometryOperation(geomOpName, geomOp, geometryType);
168
        }
169

    
170
        return index;
171

    
172
    }
173

    
174
    public int registerGeometryOperation(String geomOpName,
175
        GeometryOperation geomOp, int type, int subType)
176
    throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
177
        GeometryType geometryType = getGeometryType(type, subType);
178
        return registerGeometryOperation(geomOpName, geomOp, geometryType);
179
    }
180

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

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

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

    
223
    public int registerGeometryOperationBySuperSubType(String geomOpName,
224
        GeometryOperation geomOp, int superSubType) {       
225
        int code = -1;
226
        Iterator it = geometryTypeName.values().iterator();
227
        while (it.hasNext()) {
228
            GeometryType geometryType = (GeometryType) it.next();
229
            if (geometryType.isSubTypeOf(superSubType)) {
230
                code =
231
                    registerGeometryOperation(geomOpName, geomOp, geometryType);
232
            }
233
        }
234
        return code;
235
    }
236

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

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

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

    
255
    public GeometryType registerGeometryType(Class geomClass, String name,
256
        int type, int subType, int[] superTypes) {
257
        return registerGeometryType(geomClass, name, type, subType,
258
            superTypes, new int[0]);
259
    }
260

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

    
311
        if (!Geometry.class.isAssignableFrom(geomClass)) {
312
            throw new IllegalArgumentException(geomClass.getName()
313
                + " must implement the Geometry interface");
314
        }
315

    
316
        // Check if it is registered
317
        GeometryType geomType = null;
318
        if (type >= geometryTypes.length || subType >= geometryTypes[0].length
319
            || (geomType = geometryTypes[type][subType]) == null) {
320
            geomType =
321
                new DefaultGeometryType(geomClass, name, type, subType,
322
                    superTypes, superSubTypes);
323
            registerGeometryType(geomType);
324
        }
325

    
326
        logger.debug("Class {} registered with name {}", geomClass,
327
            geomType.getName());
328

    
329
        return geomType;
330
    }
331

    
332
    public void registerGeometryType(GeometryType geometryType) {
333
        if (geometryType.getType() >= geometryTypes.length
334
            || geometryType.getSubType() >= geometryTypes[0].length) {
335

    
336
            // Recreate the geometry type matrix if the types
337
            // or subtypes don't fit
338
            int newTypesSize =
339
                geometryType.getType() < geometryTypes.length
340
                ? geometryTypes.length : geometryType.getType() + 1;
341
            int newSubTypesSize =
342
                geometryType.getSubType() < geometryTypes[0].length
343
                ? geometryTypes[0].length : geometryType.getSubType() + 1;
344
                GeometryType[][] newMatrix =
345
                    new GeometryType[newTypesSize][newSubTypesSize];
346

    
347
                for (int i = 0; i < geometryTypes.length; i++) {
348
                    System.arraycopy(geometryTypes[i], 0, newMatrix[i], 0,
349
                        geometryTypes[i].length);
350
                }
351
                geometryTypes = newMatrix;
352
        }
353

    
354
        geometryTypes[geometryType.getType()][geometryType.getSubType()] =
355
            geometryType;
356
        geometryTypeName.put(geometryType.getName(), geometryType);
357
    }
358

    
359
    public GeometryType registerGeometryType(Class geomClass, int type,
360
        int subType) {
361
        return registerGeometryType(geomClass, null, type, subType);
362
    }
363

    
364
    public GeometryType getGeometryType(int type, int subType)
365
    throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
366
        GeometryType gType = null;
367
        if (type >= geometryTypes.length || subType >= geometryTypes[0].length) {
368
            throw new GeometryTypeNotValidException(type, subType);
369
        }
370

    
371
        gType = geometryTypes[type][subType];
372

    
373
        if (gType == null) {
374
            throw new GeometryTypeNotSupportedException(type, subType);
375
        }
376

    
377
        return gType;
378
    }
379

    
380
    public Geometry create(GeometryType geomType)
381
    throws CreateGeometryException {
382
        return geomType.create();
383
    }
384

    
385
    public Geometry create(String name) throws CreateGeometryException {
386
        if (!geometryTypeName.containsKey(name)) {
387
            throw new IllegalArgumentException(name
388
                + " has not been registered yet.");
389
        }
390
        return ((GeometryType) geometryTypeName.get(name)).create();
391
    }
392

    
393
    public Geometry create(int type, int subType)
394
    throws CreateGeometryException {
395
        try {
396
            return getGeometryType(type, subType).create();
397
        } catch (GeometryException e) {
398
            throw new CreateGeometryException(type, subType, e);
399
        }
400
    }
401

    
402
    public Curve createCurve(GeneralPathX generalPathX, int subType)
403
    throws CreateGeometryException {
404
        Curve curve = (Curve) create(TYPES.CURVE, subType);
405
        curve.setGeneralPath(generalPathX);
406
        return curve;
407
    }
408

    
409
    public NullGeometry createNullGeometry(int subType)
410
    throws CreateGeometryException {
411
        NullGeometry nullGeom = (NullGeometry) create(TYPES.NULL, subType);
412
        return nullGeom;
413
    }
414

    
415
    public Point createPoint(double x, double y, int subType)
416
    throws CreateGeometryException {
417
        Point point = (Point) create(TYPES.POINT, subType);
418
        point.setX(x);
419
        point.setY(y);
420
        return point;
421
    }
422

    
423
    public Surface createSurface(GeneralPathX generalPathX, int subType)
424
    throws CreateGeometryException {
425
        Surface surface = (Surface) create(TYPES.SURFACE, subType);
426
        surface.setGeneralPath(generalPathX);
427
        return surface;
428
    }
429

    
430
    public GeometryOperation getGeometryOperation(int opCode, int type,
431
        int subType) throws GeometryTypeNotSupportedException,
432
        GeometryOperationNotSupportedException, GeometryTypeNotValidException {
433
        GeometryType geometryType = getGeometryType(type, subType);
434
        return geometryType.getGeometryOperation(opCode);
435
    }
436

    
437
    public GeometryOperation getGeometryOperation(int opCode)
438
        throws GeometryOperationNotSupportedException {
439
        if (opCode < 0) {
440
            throw new GeometryOperationNotSupportedException(opCode);
441
        }
442
        GeometryType type =
443
            (GeometryType) geometryTypeName.get(DefaultNullGeometry.class
444
                .getName());
445
        if (type == null) {
446
            throw new GeometryOperationNotSupportedException(opCode);
447
        }
448
        return type.getGeometryOperation(opCode);
449
    }
450

    
451
    public Object invokeOperation(int opCode, Geometry geom,
452
        GeometryOperationContext ctx)
453
    throws GeometryOperationNotSupportedException,
454
    GeometryOperationException {
455
        GeometryOperation geomOp =
456
            geom.getGeometryType().getGeometryOperation(opCode);
457

    
458
        if (geomOp != null) {
459
            return geomOp.invoke(geom, ctx);
460
        }
461

    
462
        throw new GeometryOperationNotSupportedException(opCode,
463
            geom.getGeometryType());
464
    }
465

    
466
    public Object invokeOperation(String geomOpName, Geometry geom,
467
        GeometryOperationContext ctx)
468
    throws GeometryOperationNotSupportedException,
469
    GeometryOperationException {
470
        int index = geometryOperations.indexOf(geomOpName);
471
        if (index == -1) {
472
            throw new GeometryOperationNotSupportedException(-1);
473
        }
474
        return invokeOperation(index, geom, ctx);
475
    }
476

    
477
    public Object invokeOperation(String geomOpName,
478
        GeometryOperationContext ctx)
479
        throws GeometryOperationNotSupportedException,
480
        GeometryOperationException {
481
        int index = geometryOperations.indexOf(geomOpName);
482
        GeometryOperation geomOp = getGeometryOperation(index);
483
        return geomOp.invoke(null, ctx);
484
    }
485

    
486
    public Envelope createEnvelope(int subType) {
487
        // TODO: register the envelopes!!!
488
        switch (subType) {
489
        case SUBTYPES.GEOM3D:
490
            return new Envelope3D();
491
        default:
492
            return new Envelope2D();
493
        }
494
    }
495

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

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

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

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

    
565
            case PathIterator.SEG_CUBICTO:
566
                if (tmpPath == null) {
567
                    System.arraycopy(coords, 0, first, 0, 2);
568
                    tmpPath = new GeneralPathX(piter.getWindingRule());
569
                }
570
                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
571
                    coords[4], coords[5]);
572
                break;
573

    
574
            case PathIterator.SEG_CLOSE:
575
                tmpPath.lineTo(first[0], first[1]);
576
                break;
577

    
578
            } // end switch
579

    
580
            piter.next();
581

    
582
        }
583
        if (tmpPath != null) {
584
            tmpCurve = createCurve(tmpPath, subType);
585
            multiCurve.addCurve(tmpCurve);
586
        }
587

    
588
        return multiCurve;
589

    
590
    }
591

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

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

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

    
634
            case PathIterator.SEG_CUBICTO:
635
                if (tmpPath == null) {
636
                    System.arraycopy(coords, 0, first, 0, 2);
637
                    tmpPath = new GeneralPathX(piter.getWindingRule());
638
                }
639
                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
640
                    coords[4], coords[5]);
641
                break;
642

    
643
            case PathIterator.SEG_CLOSE:
644
                tmpPath.lineTo(first[0], first[1]);
645
                break;
646
            } // end switch
647

    
648
            piter.next();
649

    
650
        }
651
        if (tmpPath != null) {
652
            tmpSurface = createSurface(tmpPath, subType);
653
            multiSurface.addSurface(tmpSurface);
654
        }
655

    
656
        return multiSurface;
657

    
658
    }
659

    
660
    public int getGeometryOperationCode(String geomOpName) {
661
        if (geomOpName == null) {
662
            throw new IllegalArgumentException("geomOpName cannot be null.");
663
        }
664

    
665
        int index = geometryOperations.indexOf(geomOpName);
666
        if (index == -1) {
667
            geometryOperations.add(geomOpName);
668
            index = geometryOperations.indexOf(geomOpName);
669
        }
670
        return index;
671
    }
672

    
673
    public List getGeometryOperationNames() {
674
        List operations = new ArrayList();
675
        for (int i = 0; i < operations.size(); i++) {
676
            operations.add(geometryOperations.get(i));
677
        }
678
        return operations;
679
    }
680

    
681
    public double getFlatness() {
682
        return flatness;
683
    }
684

    
685
    public void setFlatness(double flatness) {
686
        this.flatness = flatness;
687
    }
688

    
689
    public Geometry createFrom(String wkt, String srs) throws GeometryException {
690
        GeometryOperationContext context = new GeometryOperationContext();
691
        context.setAttribute("text", wkt);
692
        context.setAttribute("srs", srs);
693
        
694
        try {
695
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
696
        } catch (GeometryOperationNotSupportedException e) {
697
            throw new GeometryException(e);
698
        } catch (GeometryOperationException e) {
699
            throw new GeometryException(e);
700
        }
701
    }
702

    
703
    public Geometry createFrom(String wkt) throws GeometryException {
704
        GeometryOperationContext context = new GeometryOperationContext();
705
        context.setAttribute("text", wkt);
706
        context.setAttribute("srs", null);
707

    
708
        try {
709
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
710
        } catch (GeometryOperationNotSupportedException e) {
711
            throw new GeometryException(e);
712
        } catch (GeometryOperationException e) {
713
            throw new GeometryException(e);
714
        }
715
    }
716

    
717
    public Geometry createFrom(byte[] wkb) throws GeometryException {
718
        GeometryOperationContext context = new GeometryOperationContext();
719
        context.setAttribute("data", wkb);
720
        try {
721
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKB, context);
722
        } catch (GeometryOperationNotSupportedException e) {
723
            throw new GeometryException(e);
724
        } catch (GeometryOperationException e) {
725
            throw new GeometryException(e);
726
        }
727
    }
728

    
729
        public GeneralPathX createGeneralPath(int rule, PathIterator pathIterator) {
730
                if( pathIterator == null ) {
731
                        return new DefaultGeneralPathX(rule);
732
                }
733
                return  new DefaultGeneralPathX(pathIterator);
734
        }
735

    
736
        public MultiPoint createMultiPoint(int subType) throws CreateGeometryException {
737
            return (MultiPoint) create(TYPES.MULTIPOINT, subType);
738
        }
739

    
740
        public Curve createCurve(int subType) throws CreateGeometryException {
741
                return (Curve) create(TYPES.CURVE, subType);
742
        }
743
        
744
        public MultiCurve createMultiCurve(int subType)
745
                        throws CreateGeometryException {
746
                return (MultiCurve) create(TYPES.MULTICURVE, subType);
747
        }
748
        
749
        public MultiSurface createMultiSurface(int subType)
750
                        throws CreateGeometryException {
751
                return (MultiSurface) create(TYPES.MULTISURFACE, subType);
752
        }
753
        
754
        public Surface createSurface(int subType) throws CreateGeometryException {
755
                return (Surface) create(TYPES.SURFACE, subType);
756
        }
757

    
758
    public SpatialIndex createDefaultMemorySpatialIndex() throws ServiceException {
759
        return this.createSpatialIndex(SpatialIndexFactoryJTS.NAME,null);
760
    }
761

    
762
    public SpatialIndex createSpatialIndex(String name, DynObject parameters) throws ServiceException {
763
        SpatialIndexFactory factory = this.getSpatialIndexFactory(name);
764
        if (factory == null) {
765
            throw new CantExistsService(name);
766
        }
767
        return (SpatialIndex) factory.create(parameters, this);
768
    }
769

    
770
    public SpatialIndexFactory getSpatialIndexFactory(String name) {
771
        return (SpatialIndexFactory) this.spatialIndexFactories.get(name);
772
    }
773

    
774
    public void addServiceFactory(ServiceFactory serviceFactory) {
775
        serviceFactory.initialize();
776
        this.spatialIndexFactories.put(serviceFactory.getName(), serviceFactory);
777
    }
778

    
779
    public Service createService(DynObject serviceParameters) throws ServiceException {
780
        throw new UnsupportedOperationException("Not supported yet.");
781
    }
782

    
783
    public DynObject createServiceParameters(String serviceName) throws ServiceException {
784
        SpatialIndexFactory factory = this.getSpatialIndexFactory(serviceName);
785
        if( factory == null ) {
786
            throw  new CantExistsService(serviceName);
787
        }
788
        return factory.createParameters();
789
    }
790

    
791
    public Service getService(DynObject parameters) throws ServiceException {
792
        return this.createSpatialIndex((String) parameters.getDynValue("serviceName"), parameters);
793
    }
794

    
795
    public class CantExistsService extends ServiceException {
796

    
797
        public CantExistsService(String serviceName) {
798
            super("Can't existe service %(service).", "_Cant_existe_service_XserviceX", 100001);
799
            setValue("service",serviceName);
800
        }
801
        
802
    }
803
}