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

History | View | Annotate | Download (29.2 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.MultiSurface;
48
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
49
import org.gvsig.fmap.geom.exception.CreateGeometryException;
50
import org.gvsig.fmap.geom.impl.spatialIndex.SpatialIndexFactoryJSI;
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
import org.gvsig.tools.dynobject.DynObject;
71
import org.gvsig.tools.service.Service;
72
import org.gvsig.tools.service.ServiceException;
73
import org.gvsig.tools.service.spi.ServiceFactory;
74

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

    
83
public class DefaultGeometryManager implements GeometryManager {
84

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

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

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

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

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

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

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

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

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

    
145
        int index = getGeometryOperationCode(geomOpName);
146

    
147
        geomType.setGeometryOperation(index, geomOp);
148

    
149
        return index;
150
    }
151

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

    
161
        int index = getGeometryOperationCode(geomOpName);
162

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

    
169
        return index;
170

    
171
    }
172

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

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

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

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

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

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

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

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

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

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

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

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

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

    
328
        return geomType;
329
    }
330

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

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

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

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

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

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

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

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

    
376
        return gType;
377
    }
378

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
577
            } // end switch
578

    
579
            piter.next();
580

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

    
587
        return multiCurve;
588

    
589
    }
590

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

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

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

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

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

    
647
            piter.next();
648

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

    
655
        return multiSurface;
656

    
657
    }
658

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

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

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

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

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

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

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

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

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

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

    
752
    public SpatialIndex createDefaultMemorySpatialIndex() throws ServiceException {
753
        return this.createSpatialIndex(SpatialIndexFactoryJTS.NAME,null);
754
    }
755

    
756
    public SpatialIndex createSpatialIndex(String name, DynObject parameters) throws ServiceException {
757
        SpatialIndexFactory factory = this.getSpatialIndexFactory(name);
758
        if (factory == null) {
759
            throw new CantExistsService(name);
760
        }
761
        return (SpatialIndex) factory.create(parameters, this);
762
    }
763

    
764
    public SpatialIndexFactory getSpatialIndexFactory(String name) {
765
        return (SpatialIndexFactory) this.spatialIndexFactories.get(name);
766
    }
767

    
768
    public void addServiceFactory(ServiceFactory serviceFactory) {
769
        serviceFactory.initialize();
770
        this.spatialIndexFactories.put(serviceFactory.getName(), serviceFactory);
771
    }
772

    
773
    public Service createService(DynObject serviceParameters) throws ServiceException {
774
        throw new UnsupportedOperationException("Not supported yet.");
775
    }
776

    
777
    public DynObject createServiceParameters(String serviceName) throws ServiceException {
778
        SpatialIndexFactory factory = this.getSpatialIndexFactory(serviceName);
779
        if( factory == null ) {
780
            throw  new CantExistsService(serviceName);
781
        }
782
        return factory.createParameters();
783
    }
784

    
785
    public Service getService(DynObject parameters) throws ServiceException {
786
        return this.createSpatialIndex((String) parameters.getDynValue("serviceName"), parameters);
787
    }
788
    
789
    public class CantExistsService extends ServiceException {
790

    
791
        public CantExistsService(String serviceName) {
792
            super("Can't existe service %(service).", "_Cant_existe_service_XserviceX", 100001);
793
            setValue("service",serviceName);
794
        }
795
        
796
    }
797
}