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

History | View | Annotate | Download (15.1 KB)

1 42260 fdiaz
/* 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 42281 fdiaz
import java.util.Collections;
29 42260 fdiaz
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.exception.ReprojectionRuntimeException;
40
import org.gvsig.fmap.geom.jts.gputils.DefaultGeneralPathX;
41
import org.gvsig.fmap.geom.jts.gputils.GeneralPathXIterator;
42
import org.gvsig.fmap.geom.jts.primitive.curve.AbstractCurve;
43
import org.gvsig.fmap.geom.jts.primitive.point.Point2D;
44
import org.gvsig.fmap.geom.jts.primitive.point.PointJTS;
45 42267 fdiaz
import org.gvsig.fmap.geom.jts.util.ArrayListCoordinateSequence;
46
import org.gvsig.fmap.geom.jts.util.JTSUtils;
47 42281 fdiaz
import org.gvsig.fmap.geom.operation.GeometryOperationException;
48
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
49 42260 fdiaz
import org.gvsig.fmap.geom.primitive.GeneralPathX;
50
import org.gvsig.fmap.geom.primitive.IGeneralPathX;
51
import org.gvsig.fmap.geom.primitive.Point;
52
53
/**
54
 * @author fdiaz
55
 *
56
 */
57 42270 fdiaz
public abstract class AbstractLine extends AbstractCurve {
58 42260 fdiaz
59
    /**
60
     *
61
     */
62
    private static final long serialVersionUID = 5034197096871344597L;
63
    private static final Logger logger = LoggerFactory.getLogger(AbstractLine.class);
64
65
    protected ArrayListCoordinateSequence coordinates;
66 42267 fdiaz
    protected PointJTS anyVertex;
67 42260 fdiaz
68
    /**
69
    *
70
    */
71
    protected AbstractLine(int subtype) {
72
        super(Geometry.TYPES.LINE, subtype);
73
    }
74
75 42283 fdiaz
    /**
76
     * @param type
77
     * @param subtype
78
     */
79
    public AbstractLine(int type, int subtype) {
80
        super(type, subtype);
81
    }
82
83 42260 fdiaz
    /*
84
     * (non-Javadoc)
85
     *
86
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#getJTS()
87
     */
88
    public com.vividsolutions.jts.geom.Geometry getJTS() {
89
        return JTSUtils.createJTSLineString(coordinates);
90
    }
91
92
    /*
93
     * (non-Javadoc)
94
     *
95
     * @see
96
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#addVertex(org.gvsig
97
     * .fmap.geom.primitive.Point)
98
     */
99
    public void addVertex(Point point) {
100
        point = fixPoint(point);
101
        coordinates.add(((PointJTS) point).getJTSCoordinate());
102 42267 fdiaz
        anyVertex = (PointJTS) point;
103 42260 fdiaz
    }
104
105
    /*
106
     * (non-Javadoc)
107
     *
108
     * @see
109
     * org.gvsig.fmap.geom.primitive.Curve#setPoints(org.gvsig.fmap.geom.primitive
110
     * .Point, org.gvsig.fmap.geom.primitive.Point)
111
     */
112
    public void setPoints(Point initialPoint, Point endPoint) {
113
        initialPoint = fixPoint(initialPoint);
114
        endPoint = fixPoint(endPoint);
115
        coordinates.clear();
116
        addVertex(initialPoint);
117
        addVertex(endPoint);
118
    }
119
120
    /**
121
     * @param initialPoint
122
     * @return
123
     */
124
    protected abstract Point fixPoint(Point point);
125
126
    /*
127
     * (non-Javadoc)
128
     *
129
     * @see
130
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#getCoordinateAt(int,
131
     * int)
132
     */
133
    public double getCoordinateAt(int index, int dimension) {
134
        return coordinates.getOrdinate(index, dimension);
135
    }
136
137
    /*
138
     * (non-Javadoc)
139
     *
140
     * @see
141
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#setCoordinateAt(int,
142
     * int, double)
143
     */
144
    public void setCoordinateAt(int index, int dimension, double value) {
145
        coordinates.setOrdinate(index, dimension, value);
146
    }
147
148
    /*
149
     * (non-Javadoc)
150
     *
151
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#removeVertex(int)
152
     */
153
    public void removeVertex(int index) {
154
        coordinates.remove(index);
155
    }
156
157
    /*
158
     * (non-Javadoc)
159
     *
160
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#getNumVertices()
161
     */
162
    public int getNumVertices() {
163
        return coordinates.size();
164
    }
165
166
    /*
167
     * (non-Javadoc)
168
     *
169
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#insertVertex(int,
170
     * org.gvsig.fmap.geom.primitive.Point)
171
     */
172
    public void insertVertex(int index, Point p) {
173
        p = fixPoint(p);
174
        coordinates.add(index, ((PointJTS) p).getJTSCoordinate());
175
    }
176
177
    /*
178
     * (non-Javadoc)
179
     *
180
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#setVertex(int,
181
     * org.gvsig.fmap.geom.primitive.Point)
182
     */
183
    public void setVertex(int index, Point p) {
184
        p = fixPoint(p);
185
        coordinates.set(index, ((PointJTS) p).getJTSCoordinate());
186
    }
187
188
    /*
189
     * (non-Javadoc)
190
     *
191
     * @see
192
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#setGeneralPath(org.
193
     * gvsig.fmap.geom.primitive.GeneralPathX)
194
     */
195
    public void setGeneralPath(GeneralPathX generalPathX) {
196
        PathIterator it = generalPathX.getPathIterator(null);
197
        double[] segment = new double[6];
198
        int i = 0;
199
        while(!it.isDone()){
200
            int type = it.currentSegment(segment);
201
            if(i==0){
202
                switch (type) {
203
                case IGeneralPathX.SEG_MOVETO:
204
                    Point p = new Point2D(segment[0], segment[1]);
205
                    p = fixPoint(p);
206
                    coordinates.add(((PointJTS)p).getJTSCoordinate());
207
                    break;
208
                default:
209
                    String message = StringUtils.replace("Type of segment %(segment)s isn't SEG_MOVETO.","%(segment)s",String.valueOf(i));
210
                    logger.warn(message);
211
                    throw new RuntimeException(message);
212
                }
213
            } else {
214 42261 fdiaz
                //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.
215
                Point p;
216 42260 fdiaz
                switch (type) {
217
                case IGeneralPathX.SEG_LINETO:
218 42261 fdiaz
                    p = new Point2D(segment[0], segment[1]);
219 42260 fdiaz
                    p = fixPoint(p);
220
                    coordinates.add(((PointJTS)p).getJTSCoordinate());
221
                    break;
222 42261 fdiaz
                case IGeneralPathX.SEG_QUADTO:
223
                    for (int j = 0; j <= 1; j++) {
224
                        p = new Point2D(segment[i], segment[i+1]);
225
                        p = fixPoint(p);
226
                        coordinates.add(((PointJTS) p).getJTSCoordinate());
227
                    }
228
                    break;
229
                case IGeneralPathX.SEG_CUBICTO:
230
                    for (int j = 0; j <= 2; j++) {
231
                        p = new Point2D(segment[i], segment[i+1]);
232
                        p = fixPoint(p);
233
                        coordinates.add(((PointJTS) p).getJTSCoordinate());
234
                    }
235
                    break;
236 42260 fdiaz
                case IGeneralPathX.SEG_CLOSE:
237
                    coordinates.add(coordinates.get(0));
238
                    break;
239
                default:
240
                    String message = StringUtils.replace("The general path has a gap in segment %(segment)s.","%(segment)s",String.valueOf(i));
241
                    logger.warn(message);
242
                    throw new RuntimeException(message);
243
                }
244
            }
245
            it.next();
246
            i++;
247
        }
248
    }
249
250
    /*
251
     * (non-Javadoc)
252
     *
253
     * @see
254
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#addMoveToVertex(org
255
     * .gvsig.fmap.geom.primitive.Point)
256
     */
257
    public void addMoveToVertex(Point point) {
258 42267 fdiaz
        notifyDeprecated("Calling deprecated metohd addMoveToVertex in Line");
259 42260 fdiaz
        throw new UnsupportedOperationException();
260
    }
261
262
    /*
263
     * (non-Javadoc)
264
     *
265
     * @see org.gvsig.fmap.geom.primitive.OrientablePrimitive#closePrimitive()
266
     */
267
    public void closePrimitive() {
268 42304 fdiaz
        if (!coordinates.isEmpty() && !coordinates.get(0).equals(coordinates.get(coordinates.size()-1))) {
269 42283 fdiaz
            coordinates.add((Coordinate)coordinates.get(0).clone());
270 42260 fdiaz
        }
271
    }
272
273
    /*
274
     * (non-Javadoc)
275
     *
276
     * @see
277
     * org.gvsig.fmap.geom.primitive.OrientablePrimitive#ensureCapacity(int)
278
     */
279
    public void ensureCapacity(int capacity) {
280 42267 fdiaz
        this.coordinates.ensureCapacity(capacity);
281 42260 fdiaz
    }
282
283
    /*
284
     * (non-Javadoc)
285
     *
286
     * @see org.gvsig.fmap.geom.Geometry#reProject(org.cresques.cts.ICoordTrans)
287
     */
288
    public void reProject(ICoordTrans ct) {
289
        if (ct == null) {
290
            return;
291
        }
292 42271 fdiaz
        for (Iterator<Coordinate> iterator = coordinates.iterator(); iterator.hasNext();) {
293 42260 fdiaz
            Coordinate coordinate = (Coordinate) iterator.next();
294
295
            java.awt.geom.Point2D p = new java.awt.geom.Point2D.Double(coordinate.x, coordinate.y);
296
            try {
297
                p = ct.convert(p, p);
298
                coordinate.x = p.getX();
299
                coordinate.y = p.getY();
300
            } catch (Exception exc) {
301
                /*
302
                 * This can happen when the reprojection lib is unable
303
                 * to reproject (for example the source point
304
                 * is out of the valid range and some computing
305
                 * problem happens)
306
                 */
307
                throw new ReprojectionRuntimeException(ct.getPOrig(), ct.getPDest(), p, exc);
308
            }
309
        }
310
    }
311
312
    /*
313
     * (non-Javadoc)
314
     *
315
     * @see
316
     * org.gvsig.fmap.geom.Geometry#transform(java.awt.geom.AffineTransform)
317
     */
318
    public void transform(AffineTransform at) {
319
        if (at == null) {
320
            return;
321
        }
322
323 42283 fdiaz
        for (int i = 0; i < coordinates.size(); i++) {
324
            Coordinate coordinate = coordinates.get(i);
325 42260 fdiaz
            java.awt.geom.Point2D p = new java.awt.geom.Point2D.Double(coordinate.x, coordinate.y);
326
327
            at.transform(p, p);
328
            coordinate.x = p.getX();
329
            coordinate.y = p.getY();
330 42283 fdiaz
331 42260 fdiaz
        }
332
    }
333
334
    /*
335
     * (non-Javadoc)
336
     *
337
     * @see org.gvsig.fmap.geom.Geometry#getDimension()
338
     */
339
    public int getDimension() {
340 42267 fdiaz
        return anyVertex.getDimension();
341 42260 fdiaz
    }
342
343
    /*
344
     * (non-Javadoc)
345
     *
346
     * @see org.gvsig.fmap.geom.Geometry#getShape(java.awt.geom.AffineTransform)
347
     */
348
    public Shape getShape(AffineTransform affineTransform) {
349 42267 fdiaz
        return new DefaultGeneralPathX(getPathIterator(affineTransform),false,0);
350 42260 fdiaz
    }
351
352
    /*
353
     * (non-Javadoc)
354
     *
355
     * @see org.gvsig.fmap.geom.Geometry#getShape()
356
     */
357
    public Shape getShape() {
358 42267 fdiaz
        return new DefaultGeneralPathX(getPathIterator(null),false,0);
359 42260 fdiaz
    }
360
361
362
    /*
363
     * (non-Javadoc)
364
     *
365
     * @see
366
     * org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform
367 42267 fdiaz
     * )
368 42260 fdiaz
     */
369 42267 fdiaz
    public PathIterator getPathIterator(AffineTransform at) {
370 42260 fdiaz
        LineIterator pi = new LineIterator(at);
371
        return pi;
372
    }
373
374
    /*
375
     * (non-Javadoc)
376
     *
377 42267 fdiaz
     * @see
378
     * org.gvsig.fmap.geom.Geometry#getPathIterator(java.awt.geom.AffineTransform
379
     * , double)
380 42260 fdiaz
     */
381 42267 fdiaz
    public PathIterator getPathIterator(AffineTransform at, double flatness) {
382
        return getPathIterator(at);
383 42260 fdiaz
    }
384
385 42275 fdiaz
    /*
386
     * (non-Javadoc)
387
     *
388
     * @see org.gvsig.fmap.geom.Geometry#getGeneralPath()
389
     */
390
    public GeneralPathX getGeneralPath() {
391
        return new DefaultGeneralPathX(getPathIterator(null), false, 0);
392
    }
393
394 42267 fdiaz
    protected class LineIterator extends GeneralPathXIterator {
395 42260 fdiaz
396
        /** Transform applied on the coordinates during iteration */
397
        private AffineTransform at;
398
399
        /** True when the point has been read once */
400
        private boolean done;
401
        private int index = 0;
402
403
        /**
404
         * Creates a new PointIterator object.
405
         *
406
         * @param p
407
         *            The polygon
408
         * @param at
409
         *            The affine transform applied to coordinates during
410
         *            iteration
411
         */
412
        public LineIterator(AffineTransform at) {
413
            super(new GeneralPathX());
414
            if (at == null) {
415
                at = new AffineTransform();
416
            }
417
418
            this.at = at;
419
            done = false;
420
        }
421
422
        /**
423
         * Return the winding rule for determining the interior of the path.
424
         *
425
         * @return <code>WIND_EVEN_ODD</code> by default.
426
         */
427
        public int getWindingRule() {
428
            return PathIterator.WIND_EVEN_ODD;
429
        }
430
431
        /**
432
         * @see java.awt.geom.PathIterator#next()
433
         */
434
        public void next() {
435 42283 fdiaz
            done = (coordinates.size() == ++index);
436 42260 fdiaz
        }
437
438
        /**
439
         * @see java.awt.geom.PathIterator#isDone()
440
         */
441
        public boolean isDone() {
442
            return done;
443
        }
444
445
        /**
446
         * @see java.awt.geom.PathIterator#currentSegment(double[])
447
         */
448
        public int currentSegment(double[] coords) {
449
            coords[0] = coordinates.getX(index);
450
            coords[1] = coordinates.getY(index);
451
            at.transform(coords, 0, coords, 0, 1);
452
453
            if (index == 0) {
454
                return PathIterator.SEG_MOVETO;
455
            } else {
456
                return PathIterator.SEG_LINETO;
457
            }
458
        }
459
460
        /*
461
         * (non-Javadoc)
462
         *
463
         * @see java.awt.geom.PathIterator#currentSegment(float[])
464
         */
465
        public int currentSegment(float[] coords) {
466
            coords[0] = (float) coordinates.getX(index);
467
            coords[1] = (float) coordinates.getY(index);
468
            at.transform(coords, 0, coords, 0, 1);
469
470
            if (index == 0) {
471
                return PathIterator.SEG_MOVETO;
472
            } else {
473
                return PathIterator.SEG_LINETO;
474
            }
475
        }
476
    }
477
478
    /*
479
     * (non-Javadoc)
480
     *
481
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#is3D()
482
     */
483
    public boolean is3D() {
484 42267 fdiaz
        return anyVertex.is3D();
485 42260 fdiaz
    }
486
487 42267 fdiaz
    protected boolean isClosed(){
488
        return coordinates.get(0).equals(coordinates.get(coordinates.size()-1));
489
    }
490 42281 fdiaz
491
    /* (non-Javadoc)
492
     * @see org.gvsig.fmap.geom.jts.GeometryJTS#flip()
493
     */
494
    public void flip() throws GeometryOperationNotSupportedException, GeometryOperationException {
495
        Collections.reverse(coordinates);
496
    }
497
498 42283 fdiaz
    protected ArrayListCoordinateSequence cloneCoordinates() {
499
        ArrayListCoordinateSequence cloned = new ArrayListCoordinateSequence();
500
        cloned.ensureCapacity(coordinates.size());
501
        for (Iterator iterator = coordinates.iterator(); iterator.hasNext();) {
502
            Coordinate coordinate = (Coordinate) iterator.next();
503
            cloned.add((Coordinate)coordinate.clone());
504
        }
505
        return cloned;
506
    }
507
508 42260 fdiaz
}