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

History | View | Annotate | Download (15.7 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.Iterator;
29

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

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

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

    
57
/**
58
 * @author fdiaz
59
 *
60
 */
61
public abstract class AbstractLine extends AbstractCurve {
62

    
63
    /**
64
     *
65
     */
66
    private static final long serialVersionUID = 5034197096871344597L;
67
    private static final Logger logger = LoggerFactory.getLogger(AbstractLine.class);
68

    
69
    protected ArrayListCoordinateSequence coordinates;
70
    protected PointJTS anyVertex;
71

    
72
    /**
73
    *
74
    */
75
    protected AbstractLine(int subtype) {
76
        super(Geometry.TYPES.LINE, subtype);
77
    }
78

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

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

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

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

    
126
    /**
127
     * @param initialPoint
128
     * @return
129
     */
130
    protected abstract Point fixPoint(Point point);
131

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
333
            at.transform(p, p);
334
            coordinate.x = p.getX();
335
            coordinate.y = p.getY();
336
        }
337
    }
338

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

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

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

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

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

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

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

    
409
    protected class LineIterator extends GeneralPathXIterator {
410

    
411
        /** Transform applied on the coordinates during iteration */
412
        private AffineTransform at;
413

    
414
        /** True when the point has been read once */
415
        private boolean done;
416
        private int index = 0;
417

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

    
433
            this.at = at;
434
            done = false;
435
        }
436

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

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

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

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

    
468
            if (index == 0) {
469
                return PathIterator.SEG_MOVETO;
470
            } else {
471
                return PathIterator.SEG_LINETO;
472
            }
473
        }
474

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

    
485
            if (index == 0) {
486
                return PathIterator.SEG_MOVETO;
487
            } else {
488
                return PathIterator.SEG_LINETO;
489
            }
490
        }
491
    }
492

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

    
502
//    /*
503
//     * (non-Javadoc)
504
//     *
505
//     * @see org.gvsig.fmap.geom.primitive.Line#toPoints()
506
//     */
507
//    public MultiPoint toPoints() throws GeometryException {
508
//        // TODO Auto-generated method stub
509
//        return null;
510
//    }
511
//
512
    /*
513
     * (non-Javadoc)
514
     *
515
     * @see org.gvsig.fmap.geom.primitive.Line#toLines()
516
     */
517
    public MultiLine toLines() throws GeometryException {
518
        // TODO Auto-generated method stub
519
        return null;
520
    }
521

    
522
    /*
523
     * (non-Javadoc)
524
     *
525
     * @see org.gvsig.fmap.geom.primitive.Line#toPolygons()
526
     */
527
    public MultiPolygon toPolygons() throws GeometryException {
528
        // TODO Auto-generated method stub
529
        return null;
530
    }
531

    
532
    protected boolean isClosed(){
533
        return coordinates.get(0).equals(coordinates.get(coordinates.size()-1));
534
    }
535
}