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

History | View | Annotate | Download (45.1 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.io.IOException;
29
import java.io.Reader;
30
import java.util.ArrayList;
31
import java.util.HashMap;
32
import java.util.Iterator;
33
import java.util.List;
34
import java.util.Map;
35
import org.apache.commons.codec.binary.Hex;
36
import org.apache.commons.io.IOUtils;
37
import org.apache.commons.lang3.StringUtils;
38
import org.cresques.cts.IProjection;
39
import org.gvsig.fmap.geom.Geometry;
40
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
41
import org.gvsig.fmap.geom.Geometry.TYPES;
42
import org.gvsig.fmap.geom.GeometryCoercionContext;
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.GeometryUtils;
47
import org.gvsig.fmap.geom.InformationbuilderWithGeometrySupport;
48
import org.gvsig.fmap.geom.SpatialIndex;
49
import org.gvsig.fmap.geom.SpatialIndexFactory;
50
import org.gvsig.fmap.geom.aggregate.MultiCurve;
51
import org.gvsig.fmap.geom.aggregate.MultiLine;
52
import org.gvsig.fmap.geom.aggregate.MultiPoint;
53
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
54
import org.gvsig.fmap.geom.aggregate.MultiPrimitive;
55
import org.gvsig.fmap.geom.aggregate.MultiSurface;
56
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
57
import org.gvsig.fmap.geom.exception.CreateGeometryException;
58
import org.gvsig.fmap.geom.jts.coerce.DefaultGeometryCoercionContext;
59
import org.gvsig.fmap.geom.jts.gputils.DefaultGeneralPathX;
60
import org.gvsig.fmap.geom.jts.primitive.DefaultNullGeometry;
61
import org.gvsig.fmap.geom.jts.primitive.Envelope2D;
62
import org.gvsig.fmap.geom.jts.primitive.Envelope3D;
63
import org.gvsig.fmap.geom.jts.spatialindex.SpatialIndexFactoryJTSQuadtree;
64
import org.gvsig.fmap.geom.jts.util.GMLUtils;
65
import org.gvsig.fmap.geom.jts.util.JTSUtils;
66
import org.gvsig.fmap.geom.operation.GeometryOperation;
67
import org.gvsig.fmap.geom.operation.GeometryOperationContext;
68
import org.gvsig.fmap.geom.operation.GeometryOperationException;
69
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
70
import org.gvsig.fmap.geom.primitive.Curve;
71
import org.gvsig.fmap.geom.primitive.Envelope;
72
import org.gvsig.fmap.geom.primitive.GeneralPathX;
73
import org.gvsig.fmap.geom.primitive.IGeneralPathX;
74
import org.gvsig.fmap.geom.primitive.Line;
75
import org.gvsig.fmap.geom.primitive.NullGeometry;
76
import org.gvsig.fmap.geom.primitive.Point;
77
import org.gvsig.fmap.geom.primitive.Polygon;
78
import org.gvsig.fmap.geom.primitive.Surface;
79
import org.gvsig.fmap.geom.type.GeometryType;
80
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
81
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
82
import org.gvsig.tools.dynobject.DynObject;
83
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
84
import org.gvsig.tools.service.Service;
85
import org.gvsig.tools.service.ServiceException;
86
import org.gvsig.tools.service.spi.ServiceFactory;
87
import org.slf4j.Logger;
88
import org.slf4j.LoggerFactory;
89

    
90
/**
91
 * Default implementation for the {@link GeometryManager}. When the
92
 * application starts, this class is registered in the {@link GeometryLocator}
93
 * using the {@link DefaultGeometryLibrary}.
94
 *
95
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
96
 */
97

    
98
@SuppressWarnings("UseSpecificCatch")
99
public class DefaultGeometryManager implements GeometryManager {
100

    
101
    private static final Logger LOGGER = LoggerFactory.getLogger(GeometryManager.class);
102
    
103
    /**
104
     * Offset for GeometryType -1 value (UNKNOWN)
105
     */
106
    private final int GEOMETRY_TYPE_OFFSET = 1;
107
    
108
    private double flatness = 0.8;
109

    
110
    private final Map spatialIndexFactories = new HashMap();
111

    
112
    /**
113
     * This list holds the unique name of all registered geometry operations.
114
     * The index in which they are stored is also the operation code used to
115
     * invoke each one of them
116
     */
117
    private final List geometryOperations = new ArrayList();
118

    
119
    /**
120
     * Common operations are registered here. Type specific operations are
121
     * registered in the corresponding GeometryType instance
122
     */
123
    // private List commonOperations = new ArrayList();
124

    
125
    /**
126
     * This map holds the instances of all registered GeometryType. The key is
127
     * the name of the specific Geometry subclass.
128
     * In other words, the string "org.gvsig.fmap.geom.primitive.Point2D" is the
129
     * hash key to obtain an instance of GeometryType holding the
130
     * operations associated to the class org.gvsig.fmap.geom.primitive.Point2D.
131
     */
132
    private final Map geometryTypeName = new HashMap();
133

    
134
    /**
135
     * Matrix of geometry types by type (row) and subtype (column). This matrix
136
     * will contain null values in the cells where a GeometryType hasn't been
137
     * registered.
138
     */
139
    private GeometryType[][] geometryTypes;
140
    
141
    // Initially create a matrix of 27 x 6, which are the current default
142
    // types and subtypes. If another type or subtype is registered, the
143
    // matrix will grow as needed
144
    private static final int DEFAULT_TYPES_SIZE = 27; // [-1, 25]
145
    private static final int DEFAULT_SUBTYPES_SIZE = 6;
146

    
147
    public DefaultGeometryManager() throws GeometryException {
148
        this(DEFAULT_TYPES_SIZE, DEFAULT_SUBTYPES_SIZE);
149
    }
150

    
151
    public DefaultGeometryManager(int initialTypesSize, int initialSubtypesSize) throws GeometryException {
152
        geometryTypes = new GeometryType[initialTypesSize][initialSubtypesSize];
153
    }
154

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

    
164
        int index = getGeometryOperationCode(geomOpName);
165

    
166
        geomType.setGeometryOperation(index, geomOp);
167

    
168
        return index;
169
    }
170

    
171
    @Override
172
    public int registerGeometryOperation(String geomOpName, GeometryOperation geomOp) {
173
        if (geomOpName == null) {
174
            throw new IllegalArgumentException("geomOpName cannot be null.");
175
        }
176
        if (geomOp == null) {
177
            throw new IllegalArgumentException("geomOp cannot be null.");
178
        }
179

    
180
        int index = getGeometryOperationCode(geomOpName);
181

    
182
        Iterator it = geometryTypeName.values().iterator();
183
        while (it.hasNext()) {
184
            GeometryType geometryType = (GeometryType) it.next();
185
            registerGeometryOperation(geomOpName, geomOp, geometryType);
186
        }
187

    
188
        return index;
189

    
190
    }
191

    
192
    @SuppressWarnings("override")
193
    public int registerGeometryOperation(String geomOpName, GeometryOperation geomOp, int type, int subType)
194
        throws GeometryTypeNotSupportedException, GeometryTypeNotValidException {
195
        GeometryType geometryType = getGeometryType(type, subType);
196
        return registerGeometryOperation(geomOpName, geomOp, geometryType);
197
    }
198

    
199
    @Override
200
    public int registerGeometryOperation(String geomOpName, GeometryOperation geomOp, int type) {
201
        int code = -1;
202
        Iterator it = geometryTypeName.values().iterator();
203
        while (it.hasNext()) {
204
            GeometryType geometryType = (GeometryType) it.next();
205
            if ((type == geometryType.getType())) {
206
                code = registerGeometryOperation(geomOpName, geomOp, geometryType);
207
            }
208
        }
209
        return code;
210
    }
211

    
212
    @Override
213
    public int registerGeometryOperationBySubtype(String geomOpName, GeometryOperation geomOp, int subType) {
214
        int code = -1;
215
        Iterator it = geometryTypeName.values().iterator();
216
        while (it.hasNext()) {
217
            GeometryType geometryType = (GeometryType) it.next();
218
            if ((subType == geometryType.getSubType())) {
219
                code = registerGeometryOperation(geomOpName, geomOp, geometryType);
220
            }
221
        }
222
        return code;
223
    }
224

    
225
    @Override
226
    public int registerGeometryOperationBySuperType(String geomOpName, GeometryOperation geomOp, int superType) {
227
        int code = -1;
228
        Iterator it = geometryTypeName.values().iterator();
229
        while (it.hasNext()) {
230
            GeometryType geometryType = (GeometryType) it.next();
231
            if (geometryType.isTypeOf(superType)) {
232
                code = registerGeometryOperation(geomOpName, geomOp, geometryType);
233
            }
234
        }
235
        return code;
236
    }
237

    
238
    @Override
239
    public int registerGeometryOperationBySuperSubType(String geomOpName, GeometryOperation geomOp, int superSubType) {
240
        int code = -1;
241
        Iterator it = geometryTypeName.values().iterator();
242
        while (it.hasNext()) {
243
            GeometryType geometryType = (GeometryType) it.next();
244
            if (geometryType.isSubTypeOf(superSubType)) {
245
                code = registerGeometryOperation(geomOpName, geomOp, geometryType);
246
            }
247
        }
248
        return code;
249
    }
250

    
251
    @Override
252
    public GeometryType registerGeometryType(Class geomClass, String name, int type, int subType) {
253
        return registerGeometryType(geomClass, name, type, subType, new int[0], new int[0]);
254
    }
255

    
256
    @Override
257
    public GeometryType registerGeometryType(Class geomClass, String name, int type, int subType, int superType,
258
        int superSubType) {
259
        return registerGeometryType(geomClass, name, type, subType, new int[] { superType }, new int[] { superSubType });
260
    }
261

    
262
    @Override
263
    public GeometryType registerGeometryType(Class geomClass, String name, int type, int subType, int superType) {
264
        return registerGeometryType(geomClass, name, type, subType, new int[] { superType }, new int[0]);
265
    }
266

    
267
    @Override
268
    public GeometryType registerGeometryType(Class geomClass, String name, int type, int subType, int[] superTypes) {
269
        return registerGeometryType(geomClass, name, type, subType, superTypes, new int[0]);
270
    }
271

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

    
321
        if (!Geometry.class.isAssignableFrom(geomClass)) {
322
            throw new IllegalArgumentException(geomClass.getName() + " must implement the Geometry interface");
323
        }
324

    
325
        int offsettedType = type + GEOMETRY_TYPE_OFFSET;
326
        // Check if it is registered
327
        GeometryType geomType = null;
328
        if (offsettedType >= geometryTypes.length || subType >= geometryTypes[0].length
329
            || (geomType = geometryTypes[offsettedType][subType]) == null) {
330
            geomType = new DefaultGeometryType(geomClass, name, type, subType, superTypes, superSubTypes); //Attention!
331
            registerGeometryType(geomType);
332
        }
333

    
334
        LOGGER.debug("Class {} registered with name {}", geomClass, geomType.getName());
335

    
336
        return geomType;
337
    }
338

    
339
    @Override
340
    public void registerGeometryType(GeometryType geometryType) {
341
        int offsettedType = geometryType.getType() + GEOMETRY_TYPE_OFFSET;
342
        if (offsettedType >= geometryTypes.length || geometryType.getSubType() >= geometryTypes[0].length) {
343

    
344
            // Recreate the geometry type matrix if the types
345
            // or subtypes don't fit
346
            int newTypesSize =
347
                offsettedType < geometryTypes.length ? geometryTypes.length : offsettedType + 1;
348
            int newSubTypesSize =
349
                geometryType.getSubType() < geometryTypes[0].length ? geometryTypes[0].length : geometryType
350
                    .getSubType() + 1;
351
            GeometryType[][] newMatrix = new GeometryType[newTypesSize][newSubTypesSize];
352

    
353
            for (int i = 0; i < geometryTypes.length; i++) {
354
                System.arraycopy(geometryTypes[i], 0, newMatrix[i], 0, geometryTypes[i].length);
355
            }
356
            geometryTypes = newMatrix;
357
        }
358

    
359
        geometryTypes[offsettedType][geometryType.getSubType()] = geometryType;
360
        geometryTypeName.put(geometryType.getName(), geometryType);
361
    }
362

    
363
    @Override
364
    public GeometryType registerGeometryType(Class geomClass, int type, int subType) {
365
        return registerGeometryType(geomClass, null, type, subType);
366
    }
367

    
368
    @Override
369
    public GeometryType getGeometryType(int type, int subType) throws GeometryTypeNotSupportedException,
370
        GeometryTypeNotValidException {
371

    
372
        int offsettedType = type + GEOMETRY_TYPE_OFFSET;
373
        
374
        if (offsettedType >= geometryTypes.length || subType >= geometryTypes[0].length) {
375
            throw new GeometryTypeNotValidException(type, subType);
376
        }
377
        GeometryType gType = geometryTypes[offsettedType][subType];
378
        if (gType == null) {
379
            throw new GeometryTypeNotSupportedException(type, subType);
380
        }
381
        return gType;
382
    }
383

    
384
    @Override
385
    public Geometry create(GeometryType geomType) throws CreateGeometryException {
386
        return geomType.create();
387
    }
388

    
389
    @Override
390
    public Geometry create(String name) throws CreateGeometryException {
391
        if (!geometryTypeName.containsKey(name)) {
392
            throw new IllegalArgumentException(name + " has not been registered yet.");
393
        }
394
        return ((GeometryType) geometryTypeName.get(name)).create();
395
    }
396

    
397
    @Override
398
    public Geometry create(int type, int subType) throws CreateGeometryException {
399
        try {
400
            return getGeometryType(type, subType).create();
401
        } catch (GeometryException e) {
402
            throw new CreateGeometryException(type, subType, e);
403
        }
404
    }
405

    
406
    @Override
407
    public Curve createCurve(GeneralPathX generalPathX, int subType) throws CreateGeometryException {
408
        Curve curve = (Curve) create(TYPES.CURVE, subType);
409
        curve.setGeneralPath(generalPathX);
410
        return curve;
411
    }
412

    
413
    @Override
414
    public NullGeometry createNullGeometry(int subType) throws CreateGeometryException {
415
        NullGeometry nullGeom = (NullGeometry) create(TYPES.NULL, subType);
416
        return nullGeom;
417
    }
418

    
419
    @Override
420
    public Point createPoint(double x, double y, int subType) throws CreateGeometryException {
421
        Point point = (Point) create(TYPES.POINT, subType);
422
        point.setX(x);
423
        point.setY(y);
424
        return point;
425
    }
426

    
427
    @Override
428
    public Surface createSurface(GeneralPathX generalPathX, int subType) throws CreateGeometryException {
429
        Surface surface = (Surface) create(TYPES.SURFACE, subType);
430
        surface.setGeneralPath(generalPathX);
431
        return surface;
432
    }
433

    
434
    @Override
435
    public GeometryOperation getGeometryOperation(int opCode, int type, int subType)
436
        throws GeometryTypeNotSupportedException, GeometryOperationNotSupportedException, GeometryTypeNotValidException {
437
        GeometryType geometryType = getGeometryType(type, subType);
438
        return geometryType.getGeometryOperation(opCode);
439
    }
440

    
441
    @Override
442
    public GeometryOperation getGeometryOperation(int opCode) throws GeometryOperationNotSupportedException {
443
        if (opCode < 0) {
444
            throw new GeometryOperationNotSupportedException(opCode);
445
        }
446
        GeometryType type = (GeometryType) geometryTypeName.get(DefaultNullGeometry.class.getName());
447
        if (type == null) {
448
            throw new GeometryOperationNotSupportedException(opCode);
449
        }
450
        return type.getGeometryOperation(opCode);
451
    }
452

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

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

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

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

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

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

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

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

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

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

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

    
569
            case PathIterator.SEG_CLOSE:
570
                tmpPath.lineTo(first[0], first[1]);
571
                break;
572

    
573
            } // end switch
574

    
575
            piter.next();
576

    
577
        }
578
        if (tmpPath != null) {
579
            tmpCurve = createCurve(tmpPath, subType);
580
            multiCurve.addCurve(tmpCurve);
581
        }
582

    
583
        return multiCurve;
584

    
585
    }
586

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

    
612
            case PathIterator.SEG_LINETO:
613
                if (tmpPath == null) {
614
                    System.arraycopy(coords, 0, first, 0, 2);
615
                    tmpPath = new GeneralPathX(piter.getWindingRule());
616
                }
617
                tmpPath.lineTo(coords[0], coords[1]);
618
                break;
619

    
620
            case PathIterator.SEG_QUADTO:
621
                if (tmpPath == null) {
622
                    System.arraycopy(coords, 0, first, 0, 2);
623
                    tmpPath = new GeneralPathX(piter.getWindingRule());
624
                }
625
                tmpPath.quadTo(coords[0], coords[1], coords[2], coords[3]);
626
                break;
627

    
628
            case PathIterator.SEG_CUBICTO:
629
                if (tmpPath == null) {
630
                    System.arraycopy(coords, 0, first, 0, 2);
631
                    tmpPath = new GeneralPathX(piter.getWindingRule());
632
                }
633
                tmpPath.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
634
                break;
635

    
636
            case PathIterator.SEG_CLOSE:
637
                tmpPath.lineTo(first[0], first[1]);
638
                break;
639
            } // end switch
640

    
641
            piter.next();
642

    
643
        }
644
        if (tmpPath != null) {
645
            tmpSurface = createSurface(tmpPath, subType);
646
            multiSurface.addSurface(tmpSurface);
647
        }
648

    
649
        return multiSurface;
650

    
651
    }
652

    
653
    @Override
654
    public MultiPoint createMultiPoint(GeneralPathX generalPathX, int subType) throws CreateGeometryException {
655
        if (subType != SUBTYPES.GEOM2D) {
656
            // FIXME Exception
657
            throw new UnsupportedOperationException();
658
        }
659
        MultiPoint multiPoint = (MultiPoint) create(TYPES.MULTIPOINT, subType);
660
        PathIterator piter = generalPathX.getPathIterator(null);
661
        Point tmpPoint;
662
        double[] coords = new double[6];
663
        int type;
664
        while (!piter.isDone()) {
665
            type = piter.currentSegment(coords);
666
            switch (type) {
667
            case PathIterator.SEG_MOVETO:
668
                tmpPoint = createPoint(coords[0], coords[1], subType);
669
                multiPoint.addPoint(tmpPoint);
670

    
671
            case PathIterator.SEG_LINETO:
672
                throw new IllegalArgumentException("The general have a SEG_LINETO.");
673

    
674
            case PathIterator.SEG_QUADTO:
675
                throw new IllegalArgumentException("The general have a SEG_QUADTO.");
676

    
677
            case PathIterator.SEG_CUBICTO:
678
                throw new IllegalArgumentException("The general have a SEG_CUBICTO.");
679

    
680
            case PathIterator.SEG_CLOSE:
681
                throw new IllegalArgumentException("The general have a SEG_CLOSE.");
682
            } // end switch
683

    
684
            piter.next();
685

    
686
        }
687
        return multiPoint;
688

    
689
    }
690

    
691
    @Override
692
    public int getGeometryOperationCode(String geomOpName) {
693
        if (geomOpName == null) {
694
            throw new IllegalArgumentException("geomOpName cannot be null.");
695
        }
696

    
697
        int index = geometryOperations.indexOf(geomOpName);
698
        if (index == -1) {
699
            geometryOperations.add(geomOpName);
700
            index = geometryOperations.indexOf(geomOpName);
701
        }
702
        return index;
703
    }
704

    
705
    @Override
706
    public List getGeometryOperationNames() {
707
        List operations = new ArrayList();
708
        for (int i = 0; i < operations.size(); i++) {
709
            operations.add(geometryOperations.get(i));
710
        }
711
        return operations;
712
    }
713

    
714
    @Override
715
    public double getFlatness() {
716
        return flatness;
717
    }
718

    
719
    @Override
720
    public void setFlatness(double flatness) {
721
        this.flatness = flatness;
722
    }
723

    
724
    @Override
725
    public Geometry createFrom(Object data) throws CreateGeometryException, GeometryException {
726
        if( data == null ) {
727
            throw new IllegalArgumentException("null data is not allowed");
728
        }
729
        if( data instanceof String ) {
730
            Geometry geom = GMLUtils.GML2Geometry((String) data);
731
            if( geom != null ) {
732
                return geom;
733
            }
734
            return this.createFrom((String)data);
735
        }
736
        if( data instanceof byte[] ) {
737
            return this.createFrom((byte[])data);
738
        }
739
        if( data instanceof com.vividsolutions.jts.geom.Geometry ) {
740
            return this.createFrom((com.vividsolutions.jts.geom.Geometry)data);
741
        }
742
        if( data instanceof Geometry ) {
743
            return ((Geometry)data).cloneGeometry();
744
        }
745
        throw new IllegalArgumentException("Type of data ("+data.getClass().getName()+") not supported.");
746
    }
747

    
748
    @Override
749
    public Geometry createFrom(String wkt, String srs) throws GeometryException {
750
        GeometryOperationContext context = new GeometryOperationContext();
751
        context.setAttribute("text", wkt);
752
        context.setAttribute("srs", srs);
753

    
754
        try {
755
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
756
        } catch (Exception e) {
757
            throw new GeometryException(e);
758
        }
759
    }
760

    
761
    private int firstNonBlank(String s) {
762
        char ch;
763
        int i=0;
764
        while(i < s.length()) {
765
            if( !Character.isSpaceChar(ch = s.charAt(i++)) ) {
766
                return ch;
767
            }
768
        }
769
        return -1;
770
    } 
771
    
772
    private int firstNonBlank(Reader r) {
773
        try {
774
            int ch;
775
            int i=0;
776
            while( (ch=r.read())!= -1) {
777
                if( !Character.isSpaceChar(ch) ) {
778
                    return ch;
779
                }
780
            }
781
            return -1;
782
        } catch (IOException ex) {
783
            return -1;
784
        }
785
    } 
786
    
787
    @Override
788
    public Geometry createFrom(String geom, IProjection srs) throws GeometryException {
789
        try {
790
            if( StringUtils.isBlank(geom) ) {
791
                return null;
792
            }
793
            int ch = firstNonBlank(geom);
794
            switch(ch) {
795
                case '0':
796
                case '1':
797
                    if( (geom.length() % 2) == 0  ) {
798
                        // it starts with 0 or 1 and the length is even. Assume it is hexwkb.
799
                        return createFrom(Hex.decodeHex(geom.toCharArray()), srs);
800
                    }
801
                    break;
802
                case '{':
803
                    try {
804
                        com.vividsolutions.jts.io.geojson.GeoJsonReader reader = new com.vividsolutions.jts.io.geojson.GeoJsonReader();
805
                        com.vividsolutions.jts.geom.Geometry geom_jts = reader.read(geom);
806
                        return JTSUtils.createGeometry(srs, geom_jts);
807
                    } catch(Exception ex) {
808
                        LOGGER.debug("Can't parse as GeoJson");
809
                    }
810
                    break;
811
                case '<':
812
                    try {
813
                        if( StringUtils.startsWithIgnoreCase(geom.trim(),"<gml:") ) {
814
                            com.vividsolutions.jts.io.gml2.GMLReader reader = new com.vividsolutions.jts.io.gml2.GMLReader();
815
                            com.vividsolutions.jts.geom.Geometry geom_jts = reader.read(
816
                                    geom, 
817
                                    new com.vividsolutions.jts.geom.GeometryFactory()
818
                            );
819
                            return JTSUtils.createGeometry(srs, geom_jts);
820
                        }
821
                    } catch(Exception ex) {
822
                        LOGGER.debug("Can't parse as GML");
823
                    }
824
                    break;
825
            }
826
            GeometryOperationContext context = new GeometryOperationContext();
827
            context.setAttribute("text", geom);
828
            context.setAttribute("srs", srs);
829

    
830
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
831
        } catch (Exception e) {
832
            throw new GeometryException(e);
833
        }
834
    }
835

    
836
    @Override
837
    public Geometry createFrom(Reader geom, IProjection srs) throws GeometryException {
838
        try {
839
            if( geom.markSupported() ) {
840
                geom.mark(10240);
841
                int ch = firstNonBlank(geom);
842
                switch(ch) {
843
                    case '0':
844
                    case '1':
845
                        return createFrom(Hex.decodeHex(IOUtils.toCharArray(geom)), srs);
846
                    case '{':
847
                        try {
848
                            com.vividsolutions.jts.io.geojson.GeoJsonReader reader = new com.vividsolutions.jts.io.geojson.GeoJsonReader();
849
                            com.vividsolutions.jts.geom.Geometry geom_jts = reader.read(geom);
850
                            return JTSUtils.createGeometry(srs, geom_jts);
851
                        } catch(Exception ex) {
852
                            LOGGER.debug("Can't parse as GeoJson");
853
                        }
854
                        break;
855
                    case '<':
856
                        try {
857
                            char[] buffer = new char[100];
858
                            IOUtils.read(geom, buffer);
859
                            String s = new String(buffer);
860
                            if( StringUtils.startsWithIgnoreCase(s,"<gml:") ) {
861
                                com.vividsolutions.jts.io.gml2.GMLReader reader = new com.vividsolutions.jts.io.gml2.GMLReader();
862
                                com.vividsolutions.jts.geom.Geometry geom_jts = reader.read(
863
                                        geom, 
864
                                        new com.vividsolutions.jts.geom.GeometryFactory()
865
                                );
866
                                return JTSUtils.createGeometry(srs, geom_jts);
867
                            }
868
                        } catch(Exception ex) {
869
                            LOGGER.debug("Can't parse as GML");
870
                        }
871
                        break;
872
                }
873
                geom.reset();
874
            }
875
            GeometryOperationContext context = new GeometryOperationContext();
876
            context.setAttribute("reader", geom);
877
            context.setAttribute("srs", srs);
878

    
879
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKT, context);
880
        } catch (Exception e) {
881
            throw new GeometryException(e);
882
        }
883
    }
884

    
885
    @Override
886
    public Geometry createFrom(String wkt) throws GeometryException {
887
        return this.createFrom(wkt, (IProjection)null);
888
    }
889

    
890
    public Geometry createFrom(IProjection proj, com.vividsolutions.jts.geom.Geometry geom) throws GeometryException {
891
        return JTSUtils.createGeometry(proj, geom);
892
    }
893

    
894
    @Override
895
    public Geometry createFromQuietly(String wkt) {
896
        try {
897
            return this.createFrom(wkt);
898
        } catch(Exception ex) {
899
            return null;
900
        }
901
    }
902
    
903
    @Override
904
    public Geometry createFrom(byte[] wkb) throws GeometryException {
905
        GeometryOperationContext context = new GeometryOperationContext();
906
        context.setAttribute("data", wkb);
907
        try {
908
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKB, context);
909
        } catch (GeometryOperationNotSupportedException e) {
910
            throw new GeometryException(e);
911
        } catch (GeometryOperationException e) {
912
            throw new GeometryException(e);
913
        }
914
    }
915

    
916
    @Override
917
    public Geometry createFrom(byte[] wkb, IProjection srs) throws GeometryException {
918
        GeometryOperationContext context = new GeometryOperationContext();
919
        context.setAttribute("data", wkb);
920
        context.setAttribute("srs", srs);
921
        try {
922
            return (Geometry) this.invokeOperation(OPERATIONS.FROMWKB, context);
923
        } catch (Exception e) {
924
            throw new GeometryException(e);
925
        }
926
    }
927

    
928
    @Override
929
    public IGeneralPathX createGeneralPath(int rule, PathIterator pathIterator) {
930
        if (pathIterator == null) {
931
            return new DefaultGeneralPathX(rule);
932
        }
933
        return new DefaultGeneralPathX(pathIterator, false, 0);
934
    }
935

    
936
    @Override
937
    public MultiPoint createMultiPoint(int subType) throws CreateGeometryException {
938
        return (MultiPoint) create(TYPES.MULTIPOINT, subType);
939
    }
940

    
941
    @Override
942
    public Line createLine(int subType) throws CreateGeometryException {
943
        return (Line) create(TYPES.CURVE, subType);
944
    }
945

    
946
    @Override
947
    public Curve createCurve(int subType) throws CreateGeometryException {
948
        return (Curve) create(TYPES.CURVE, subType);
949
    }
950

    
951
    @Override
952
    public MultiCurve createMultiCurve(int subType) throws CreateGeometryException {
953
        return (MultiCurve) create(TYPES.MULTICURVE, subType);
954
    }
955

    
956
    @Override
957
    public MultiLine createMultiLine(int subType) throws CreateGeometryException {
958
        return (MultiLine) create(TYPES.MULTILINE, subType);
959
    }
960

    
961
    @Override
962
    public MultiSurface createMultiSurface(int subType) throws CreateGeometryException {
963
        return (MultiSurface) create(TYPES.MULTISURFACE, subType);
964
    }
965

    
966
    @Override
967
    public MultiPolygon createMultiPolygon(int subType) throws CreateGeometryException {
968
        return (MultiPolygon) create(TYPES.MULTIPOLYGON, subType);
969
    }
970

    
971
    @Override
972
    public Polygon createPolygon(int subType) throws CreateGeometryException {
973
        return (Polygon) create(TYPES.SURFACE, subType);
974
    }
975

    
976
    @Override
977
    public Surface createSurface(int subType) throws CreateGeometryException {
978
        return (Surface) create(TYPES.SURFACE, subType);
979
    }
980

    
981
    @Override
982
    public SpatialIndex createDefaultMemorySpatialIndex() throws ServiceException {
983
        return this.createSpatialIndex(SpatialIndexFactoryJTSQuadtree.NAME, null);
984
    }
985

    
986
    @Override
987
    public SpatialIndex createSpatialIndex(String name, DynObject parameters) throws ServiceException {
988
        SpatialIndexFactory factory = this.getSpatialIndexFactory(name);
989
        if (factory == null) {
990
            throw new CantExistsService(name);
991
        }
992
        return (SpatialIndex) factory.create(parameters, this);
993
    }
994

    
995
    @Override
996
    public SpatialIndexFactory getSpatialIndexFactory(String name) {
997
        return (SpatialIndexFactory) this.spatialIndexFactories.get(name);
998
    }
999

    
1000
    @Override
1001
    public void addServiceFactory(ServiceFactory serviceFactory) {
1002
        serviceFactory.initialize();
1003
        this.spatialIndexFactories.put(serviceFactory.getName(), serviceFactory);
1004
    }
1005

    
1006
    @Override
1007
    public Service createService(DynObject serviceParameters) throws ServiceException {
1008
        throw new UnsupportedOperationException("Not supported yet.");
1009
    }
1010

    
1011
    @Override
1012
    public DynObject createServiceParameters(String serviceName) throws ServiceException {
1013
        SpatialIndexFactory factory = this.getSpatialIndexFactory(serviceName);
1014
        if (factory == null) {
1015
            throw new CantExistsService(serviceName);
1016
        }
1017
        return factory.createParameters();
1018
    }
1019

    
1020
    @Override
1021
    public Service getService(DynObject parameters) throws ServiceException {
1022
        return this.createSpatialIndex((String) parameters.getDynValue("serviceName"), parameters);
1023
    }
1024

    
1025
    @Override
1026
    public MultiPrimitive createMultiPrimitive(GeometryType geometryType) throws CreateGeometryException {
1027
        int type = geometryType.getType();
1028
        int subtype = geometryType.getSubType();
1029
        if(isSubtype(Geometry.TYPES.POINT, type)){
1030
            return createMultiPoint(subtype);
1031
        }
1032
        if(isSubtype(Geometry.TYPES.CURVE, type)){
1033
            return createMultiCurve(subtype);
1034
        }
1035
        if(isSubtype(Geometry.TYPES.SURFACE, type)){
1036
            return createMultiSurface(subtype);
1037
        }
1038
        
1039
        throw new CreateGeometryException(type, subtype, null);
1040
    }
1041

    
1042
    public class CantExistsService extends ServiceException {
1043

    
1044
        public CantExistsService(String serviceName) {
1045
            super("Can't existe service %(service).", "_Cant_existe_service_XserviceX", 100001);
1046
            setValue("service", serviceName);
1047
        }
1048

    
1049
    }
1050

    
1051
    @Override
1052
    public InformationbuilderWithGeometrySupport createInformacionBuilder() {
1053
        return new BaseInformationBuilderWithGeometrySupport();
1054
    }
1055

    
1056
    @Override
1057
    public boolean isSubtype(int geomTypeParent, int geomTypeChild) {
1058
        // Esto es un implementacion patatera que habria que mejorar,
1059
        // pero mejor aqui que esparcida por todas partes en donde se
1060
        // necesite.
1061
        if( geomTypeParent == geomTypeChild ) {
1062
            return true;
1063
        }
1064
        if( geomTypeParent == Geometry.TYPES.GEOMETRY ) {
1065
            return true;
1066
        }
1067
        switch(geomTypeParent) {
1068
        case Geometry.TYPES.MULTICURVE:
1069
            return geomTypeChild==Geometry.TYPES.MULTILINE ;
1070
        case Geometry.TYPES.MULTISURFACE:
1071
            return geomTypeChild==Geometry.TYPES.MULTIPOLYGON ;
1072
        case Geometry.TYPES.MULTIPOINT:
1073
            return geomTypeChild==Geometry.TYPES.MULTIPOINT ;
1074

    
1075
        case Geometry.TYPES.CURVE:
1076
            return
1077
                geomTypeChild == Geometry.TYPES.CURVE ||
1078
                geomTypeChild == Geometry.TYPES.LINE ||
1079
                geomTypeChild == Geometry.TYPES.ARC ||
1080
                geomTypeChild == Geometry.TYPES.SPLINE ||
1081
                geomTypeChild == Geometry.TYPES.CIRCUMFERENCE ||
1082
                geomTypeChild == Geometry.TYPES.PERIELLIPSE
1083
                ;
1084
        case Geometry.TYPES.SURFACE:
1085
            return
1086
            geomTypeChild==Geometry.TYPES.SURFACE ||
1087
            geomTypeChild==Geometry.TYPES.POLYGON ||
1088
            geomTypeChild == Geometry.TYPES.CIRCLE ||
1089
            geomTypeChild == Geometry.TYPES.ELLIPSE ||
1090
            geomTypeChild == Geometry.TYPES.RING ||
1091
            geomTypeChild == Geometry.TYPES.FILLEDSPLINE ||
1092
            geomTypeChild == Geometry.TYPES.ELLIPTICARC
1093
            ;
1094
        case Geometry.TYPES.POINT:
1095
            return geomTypeChild==Geometry.TYPES.POINT ;
1096
        }
1097
        return false;
1098
    }
1099
    
1100
    @Override
1101
    public boolean canAggregate(int geomTypeParent, int geomTypeChild) {
1102
        
1103
        switch(geomTypeParent) {
1104
        case Geometry.TYPES.MULTICURVE:
1105
        case Geometry.TYPES.MULTILINE:
1106
            return isSubtype(Geometry.TYPES.CURVE, geomTypeChild);
1107
        case Geometry.TYPES.MULTISURFACE:
1108
        case Geometry.TYPES.MULTIPOLYGON:
1109
            return isSubtype(Geometry.TYPES.SURFACE, geomTypeChild);
1110
        case Geometry.TYPES.MULTIPOINT:
1111
            return isSubtype(Geometry.TYPES.POINT, geomTypeChild);
1112
        }
1113
        return false;
1114
    }
1115

    
1116
    @Override
1117
    public GeometryCoercionContext createGeometryCoercionContext() {
1118
        return new DefaultGeometryCoercionContext();
1119
    }
1120
    
1121
    
1122
    public static void main(String[] args) throws GeometryException, GeometryOperationNotSupportedException, GeometryOperationException {
1123
        String s;
1124
        new DefaultLibrariesInitializer().fullInitialize();
1125
//        s =  GeometryUtils.formatCoordinate("%-%d? %m' %s'' N", 39.89);
1126
//        System.out.println(s);
1127
//        s =  GeometryUtils.formatCoordinate("%-%d? %m' %.0s'' N", 39.89);
1128
//        System.out.println(s);
1129
//        s =  GeometryUtils.formatCoordinate("%+%d? %m' %.2s'' N (%4.4D)", 39.89);
1130
//        System.out.println(s);
1131
//        s =  GeometryUtils.formatCoordinate("%-%d? %m' N", -39.89);
1132
//        System.out.println(s);
1133
//        s =  GeometryUtils.formatCoordinate("%-%d? %m' N (%4.4D)", 39.89);
1134
//        System.out.println(s);
1135
        //Geometry g = GeometryUtils.createFrom("00000007d50000000100000007d20000002341258d57c2b73acf4150bf008a45b87241258d5eb2faa5364150befedb0f995841258d6aeb851eb84150befbeeb851ec41258d723d70a3d74150bef9d51eb85241258d7e428f5c294150bef677ae147b41258d9d147ae1484150beeea47ae14841258dbc28f5c28f4150bee72ae147ae41258dc7ae147ae14150bee468f5c28f41258dcc6b851eb84150bee31999999a41258dd1666666664150bee18b851eb841258dd8d70a3d714150bedf1d70a3d741258ddea8f5c28f4150bedc951eb85241258de3eb851eb84150bed99ccccccd41258dea3d70a3d74150bed6351eb85241258defbd70a3d74150bed3728f5c2941258df39999999a4150bed1751eb85241258df6c7ae147b4150bed01c28f5c341258df86b851eb84150becf1f5c28f641258dfa1999999a4150becd4666666641258dfb6147ae144150becbc51eb85241258dfd1999999a4150bec9a000000041258dfec28f5c294150bec753d70a3d41258e001eb851ec4150bec2f666666641258e047ae147ae4150beb73147ae1441258e054ccccccd4150beb3bc28f5c341258e054ccccccd4150beb2d70a3d7141258e05947ae1484150beb2047ae14841258e053d70a3d74150beb17333333341258e03a8f5c28f4150beb0e47ae14841258de69999999a4150beaca3d70a3d41258db10f5c28f64150bea46d70a3d741258dabdc28f5c34150bea3928f5c2941258da8dc28f5c34150bea300a3d70a41258da623d70a3d4150bea26147ae1441258da34ccccccd4150bea19d70a3d7");
1136
        //Geometry g = GeometryUtils.createFrom("MULTILINESTRING M ((745920.412801 4319733.74841197 -9999,745923.444481 4319733.242374 -9999,745930.962949 4319734.760282 -9999,745937.102608 4319738.899755 -9999,745941.242081 4319745.039415 -9999,745942.759989 4319752.557882 -9999,745941.242081 4319760.07635 -9999,745937.102608 4319766.216009 -9999,745930.962949 4319770.355482 -9999,745923.444481 4319771.87339 -9999,745915.926014 4319770.355482 -9999,745914.042603266 4319769.08565144 -9999,745911.2302267 4319767.2327453 -9999))");
1137
        Geometry g = GeometryUtils.createFrom("0105000060E66400000100000001020000400D00000016A75AD380C3264156FBE56F7D7A5041000000008087C3C07D0393E386C326413D0E834F7D7A5041000000008087C3C0BDA607ED95C32641D575A8B07D7A5041000000008087C3C029098934A2C32641FF9595B97E7A5041000000008087C3C0740AF27BAAC326417EC68542807A5041000000008087C3C039471D85ADC32641B456B423827A5041000000008087C3C0740AF27BAAC326411CEBE204847A5041000000008087C3C029098934A2C326416A17D38D857A5041000000008087C3C0BDA607ED95C326419337C096867A5041000000008087C3C07D0393E386C326412C9FE5F7867A5041000000008087C3C0CB811EDA77C326419337C096867A5041000000008087C3C06518D01574C3264130507B45867A5041000000008087C3C02646E0756EC32641894CE5CE857A5041000000008087C3C0");
1138
        String hexwkb = g.convertToHexWKB();
1139
        String hexewkb = g.convertToHexEWKB();
1140
        //byte[] b = g.convertToEWKB();
1141
        
1142
        System.out.println(hexwkb);
1143
        System.out.println(hexewkb);
1144
    }
1145
}