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 / primitive / curve / line / AbstractLine.java @ 42281

History | View | Annotate | Download (15.4 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2015 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.geom.jts.primitive.curve.line;
24

    
25
import java.awt.Shape;
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.PathIterator;
28
import java.util.Collections;
29
import java.util.Iterator;
30

    
31
import com.vividsolutions.jts.geom.Coordinate;
32

    
33
import org.apache.commons.lang3.StringUtils;
34
import org.cresques.cts.ICoordTrans;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38
import org.gvsig.fmap.geom.Geometry;
39
import org.gvsig.fmap.geom.GeometryException;
40
import org.gvsig.fmap.geom.aggregate.MultiLine;
41
import org.gvsig.fmap.geom.aggregate.MultiPoint;
42
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
43
import org.gvsig.fmap.geom.exception.ReprojectionRuntimeException;
44
import org.gvsig.fmap.geom.handler.Handler;
45
import org.gvsig.fmap.geom.jts.gputils.DefaultGeneralPathX;
46
import org.gvsig.fmap.geom.jts.gputils.GeneralPathXIterator;
47
import org.gvsig.fmap.geom.jts.primitive.curve.AbstractCurve;
48
import org.gvsig.fmap.geom.jts.primitive.point.Point2D;
49
import org.gvsig.fmap.geom.jts.primitive.point.PointJTS;
50
import org.gvsig.fmap.geom.jts.util.ArrayListCoordinateSequence;
51
import org.gvsig.fmap.geom.jts.util.JTSUtils;
52
import org.gvsig.fmap.geom.jts.util.ReadOnlyCoordinates;
53
import org.gvsig.fmap.geom.operation.GeometryOperationException;
54
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
55
import org.gvsig.fmap.geom.primitive.GeneralPathX;
56
import org.gvsig.fmap.geom.primitive.IGeneralPathX;
57
import org.gvsig.fmap.geom.primitive.Line;
58
import org.gvsig.fmap.geom.primitive.Point;
59

    
60
/**
61
 * @author fdiaz
62
 *
63
 */
64
public abstract class AbstractLine extends AbstractCurve {
65

    
66
    /**
67
     *
68
     */
69
    private static final long serialVersionUID = 5034197096871344597L;
70
    private static final Logger logger = LoggerFactory.getLogger(AbstractLine.class);
71

    
72
    protected ArrayListCoordinateSequence coordinates;
73
    protected PointJTS anyVertex;
74

    
75
    /**
76
    *
77
    */
78
    protected AbstractLine(int subtype) {
79
        super(Geometry.TYPES.LINE, subtype);
80
    }
81

    
82
    /*
83
     * (non-Javadoc)
84
     *
85
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#getJTS()
86
     */
87
    public com.vividsolutions.jts.geom.Geometry getJTS() {
88
        return JTSUtils.createJTSLineString(coordinates);
89
    }
90

    
91
    /*
92
     * (non-Javadoc)
93
     *
94
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#getVertex(int)
95
     */
96
    public Point getVertex(int index) {
97
        anyVertex.setJTSCoordinate(coordinates.get(index));
98
        return anyVertex;
99
    }
100

    
101
    /*
102
     * (non-Javadoc)
103
     *
104
     * @see
105
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#addVertex(org.gvsig
106
     * .fmap.geom.primitive.Point)
107
     */
108
    public void addVertex(Point point) {
109
        point = fixPoint(point);
110
        coordinates.add(((PointJTS) point).getJTSCoordinate());
111
        anyVertex = (PointJTS) point;
112
    }
113

    
114
    /*
115
     * (non-Javadoc)
116
     *
117
     * @see
118
     * org.gvsig.fmap.geom.primitive.Curve#setPoints(org.gvsig.fmap.geom.primitive
119
     * .Point, org.gvsig.fmap.geom.primitive.Point)
120
     */
121
    public void setPoints(Point initialPoint, Point endPoint) {
122
        initialPoint = fixPoint(initialPoint);
123
        endPoint = fixPoint(endPoint);
124
        coordinates.clear();
125
        addVertex(initialPoint);
126
        addVertex(endPoint);
127
    }
128

    
129
    /**
130
     * @param initialPoint
131
     * @return
132
     */
133
    protected abstract Point fixPoint(Point point);
134

    
135
    /*
136
     * (non-Javadoc)
137
     *
138
     * @see
139
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#getCoordinateAt(int,
140
     * int)
141
     */
142
    public double getCoordinateAt(int index, int dimension) {
143
        return coordinates.getOrdinate(index, dimension);
144
    }
145

    
146
    /*
147
     * (non-Javadoc)
148
     *
149
     * @see
150
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#setCoordinateAt(int,
151
     * int, double)
152
     */
153
    public void setCoordinateAt(int index, int dimension, double value) {
154
        coordinates.setOrdinate(index, dimension, value);
155
    }
156

    
157
    /*
158
     * (non-Javadoc)
159
     *
160
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#removeVertex(int)
161
     */
162
    public void removeVertex(int index) {
163
        coordinates.remove(index);
164
    }
165

    
166
    /*
167
     * (non-Javadoc)
168
     *
169
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#getNumVertices()
170
     */
171
    public int getNumVertices() {
172
        return coordinates.size();
173
    }
174

    
175
    /*
176
     * (non-Javadoc)
177
     *
178
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#insertVertex(int,
179
     * org.gvsig.fmap.geom.primitive.Point)
180
     */
181
    public void insertVertex(int index, Point p) {
182
        p = fixPoint(p);
183
        coordinates.add(index, ((PointJTS) p).getJTSCoordinate());
184
    }
185

    
186
    /*
187
     * (non-Javadoc)
188
     *
189
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#setVertex(int,
190
     * org.gvsig.fmap.geom.primitive.Point)
191
     */
192
    public void setVertex(int index, Point p) {
193
        p = fixPoint(p);
194
        coordinates.set(index, ((PointJTS) p).getJTSCoordinate());
195
    }
196

    
197
    /*
198
     * (non-Javadoc)
199
     *
200
     * @see
201
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#setGeneralPath(org.
202
     * gvsig.fmap.geom.primitive.GeneralPathX)
203
     */
204
    public void setGeneralPath(GeneralPathX generalPathX) {
205
        PathIterator it = generalPathX.getPathIterator(null);
206
        double[] segment = new double[6];
207
        int i = 0;
208
        while(!it.isDone()){
209
            int type = it.currentSegment(segment);
210
            if(i==0){
211
                switch (type) {
212
                case IGeneralPathX.SEG_MOVETO:
213
                    Point p = new Point2D(segment[0], segment[1]);
214
                    p = fixPoint(p);
215
                    coordinates.add(((PointJTS)p).getJTSCoordinate());
216
                    break;
217
                default:
218
                    String message = StringUtils.replace("Type of segment %(segment)s isn't SEG_MOVETO.","%(segment)s",String.valueOf(i));
219
                    logger.warn(message);
220
                    throw new RuntimeException(message);
221
                }
222
            } else {
223
                //Dudo de que los casos SEG_QUADTO y SEG_CUBICTO est?n bien pero se hac?a lo mismo en la librer?a de geometr?as vieja.
224
                Point p;
225
                switch (type) {
226
                case IGeneralPathX.SEG_LINETO:
227
                    p = new Point2D(segment[0], segment[1]);
228
                    p = fixPoint(p);
229
                    coordinates.add(((PointJTS)p).getJTSCoordinate());
230
                    break;
231
                case IGeneralPathX.SEG_QUADTO:
232
                    for (int j = 0; j <= 1; j++) {
233
                        p = new Point2D(segment[i], segment[i+1]);
234
                        p = fixPoint(p);
235
                        coordinates.add(((PointJTS) p).getJTSCoordinate());
236
                    }
237
                    break;
238
                case IGeneralPathX.SEG_CUBICTO:
239
                    for (int j = 0; j <= 2; j++) {
240
                        p = new Point2D(segment[i], segment[i+1]);
241
                        p = fixPoint(p);
242
                        coordinates.add(((PointJTS) p).getJTSCoordinate());
243
                    }
244
                    break;
245
                case IGeneralPathX.SEG_CLOSE:
246
                    coordinates.add(coordinates.get(0));
247
                    break;
248
                default:
249
                    String message = StringUtils.replace("The general path has a gap in segment %(segment)s.","%(segment)s",String.valueOf(i));
250
                    logger.warn(message);
251
                    throw new RuntimeException(message);
252
                }
253
            }
254
            it.next();
255
            i++;
256
        }
257
    }
258

    
259
    /*
260
     * (non-Javadoc)
261
     *
262
     * @see
263
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#addMoveToVertex(org
264
     * .gvsig.fmap.geom.primitive.Point)
265
     */
266
    public void addMoveToVertex(Point point) {
267
        notifyDeprecated("Calling deprecated metohd addMoveToVertex in Line");
268
        throw new UnsupportedOperationException();
269
    }
270

    
271
    /*
272
     * (non-Javadoc)
273
     *
274
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#closePrimitive()
275
     */
276
    public void closePrimitive() {
277
        if (!coordinates.get(0).equals(coordinates.get(coordinates.size()))) {
278
            coordinates.add(coordinates.get(coordinates.size()));
279
        }
280
    }
281

    
282
    /*
283
     * (non-Javadoc)
284
     *
285
     * @see
286
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#ensureCapacity(int)
287
     */
288
    public void ensureCapacity(int capacity) {
289
        this.coordinates.ensureCapacity(capacity);
290
    }
291

    
292
    /*
293
     * (non-Javadoc)
294
     *
295
     * @see org.gvsig.fmap.geom.Geometry#reProject(org.cresques.cts.ICoordTrans)
296
     */
297
    public void reProject(ICoordTrans ct) {
298
        if (ct == null) {
299
            return;
300
        }
301
        for (Iterator<Coordinate> iterator = coordinates.iterator(); iterator.hasNext();) {
302
            Coordinate coordinate = (Coordinate) iterator.next();
303

    
304
            java.awt.geom.Point2D p = new java.awt.geom.Point2D.Double(coordinate.x, coordinate.y);
305
            try {
306
                p = ct.convert(p, p);
307
                coordinate.x = p.getX();
308
                coordinate.y = p.getY();
309
            } catch (Exception exc) {
310
                /*
311
                 * This can happen when the reprojection lib is unable
312
                 * to reproject (for example the source point
313
                 * is out of the valid range and some computing
314
                 * problem happens)
315
                 */
316
                throw new ReprojectionRuntimeException(ct.getPOrig(), ct.getPDest(), p, exc);
317
            }
318
        }
319
    }
320

    
321
    /*
322
     * (non-Javadoc)
323
     *
324
     * @see
325
     * org.gvsig.fmap.geom.Geometry#transform(java.awt.geom.AffineTransform)
326
     */
327
    public void transform(AffineTransform at) {
328
        if (at == null) {
329
            return;
330
        }
331

    
332
        for (Iterator<Coordinate> iterator = coordinates.iterator(); iterator.hasNext();) {
333
            Coordinate coordinate = (Coordinate) iterator.next();
334
            java.awt.geom.Point2D p = new java.awt.geom.Point2D.Double(coordinate.x, coordinate.y);
335

    
336
            at.transform(p, p);
337
            coordinate.x = p.getX();
338
            coordinate.y = p.getY();
339
        }
340
    }
341

    
342
    /*
343
     * (non-Javadoc)
344
     *
345
     * @see org.gvsig.fmap.geom.Geometry#getDimension()
346
     */
347
    public int getDimension() {
348
        return anyVertex.getDimension();
349
    }
350

    
351
    /*
352
     * (non-Javadoc)
353
     *
354
     * @see org.gvsig.fmap.geom.Geometry#getShape(java.awt.geom.AffineTransform)
355
     */
356
    public Shape getShape(AffineTransform affineTransform) {
357
        return new DefaultGeneralPathX(getPathIterator(affineTransform),false,0);
358
    }
359

    
360
    /*
361
     * (non-Javadoc)
362
     *
363
     * @see org.gvsig.fmap.geom.Geometry#getShape()
364
     */
365
    public Shape getShape() {
366
        return new DefaultGeneralPathX(getPathIterator(null),false,0);
367
    }
368

    
369
    /*
370
     * (non-Javadoc)
371
     *
372
     * @see org.gvsig.fmap.geom.Geometry#getHandlers(int)
373
     */
374
    public Handler[] getHandlers(int type) {
375
        String message = "Calling deprecated method getHandlers of a line";
376
        notifyDeprecated(message);
377
        throw new UnsupportedOperationException(message);
378
    }
379

    
380
    /*
381
     * (non-Javadoc)
382
     *
383
     * @see
384
     * org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform
385
     * )
386
     */
387
    public PathIterator getPathIterator(AffineTransform at) {
388
        LineIterator pi = new LineIterator(at);
389
        return pi;
390
    }
391

    
392
    /*
393
     * (non-Javadoc)
394
     *
395
     * @see
396
     * org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform
397
     * , double)
398
     */
399
    public PathIterator getPathIterator(AffineTransform at, double flatness) {
400
        return getPathIterator(at);
401
    }
402

    
403
    /*
404
     * (non-Javadoc)
405
     *
406
     * @see org.gvsig.fmap.geom.Geometry#getGeneralPath()
407
     */
408
    public GeneralPathX getGeneralPath() {
409
        return new DefaultGeneralPathX(getPathIterator(null), false, 0);
410
    }
411

    
412
    protected class LineIterator extends GeneralPathXIterator {
413

    
414
        /** Transform applied on the coordinates during iteration */
415
        private AffineTransform at;
416

    
417
        /** True when the point has been read once */
418
        private boolean done;
419
        private int index = 0;
420

    
421
        /**
422
         * Creates a new PointIterator object.
423
         *
424
         * @param p
425
         *            The polygon
426
         * @param at
427
         *            The affine transform applied to coordinates during
428
         *            iteration
429
         */
430
        public LineIterator(AffineTransform at) {
431
            super(new GeneralPathX());
432
            if (at == null) {
433
                at = new AffineTransform();
434
            }
435

    
436
            this.at = at;
437
            done = false;
438
        }
439

    
440
        /**
441
         * Return the winding rule for determining the interior of the path.
442
         *
443
         * @return <code>WIND_EVEN_ODD</code> by default.
444
         */
445
        public int getWindingRule() {
446
            return PathIterator.WIND_EVEN_ODD;
447
        }
448

    
449
        /**
450
         * @see java.awt.geom.PathIterator#next()
451
         */
452
        public void next() {
453
            done = (coordinates.size() == index++);
454
        }
455

    
456
        /**
457
         * @see java.awt.geom.PathIterator#isDone()
458
         */
459
        public boolean isDone() {
460
            return done;
461
        }
462

    
463
        /**
464
         * @see java.awt.geom.PathIterator#currentSegment(double[])
465
         */
466
        public int currentSegment(double[] coords) {
467
            coords[0] = coordinates.getX(index);
468
            coords[1] = coordinates.getY(index);
469
            at.transform(coords, 0, coords, 0, 1);
470

    
471
            if (index == 0) {
472
                return PathIterator.SEG_MOVETO;
473
            } else {
474
                return PathIterator.SEG_LINETO;
475
            }
476
        }
477

    
478
        /*
479
         * (non-Javadoc)
480
         *
481
         * @see java.awt.geom.PathIterator#currentSegment(float[])
482
         */
483
        public int currentSegment(float[] coords) {
484
            coords[0] = (float) coordinates.getX(index);
485
            coords[1] = (float) coordinates.getY(index);
486
            at.transform(coords, 0, coords, 0, 1);
487

    
488
            if (index == 0) {
489
                return PathIterator.SEG_MOVETO;
490
            } else {
491
                return PathIterator.SEG_LINETO;
492
            }
493
        }
494
    }
495

    
496
    /*
497
     * (non-Javadoc)
498
     *
499
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#is3D()
500
     */
501
    public boolean is3D() {
502
        return anyVertex.is3D();
503
    }
504

    
505
    protected boolean isClosed(){
506
        return coordinates.get(0).equals(coordinates.get(coordinates.size()-1));
507
    }
508

    
509
    /* (non-Javadoc)
510
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#flip()
511
     */
512
    public void flip() throws GeometryOperationNotSupportedException, GeometryOperationException {
513
        Collections.reverse(coordinates);
514
    }
515

    
516
}