Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / impl / DefaultGeometryManager.java @ 30765

History | View | Annotate | Download (26.8 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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 2
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
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2009 {Iver T.I.}   {Task}
26
 */
27

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

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

    
37
import org.gvsig.fmap.geom.Geometry;
38
import org.gvsig.fmap.geom.GeometryLocator;
39
import org.gvsig.fmap.geom.GeometryManager;
40
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
41
import org.gvsig.fmap.geom.Geometry.TYPES;
42
import org.gvsig.fmap.geom.aggregate.MultiCurve;
43
import org.gvsig.fmap.geom.aggregate.MultiSurface;
44
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
45
import org.gvsig.fmap.geom.exception.CreateGeometryException;
46
import org.gvsig.fmap.geom.operation.GeometryOperation;
47
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
48
import org.gvsig.fmap.geom.operation.GeometryOperationException;
49
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
50
import org.gvsig.fmap.geom.primitive.Curve;
51
import org.gvsig.fmap.geom.primitive.Envelope;
52
import org.gvsig.fmap.geom.primitive.GeneralPathX;
53
import org.gvsig.fmap.geom.primitive.NullGeometry;
54
import org.gvsig.fmap.geom.primitive.Point;
55
import org.gvsig.fmap.geom.primitive.Surface;
56
import org.gvsig.fmap.geom.primitive.impl.Envelope2D;
57
import org.gvsig.fmap.geom.primitive.impl.Envelope3D;
58
import org.gvsig.fmap.geom.type.GeometryType;
59
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
60
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
61
import org.gvsig.fmap.geom.type.impl.DefaultGeometryType;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

    
65
import com.vividsolutions.jts.geom.GeometryFactory;
66

    
67
/**
68
 * Default implementation for the {@link GeometryManager}. When the
69
 * application starts, this class is registered in the
70
 * {@link GeometryLocator} using the {@link DefaultGeometryLibrary}.
71
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
72
 */
73

    
74
public class DefaultGeometryManager implements GeometryManager{
75
        private static final Logger logger = LoggerFactory.getLogger(GeometryManager.class);
76
        private double flatness = 0.8;
77
        
78
        private static GeometryManager instance;
79

    
80
        /** This list holds the unique name of all registered geometry operations.
81
         * The index in which they are stored is also the operation code used to invoke each one of them */
82
        private List geometryOperations = new ArrayList();
83

    
84
        /** Common operations are registered here. Type specific operations are registered in the corresponding GeometryType instance */
85
        //private List commonOperations = new ArrayList();
86

    
87
        /** This map holds the instances of all registered GeometryType. The key is the name of the specific Geometry subclass.
88
         * In other words, the string "org.gvsig.fmap.geom.primitive.Point2D" is the hash key to obtain an instance of GeometryType holding the
89
         * operations associated to the class org.gvsig.fmap.geom.primitive.Point2D.
90
         */
91
        private Map geometryTypeName = new HashMap();
92

    
93
        /**
94
         * This attribute is used to keep the relationship between type,
95
         * subtype and GeometryType. The key is the type and the
96
         * value is other Map with the GeometryTypes
97
         */
98
        private Map geometrySubtypes = new HashMap();
99

    
100
        /**
101
         * This array contains all the geometry types.
102
         */
103
        private ArrayList geometryTypeList = new ArrayList();
104

    
105
        /** GeometryType index counter. Each time a new geometry type (not predefined) is registered it is assigned this counter's value as index and after that
106
         * it is incremented by 1 */
107
        private int geometryTypeIndex = 0;//Geometry.EXTENDED_GEOMTYPE_OFFSET; //65536;//2^16
108

    
109
        /**
110
         * Geometry Factory
111
         */
112
        private GeometryFactory factory = new GeometryFactory();
113

    
114
        /**
115
         * The GeometryManager has to have a public constructor
116
         * that will be invoked by a extension point.
117
         */
118
        public DefaultGeometryManager() {
119
                this.registerGeometryFactory(new GeometryFactory());
120
        }
121

    
122
        /**
123
         * Registers a GeometryFactory that will be used instead of the default one.
124
         * @param factory
125
         */
126
        private void registerGeometryFactory(GeometryFactory factory) {
127
                this.factory = factory;
128
        }
129

    
130
        /**
131
         * Returns the current geometry factory
132
         * @return
133
         */
134
        public GeometryFactory getGeometryFactory() {
135
                return factory;
136
        }
137

    
138
        /*
139
         * (non-Javadoc)
140
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryOperation(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperation, org.gvsig.fmap.geom.type.GeometryType)
141
         */
142
        public int registerGeometryOperation(String geomOpName,
143
                        GeometryOperation geomOp, GeometryType geomType) {
144
                if (geomOp == null) {
145
                        throw new IllegalArgumentException("geomOp cannot be null.");
146
                }
147
                if (geomType == null) {
148
                        throw new IllegalArgumentException("geomType cannot be null.");
149
                }
150

    
151
                int index = getGeometryOperationCode(geomOpName);
152

    
153
                geomType.setGeometryOperation(index, geomOp);
154

    
155
                return index;
156
        }
157

    
158
        /*
159
         * (non-Javadoc)
160
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryOperation(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperation)
161
         */
162
        public int registerGeometryOperation(String geomOpName,
163
                        GeometryOperation geomOp) {
164
                if (geomOpName == null) {
165
                        throw new IllegalArgumentException("geomOpName cannot be null.");
166
                }
167
                if (geomOp == null) {
168
                        throw new IllegalArgumentException("geomOp cannot be null.");
169
                }
170

    
171
                int index = getGeometryOperationCode(geomOpName);
172

    
173
                Iterator it = geometryTypeName.keySet().iterator();
174
                while (it.hasNext()){
175
                        String className = (String)it.next();
176
                        GeometryType geometryType = (GeometryType) geometryTypeName.get(className);
177
                        registerGeometryOperation(geomOpName, geomOp, geometryType);
178
                }
179

    
180
                return index;
181

    
182
        }
183

    
184
        /**
185
         * Registers a GeometryOperation associated to a GeometryType.
186
         * Returns an unique index that is used later to identify and invoke the operation.<br>
187
         *
188
         * By convention, the return value should be stored in a public constant within the class implementing
189
         * the operation:<BR>
190
         * <pre>
191
         * public class MyOperation extends GeometryOperation {
192
         *   public static final int CODE =
193
         *     GeometryManager.getInstance()
194
         *        .registerGeometryOperation("MyOperation", new MyOperation(), MyGeometry.class);
195
         * }
196
         * </pre>
197
         *
198
         * This method is only used if you have not a reference to the GeometryType associated to the
199
         * geometry class. If you have such reference then it is slightly faster to use the method that receives
200
         * the GeometryType.<br>
201
         *
202
         * @param geomOpName Operation's unique name
203
         * @param geomOp Specific GeometryOperation's instance implementing this operation
204
         * @param geomClass Geometry implementation class
205
         * @return Index assigned to this operation. This index is used later to access the operation.
206
         */
207
        private int registerGeometryOperation(String geomOpName,
208
                        GeometryOperation geomOp, Class geomClass) {
209

    
210
                GeometryType geomType = getGeometryType(geomClass);
211
                return registerGeometryOperation(geomOpName, geomOp, geomType);
212
        }
213

    
214
        /**
215
         * Registers a GeometryOperation associated to a GeometryType.
216
         * Returns an unique index that is used later to identify and invoke the operation.<br>
217
         *
218
         * By convention, the return value should be stored in a public constant within the class implementing
219
         * the operation:<BR>
220
         * <pre>
221
         * public class MyOperation extends GeometryOperation {
222
         *   public static final int CODE =
223
         *     GeometryManager.getInstance()
224
         *        .registerGeometryOperation("MyOperation", MyOperation.class, myGeomType);
225
         * }
226
         * </pre>
227
         *
228
         * @param geomOpName Operation's unique name
229
         * @param geomOpClass GeometryOperation class
230
         * @param geomType GeometryType instance to which this operation should be associated
231
         * @return Index assigned to this operation. This index is used later to access the operation.
232
         * @throws IllegalAccessException, {@link InstantiationException} Either exception maybe thrown when
233
         * trying to instance the geometry operation class.
234
         */
235
        private int registerGeometryOperation(String geomOpName, Class geomOpClass,
236
                        GeometryType geomType)
237
        throws IllegalAccessException, InstantiationException {
238

    
239
                GeometryOperation geomOp = (GeometryOperation) geomOpClass.newInstance();
240
                return registerGeometryOperation(geomOpName, geomOp, geomType);
241
        }
242

    
243
        /* (non-Javadoc)
244
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryOperation(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperation, int, int)
245
         */
246
        public int registerGeometryOperation(String geomOpName,
247
                        GeometryOperation geomOp, int type, int subType) throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
248
                GeometryType geometryType = getGeometryType(type, subType);
249
                return registerGeometryOperation(geomOpName, geomOp, geometryType);
250
        }
251

    
252
        /* (non-Javadoc)
253
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryOperation(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperation, int)
254
         */
255
        public int registerGeometryOperation(String geomOpName,
256
                        GeometryOperation geomOp, int type) {
257
                Iterator it = geometryTypeName.keySet().iterator();
258
                int code = -1;
259
                while (it.hasNext()){
260
                        String className = (String)it.next();
261
                        GeometryType geometryType = (GeometryType) geometryTypeName.get(className);
262
                        if ((type == geometryType.getType())) {
263
                                code = registerGeometryOperation(geomOpName, geomOp, geometryType);
264
                        }
265
                        {
266
                        }
267
                }
268
                return code;
269
        }
270

    
271
        /* (non-Javadoc)
272
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryOperationBySubtype(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperation, int)
273
         */
274
        public int registerGeometryOperationBySubtype(String geomOpName,
275
                        GeometryOperation geomOp, int subType) {
276
                Iterator it = geometryTypeName.keySet().iterator();
277
                int code = -1;
278
                while (it.hasNext()){
279
                        String className = (String)it.next();
280
                        GeometryType geometryType = (GeometryType) geometryTypeName.get(className);
281
                        if ((subType == geometryType.getSubType())) {
282
                                code = registerGeometryOperation(geomOpName, geomOp, geometryType);
283
                        }
284
                        {
285
                        }
286
                }
287
                return code;
288
        }
289

    
290
        /*
291
         * (non-Javadoc)
292
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryType(java.lang.Class, java.lang.String, int)
293
         */
294
        public GeometryType registerGeometryType(Class geomClass, String name, int type, int subType) {
295
                return registerGeometryType(geomClass, name, geometryTypeIndex++, type, subType);
296
        }
297

    
298
        /**
299
         * Registers a Geometry implementation class with a predefined geometry type and returns the
300
         * associated GeometryType instance. Available predefined types are defined in {@link Geometry.TYPES}
301
         * If the class is already registered then this method throws an IllegalArgumentException.<br>
302
         *
303
         * How to register a geometry class with a predefined type:
304
         * <pre>
305
         *
306
         * public class Point2D implements Point {
307
         *   private static final GeometryType geomType = GeometryManager.getInstance()
308
         *           .registerBasicGeometryType(Point2D.class, "Point2D", Geometry.TYPES.POINT);
309
         *
310
         *   public static final int CODE = geomType.getId();
311
         * ...
312
         *   public int getType() {
313
         *      return geomType.getType();
314
         *   }
315
         * }
316
         * </pre>
317
         *
318
         * @param geomClass
319
         *            Geometry subclass. It must not be null and must implement Geometry, otherwise an exception
320
         *            is raised.
321
         * @param name
322
         *                           Symbolic name for the geometry type, it can be null. If it is null then the symbolic name
323
         *                       will be the simple class name.
324
         * @param id
325
         *                           Geometry identifier.
326
         * @param type
327
         *                           Type of geometry. Must be a value defined in {@link Geometry.TYPES}
328
         * @param subType
329
         * SubType of geometry. Must be a value defined in {@link Geometry.SUBTYPES}
330
         * @return Instance of GeometryType associated to the Geometry implementation class
331
         *         geomClass
332
         * @throws IllegalArgumentException
333
         *             If geomClass is null or does not implement Geometry
334
         */
335
        private GeometryType registerGeometryType(Class geomClass, String name, int id,
336
                        int type, int subType){
337
                if (geomClass == null) {
338
                        throw new IllegalArgumentException("geomClass cannot be null.");
339
                }
340

    
341
                if (!Geometry.class.isAssignableFrom(geomClass)) {
342
                        throw new IllegalArgumentException(geomClass.getName()
343
                                        + " must implement the Geometry interface");
344
                }
345

    
346
                // Check if it is registered
347
                GeometryType geomType = (GeometryType) geometryTypeName.get(geomClass
348
                                .getName());
349

    
350
                // If it is not, register it
351
                if (geomType == null) {
352
                        geomType = new DefaultGeometryType(geomClass, name, id, type, subType);
353
                        geometryTypeName.put(geomClass.getName(), geomType);
354
                        geometryTypeList.add(id, geomType);
355
                        Map subTypes = null;
356
                        Integer key = new Integer(type);
357
                        if (!geometrySubtypes.containsKey(key)){
358
                                subTypes = new HashMap();
359
                                geometrySubtypes.put(key, subTypes);
360
                        }else{
361
                                subTypes = (HashMap)geometrySubtypes.get(key);
362
                        }
363
                        subTypes.put(new Integer(subType), geomType);
364
                } else {
365
                        // If it is already registered, throw exception
366
                        geometryTypeIndex--;
367
                        //throw new IllegalArgumentException("Attempt to register a geometry type that is already registered: " + geomClass.getName());
368
                }
369
                logger.debug("Class " + geomClass + " registered with name " + geomType.getName());
370

    
371
                return geomType;
372
        }
373

    
374
        /*
375
         * (non-Javadoc)
376
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryType(java.lang.Class, int)
377
         */
378
        public GeometryType registerGeometryType(Class geomClass, int type, int subType) {
379
                return registerGeometryType(geomClass, null, type, subType);
380
        }
381

    
382
        /**
383
         * Returns an instance of GeometryType given the associated Geometry implementation
384
         * class.
385
         *
386
         * @param geomClass
387
         * @return Instance of GeometryType associated to the Geometry implementation class
388
         */
389
        private GeometryType getGeometryType(Class geomClass) {
390
                logger.debug("getting " + geomClass.getName());
391
                return (GeometryType) geometryTypeName.get(geomClass.getName());
392
        }
393

    
394
        /*
395
         * (non-Javadoc)
396
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryType(java.lang.String)
397
         */
398
        public GeometryType getGeometryType(String className) throws GeometryTypeNotSupportedException {
399
                if (!geometryTypeName.containsKey(className)){
400
                        throw new GeometryTypeNotSupportedException(className);
401
                }
402
                return (GeometryType) geometryTypeName.get(className);
403
        }
404

    
405
        /* (non-Javadoc)
406
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryType(int, int)
407
         */
408
        public GeometryType getGeometryType(int type, int subType) throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
409
                Iterator it = geometryTypeName.keySet().iterator();
410
                while (it.hasNext()){
411
                        String className = (String)it.next();
412
                        GeometryType geometryType = getGeometryType(className);
413
                        if ((type == geometryType.getType()) &&
414
                                        (subType == geometryType.getSubType())){
415
                                return geometryType;
416
                        }
417
                        if (subType == SUBTYPES.UNKNOWN){
418
                                throw new GeometryTypeNotValidException(type, subType);
419
                        }
420
                }
421
                throw new GeometryTypeNotSupportedException(type, subType);
422
        }
423

    
424
        /*
425
         * (non-Javadoc)
426
         * @see org.gvsig.fmap.geom.GeometryManager#create(org.gvsig.fmap.geom.type.GeometryType)
427
         */
428
        public Geometry create(GeometryType geomType) throws CreateGeometryException{
429
                return geomType.create();
430
        }
431

    
432
        /*
433
         * (non-Javadoc)
434
         * @see org.gvsig.fmap.geom.GeometryManager#create(java.lang.String)
435
         */
436
        public Geometry create(String name) throws CreateGeometryException{
437
                if (!geometryTypeName.containsKey(name)){
438
                        throw new IllegalArgumentException(name + " has not been registered yet.");
439
                }
440
                return ((GeometryType)geometryTypeName.get(name)).create();
441
        }
442

    
443
        /*
444
         * (non-Javadoc)
445
         * @see org.gvsig.fmap.geom.GeometryManager#create(int)
446
         */
447
        public Geometry create(int type, int subType) throws CreateGeometryException{
448
                if (!geometrySubtypes.containsKey(new Integer(type))){
449
                        throw new IllegalArgumentException("geometry type" + type + " has not been registered yet.");
450
                }
451
                Map subtypes = (Map)geometrySubtypes.get(new Integer(type));
452
                if (!subtypes.containsKey(new Integer(subType))){
453
                        throw new IllegalArgumentException("geometry subtype" + subType + " has not been registered yet.");
454
                }
455
                return ((GeometryType)subtypes.get(new Integer(subType))).create();
456
        }
457

    
458

    
459
        /* (non-Javadoc)
460
         * @see org.gvsig.fmap.geom.GeometryManager#createCurve(org.gvsig.fmap.geom.primitive.GeneralPathX, int)
461
         */
462
        public Curve createCurve(GeneralPathX generalPathX, int subType)
463
        throws CreateGeometryException {
464
                Curve curve = (Curve)create(TYPES.CURVE, subType);
465
                curve.setGeneralPath(generalPathX);
466
                return curve;
467
        }
468

    
469
        /* (non-Javadoc)
470
         * @see org.gvsig.fmap.geom.GeometryManager#createNullGeometry(int)
471
         */
472
        public NullGeometry createNullGeometry(int subType)
473
        throws CreateGeometryException {
474
                NullGeometry nullGeom = (NullGeometry)create(TYPES.NULL, subType);
475
                return nullGeom;
476
        }
477

    
478
        /* (non-Javadoc)
479
         * @see org.gvsig.fmap.geom.GeometryManager#createPoint(double, double, int)
480
         */
481
        public Point createPoint(double x, double y, int subType)
482
        throws CreateGeometryException {
483
                Point point = (Point)create(TYPES.POINT, subType);
484
                point.setX(x);
485
                point.setY(y);
486
                return point;
487
        }
488

    
489
        /* (non-Javadoc)
490
         * @see org.gvsig.fmap.geom.GeometryManager#createSurface(org.gvsig.fmap.geom.primitive.GeneralPathX, int)
491
         */
492
        public Surface createSurface(GeneralPathX generalPathX, int subType)
493
        throws CreateGeometryException {
494
                Surface surface = (Surface)create(TYPES.SURFACE, subType);
495
                surface.setGeneralPath(generalPathX);
496
                return surface;
497
        }
498

    
499
        /* (non-Javadoc)
500
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryOperation(int, int, int)
501
         */
502
        public GeometryOperation getGeometryOperation(int opCode, int type,
503
                        int subType) throws GeometryTypeNotSupportedException,
504
                        GeometryOperationNotSupportedException, GeometryTypeNotValidException {
505
                GeometryType geometryType = getGeometryType(type, subType);
506
                return geometryType.getGeometryOperation(opCode);
507
        }
508

    
509
        //        /*
510
        //         * (non-Javadoc)
511
        //         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryOperation(java.lang.Class, int)
512
        //         */
513
        //        private GeometryOperation getGeometryOperation(Class geomClass, int opCode) throws GeometryTypeNotSupportedException, GeometryOperationNotSupportedException {
514
        //
515
        //                GeometryOperation geomOp = null;
516
        //
517
        //                // Check if it is a common operation, and if so, get it from the common registry
518
        //                if (opCode >= COMMON_OPS_OFFSET) {
519
        //                        geomOp = ((GeometryOperation)commonOperations.get(opCode - COMMON_OPS_OFFSET));
520
        //
521
        //                        if (geomOp == null) {
522
        //                                throw new GeometryOperationNotSupportedException(opCode);
523
        //                        }
524
        //                } else {
525
        //                        // If it is type specific, get it from its type        registry
526
        //                        if (geomClass != null) {
527
        //                                GeometryType geomType = getGeometryType(geomClass);
528
        //
529
        //                                // If the geometry type is not registered, throw an exception
530
        //                                if (geomType == null) {
531
        //                                        throw new GeometryTypeNotSupportedException(geomClass);
532
        //                                }
533
        //
534
        //                                // Get the operation
535
        //                                geomOp = geomType.getGeometryOperation(opCode);
536
        //
537
        //                                // If the operation is not registered throw an exception
538
        //                                if (geomOp == null) {
539
        //                                        throw new GeometryOperationNotSupportedException(opCode, geomType);
540
        //                                }
541
        //                        }
542
        //                }
543
        //                return geomOp;
544
        //        }
545

    
546
        /*
547
         * (non-Javadoc)
548
         * @see org.gvsig.fmap.geom.GeometryManager#invokeOperation(int, org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.geom.operation.GeometryOperationContext)
549
         */
550
        public Object invokeOperation(int opCode, Geometry geom, GeometryOperationContext ctx) throws GeometryOperationNotSupportedException, GeometryOperationException {
551
                GeometryOperation geomOp = geom.getGeometryType().getGeometryOperation(opCode);
552

    
553
                if (geomOp != null) {
554
                        return geomOp.invoke(geom, ctx);
555
                }
556

    
557
                throw new GeometryOperationNotSupportedException(opCode, geom.getGeometryType());
558
        }
559

    
560
        /* (non-Javadoc)
561
         * @see org.gvsig.fmap.geom.GeometryManager#invokeOperation(java.lang.String, org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.geom.operation.GeometryOperationContext)
562
         */
563
        public Object invokeOperation(String geomOpName, Geometry geom,
564
                        GeometryOperationContext ctx)
565
        throws GeometryOperationNotSupportedException,
566
        GeometryOperationException {
567
                int index = geometryOperations.indexOf(geomOpName);
568
                if (index == -1){
569
                        throw new GeometryOperationNotSupportedException(-1);
570
                }
571
                return invokeOperation(index, geom, ctx);
572
        }
573

    
574
        /*
575
         * (non-Javadoc)
576
         * @see org.gvsig.fmap.geom.GeometryManager#unregisterGeometryType(java.lang.Class)
577
         */
578
        public GeometryType unregisterGeometryType(Class geomClass) {
579
                return (GeometryType) geometryTypeName.remove(geomClass.getName());
580
        }
581

    
582
        /* (non-Javadoc)
583
         * @see org.gvsig.fmap.geom.GeometryManager#createEnvelope(int)
584
         */
585
        public Envelope createEnvelope(int subType) {
586
                //TODO: register the envelopes!!!
587
                switch (subType){
588
                case SUBTYPES.GEOM2DZ:
589
                case SUBTYPES.GEOM3D:
590
                        return new Envelope3D();
591
                default:
592
                        return new Envelope2D();
593
                }
594
        }
595

    
596

    
597
        /* (non-Javadoc)
598
         * @see org.gvsig.fmap.geom.GeometryManager#createEnvelope(double, double, double, double)
599
         */
600
        public Envelope createEnvelope(double minX, double minY, double maxX,
601
                        double maxY, int subType) throws CreateEnvelopeException {
602
                Envelope envelope = null;
603
                org.gvsig.fmap.geom.primitive.Point min = null;
604
                org.gvsig.fmap.geom.primitive.Point max = null;
605
                try {
606
                        min = (org.gvsig.fmap.geom.primitive.Point)create(TYPES.POINT, subType);
607
                        min.setX(minX);
608
                        min.setY(minY);
609
                        max = (org.gvsig.fmap.geom.primitive.Point)create(TYPES.POINT, subType);
610
                        max.setX(maxX);
611
                        max.setY(maxY);
612
                }catch (CreateGeometryException e){
613
                        throw new CreateEnvelopeException(subType, e);
614
                }
615
                envelope = createEnvelope(subType);
616
                envelope.setLowerCorner(min);
617
                envelope.setUpperCorner(max);
618
                return envelope;
619
        }
620

    
621
        public MultiCurve createMultiCurve(GeneralPathX generalPathX, int subType)
622
                        throws CreateGeometryException {
623
                if (subType != SUBTYPES.GEOM2D){
624
                        // FIXME Exception
625
                        throw new UnsupportedOperationException();
626
                }
627
                MultiCurve multiCurve = (MultiCurve) create(TYPES.MULTICURVE, subType);
628
                PathIterator piter = generalPathX.getPathIterator(null);
629
                GeneralPathX tmpPath = null;
630
                Curve tmpCurve = null;
631
                double[] coords = new double[6];
632
                double[] first = new double[6];
633
                int type;
634
                while (!piter.isDone()) {
635
                        type = piter.currentSegment(coords);
636
                        switch (type) {
637
                        case PathIterator.SEG_MOVETO:
638
                                if (tmpPath != null){
639
                                        tmpCurve = createCurve(tmpPath, subType);
640
                                        multiCurve.addCurve(tmpCurve);
641
                                }
642
                                System.arraycopy(coords, 0, first, 0, 2);
643
                                tmpPath =  new GeneralPathX(piter.getWindingRule());
644
                                tmpPath.moveTo(coords[0], coords[1]);
645
                                break;
646

    
647

    
648
                        case PathIterator.SEG_LINETO:
649
                                if (tmpPath == null) {
650
                                        System.arraycopy(coords, 0, first, 0, 2);
651
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
652
                                }
653
                                tmpPath.lineTo(coords[0], coords[1]);
654
                                break;
655

    
656

    
657
                        case PathIterator.SEG_QUADTO:
658
                                if (tmpPath == null) {
659
                                        System.arraycopy(coords, 0, first, 0, 2);
660
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
661
                                }
662
                                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
663
                                break;
664

    
665
                        case PathIterator.SEG_CUBICTO:
666
                                if (tmpPath == null) {
667
                                        System.arraycopy(coords, 0, first, 0, 2);
668
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
669
                                }
670
                                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
671
                                                coords[4], coords[5]);
672
                                 break;
673

    
674
                        case PathIterator.SEG_CLOSE:
675
                                tmpPath.lineTo(first[0], first[1]);
676
                                 break;
677

    
678
                        } // end switch
679

    
680
                        piter.next();
681

    
682
                }
683
                if (tmpPath != null) {
684
                        tmpCurve = createCurve(tmpPath, subType);
685
                        multiCurve.addCurve(tmpCurve);
686
                }
687

    
688
                return multiCurve;
689

    
690
        }
691

    
692
        public MultiSurface createMultiSurface(GeneralPathX generalPathX,
693
                        int subType)
694
                        throws CreateGeometryException {
695
                if (subType != SUBTYPES.GEOM2D) {
696
                        // FIXME Exception
697
                        throw new UnsupportedOperationException();
698
                }
699
                MultiSurface multiSurface = (MultiSurface) create(TYPES.MULTISURFACE,
700
                                subType);
701
                PathIterator piter = generalPathX.getPathIterator(null);
702
                GeneralPathX tmpPath = null;
703
                Surface tmpSurface = null;
704
                double[] coords = new double[6];
705
                double[] first = new double[6];
706
                int type;
707
                while (!piter.isDone()) {
708
                        type = piter.currentSegment(coords);
709
                        switch (type) {
710
                        case PathIterator.SEG_MOVETO:
711
                                if (tmpPath != null) {
712
                                        tmpSurface = createSurface(tmpPath, subType);
713
                                        multiSurface.addSurface(tmpSurface);
714
                                }
715
                                System.arraycopy(coords, 0, first, 0, 2);
716
                                tmpPath = new GeneralPathX(piter.getWindingRule());
717
                                tmpPath.moveTo(coords[0], coords[1]);
718

    
719
                        case PathIterator.SEG_LINETO:
720
                                if (tmpPath == null) {
721
                                        System.arraycopy(coords, 0, first, 0, 2);
722
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
723
                                }
724
                                tmpPath.lineTo(coords[0], coords[1]);
725
                                break;
726

    
727

    
728
                        case PathIterator.SEG_QUADTO:
729
                                if (tmpPath == null) {
730
                                        System.arraycopy(coords, 0, first, 0, 2);
731
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
732
                                }
733
                                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
734
                                break;
735

    
736
                        case PathIterator.SEG_CUBICTO:
737
                                if (tmpPath == null) {
738
                                        System.arraycopy(coords, 0, first, 0, 2);
739
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
740
                                }
741
                                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
742
                                                coords[4], coords[5]);
743
                                break;
744

    
745
                        case PathIterator.SEG_CLOSE:
746
                                tmpPath.lineTo(first[0], first[1]);
747
                                break;
748
                        } // end switch
749

    
750
                        piter.next();
751

    
752
                }
753
                if (tmpPath != null) {
754
                        tmpSurface = createSurface(tmpPath, subType);
755
                        multiSurface.addSurface(tmpSurface);
756
                }
757

    
758
                return multiSurface;
759

    
760
        }
761

    
762
        /* (non-Javadoc)
763
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryOperationCode(java.lang.String)
764
         */
765
        public int getGeometryOperationCode(String geomOpName) {
766
                if (geomOpName == null) {
767
                        throw new IllegalArgumentException("geomOpName cannot be null.");
768
                }
769

    
770
                int index = geometryOperations.indexOf(geomOpName);
771
                if (index == -1) {
772
                        geometryOperations.add(geomOpName);
773
                        index = geometryOperations.indexOf(geomOpName);
774
                }
775
                return index;
776
        }
777

    
778
        /* (non-Javadoc)
779
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryOperationNames()
780
         */
781
        public List getGeometryOperationNames() {
782
                ArrayList operations = new ArrayList();
783
                for (int i=0 ; i<operations.size() ; i++){
784
                        operations.add(geometryOperations.get(i));
785
                }
786
                return operations;
787
        }
788

    
789
        /*
790
         * (non-Javadoc)
791
         * @see org.gvsig.fmap.geom.GeometryManager#getFlatness()
792
         */
793
        public double getFlatness() {
794
                return flatness;
795
        }
796

    
797
        /*
798
         * (non-Javadoc)
799
         * @see org.gvsig.fmap.geom.GeometryManager#setFlatness(double)
800
         */
801
        public void setFlatness(double flatness) {
802
                this.flatness = flatness;
803
        }        
804
}
805