Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_geometries / src / org / gvsig / fmap / geom / impl / DefaultGeometryManager.java @ 34140

History | View | Annotate | Download (29.3 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.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39

    
40
import org.gvsig.fmap.geom.Geometry;
41
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
42
import org.gvsig.fmap.geom.Geometry.TYPES;
43
import org.gvsig.fmap.geom.GeometryException;
44
import org.gvsig.fmap.geom.GeometryLocator;
45
import org.gvsig.fmap.geom.GeometryManager;
46
import org.gvsig.fmap.geom.aggregate.MultiCurve;
47
import org.gvsig.fmap.geom.aggregate.MultiSurface;
48
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
49
import org.gvsig.fmap.geom.exception.CreateGeometryException;
50
import org.gvsig.fmap.geom.operation.GeometryOperation;
51
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
52
import org.gvsig.fmap.geom.operation.GeometryOperationException;
53
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
54
import org.gvsig.fmap.geom.operation.fromwkb.FromWKBGeometryOperationContext;
55
import org.gvsig.fmap.geom.operation.fromwkt.FromWKTGeometryOperationContext;
56
import org.gvsig.fmap.geom.primitive.Curve;
57
import org.gvsig.fmap.geom.primitive.Envelope;
58
import org.gvsig.fmap.geom.primitive.GeneralPathX;
59
import org.gvsig.fmap.geom.primitive.NullGeometry;
60
import org.gvsig.fmap.geom.primitive.Point;
61
import org.gvsig.fmap.geom.primitive.Surface;
62
import org.gvsig.fmap.geom.primitive.impl.DefaultNullGeometry;
63
import org.gvsig.fmap.geom.primitive.impl.Envelope2D;
64
import org.gvsig.fmap.geom.primitive.impl.Envelope3D;
65
import org.gvsig.fmap.geom.type.GeometryType;
66
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
67
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
68
import org.gvsig.fmap.geom.type.impl.DefaultGeometryType;
69

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

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

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

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

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

    
94
        /**
95
         * Matrix of geometry types by type (row) and subtype (column). This matrix
96
         * will contain null values in the cells where a GeometryType hasn't been
97
         * registered.
98
         */
99
        private GeometryType[][] geometryTypes;
100

    
101
        /** 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
102
         * it is incremented by 1 */
103
        private int geometryTypeIndex = 0;//Geometry.EXTENDED_GEOMTYPE_OFFSET; //65536;//2^16
104

    
105
        // Initially create a matrix of 17 x 6, which are the current default
106
        // types and subtypes. If another type or subtype is registered, the
107
        // matrix will grow as needed
108
        private static final int DEFAULT_TYPES_SIZE = 17;
109
        private static final int DEFAULT_SUBTYPES_SIZE = 6;
110

    
111
        public DefaultGeometryManager() {
112
                this(DEFAULT_TYPES_SIZE, DEFAULT_SUBTYPES_SIZE);
113
        }
114

    
115
        public DefaultGeometryManager(int initialTypesSize, int initialSubtypesSize) {
116
                geometryTypes = new GeometryType[initialTypesSize][initialSubtypesSize];
117
        }
118

    
119
        /*
120
         * (non-Javadoc)
121
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryOperation(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperation, org.gvsig.fmap.geom.type.GeometryType)
122
         */
123
        public int registerGeometryOperation(String geomOpName,
124
                        GeometryOperation geomOp, GeometryType geomType) {
125
                if (geomOp == null) {
126
                        throw new IllegalArgumentException("geomOp cannot be null.");
127
                }
128
                if (geomType == null) {
129
                        throw new IllegalArgumentException("geomType cannot be null.");
130
                }
131

    
132
                int index = getGeometryOperationCode(geomOpName);
133

    
134
                geomType.setGeometryOperation(index, geomOp);
135

    
136
                return index;
137
        }
138

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

    
152
                int index = getGeometryOperationCode(geomOpName);
153

    
154
                Iterator it = geometryTypeName.keySet().iterator();
155
                while (it.hasNext()){
156
                        String className = (String)it.next();
157
                        GeometryType geometryType = (GeometryType) geometryTypeName.get(className);
158
                        registerGeometryOperation(geomOpName, geomOp, geometryType);
159
                }
160

    
161
                return index;
162

    
163
        }
164

    
165
        // /**
166
        // * Registers a GeometryOperation associated to a GeometryType.
167
        // * Returns an unique index that is used later to identify and invoke the
168
        // operation.<br>
169
        // *
170
        // * By convention, the return value should be stored in a public constant
171
        // within the class implementing
172
        // * the operation:<BR>
173
        // * <pre>
174
        // * public class MyOperation extends GeometryOperation {
175
        // * public static final int CODE =
176
        // * GeometryManager.getInstance()
177
        // * .registerGeometryOperation("MyOperation", new MyOperation(),
178
        // MyGeometry.class);
179
        // * }
180
        // * </pre>
181
        // *
182
        // * This method is only used if you have not a reference to the
183
        // GeometryType associated to the
184
        // * geometry class. If you have such reference then it is slightly faster
185
        // to use the method that receives
186
        // * the GeometryType.<br>
187
        // *
188
        // * @param geomOpName Operation's unique name
189
        // * @param geomOp Specific GeometryOperation's instance implementing this
190
        // operation
191
        // * @param geomClass Geometry implementation class
192
        // * @return Index assigned to this operation. This index is used later to
193
        // access the operation.
194
        // */
195
        // private int registerGeometryOperation(String geomOpName,
196
        // GeometryOperation geomOp, Class geomClass) {
197
        //
198
        // GeometryType geomType = getGeometryType(geomClass);
199
        // return registerGeometryOperation(geomOpName, geomOp, geomType);
200
        // }
201

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

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

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

    
264
        /* (non-Javadoc)
265
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryOperationBySubtype(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperation, int)
266
         */
267
        public int registerGeometryOperationBySubtype(String geomOpName,
268
                        GeometryOperation geomOp, int subType) {
269
                Iterator it = geometryTypeName.keySet().iterator();
270
                int code = -1;
271
                while (it.hasNext()){
272
                        String className = (String)it.next();
273
                        GeometryType geometryType = (GeometryType) geometryTypeName.get(className);
274
                        if ((subType == geometryType.getSubType())) {
275
                                code = registerGeometryOperation(geomOpName, geomOp, geometryType);
276
                        }
277
                }
278
                return code;
279
        }
280

    
281
        /*
282
         * (non-Javadoc)
283
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryType(java.lang.Class, java.lang.String, int)
284
         */
285
        public GeometryType registerGeometryType(Class geomClass, String name, int type, int subType) {
286
                return registerGeometryType(geomClass, name, geometryTypeIndex++, type, subType);
287
        }
288

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

    
332
                if (!Geometry.class.isAssignableFrom(geomClass)) {
333
                        throw new IllegalArgumentException(geomClass.getName()
334
                                        + " must implement the Geometry interface");
335
                }
336

    
337
                // Check if it is registered
338
                GeometryType geomType = null;
339
                if (type >= geometryTypes.length || subType >= geometryTypes[0].length
340
                                || (geomType = geometryTypes[type][subType]) == null) {
341
                        geomType =
342
                                        new DefaultGeometryType(geomClass, name, id, type, subType);
343
                        registerGeometryType(geomType);
344
                        geometryTypeName.put(geomClass.getName(), geomType);
345
                }
346

    
347
                logger.debug("Class {} registered with name {}", geomClass,
348
                                geomType.getName());
349

    
350
                return geomType;
351
        }
352

    
353
        private void registerGeometryType(GeometryType geometryType) {
354
                if (geometryType.getType() >= geometryTypes.length
355
                                || geometryType.getSubType() >= geometryTypes[0].length) {
356

    
357
                        // Recreate the geometry type matrix if the types
358
                        // or subtypes don't fit
359
                        int newTypesSize =
360
                                        geometryType.getType() < geometryTypes.length ? geometryTypes.length
361
                                                        : geometryType.getType() + 1;
362
                        int newSubTypesSize =
363
                                        geometryType.getSubType() < geometryTypes[0].length ? geometryTypes[0].length
364
                                                        : geometryType.getSubType() + 1;
365
                        GeometryType[][] newMatrix =
366
                                        new GeometryType[newTypesSize][newSubTypesSize];
367

    
368
                        for (int i = 0; i < geometryTypes.length; i++) {
369
                                System.arraycopy(geometryTypes[i], 0, newMatrix[i], 0,
370
                                                geometryTypes[i].length);
371
                        }
372
                        geometryTypes = newMatrix;
373
                }
374

    
375
                geometryTypes[geometryType.getType()][geometryType.getSubType()] =
376
                                geometryType;
377
        }
378

    
379
        /*
380
         * (non-Javadoc)
381
         * @see org.gvsig.fmap.geom.GeometryManager#registerGeometryType(java.lang.Class, int)
382
         */
383
        public GeometryType registerGeometryType(Class geomClass, int type, int subType) {
384
                return registerGeometryType(geomClass, null, type, subType);
385
        }
386

    
387
        // /**
388
        // * Returns an instance of GeometryType given the associated Geometry
389
        // implementation
390
        // * class.
391
        // *
392
        // * @param geomClass
393
        // * @return Instance of GeometryType associated to the Geometry
394
        // implementation class
395
        // */
396
        // private GeometryType getGeometryType(Class geomClass) {
397
        // logger.debug("getting " + geomClass.getName());
398
        // return (GeometryType) geometryTypeName.get(geomClass.getName());
399
        // }
400

    
401
        /*
402
         * (non-Javadoc)
403
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryType(java.lang.String)
404
         */
405
        public GeometryType getGeometryType(String className) throws GeometryTypeNotSupportedException {
406
                if (!geometryTypeName.containsKey(className)){
407
                        throw new GeometryTypeNotSupportedException(className);
408
                }
409
                return (GeometryType) geometryTypeName.get(className);
410
        }
411

    
412
        /* (non-Javadoc)
413
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryType(int, int)
414
         */
415
        public GeometryType getGeometryType(int type, int subType) throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
416
                GeometryType gType = null;
417
                if (type >= geometryTypes.length || subType >= geometryTypes[0].length) {
418
                        throw new GeometryTypeNotValidException(type, subType);
419
                }
420

    
421
                gType = geometryTypes[type][subType];
422

    
423
                if (gType == null) {
424
                        throw new GeometryTypeNotSupportedException(type, subType);
425
                }
426

    
427
                return gType;
428

    
429
                // Iterator it = geometryTypeName.keySet().iterator();
430
                // while (it.hasNext()){
431
                // String className = (String)it.next();
432
                // GeometryType geometryType = getGeometryType(className);
433
                // if ((type == geometryType.getType()) &&
434
                // (subType == geometryType.getSubType())){
435
                // return geometryType;
436
                // }
437
                // if (subType == SUBTYPES.UNKNOWN){
438
                // throw new GeometryTypeNotValidException(type, subType);
439
                // }
440
                // }
441
                // throw new GeometryTypeNotSupportedException(type, subType);
442
        }
443

    
444
        /*
445
         * (non-Javadoc)
446
         * @see org.gvsig.fmap.geom.GeometryManager#create(org.gvsig.fmap.geom.type.GeometryType)
447
         */
448
        public Geometry create(GeometryType geomType) throws CreateGeometryException{
449
                return geomType.create();
450
        }
451

    
452
        /*
453
         * (non-Javadoc)
454
         * @see org.gvsig.fmap.geom.GeometryManager#create(java.lang.String)
455
         */
456
        public Geometry create(String name) throws CreateGeometryException{
457
                if (!geometryTypeName.containsKey(name)){
458
                        throw new IllegalArgumentException(name + " has not been registered yet.");
459
                }
460
                return ((GeometryType)geometryTypeName.get(name)).create();
461
        }
462

    
463
        /*
464
         * (non-Javadoc)
465
         * @see org.gvsig.fmap.geom.GeometryManager#create(int)
466
         */
467
        public Geometry create(int type, int subType)
468
                        throws CreateGeometryException {
469
                try {
470
                        return getGeometryType(type, subType).create();
471
                } catch (GeometryException e) {
472
                        throw new CreateGeometryException(type, subType, e);
473
                }
474
        }
475

    
476

    
477
        /* (non-Javadoc)
478
         * @see org.gvsig.fmap.geom.GeometryManager#createCurve(org.gvsig.fmap.geom.primitive.GeneralPathX, int)
479
         */
480
        public Curve createCurve(GeneralPathX generalPathX, int subType)
481
                        throws CreateGeometryException {
482
                Curve curve = (Curve)create(TYPES.CURVE, subType);
483
                curve.setGeneralPath(generalPathX);
484
                return curve;
485
        }
486

    
487
        /* (non-Javadoc)
488
         * @see org.gvsig.fmap.geom.GeometryManager#createNullGeometry(int)
489
         */
490
        public NullGeometry createNullGeometry(int subType)
491
                        throws CreateGeometryException {
492
                NullGeometry nullGeom = (NullGeometry)create(TYPES.NULL, subType);
493
                return nullGeom;
494
        }
495

    
496
        /* (non-Javadoc)
497
         * @see org.gvsig.fmap.geom.GeometryManager#createPoint(double, double, int)
498
         */
499
        public Point createPoint(double x, double y, int subType)
500
                        throws CreateGeometryException {
501
                Point point = (Point)create(TYPES.POINT, subType);
502
                point.setX(x);
503
                point.setY(y);
504
                return point;
505
        }
506

    
507
        /* (non-Javadoc)
508
         * @see org.gvsig.fmap.geom.GeometryManager#createSurface(org.gvsig.fmap.geom.primitive.GeneralPathX, int)
509
         */
510
        public Surface createSurface(GeneralPathX generalPathX, int subType)
511
                        throws CreateGeometryException {
512
                Surface surface = (Surface)create(TYPES.SURFACE, subType);
513
                surface.setGeneralPath(generalPathX);
514
                return surface;
515
        }
516

    
517
        /* (non-Javadoc)
518
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryOperation(int, int, int)
519
         */
520
        public GeometryOperation getGeometryOperation(int opCode, int type,
521
                        int subType) throws GeometryTypeNotSupportedException,
522
                        GeometryOperationNotSupportedException, GeometryTypeNotValidException {
523
                GeometryType geometryType = getGeometryType(type, subType);
524
                return geometryType.getGeometryOperation(opCode);
525
        }
526

    
527
        //        /*
528
        //         * (non-Javadoc)
529
        //         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryOperation(java.lang.Class, int)
530
        //         */
531
        //        private GeometryOperation getGeometryOperation(Class geomClass, int opCode) throws GeometryTypeNotSupportedException, GeometryOperationNotSupportedException {
532
        //
533
        //                GeometryOperation geomOp = null;
534
        //
535
        //                // Check if it is a common operation, and if so, get it from the common registry
536
        //                if (opCode >= COMMON_OPS_OFFSET) {
537
        //                        geomOp = ((GeometryOperation)commonOperations.get(opCode - COMMON_OPS_OFFSET));
538
        //
539
        //                        if (geomOp == null) {
540
        //                                throw new GeometryOperationNotSupportedException(opCode);
541
        //                        }
542
        //                } else {
543
        //                        // If it is type specific, get it from its type        registry
544
        //                        if (geomClass != null) {
545
        //                                GeometryType geomType = getGeometryType(geomClass);
546
        //
547
        //                                // If the geometry type is not registered, throw an exception
548
        //                                if (geomType == null) {
549
        //                                        throw new GeometryTypeNotSupportedException(geomClass);
550
        //                                }
551
        //
552
        //                                // Get the operation
553
        //                                geomOp = geomType.getGeometryOperation(opCode);
554
        //
555
        //                                // If the operation is not registered throw an exception
556
        //                                if (geomOp == null) {
557
        //                                        throw new GeometryOperationNotSupportedException(opCode, geomType);
558
        //                                }
559
        //                        }
560
        //                }
561
        //                return geomOp;
562
        //        }
563

    
564
        /*
565
         * (non-Javadoc)
566
         * @see org.gvsig.fmap.geom.GeometryManager#invokeOperation(int, org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.geom.operation.GeometryOperationContext)
567
         */
568
        public Object invokeOperation(int opCode, Geometry geom, GeometryOperationContext ctx) throws GeometryOperationNotSupportedException, GeometryOperationException {
569
                GeometryOperation geomOp = geom.getGeometryType().getGeometryOperation(opCode);
570

    
571
                if (geomOp != null) {
572
                        return geomOp.invoke(geom, ctx);
573
                }
574

    
575
                throw new GeometryOperationNotSupportedException(opCode, geom.getGeometryType());
576
        }
577

    
578
        /* (non-Javadoc)
579
         * @see org.gvsig.fmap.geom.GeometryManager#invokeOperation(java.lang.String, org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.geom.operation.GeometryOperationContext)
580
         */
581
        public Object invokeOperation(String geomOpName, Geometry geom,
582
                        GeometryOperationContext ctx)
583
        throws GeometryOperationNotSupportedException,
584
        GeometryOperationException {
585
                int index = geometryOperations.indexOf(geomOpName);
586
                if (index == -1){
587
                        throw new GeometryOperationNotSupportedException(-1);
588
                }
589
                return invokeOperation(index, geom, ctx);
590
        }
591
        
592
        /*
593
         * (non-Javadoc)
594
         * @see org.gvsig.fmap.geom.GeometryManager#invokeOperation(java.lang.String, org.gvsig.fmap.geom.operation.GeometryOperationContext)
595
         */
596
        public Object invokeOperation(String geomOpName, GeometryOperationContext ctx) 
597
                throws GeometryOperationNotSupportedException, GeometryOperationException {
598
                int index = geometryOperations.indexOf(geomOpName);
599
                if (index == -1) 
600
                        throw new GeometryOperationNotSupportedException(-1);
601
                DefaultGeometryType type = (DefaultGeometryType)geometryTypeName.get(DefaultNullGeometry.class.getName());
602
                if(type != null) {
603
                        GeometryOperation geomOp = type.getGeometryOperation(index);
604
                        return geomOp.invoke(null, ctx);
605
                }
606
                return null;
607
        }
608

    
609
        /*
610
         * (non-Javadoc)
611
         * @see org.gvsig.fmap.geom.GeometryManager#unregisterGeometryType(java.lang.Class)
612
         */
613
        public GeometryType unregisterGeometryType(Class geomClass) {
614
                return (GeometryType) geometryTypeName.remove(geomClass.getName());
615
        }
616

    
617
        /* (non-Javadoc)
618
         * @see org.gvsig.fmap.geom.GeometryManager#createEnvelope(int)
619
         */
620
        public Envelope createEnvelope(int subType) {
621
                //TODO: register the envelopes!!!
622
                switch (subType){
623
                case SUBTYPES.GEOM2DZ:
624
                case SUBTYPES.GEOM3D:
625
                        return new Envelope3D();
626
                default:
627
                        return new Envelope2D();
628
                }
629
        }
630

    
631

    
632
        /* (non-Javadoc)
633
         * @see org.gvsig.fmap.geom.GeometryManager#createEnvelope(double, double, double, double)
634
         */
635
        public Envelope createEnvelope(double minX, double minY, double maxX,
636
                        double maxY, int subType) throws CreateEnvelopeException {
637
                org.gvsig.fmap.geom.primitive.Point min = null;
638
                org.gvsig.fmap.geom.primitive.Point max = null;
639
                try {
640
                        GeometryType gType = getGeometryType(TYPES.POINT, subType);
641
                        min = (Point) gType.create();
642
                        min.setX(minX);
643
                        min.setY(minY);
644
                        max = (Point) gType.create();
645
                        max.setX(maxX);
646
                        max.setY(maxY);
647
                        // min = createPoint(minX, minY, subType);
648
                        // max = createPoint(maxX, maxY, subType);
649
                } catch (CreateGeometryException e) {
650
                        throw new CreateEnvelopeException(subType, e);
651
                } catch (GeometryTypeNotSupportedException e) {
652
                        throw new CreateEnvelopeException(subType, e);
653
                } catch (GeometryTypeNotValidException e) {
654
                        throw new CreateEnvelopeException(subType, e);
655
                }
656
                switch (subType) {
657
                case SUBTYPES.GEOM2D:
658
                case SUBTYPES.GEOM2DM:
659
                        // Small optimization to directly create an Envelope2D
660
                        // return new Envelope2D(minX, minY, maxX, maxY);
661
                        return new Envelope2D(min, max);
662
                default:
663
                        Envelope envelope = createEnvelope(subType);
664
                        envelope.setLowerCorner(min);
665
                        envelope.setUpperCorner(max);
666
                        return envelope;
667
                }
668
        }
669

    
670
        public MultiCurve createMultiCurve(GeneralPathX generalPathX, int subType)
671
                        throws CreateGeometryException {
672
                if (subType != SUBTYPES.GEOM2D){
673
                        // FIXME Exception
674
                        throw new UnsupportedOperationException();
675
                }
676
                MultiCurve multiCurve = (MultiCurve) create(TYPES.MULTICURVE, subType);
677
                PathIterator piter = generalPathX.getPathIterator(null);
678
                GeneralPathX tmpPath = null;
679
                Curve tmpCurve = null;
680
                double[] coords = new double[6];
681
                double[] first = new double[6];
682
                int type;
683
                while (!piter.isDone()) {
684
                        type = piter.currentSegment(coords);
685
                        switch (type) {
686
                        case PathIterator.SEG_MOVETO:
687
                                if (tmpPath != null){
688
                                        tmpCurve = createCurve(tmpPath, subType);
689
                                        multiCurve.addCurve(tmpCurve);
690
                                }
691
                                System.arraycopy(coords, 0, first, 0, 2);
692
                                tmpPath =  new GeneralPathX(piter.getWindingRule());
693
                                tmpPath.moveTo(coords[0], coords[1]);
694
                                break;
695

    
696

    
697
                        case PathIterator.SEG_LINETO:
698
                                if (tmpPath == null) {
699
                                        System.arraycopy(coords, 0, first, 0, 2);
700
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
701
                                }
702
                                tmpPath.lineTo(coords[0], coords[1]);
703
                                break;
704

    
705

    
706
                        case PathIterator.SEG_QUADTO:
707
                                if (tmpPath == null) {
708
                                        System.arraycopy(coords, 0, first, 0, 2);
709
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
710
                                }
711
                                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
712
                                break;
713

    
714
                        case PathIterator.SEG_CUBICTO:
715
                                if (tmpPath == null) {
716
                                        System.arraycopy(coords, 0, first, 0, 2);
717
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
718
                                }
719
                                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
720
                                                coords[4], coords[5]);
721
                                 break;
722

    
723
                        case PathIterator.SEG_CLOSE:
724
                                tmpPath.lineTo(first[0], first[1]);
725
                                 break;
726

    
727
                        } // end switch
728

    
729
                        piter.next();
730

    
731
                }
732
                if (tmpPath != null) {
733
                        tmpCurve = createCurve(tmpPath, subType);
734
                        multiCurve.addCurve(tmpCurve);
735
                }
736

    
737
                return multiCurve;
738

    
739
        }
740

    
741
        public MultiSurface createMultiSurface(GeneralPathX generalPathX,
742
                        int subType) throws CreateGeometryException {
743
                if (subType != SUBTYPES.GEOM2D) {
744
                        // FIXME Exception
745
                        throw new UnsupportedOperationException();
746
                }
747
                MultiSurface multiSurface = (MultiSurface) create(TYPES.MULTISURFACE,
748
                                subType);
749
                PathIterator piter = generalPathX.getPathIterator(null);
750
                GeneralPathX tmpPath = null;
751
                Surface tmpSurface = null;
752
                double[] coords = new double[6];
753
                double[] first = new double[6];
754
                int type;
755
                while (!piter.isDone()) {
756
                        type = piter.currentSegment(coords);
757
                        switch (type) {
758
                        case PathIterator.SEG_MOVETO:
759
                                if (tmpPath != null) {
760
                                        tmpSurface = createSurface(tmpPath, subType);
761
                                        multiSurface.addSurface(tmpSurface);
762
                                }
763
                                System.arraycopy(coords, 0, first, 0, 2);
764
                                tmpPath = new GeneralPathX(piter.getWindingRule());
765
                                tmpPath.moveTo(coords[0], coords[1]);
766

    
767
                        case PathIterator.SEG_LINETO:
768
                                if (tmpPath == null) {
769
                                        System.arraycopy(coords, 0, first, 0, 2);
770
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
771
                                }
772
                                tmpPath.lineTo(coords[0], coords[1]);
773
                                break;
774

    
775

    
776
                        case PathIterator.SEG_QUADTO:
777
                                if (tmpPath == null) {
778
                                        System.arraycopy(coords, 0, first, 0, 2);
779
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
780
                                }
781
                                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
782
                                break;
783

    
784
                        case PathIterator.SEG_CUBICTO:
785
                                if (tmpPath == null) {
786
                                        System.arraycopy(coords, 0, first, 0, 2);
787
                                        tmpPath = new GeneralPathX(piter.getWindingRule());
788
                                }
789
                                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3],
790
                                                coords[4], coords[5]);
791
                                break;
792

    
793
                        case PathIterator.SEG_CLOSE:
794
                                tmpPath.lineTo(first[0], first[1]);
795
                                break;
796
                        } // end switch
797

    
798
                        piter.next();
799

    
800
                }
801
                if (tmpPath != null) {
802
                        tmpSurface = createSurface(tmpPath, subType);
803
                        multiSurface.addSurface(tmpSurface);
804
                }
805

    
806
                return multiSurface;
807

    
808
        }
809

    
810
        /* (non-Javadoc)
811
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryOperationCode(java.lang.String)
812
         */
813
        public int getGeometryOperationCode(String geomOpName) {
814
                if (geomOpName == null) {
815
                        throw new IllegalArgumentException("geomOpName cannot be null.");
816
                }
817

    
818
                int index = geometryOperations.indexOf(geomOpName);
819
                if (index == -1) {
820
                        geometryOperations.add(geomOpName);
821
                        index = geometryOperations.indexOf(geomOpName);
822
                }
823
                return index;
824
        }
825

    
826
        /* (non-Javadoc)
827
         * @see org.gvsig.fmap.geom.GeometryManager#getGeometryOperationNames()
828
         */
829
        public List getGeometryOperationNames() {
830
                List operations = new ArrayList();
831
                for (int i=0 ; i<operations.size() ; i++){
832
                        operations.add(geometryOperations.get(i));
833
                }
834
                return operations;
835
        }
836

    
837
        /*
838
         * (non-Javadoc)
839
         * @see org.gvsig.fmap.geom.GeometryManager#getFlatness()
840
         */
841
        public double getFlatness() {
842
                return flatness;
843
        }
844

    
845
        /*
846
         * (non-Javadoc)
847
         * @see org.gvsig.fmap.geom.GeometryManager#setFlatness(double)
848
         */
849
        public void setFlatness(double flatness) {
850
                this.flatness = flatness;
851
        }
852

    
853
        public Geometry createFrom(String wkt, String srs) throws GeometryException {
854
                FromWKTGeometryOperationContext context = new FromWKTGeometryOperationContext(wkt,srs);
855
                try {
856
                        return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
857
                } catch (GeometryOperationNotSupportedException e) {
858
                        throw new  GeometryException(e);
859
                } catch (GeometryOperationException e) {
860
                        throw new  GeometryException(e);
861
                }
862
        }
863

    
864
        public Geometry createFrom(byte[] wkb) throws GeometryException {
865
                FromWKBGeometryOperationContext context = new FromWKBGeometryOperationContext();
866
                context.setData(wkb);
867
                try {
868
                        return (Geometry) this.invokeOperation(OPERATIONS.FROMWKB, context);
869
                } catch (GeometryOperationNotSupportedException e) {
870
                        throw new  GeometryException(e);
871
                } catch (GeometryOperationException e) {
872
                        throw new  GeometryException(e);
873
                }
874
        }        
875
}