Statistics
| Revision:

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

History | View | Annotate | Download (29.5 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.jts;
26

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

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

    
37
import org.gvsig.fmap.geom.Geometry;
38
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
39
import org.gvsig.fmap.geom.Geometry.TYPES;
40
import org.gvsig.fmap.geom.GeometryException;
41
import org.gvsig.fmap.geom.GeometryLocator;
42
import org.gvsig.fmap.geom.GeometryManager;
43
import org.gvsig.fmap.geom.SpatialIndex;
44
import org.gvsig.fmap.geom.SpatialIndexFactory;
45
import org.gvsig.fmap.geom.aggregate.MultiCurve;
46
import org.gvsig.fmap.geom.aggregate.MultiLine;
47
import org.gvsig.fmap.geom.aggregate.MultiPoint;
48
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
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.jts.gputils.DefaultGeneralPathX;
53
import org.gvsig.fmap.geom.jts.primitive.DefaultNullGeometry;
54
import org.gvsig.fmap.geom.jts.primitive.Envelope2D;
55
import org.gvsig.fmap.geom.jts.primitive.Envelope3D;
56
import org.gvsig.fmap.geom.jts.spatialindex.SpatialIndexFactoryJSI;
57
import org.gvsig.fmap.geom.jts.spatialindex.SpatialIndexFactoryJTS;
58
import org.gvsig.fmap.geom.jts.util.JTSUtils;
59
import org.gvsig.fmap.geom.operation.GeometryOperation;
60
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
61
import org.gvsig.fmap.geom.operation.GeometryOperationException;
62
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
63
import org.gvsig.fmap.geom.primitive.Curve;
64
import org.gvsig.fmap.geom.primitive.Envelope;
65
import org.gvsig.fmap.geom.primitive.GeneralPathX;
66
import org.gvsig.fmap.geom.primitive.IGeneralPathX;
67
import org.gvsig.fmap.geom.primitive.Line;
68
import org.gvsig.fmap.geom.primitive.NullGeometry;
69
import org.gvsig.fmap.geom.primitive.Point;
70
import org.gvsig.fmap.geom.primitive.Polygon;
71
import org.gvsig.fmap.geom.primitive.Surface;
72
import org.gvsig.fmap.geom.type.GeometryType;
73
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
74
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
75
import org.gvsig.tools.dynobject.DynObject;
76
import org.gvsig.tools.service.Service;
77
import org.gvsig.tools.service.ServiceException;
78
import org.gvsig.tools.service.spi.ServiceFactory;
79

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

    
88
public class DefaultGeometryManager implements GeometryManager {
89

    
90
    private static final Logger logger = LoggerFactory.getLogger(GeometryManager.class);
91
    private double flatness = 0.8;
92

    
93
    private Map spatialIndexFactories = new HashMap();
94

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

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

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

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

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

    
130
    public DefaultGeometryManager() throws GeometryException {
131
        this(DEFAULT_TYPES_SIZE, DEFAULT_SUBTYPES_SIZE);
132
    }
133

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

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

    
148
        int index = getGeometryOperationCode(geomOpName);
149

    
150
        geomType.setGeometryOperation(index, geomOp);
151

    
152
        return index;
153
    }
154

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

    
163
        int index = getGeometryOperationCode(geomOpName);
164

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

    
171
        return index;
172

    
173
    }
174

    
175
    public int registerGeometryOperation(String geomOpName, 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, 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 = registerGeometryOperation(geomOpName, geomOp, geometryType);
188
            }
189
        }
190
        return code;
191
    }
192

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

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

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

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

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

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

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

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

    
296
        if (!Geometry.class.isAssignableFrom(geomClass)) {
297
            throw new IllegalArgumentException(geomClass.getName() + " must implement the Geometry interface");
298
        }
299

    
300
        // Check if it is registered
301
        GeometryType geomType = null;
302
        if (type >= geometryTypes.length || subType >= geometryTypes[0].length
303
            || (geomType = geometryTypes[type][subType]) == null) {
304
            geomType = new DefaultGeometryType(geomClass, name, type, subType, superTypes, superSubTypes);
305
            registerGeometryType(geomType);
306
        }
307

    
308
        logger.debug("Class {} registered with name {}", geomClass, geomType.getName());
309

    
310
        return geomType;
311
    }
312

    
313
    public void registerGeometryType(GeometryType geometryType) {
314
        if (geometryType.getType() >= geometryTypes.length || geometryType.getSubType() >= geometryTypes[0].length) {
315

    
316
            // Recreate the geometry type matrix if the types
317
            // or subtypes don't fit
318
            int newTypesSize =
319
                geometryType.getType() < geometryTypes.length ? geometryTypes.length : geometryType.getType() + 1;
320
            int newSubTypesSize =
321
                geometryType.getSubType() < geometryTypes[0].length ? geometryTypes[0].length : geometryType
322
                    .getSubType() + 1;
323
            GeometryType[][] newMatrix = new GeometryType[newTypesSize][newSubTypesSize];
324

    
325
            for (int i = 0; i < geometryTypes.length; i++) {
326
                System.arraycopy(geometryTypes[i], 0, newMatrix[i], 0, geometryTypes[i].length);
327
            }
328
            geometryTypes = newMatrix;
329
        }
330

    
331
        geometryTypes[geometryType.getType()][geometryType.getSubType()] = geometryType;
332
        geometryTypeName.put(geometryType.getName(), geometryType);
333
    }
334

    
335
    public GeometryType registerGeometryType(Class geomClass, int type, int subType) {
336
        return registerGeometryType(geomClass, null, type, subType);
337
    }
338

    
339
    public GeometryType getGeometryType(int type, int subType) throws GeometryTypeNotSupportedException,
340
        GeometryTypeNotValidException {
341
        GeometryType gType = null;
342
        if (type >= geometryTypes.length || subType >= geometryTypes[0].length) {
343
            throw new GeometryTypeNotValidException(type, subType);
344
        }
345

    
346
        gType = geometryTypes[type][subType];
347

    
348
        if (gType == null) {
349
            throw new GeometryTypeNotSupportedException(type, subType);
350
        }
351

    
352
        return gType;
353
    }
354

    
355
    public Geometry create(GeometryType geomType) throws CreateGeometryException {
356
        return geomType.create();
357
    }
358

    
359
    public Geometry create(String name) throws CreateGeometryException {
360
        if (!geometryTypeName.containsKey(name)) {
361
            throw new IllegalArgumentException(name + " has not been registered yet.");
362
        }
363
        return ((GeometryType) geometryTypeName.get(name)).create();
364
    }
365

    
366
    public Geometry create(int type, int subType) throws CreateGeometryException {
367
        try {
368
            return getGeometryType(type, subType).create();
369
        } catch (GeometryException e) {
370
            throw new CreateGeometryException(type, subType, e);
371
        }
372
    }
373

    
374
    public Curve createCurve(GeneralPathX generalPathX, int subType) throws CreateGeometryException {
375
        Curve curve = (Curve) create(TYPES.CURVE, subType);
376
        curve.setGeneralPath(generalPathX);
377
        return curve;
378
    }
379

    
380
    public NullGeometry createNullGeometry(int subType) throws CreateGeometryException {
381
        NullGeometry nullGeom = (NullGeometry) create(TYPES.NULL, subType);
382
        return nullGeom;
383
    }
384

    
385
    public Point createPoint(double x, double y, int subType) throws CreateGeometryException {
386
        Point point = (Point) create(TYPES.POINT, subType);
387
        point.setX(x);
388
        point.setY(y);
389
        return point;
390
    }
391

    
392
    public Surface createSurface(GeneralPathX generalPathX, int subType) throws CreateGeometryException {
393
        Surface surface = (Surface) create(TYPES.SURFACE, subType);
394
        surface.setGeneralPath(generalPathX);
395
        return surface;
396
    }
397

    
398
    public GeometryOperation getGeometryOperation(int opCode, int type, int subType)
399
        throws GeometryTypeNotSupportedException, GeometryOperationNotSupportedException, GeometryTypeNotValidException {
400
        GeometryType geometryType = getGeometryType(type, subType);
401
        return geometryType.getGeometryOperation(opCode);
402
    }
403

    
404
    public GeometryOperation getGeometryOperation(int opCode) throws GeometryOperationNotSupportedException {
405
        if (opCode < 0) {
406
            throw new GeometryOperationNotSupportedException(opCode);
407
        }
408
        GeometryType type = (GeometryType) geometryTypeName.get(DefaultNullGeometry.class.getName());
409
        if (type == null) {
410
            throw new GeometryOperationNotSupportedException(opCode);
411
        }
412
        return type.getGeometryOperation(opCode);
413
    }
414

    
415
    public Object invokeOperation(int opCode, Geometry geom, GeometryOperationContext ctx)
416
        throws GeometryOperationNotSupportedException, GeometryOperationException {
417
        GeometryOperation geomOp = geom.getGeometryType().getGeometryOperation(opCode);
418

    
419
        if (geomOp != null) {
420
            return geomOp.invoke(geom, ctx);
421
        }
422

    
423
        throw new GeometryOperationNotSupportedException(opCode, geom.getGeometryType());
424
    }
425

    
426
    public Object invokeOperation(String geomOpName, Geometry geom, GeometryOperationContext ctx)
427
        throws GeometryOperationNotSupportedException, GeometryOperationException {
428
        int index = geometryOperations.indexOf(geomOpName);
429
        if (index == -1) {
430
            throw new GeometryOperationNotSupportedException(-1);
431
        }
432
        return invokeOperation(index, geom, ctx);
433
    }
434

    
435
    public Object invokeOperation(String geomOpName, GeometryOperationContext ctx)
436
        throws GeometryOperationNotSupportedException, GeometryOperationException {
437
        int index = geometryOperations.indexOf(geomOpName);
438
        GeometryOperation geomOp = getGeometryOperation(index);
439
        return geomOp.invoke(null, ctx);
440
    }
441

    
442
    public Envelope createEnvelope(int subType) {
443
        // TODO: register the envelopes!!!
444
        switch (subType) {
445
        case SUBTYPES.GEOM3D:
446
            return new Envelope3D();
447
        default:
448
            return new Envelope2D();
449
        }
450
    }
451

    
452
    public Envelope createEnvelope(double minX, double minY, double maxX, double maxY, int subType)
453
        throws CreateEnvelopeException {
454
        org.gvsig.fmap.geom.primitive.Point min = null;
455
        org.gvsig.fmap.geom.primitive.Point max = null;
456
        try {
457
            min = createPoint(minX, minY, subType);
458
            max = createPoint(maxX, maxY, subType);
459
        } catch (CreateGeometryException e) {
460
            throw new CreateEnvelopeException(subType, e);
461
        }
462
        switch (subType) {
463
        case SUBTYPES.GEOM2D:
464
        case SUBTYPES.GEOM2DM:
465
            // Small optimization to directly create an Envelope2D
466
            // return new Envelope2D(minX, minY, maxX, maxY);
467
            return new Envelope2D(min, max);
468
        default:
469
            Envelope envelope = createEnvelope(subType);
470
            envelope.setLowerCorner(min);
471
            envelope.setUpperCorner(max);
472
            return envelope;
473
        }
474
    }
475

    
476
    public MultiCurve createMultiCurve(GeneralPathX generalPathX, int subType) throws CreateGeometryException {
477
        if (subType != SUBTYPES.GEOM2D) {
478
            // FIXME Exception
479
            throw new UnsupportedOperationException();
480
        }
481
        MultiCurve multiCurve = (MultiCurve) create(TYPES.MULTICURVE, subType);
482
        PathIterator piter = generalPathX.getPathIterator(null);
483
        GeneralPathX tmpPath = null;
484
        Curve tmpCurve = null;
485
        double[] coords = new double[6];
486
        double[] first = new double[6];
487
        int type;
488
        while (!piter.isDone()) {
489
            type = piter.currentSegment(coords);
490
            switch (type) {
491
            case PathIterator.SEG_MOVETO:
492
                if (tmpPath != null) {
493
                    tmpCurve = createCurve(tmpPath, subType);
494
                    multiCurve.addCurve(tmpCurve);
495
                }
496
                System.arraycopy(coords, 0, first, 0, 2);
497
                tmpPath = new GeneralPathX(piter.getWindingRule());
498
                tmpPath.moveTo(coords[0], coords[1]);
499
                break;
500

    
501
            case PathIterator.SEG_LINETO:
502
                if (tmpPath == null) {
503
                    System.arraycopy(coords, 0, first, 0, 2);
504
                    tmpPath = new GeneralPathX(piter.getWindingRule());
505
                }
506
                tmpPath.lineTo(coords[0], coords[1]);
507
                break;
508

    
509
            case PathIterator.SEG_QUADTO:
510
                if (tmpPath == null) {
511
                    System.arraycopy(coords, 0, first, 0, 2);
512
                    tmpPath = new GeneralPathX(piter.getWindingRule());
513
                }
514
                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
515
                break;
516

    
517
            case PathIterator.SEG_CUBICTO:
518
                if (tmpPath == null) {
519
                    System.arraycopy(coords, 0, first, 0, 2);
520
                    tmpPath = new GeneralPathX(piter.getWindingRule());
521
                }
522
                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
523
                break;
524

    
525
            case PathIterator.SEG_CLOSE:
526
                tmpPath.lineTo(first[0], first[1]);
527
                break;
528

    
529
            } // end switch
530

    
531
            piter.next();
532

    
533
        }
534
        if (tmpPath != null) {
535
            tmpCurve = createCurve(tmpPath, subType);
536
            multiCurve.addCurve(tmpCurve);
537
        }
538

    
539
        return multiCurve;
540

    
541
    }
542

    
543
    public MultiSurface createMultiSurface(GeneralPathX generalPathX, int subType) throws CreateGeometryException {
544
        if (subType != SUBTYPES.GEOM2D) {
545
            // FIXME Exception
546
            throw new UnsupportedOperationException();
547
        }
548
        MultiSurface multiSurface = (MultiSurface) create(TYPES.MULTISURFACE, subType);
549
        PathIterator piter = generalPathX.getPathIterator(null);
550
        GeneralPathX tmpPath = null;
551
        Surface tmpSurface = null;
552
        double[] coords = new double[6];
553
        double[] first = new double[6];
554
        int type;
555
        while (!piter.isDone()) {
556
            type = piter.currentSegment(coords);
557
            switch (type) {
558
            case PathIterator.SEG_MOVETO:
559
                if (tmpPath != null) {
560
                    tmpSurface = createSurface(tmpPath, subType);
561
                    multiSurface.addSurface(tmpSurface);
562
                }
563
                System.arraycopy(coords, 0, first, 0, 2);
564
                tmpPath = new GeneralPathX(piter.getWindingRule());
565
                tmpPath.moveTo(coords[0], coords[1]);
566

    
567
            case PathIterator.SEG_LINETO:
568
                if (tmpPath == null) {
569
                    System.arraycopy(coords, 0, first, 0, 2);
570
                    tmpPath = new GeneralPathX(piter.getWindingRule());
571
                }
572
                tmpPath.lineTo(coords[0], coords[1]);
573
                break;
574

    
575
            case PathIterator.SEG_QUADTO:
576
                if (tmpPath == null) {
577
                    System.arraycopy(coords, 0, first, 0, 2);
578
                    tmpPath = new GeneralPathX(piter.getWindingRule());
579
                }
580
                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
581
                break;
582

    
583
            case PathIterator.SEG_CUBICTO:
584
                if (tmpPath == null) {
585
                    System.arraycopy(coords, 0, first, 0, 2);
586
                    tmpPath = new GeneralPathX(piter.getWindingRule());
587
                }
588
                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
589
                break;
590

    
591
            case PathIterator.SEG_CLOSE:
592
                tmpPath.lineTo(first[0], first[1]);
593
                break;
594
            } // end switch
595

    
596
            piter.next();
597

    
598
        }
599
        if (tmpPath != null) {
600
            tmpSurface = createSurface(tmpPath, subType);
601
            multiSurface.addSurface(tmpSurface);
602
        }
603

    
604
        return multiSurface;
605

    
606
    }
607

    
608
    public int getGeometryOperationCode(String geomOpName) {
609
        if (geomOpName == null) {
610
            throw new IllegalArgumentException("geomOpName cannot be null.");
611
        }
612

    
613
        int index = geometryOperations.indexOf(geomOpName);
614
        if (index == -1) {
615
            geometryOperations.add(geomOpName);
616
            index = geometryOperations.indexOf(geomOpName);
617
        }
618
        return index;
619
    }
620

    
621
    public List getGeometryOperationNames() {
622
        List operations = new ArrayList();
623
        for (int i = 0; i < operations.size(); i++) {
624
            operations.add(geometryOperations.get(i));
625
        }
626
        return operations;
627
    }
628

    
629
    public double getFlatness() {
630
        return flatness;
631
    }
632

    
633
    public void setFlatness(double flatness) {
634
        this.flatness = flatness;
635
    }
636

    
637
    public Geometry createFrom(String wkt, String srs) throws GeometryException {
638
        GeometryOperationContext context = new GeometryOperationContext();
639
        context.setAttribute("text", wkt);
640
        context.setAttribute("srs", srs);
641

    
642
        try {
643
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
644
        } catch (GeometryOperationNotSupportedException e) {
645
            throw new GeometryException(e);
646
        } catch (GeometryOperationException e) {
647
            throw new GeometryException(e);
648
        }
649
    }
650

    
651
    public Geometry createFrom(com.vividsolutions.jts.geom.Geometry geom) throws GeometryException {
652
        return JTSUtils.createGeometry(geom);
653
    }
654

    
655
    public Geometry createFrom(String wkt) throws GeometryException {
656
        GeometryOperationContext context = new GeometryOperationContext();
657
        context.setAttribute("text", wkt);
658
        context.setAttribute("srs", null);
659

    
660
        try {
661
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
662
        } catch (GeometryOperationNotSupportedException e) {
663
            throw new GeometryException(e);
664
        } catch (GeometryOperationException e) {
665
            throw new GeometryException(e);
666
        }
667
    }
668

    
669
    public Geometry createFrom(byte[] wkb) throws GeometryException {
670
        GeometryOperationContext context = new GeometryOperationContext();
671
        context.setAttribute("data", wkb);
672
        try {
673
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKB, context);
674
        } catch (GeometryOperationNotSupportedException e) {
675
            throw new GeometryException(e);
676
        } catch (GeometryOperationException e) {
677
            throw new GeometryException(e);
678
        }
679
    }
680

    
681
    public IGeneralPathX createGeneralPath(int rule, PathIterator pathIterator) {
682
        if (pathIterator == null) {
683
            return new DefaultGeneralPathX(rule);
684
        }
685
        return new DefaultGeneralPathX(pathIterator, false, 0);
686
    }
687

    
688
    public MultiPoint createMultiPoint(int subType) throws CreateGeometryException {
689
        return (MultiPoint) create(TYPES.MULTIPOINT, subType);
690
    }
691

    
692
    public Line createLine(int subType) throws CreateGeometryException {
693
        return (Line) create(TYPES.CURVE, subType);
694
    }
695

    
696
    public Curve createCurve(int subType) throws CreateGeometryException {
697
        return (Curve) create(TYPES.CURVE, subType);
698
    }
699

    
700
    public MultiCurve createMultiCurve(int subType) throws CreateGeometryException {
701
        return (MultiCurve) create(TYPES.MULTICURVE, subType);
702
    }
703

    
704
    public MultiLine createMultiLine(int subType) throws CreateGeometryException {
705
        return (MultiLine) create(TYPES.MULTILINE, subType);
706
    }
707

    
708
    public MultiSurface createMultiSurface(int subType) throws CreateGeometryException {
709
        return (MultiSurface) create(TYPES.MULTISURFACE, subType);
710
    }
711

    
712
    public MultiPolygon createMultiPolygon(int subType) throws CreateGeometryException {
713
        return (MultiPolygon) create(TYPES.MULTIPOLYGON, subType);
714
    }
715

    
716
    public Polygon createPolygon(int subType) throws CreateGeometryException {
717
        return (Polygon) create(TYPES.SURFACE, subType);
718
    }
719

    
720
    public Surface createSurface(int subType) throws CreateGeometryException {
721
        return (Surface) create(TYPES.SURFACE, subType);
722
    }
723

    
724
    public SpatialIndex createDefaultMemorySpatialIndex() throws ServiceException {
725
        return this.createSpatialIndex(SpatialIndexFactoryJTS.NAME, null);
726
    }
727

    
728
    public SpatialIndex createSpatialIndex(String name, DynObject parameters) throws ServiceException {
729
        SpatialIndexFactory factory = this.getSpatialIndexFactory(name);
730
        if (factory == null) {
731
            throw new CantExistsService(name);
732
        }
733
        return (SpatialIndex) factory.create(parameters, this);
734
    }
735

    
736
    public SpatialIndexFactory getSpatialIndexFactory(String name) {
737
        return (SpatialIndexFactory) this.spatialIndexFactories.get(name);
738
    }
739

    
740
    public void addServiceFactory(ServiceFactory serviceFactory) {
741
        serviceFactory.initialize();
742
        this.spatialIndexFactories.put(serviceFactory.getName(), serviceFactory);
743
    }
744

    
745
    public Service createService(DynObject serviceParameters) throws ServiceException {
746
        throw new UnsupportedOperationException("Not supported yet.");
747
    }
748

    
749
    public DynObject createServiceParameters(String serviceName) throws ServiceException {
750
        SpatialIndexFactory factory = this.getSpatialIndexFactory(serviceName);
751
        if (factory == null) {
752
            throw new CantExistsService(serviceName);
753
        }
754
        return factory.createParameters();
755
    }
756

    
757
    public Service getService(DynObject parameters) throws ServiceException {
758
        return this.createSpatialIndex((String) parameters.getDynValue("serviceName"), parameters);
759
    }
760

    
761
    public class CantExistsService extends ServiceException {
762

    
763
        public CantExistsService(String serviceName) {
764
            super("Can't existe service %(service).", "_Cant_existe_service_XserviceX", 100001);
765
            setValue("service", serviceName);
766
        }
767

    
768
    }
769
}