Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / datastruct / ExtentImpl.java @ 4436

History | View | Annotate | Download (17.5 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.impl.datastruct;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.NoninvertibleTransformException;
26
import java.awt.geom.Point2D;
27
import java.awt.geom.Rectangle2D;
28
import java.text.DecimalFormat;
29

    
30
import org.cresques.cts.ICoordTrans;
31
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
32
import org.gvsig.fmap.dal.coverage.datastruct.GridExtent;
33
import org.gvsig.raster.impl.grid.GridExtentImpl;
34
import org.gvsig.tools.ToolsLocator;
35
import org.gvsig.tools.dynobject.DynStruct;
36
import org.gvsig.tools.persistence.PersistenceManager;
37
import org.gvsig.tools.persistence.PersistentState;
38
import org.gvsig.tools.persistence.exception.PersistenceException;
39

    
40
/**
41
 *        Clase que getiona el extent de una imagen
42
 *
43
 *  @author Luis W.Sevilla (sevilla_lui@gva.es)
44
 */
45
public class ExtentImpl implements Extent {
46
        public static final String PERSISTENT_NAME        = "Extent_Persistent";
47
    public static final String PERSISTENT_DESCRIPTION = "Extent Persistent";
48

    
49
    Point2D min = null;
50
    Point2D max = null;
51

    
52
    Point2D ul = new Point2D.Double(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
53
    Point2D lr = new Point2D.Double(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
54
    Point2D ur = new Point2D.Double(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
55
    Point2D ll = new Point2D.Double(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
56

    
57
    /**
58
     * Constructor sin par?metros
59
     */
60
    public ExtentImpl() {
61
        min = new Point2D.Double(999999999.0, 999999999.0);
62
        max = new Point2D.Double(-999999999.0, -999999999.0);
63
    }
64

    
65
    /**
66
     * Constructor
67
     * @param ul punto que representa la esquina superior izquierda
68
     * @param lr punto que representa la esquina inferior derecha
69
     */
70
    public ExtentImpl(Point2D ul, Point2D lr) {
71
            this.ul = ul;
72
            this.lr = lr;
73
        newExtent(ul.getX(), ul.getY(), lr.getX(), lr.getY());
74
    }
75

    
76
    /**
77
     * Constructor
78
     * @param ul punto que representa la esquina superior izquierda
79
     * @param lr punto que representa la esquina inferior derecha
80
     * @param ur punto que representa la esquina superior derecha
81
     * @param ll punto que representa la esquina inferior izquierda
82
     */
83
    public ExtentImpl(Point2D ul, Point2D lr, Point2D ur, Point2D ll) {
84
            this.ul = ul;
85
            this.lr = lr;
86
            this.ur = ur;
87
            this.ll = ll;
88
            min = new Point2D.Double(
89
                                    Math.min(Math.min(ul.getX(), lr.getX()), Math.min(ur.getX(), ll.getX())),
90
                                    Math.min(Math.min(ul.getY(), lr.getY()), Math.min(ur.getY(), ll.getY())));
91
              max = new Point2D.Double(
92
                                      Math.max(Math.max(ul.getX(), lr.getX()), Math.max(ur.getX(), ll.getX())),
93
                                      Math.max(Math.max(ul.getY(), lr.getY()), Math.max(ur.getY(), ll.getY())));
94
    }
95

    
96
    /**
97
     * Contructor
98
     * @param x1 punto que representa la coordenada X de la esquina superior izquierda
99
     * @param y1 punto que representa la coordenada Y de la esquina superior izquierda
100
     * @param x2 punto que representa la coordenada X de la esquina inferior derecha
101
     * @param y2 punto que representa la coordenada Y de la esquina inferior derecha
102
     */
103
    public ExtentImpl(double x1, double y1, double x2, double y2) {
104
            ul.setLocation(x1, y1);
105
            lr.setLocation(x2, y2);
106
        newExtent(x1, y1, x2, y2);
107
    }
108

    
109
    /**
110
     * Constructor
111
     * @param r        Rectangulo 2D
112
     */
113
    public ExtentImpl(Rectangle2D r) {
114
            ul.setLocation(r.getX(), r.getY() + r.getHeight());
115
            lr.setLocation(r.getX() + r.getWidth(), r.getY());
116
        newExtent(r.getX(), r.getY(), r.getX() + r.getWidth(),
117
                  r.getY() + r.getHeight());
118
    }
119

    
120
    /**
121
     * Constructor de copia
122
     * @param ext        Objeto Extent
123
     */
124
    public ExtentImpl(Extent ext) {
125
            ul.setLocation(ext.getULX(), ext.getULY());
126
            lr.setLocation(ext.getLRX(), ext.getLRY());
127
            ur.setLocation(ext.getURX(), ext.getURY());
128
            ll.setLocation(ext.getLLX(), ext.getLLY());
129
        min = new Point2D.Double(ext.minX(), ext.minY());
130
        max = new Point2D.Double(ext.maxX(), ext.maxY());
131
    }
132

    
133
    public Extent encloseBoundinBoxes(Extent ext) {
134
            Point2D pUl = new Point2D.Double(
135
                            Math.min(getULX(), ext.getULX()),
136
                            Math.max(getULY(), ext.getULY()));
137
            Point2D pLr = new Point2D.Double(
138
                            Math.max(getLRX(), ext.getLRX()),
139
                            Math.min(getLRY(), ext.getLRY()));
140
            return new ExtentImpl(pUl, pLr);
141
    }
142

    
143
    public Extent intersection(Extent ext) {
144
            if(intersects(ext)) {
145
                    Point2D pUl = new Point2D.Double(
146
                                    Math.max(getULX(), ext.getULX()),
147
                                    Math.min(getULY(), ext.getULY()));
148
                    Point2D pLr = new Point2D.Double(
149
                                    Math.min(getLRX(), ext.getLRX()),
150
                                    Math.max(getLRY(), ext.getLRY()));
151
                    return new ExtentImpl(pUl, pLr);
152
            }
153
            return null;
154
    }
155

    
156
    public boolean intersects(Extent ext) {
157
            if (getMin().getX() > ext.getMax().getX())
158
                    return false;
159
            else if (getMax().getX() < ext.getMin().getX())
160
                    return false;
161
            if (getMin().getY() > ext.getMax().getY())
162
                    return false;
163
            else if (getMax().getY() < ext.getMin().getY())
164
                    return false;
165
            return true;
166
    }
167

    
168
    public GridExtent getGridExtent(double cellSize) {
169
            return new GridExtentImpl(this, cellSize);
170
    }
171

    
172
    public Extent clone() {
173
            ExtentImpl e = new ExtentImpl();
174
        e.min = min != null ? (Point2D) min.clone() : null;
175
        e.max = max != null ? (Point2D) max.clone() : null;
176

    
177
        e.ul = ul != null ? (Point2D) ul.clone() : null;
178
        e.lr = lr != null ? (Point2D) lr.clone() : null;
179
        e.ur = ur != null ? (Point2D) ur.clone() : null;
180
        e.ll = ll != null ? (Point2D) ll.clone() : null;
181
        return e;
182
    }
183

    
184
    private void newExtent(double x1, double y1, double x2, double y2) {
185
        min = new Point2D.Double(Math.min(x1, x2), Math.min(y1, y2));
186
        max = new Point2D.Double(Math.max(x1, x2), Math.max(y1, y2));
187
    }
188

    
189
    /**
190
     * Obtiene la coordenada X m?nima
191
     * @return valor de la coordenada X m?nima
192
     */
193
    public double minX() {
194
        return min.getX();
195
    }
196

    
197
    /**
198
     * Obtiene la coordenada Y m?nima
199
     * @return valor de la coordenada X m?nima
200
     */
201
    public double minY() {
202
        return min.getY();
203
    }
204

    
205
    /**
206
     * Obtiene la coordenada X m?xima
207
     * @return valor de la coordenada X m?xima
208
     */
209
    public double maxX() {
210
        return max.getX();
211
    }
212

    
213
    /**
214
     * Obtiene la coordenada Y m?xima
215
     * @return valor de la coordenada Y m?xima
216
     */
217
    public double maxY() {
218
        return max.getY();
219
    }
220

    
221
    /**
222
     * Obtiene el punto m?nimo
223
     * @return m?nimo
224
     */
225
    public Point2D getMin() {
226
        return min;
227
    }
228

    
229
    /**
230
     * Obtiene el punto m?ximo
231
     * @return m?ximo
232
     */
233
    public Point2D getMax() {
234
        return max;
235
    }
236

    
237
    public boolean isAt(Point2D pt) {
238
        if (pt.getX() < minX())
239
            return false;
240

    
241
        if (pt.getX() > maxX())
242
            return false;
243

    
244
        if (pt.getY() < minY())
245
            return false;
246

    
247
        if (pt.getY() > maxY())
248
            return false;
249

    
250
        return true;
251
    }
252

    
253
    public double width() {
254
        return Math.abs(maxX() - minX());
255
    }
256

    
257
    public double height() {
258
        return Math.abs(maxY() - minY());
259
    }
260

    
261
    /**
262
     * Obtiene el centro en X del extent
263
     * @return coordinate X of center
264
     */
265
    public double getCenterX() {
266
            return minX() + (width() / 2);
267
    }
268

    
269
    /**
270
     * Obtiene el centro en Y del extent
271
     * @return coordinate Y of center
272
     */
273
    public double getCenterY() {
274
            return minY() + (height() / 2);
275
    }
276

    
277
    /**
278
     * Verifica un punto, y modifica el extent si no est? incluido
279
     * @param pt
280
     */
281
    public void add(Point2D pt) {
282
        if (pt == null) {
283
            return;
284
        }
285

    
286
        min.setLocation(Math.min(pt.getX(), minX()), Math.min(pt.getY(), minY()));
287
        max.setLocation(Math.max(pt.getX(), maxX()), Math.max(pt.getY(), maxY()));
288
    }
289

    
290
    public void add(Extent ext) {
291
        if (ext == null) {
292
            return;
293
        }
294

    
295
        min.setLocation(Math.min(ext.minX(), minX()),
296
                        Math.min(ext.minY(), minY()));
297
        max.setLocation(Math.max(ext.maxX(), maxX()),
298
                        Math.max(ext.maxY(), maxY()));
299
    }
300

    
301
    /**
302
     * Obtiene la escala
303
     * @param width        Ancho
304
     * @param height        Alto
305
     * @return the scale
306
     */
307
    public double[] getScale(int width, int height) {
308
        return getScale((double) width, (double) height);
309
    }
310

    
311
    public double[] getScale(double width, double height) {
312
        double[] scale = new double[2];
313
        scale[0] = ((float) width) / width();
314
        scale[1] = ((float) height) / height();
315

    
316
        return scale;
317
    }
318

    
319
    public Rectangle2D toRectangle2D() {
320
        return new Rectangle2D.Double(minX(), minY(), width(), height());
321
    }
322

    
323
    public String toString() {
324
        DecimalFormat format = new DecimalFormat("####.000");
325

    
326
        return "Extent: (" + format.format(minX()) + "," +
327
               format.format(minY()) + "), (" + format.format(maxX()) + "," +
328
               format.format(maxY()) + ")";
329
    }
330

    
331
    public interface Has {
332
        public Extent getExtent();
333
    }
334

    
335
    public Point2D getUL() {
336
            return (Point2D)ul.clone();
337
    }
338

    
339
    public Point2D getLR() {
340
            return (Point2D)lr.clone();
341
    }
342

    
343
    /**
344
     * Obtiene la coordenada X de la esquina superior izquierda. Esta, en condiciones normales
345
     * conincide con el minimo en X pero cuando un raster est? rotado esto puede variar.
346
     * @return ulx
347
     */
348
    public double getULX() {
349
            if(ul.getX() == -999999999.0)
350
                    return minX();
351
            return ul.getX();
352
    }
353

    
354
    /**
355
     * Obtiene la coordenada Y de la esquina superior izquierda. Esta, en condiciones normales
356
     * conincide con el maximo en Y pero cuando un raster est? rotado esto puede variar.
357
     * @return uly
358
     */
359
    public double getULY() {
360
            if(ul.getY() == -999999999.0)
361
                    return maxY();
362
            return ul.getY();
363
    }
364

    
365
    /**
366
     * Obtiene la coordenada X de la esquina inferior derecha. Esta, en condiciones normales
367
     * conincide con el m?ximo en X pero cuando un raster est? rotado esto puede variar.
368
     * @return lrx
369
     */
370
    public double getLRX() {
371
            if(lr.getX() == -999999999.0)
372
                    return maxX();
373
            return lr.getX();
374
    }
375

    
376
    /**
377
     * Obtiene la coordenada Y de la esquina inferior derecha. Esta, en condiciones normales
378
     * conincide con el minimo en Y pero cuando un raster est? rotado esto puede variar.
379
     * @return lry
380
     */
381
    public double getLRY() {
382
            if(lr.getY() == -999999999.0)
383
                    return minY();
384
            return lr.getY();
385
    }
386

    
387
    /**
388
     * Obtiene la coordenada X de la esquina superior derecha.
389
     * @return urx
390
     */
391
    public double getURX() {
392
            return ur.getX();
393
    }
394

    
395
    /**
396
     * Obtiene la coordenada Y de la esquina superior derecha.
397
     * @return uly
398
     */
399
    public double getURY() {
400
            return ur.getY();
401
    }
402

    
403
    /**
404
     * Obtiene la coordenada X de la esquina inferior izquierda.
405
     * @return lrx
406
     */
407
    public double getLLX() {
408
            return ll.getX();
409
    }
410

    
411
    /**
412
     * Obtiene la coordenada Y de la esquina inferior izquierda.
413
     * @return lly
414
     */
415
    public double getLLY() {
416
            return ll.getY();
417
    }
418

    
419
    /**
420
     * Asigna la coordenada X de la esquina superior izquierda al m?nimo X
421
     */
422
    public void setULXToMin() {
423
            ul.setLocation(minX(), ul.getY());
424
            lr.setLocation(maxX(), lr.getY());
425
    }
426

    
427
    /**
428
     * Asigna la coordenada X de la esquina superior izquierda al m?ximo X
429
     */
430
    public void setULXToMax() {
431
            ul.setLocation(maxX(), ul.getY());
432
            lr.setLocation(minX(), lr.getY());
433
    }
434

    
435
    /**
436
     * Asigna la coordenada Y de la esquina superior izquierda al m?nimo Y
437
     */
438
    public void setULYToMin() {
439
            ul.setLocation(ul.getX(), minY());
440
            lr.setLocation(lr.getX(), maxY());
441
    }
442

    
443
    /**
444
     * Asigna la coordenada Y de la esquina superior izquierda al m?ximo Y
445
     */
446
    public void setULYToMax() {
447
            ul.setLocation(ul.getX(), maxY());
448
            lr.setLocation(lr.getX(), minY());
449
    }
450

    
451
    /**
452
     * Asigna la coordenada X de la esquina inferior derecha al m?nimo X
453
     */
454
    public void setLRXToMin() {
455
            lr.setLocation(minX(), lr.getY());
456
            ul.setLocation(maxX(), ul.getY());
457

    
458
    }
459

    
460
    /**
461
     * Asigna la coordenada X de la esquina inferior derecha al m?ximo X
462
     */
463
    public void setLRXToMax() {
464
            lr.setLocation(maxX(), lr.getY());
465
            ul.setLocation(minX(), ul.getY());
466
    }
467

    
468
    /**
469
     * Asigna la coordenada Y de la esquina inferior derecha al m?nimo Y
470
     */
471
    public void setLRYToMin() {
472
            lr.setLocation(lr.getX(), minY());
473
            ul.setLocation(ul.getX(), maxX());
474
    }
475

    
476
    /**
477
     * Asigna la coordenada Y de la esquina inferior derecha al m?ximo Y
478
     */
479
    public void setLRYToMax() {
480
            lr.setLocation(lr.getX(), maxY());
481
            ul.setLocation(ul.getX(), minY());
482
    }
483

    
484
        public Extent convert(ICoordTrans trans) {
485
                Rectangle2D rect = new Rectangle2D.Double(getURX(), getLRY(), width(), height());
486
                Rectangle2D rectDest = trans.convert(rect);
487
                if (rectDest == null){
488
                        return null;
489
                }
490

    
491
                return new ExtentImpl(
492
                                rectDest.getMinX(),
493
                                rectDest.getMaxY(),
494
                                rectDest.getMaxX(),
495
                                rectDest.getMinY());
496
        }
497

    
498
        public boolean equals(Object obj) {
499
                if(!(obj instanceof Extent))
500
                        return false;
501
                Extent e1 = (Extent)obj;
502
                return (this.getULX() == e1.getULX() &&
503
                                this.getULY() == e1.getULY() &&
504
                                this.getLRX() == e1.getLRX() &&
505
                                this.getLRY() == e1.getLRY() &&
506
                                this.getURX() == e1.getURX() &&
507
                                this.getURY() == e1.getURY() &&
508
                                this.getLLX() == e1.getLLX() &&
509
                                this.getLLY() == e1.getLLY());
510
        }
511

    
512
        /**
513
         * Given a cell size, converts a point in raster coordinates to world coordinates
514
         * @param pt Point to transform
515
         */
516
        public Point2D rasterToWorld(Point2D pt, double cellsize) {
517
                Point2D p = new Point2D.Double();
518
                AffineTransform at = new AffineTransform(cellsize, 0, 0, -cellsize, getULX(), getULY());
519
                at.transform(pt, p);
520
                return p;
521
        }
522

    
523
        /**
524
         * Given a cell size, converts a point in world coordinates to pixel coordinates
525
         * @param pt Point to transform
526
         */
527
        public Point2D worldToRaster(Point2D pt, double cellsize) {
528
                Point2D p = new Point2D.Double();
529
                AffineTransform at = new AffineTransform(cellsize, 0, 0, -cellsize, getULX(), getULY());
530
                try {
531
                        at.inverseTransform(pt, p);
532
                } catch (NoninvertibleTransformException e) {
533
                        return pt;
534
                }
535
                return p;
536
        }
537

    
538
        public void loadFromState(PersistentState state)
539
                        throws PersistenceException {
540
                double ulx = state.getDouble("ulx");
541
                double uly = state.getDouble("uly");
542
                double lrx = state.getDouble("lrx");
543
                double lry = state.getDouble("lry");
544
                double urx = state.getDouble("urx");
545
                double ury = state.getDouble("ury");
546
                double llx = state.getDouble("llx");
547
                double lly = state.getDouble("lly");
548
                ul.setLocation(ulx, uly);
549
            lr.setLocation(lrx, lry);
550
            ur.setLocation(urx, ury);
551
            ll.setLocation(llx, lly);
552
            if(        ur.getX() != Double.POSITIVE_INFINITY &&
553
                    ur.getY() != Double.POSITIVE_INFINITY &&
554
                    ll.getX() != Double.POSITIVE_INFINITY &&
555
                    ll.getY() != Double.POSITIVE_INFINITY) {
556
                    min = new Point2D.Double(
557
                                    Math.min(Math.min(ul.getX(), lr.getX()), Math.min(ur.getX(), ll.getX())),
558
                                    Math.min(Math.min(ul.getY(), lr.getY()), Math.min(ur.getY(), ll.getY())));
559
                    max = new Point2D.Double(
560
                                      Math.max(Math.max(ul.getX(), lr.getX()), Math.max(ur.getX(), ll.getX())),
561
                                      Math.max(Math.max(ul.getY(), lr.getY()), Math.max(ur.getY(), ll.getY())));
562
            } else {
563
                    newExtent(ulx, uly, lrx, lry);
564
            }
565
        }
566

    
567
        public void saveToState(PersistentState state) throws PersistenceException {
568
                state.set("ulx", getULX());
569
                state.set("uly", getULY());
570
                state.set("lrx", getLRX());
571
                state.set("lry", getLRY());
572
                state.set("urx", getURX());
573
                state.set("ury", getURY());
574
                state.set("llx", getLLX());
575
                state.set("lly", getLLY());
576
        }
577

    
578
        public static void registerPersistence() {
579
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
580
                DynStruct definition = manager.getDefinition(PERSISTENT_NAME);
581
                if( definition == null ) {
582
                        definition = manager.addDefinition(
583
                                        Extent.class,
584
                                        PERSISTENT_NAME,
585
                                        PERSISTENT_DESCRIPTION,
586
                                        null,
587
                                        null
588
                        );
589

    
590
                        definition.addDynFieldDouble("ulx").setMandatory(true);
591
                        definition.addDynFieldDouble("uly").setMandatory(true);
592
                        definition.addDynFieldDouble("lrx").setMandatory(true);
593
                        definition.addDynFieldDouble("lry").setMandatory(true);
594
                        definition.addDynFieldDouble("urx").setMandatory(false);
595
                        definition.addDynFieldDouble("ury").setMandatory(false);
596
                        definition.addDynFieldDouble("llx").setMandatory(false);
597
                        definition.addDynFieldDouble("lly").setMandatory(false);
598
                }
599
        }
600

    
601
        protected void finalize() throws Throwable {
602
                min = null;
603
            max = null;
604
            ul  = null;
605
            lr  = null;
606
            ur  = null;
607
            ll  = null;
608
                super.finalize();
609
        }
610
}