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

History | View | Annotate | Download (29.6 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.PointGeometryType;
71
import org.gvsig.fmap.geom.primitive.Polygon;
72
import org.gvsig.fmap.geom.primitive.Surface;
73
import org.gvsig.fmap.geom.type.GeometryType;
74
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
75
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
76
import org.gvsig.tools.dynobject.DynObject;
77
import org.gvsig.tools.service.Service;
78
import org.gvsig.tools.service.ServiceException;
79
import org.gvsig.tools.service.spi.ServiceFactory;
80

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

    
89
public class DefaultGeometryManager implements GeometryManager {
90

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

    
94
    private Map spatialIndexFactories = new HashMap();
95

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

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

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

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

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

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

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

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

    
149
        int index = getGeometryOperationCode(geomOpName);
150

    
151
        geomType.setGeometryOperation(index, geomOp);
152

    
153
        return index;
154
    }
155

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

    
164
        int index = getGeometryOperationCode(geomOpName);
165

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

    
172
        return index;
173

    
174
    }
175

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

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

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

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

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

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

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

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

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

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

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

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

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

    
311
        return geomType;
312
    }
313

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

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

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

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

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

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

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

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

    
353
        return gType;
354
    }
355

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
530
            } // end switch
531

    
532
            piter.next();
533

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

    
540
        return multiCurve;
541

    
542
    }
543

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

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

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

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

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

    
597
            piter.next();
598

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

    
605
        return multiSurface;
606

    
607
    }
608

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
762
    public class CantExistsService extends ServiceException {
763

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

    
769
    }
770
}