Statistics
| Revision:

root / org.gvsig.projection.jcrs / trunk / org.gvsig.projection.jcrs / org.gvsig.projection.jcrs.lib / src / main / java / org / gvsig / crs / Crs.java @ 468

History | View | Annotate | Download (29.3 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 Instituto de Desarrollo Regional and Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   Instituto de Desarrollo Regional (Universidad de Castilla La-Mancha)
34
 *   Campus Universitario s/n
35
 *   02071 Alabacete
36
 *   Spain
37
 *
38
 *   +34 967 599 200
39
 */
40

    
41
package org.gvsig.crs;
42

    
43
import java.awt.Color;
44
import java.awt.Graphics2D;
45
import java.awt.geom.Point2D;
46
import java.awt.geom.Rectangle2D;
47
import java.text.MessageFormat;
48
import java.util.Vector;
49

    
50
import org.apache.commons.lang3.StringUtils;
51
import org.cresques.cts.ICRSFactory;
52
import org.cresques.cts.ICoordTrans;
53
import org.cresques.cts.IDatum;
54
import org.cresques.cts.IProjection;
55
import org.cresques.geo.ViewPortData;
56
import org.gdal.osr.SpatialReference;
57
import org.slf4j.Logger;
58
import org.slf4j.LoggerFactory;
59

    
60
import org.gvsig.crs.proj.CrsProj;
61
import org.gvsig.crs.proj.OperationCrsException;
62
import org.gvsig.fmap.crs.CRSFactory;
63

    
64
/**
65
 * Clase que construye el CRS a partir de la cadena WKT
66
 * @author Jos? Luis G?mez Mart?nez (jolugomar@gmail.com)
67
 * @author Diego Guerrero Sevilla (diego.guerrero@uclm.es)
68
 * @author Miguel Garc?a Jim?nez (garciajimenez.miguel@gmail.com)
69
 *
70
 */
71
public class Crs implements ICrs {
72

    
73
    private static final Logger logger = LoggerFactory.getLogger(Crs.class);
74

    
75
    private static final Color basicGridColor = new Color(64, 64, 64, 128);
76
    private Proj4 proj4;
77
    private String proj4String;
78
    private String trans;
79
    // private String transOrigin = "";
80
    private String abrev;
81
    private String name = "";
82
    private CrsProj crsProj;
83
    private CrsProj crsBase = null;
84
    private CrsWkt crsWkt;
85
    private int epsg_code = 23030;
86
    String sourceTrParams = null;
87
    String targetTrParams = null;
88
    String wkt = null;
89
    Color gridColor = basicGridColor;
90
    CRSDatum datum = null;
91

    
92
    private SpatialReference spatialReference = null;
93

    
94

    
95
    /**
96
     * @param spatialReference
97
     *
98
     */
99
    public Crs(SpatialReference spatialReference) {
100
            initFromSpatialReference(spatialReference);
101
    }
102

    
103
    /**
104
     * @param spatialReference
105
     */
106
    private void initFromSpatialReference(SpatialReference spatialReference) {
107
        this.spatialReference = spatialReference;
108
        String authorityCode = spatialReference.GetAuthorityCode(null);
109
        String authorityName = spatialReference.GetAuthorityName(null);
110
        spatialReference.Fixup();
111
        if(authorityCode==null || authorityName==null){
112
            try {
113
                spatialReference.AutoIdentifyEPSG();
114
                authorityCode = spatialReference.GetAuthorityCode(null);
115
                authorityName = spatialReference.GetAuthorityName(null);
116
            } catch (Exception e) {
117
                logger.error("Can't autoidentifyEPSG.", e);
118
            }
119
        }
120
        if(!StringUtils.isEmpty(authorityCode) && !StringUtils.isEmpty(authorityName)){
121
            name = authorityName+":"+authorityCode;
122
        }
123
        abrev = name;
124
        epsg_code = Integer.parseInt(authorityCode);
125

    
126
        datum = new CRSDatum(spatialReference.GetSemiMajor(), spatialReference.GetInvFlattening());
127
        proj4String = spatialReference.ExportToProj4();
128
//            crsWkt = new CrsWkt(authorityName+":"+authorityCode);
129
        crsWkt = new CrsWkt(spatialReference);
130
        setWKT(spatialReference.ExportToWkt());
131
    }
132

    
133
    /**
134
     * @param epsgCode
135
     * @param aut
136
     * @throws CrsException
137
     */
138
    public Crs(int epsgCode, int aut) throws CrsException {
139
        String strEpsgCode = "";
140
        if (aut == 1) {
141
            strEpsgCode = "EPSG:" + epsgCode;
142
        } else if (aut == 2) {
143
            strEpsgCode = "ESRI:" + epsgCode;
144
        } else if (aut == 3) {
145
            strEpsgCode = "IAU2000:" + epsgCode;
146
        } else if (aut == 4) {
147
            strEpsgCode = "USR:" + epsgCode;
148
        } else
149
            System.out.println("Error, autorithy err?neo");
150
        crsWkt = new CrsWkt(strEpsgCode);
151
        setWKT(crsWkt.getWkt());
152
    }
153

    
154
    /**
155
     * Construye un CRS a partir del c?digo EPSG o de la cadena WKT.
156
     *
157
     * @param code
158
     * @throws CrsException
159
     */
160
    public Crs(String code) throws CrsException {
161
        String fullCode;
162
        setWKT(code);
163
        if (code.charAt(0) == 'E' || code.charAt(0) == 'G' || code.charAt(0) == 'P')
164
            fullCode = code;
165
        else
166
            fullCode = "EPSG:" + code;
167
        if (code.length() < 15) {
168
            code = code.substring(code.indexOf(":") + 1);
169
            try {
170
                // Creamos el objeto que tendra los diferentes parametros de la
171
                // cadena Wkt
172
                crsWkt = new CrsWkt(fullCode);
173
                setName(fullCode);
174
                setAbrev(fullCode);
175

    
176
            } catch (NumberFormatException e) {
177
                logger.error("Can't Wkt.", e);
178
            }
179
        } else {
180
            String aux;
181
            String code2 = "";
182
            for (int i = 0; i < code.length(); i++) {
183
                aux = "" + code.charAt(i);
184
                if (!aux.equals(" ")) {
185
                    code2 += aux;
186
                } else {
187
                    code2 += "";
188
                }
189
            }
190
            crsWkt = new CrsWkt(code2);
191

    
192
            setName(fullCode);
193
            // setAbrev(crsWkt.getName());
194
            setAbrev(crsWkt.getAuthority()[0] + ":" + crsWkt.getAuthority()[1]);
195

    
196
        }
197
        // Asignar el datum y el crs base (en el caso de ser projectado):
198
        if (!(crsWkt.getSpheroid()[1].equals("") || crsWkt.getSpheroid()[2].equals(""))) {
199
            double eSemiMajorAxis = Double.valueOf(crsWkt.getSpheroid()[1]).doubleValue();
200
            double eIFlattening = Double.valueOf(crsWkt.getSpheroid()[2]).doubleValue();
201
            datum = new CRSDatum(eSemiMajorAxis, eIFlattening);
202

    
203
            // crs base (en el caso de ser projectado):
204
            /*
205
             * if(this.isProjected()){
206
             * String proj4Base = "+proj=latlong +a=" + crsWkt.getSpheroid()[1]
207
             * + " +rf=" + crsWkt.getSpheroid()[2] ;
208
             * crsBase = new CrsProj(proj4Base);
209
             * }
210
             */
211
        }
212
    }
213

    
214
    /**
215
     * Construye un CRS a partir del c?digo EPSG o de la cadena WKT.
216
     *
217
     * @param epsg_cod
218
     * @param code
219
     * @throws CrsException
220
     */
221
    public Crs(int epsg_cod, String code) throws CrsException {
222
//        String fullCode;
223
        setWKT(code);
224
        setCode(epsg_cod);
225
//        if (code != null || code.charAt(0) == 'E' || code.charAt(0) == 'G' || code.charAt(0) == 'P')
226
//            fullCode = code;
227
//        else
228
//            fullCode = "EPSG:" + code;
229

    
230
        SpatialReference sr = new SpatialReference();
231
//        Vector<String> vector = new Vector<String>();
232
//        vector.add(code);
233
//        sr.ImportFromWkt(vector);
234
        sr.ImportFromWkt(code);
235
        initFromSpatialReference(sr);
236

    
237
//        String cod = "";
238
//        if (code.length() < 15) {
239
//            code = code.substring(code.indexOf(":") + 1);
240
//            try {
241
//                // Creamos el objeto que tendra los diferentes parametros de la
242
//                // cadena Wkt
243
//                crsWkt = new CrsWkt(fullCode);
244
//                setName(fullCode);
245
//                setAbrev(fullCode);
246
//
247
//            } catch (NumberFormatException e) {
248
//                logger.error("Can't get Wkt.", e);
249
//            }
250
//        } else {
251
//            String aux;
252
//            String code2 = "";
253
//            for (int i = 0; i < code.length(); i++) {
254
//                aux = "" + code.charAt(i);
255
//                if (!aux.equals(" ")) {
256
//                    code2 += aux;
257
//                } else {
258
//                    code2 += "";
259
//                }
260
//            }
261
//            crsWkt = new CrsWkt(code2);
262
//            /*
263
//             * Arreglo temporal para ver si funcionan de la iau2000 las
264
//             * proyecciones
265
//             * cilindrica equidistante y oblicua cilindrica equidistante
266
//             * que no estan en gdal, por lo que asignaremos directamente su
267
//             * cadena
268
//             * en proj4 para trabajar con ellas
269
//             */
270
//            if (!crsWkt.getProjection().equals("Equidistant_Cylindrical")
271
//                && !crsWkt.getProjection().equals("Oblique_Cylindrical_Equal_Area")) {
272
//                setName(fullCode);
273
//                // setAbrev(crsWkt.getName());
274
//                setAbrev(crsWkt.getAuthority()[0] + ":" + crsWkt.getAuthority()[1]);
275
//            } else if (crsWkt.getProjection().equals("Equidistant_Cylindrical")) {
276
//                String spheroid1 = crsWkt.getSpheroid()[1];
277
//                String spheroid2 = crsWkt.getSpheroid()[2];
278
//                String centralMeridian = "";
279
//                String falseNorthing = "";
280
//                String falseEasting = "";
281
//                String standardParallel1 = "0.0";
282
//                for (int i = 0; i < crsWkt.getParam_name().length; i++) {
283
//                    if (crsWkt.getParam_name()[i].equals("Central_Meridian"))
284
//                        centralMeridian = crsWkt.getParam_value()[i];
285
//                    if (crsWkt.getParam_name()[i].equals("False_Easting"))
286
//                        falseEasting = crsWkt.getParam_value()[i];
287
//                    if (crsWkt.getParam_name()[i].equals("False_Northing"))
288
//                        falseNorthing = crsWkt.getParam_value()[i];
289
//                    if (crsWkt.getParam_name()[i].equals("Standard_Parallel_1"))
290
//                        standardParallel1 = crsWkt.getParam_value()[i];
291
//                }
292
//                if (spheroid2.equals("0.0")) {
293
//                    proj4String =
294
//                        "+proj=eqc +a=" + spheroid1 + " +lon_0=" + centralMeridian + " +x_0=" + falseEasting + " +y_0="
295
//                            + falseNorthing + " +lat_ts=" + standardParallel1;
296
//                } else {
297
//                    proj4String =
298
//                        "+proj=eqc +a=" + spheroid1 + " +rf=" + spheroid2 + " +lon_0=" + centralMeridian + " +x_0="
299
//                            + falseEasting + " +y_0=" + falseNorthing + " +lat_ts=" + standardParallel1;
300
//                }
301
//                setName(fullCode);
302
//                // setAbrev(crsWkt.getName());
303
//                setAbrev(crsWkt.getAuthority()[0] + ":" + crsWkt.getAuthority()[1]);
304
//
305
//            } else if (crsWkt.getProjection().equals("Oblique_Cylindrical_Equal_Area")) {
306
//                String spheroid1 = crsWkt.getSpheroid()[1];
307
//                String spheroid2 = crsWkt.getSpheroid()[2];
308
//                String centralMeridian = "";
309
//                String falseNorthing = "";
310
//                String falseEasting = "";
311
//                String standardParallel1 = "";
312
//                String standardParallel2 = "0.0";
313
//                for (int i = 0; i < crsWkt.getParam_name().length; i++) {
314
//                    if (crsWkt.getParam_name()[i].equals("Central_Meridian"))
315
//                        centralMeridian = crsWkt.getParam_value()[i];
316
//                    if (crsWkt.getParam_name()[i].equals("False_Easting"))
317
//                        falseEasting = crsWkt.getParam_value()[i];
318
//                    if (crsWkt.getParam_name()[i].equals("False_Northing"))
319
//                        falseNorthing = crsWkt.getParam_value()[i];
320
//                    if (crsWkt.getParam_name()[i].equals("Standard_Parallel_1"))
321
//                        standardParallel1 = crsWkt.getParam_value()[i];
322
//                    if (crsWkt.getParam_name()[i].equals("Standard_Parallel_2"))
323
//                        standardParallel2 = crsWkt.getParam_value()[i];
324
//                }
325
//                if (spheroid2.equals("0.0")) {
326
//                    proj4String =
327
//                        "+proj=ocea +a=" + spheroid1 + " +lon_0=" + centralMeridian + " +x_0=" + falseEasting
328
//                            + " +y_0=" + falseNorthing + " +lat_1=" + standardParallel1 + " +lat_2="
329
//                            + standardParallel2 + " +lon_1=long_1" + " +lon_2=long_2 +no_defs";
330
//                } else {
331
//                    proj4String =
332
//                        "+proj=ocea +a=" + spheroid1 + " +rf=" + spheroid2 + " +lon_0=" + centralMeridian + " +x_0="
333
//                            + falseEasting + " +y_0=" + falseNorthing + " +lat_1=" + standardParallel1 + " +lat_2="
334
//                            + standardParallel2 + " +lon_1=long_1" + " +lon_2=long_2 +no_defs";
335
//                }
336
//                setName(fullCode);
337
//                // setAbrev(crsWkt.getName());
338
//                setAbrev(crsWkt.getAuthority()[0] + ":" + crsWkt.getAuthority()[1]);
339
//            }
340
//        }
341
//        // Asignar el datum:
342
//        if (!(crsWkt.getSpheroid()[1].equals("") || crsWkt.getSpheroid()[2].equals(""))) {
343
//            double eSemiMajorAxis = Double.valueOf(crsWkt.getSpheroid()[1]).doubleValue();
344
//            double eIFlattening = Double.valueOf(crsWkt.getSpheroid()[2]).doubleValue();
345
//            datum = new CRSDatum(eSemiMajorAxis, eIFlattening);
346
//
347
//            // Crs base (en el caso de ser projectado):
348
//            /*
349
//             * if(this.isProjected()){
350
//             * String proj4Base = "+proj=latlong +a=" + crsWkt.getSpheroid()[1]
351
//             * + " +rf=" + crsWkt.getSpheroid()[2] ;
352
//             * crsBase = new CrsProj(proj4Base);
353
//             * }
354
//             */
355
//        }
356
    }
357

    
358
    /**
359
     * Construye un CRS a partir del c?digo EPSG o de la cadena WKT.
360
     * En el caso de WKT le a?ade a la cadena proj4 el string params.
361
     *
362
     * @param epsg_cod
363
     * @param code
364
     * @param params
365
     * @throws CrsException
366
     */
367
    public Crs(int epsg_cod, String code, String params) throws CrsException {
368
        String fullCode;
369
        setCode(epsg_cod);
370
        setWKT(code);
371
        if (code.charAt(0) == 'E' || code.charAt(0) == 'G' || code.charAt(0) == 'P')
372
            fullCode = code;
373
        else
374
            fullCode = "EPSG:" + code;
375
        if (code.length() < 15) {
376
            code = code.substring(code.indexOf(":") + 1);
377
            try {
378
                // Creamos el objeto que tendra los diferentes parametros de la
379
                // cadena Wkt
380
                crsWkt = new CrsWkt(fullCode);
381

    
382
                setName(fullCode);
383
                setAbrev(fullCode);
384

    
385
            } catch (NumberFormatException e) {
386
                logger.error("Can't get Wkt.", e);
387
            }
388
        } else {
389
            String aux;
390
            String code2 = "";
391
            for (int i = 0; i < code.length(); i++) {
392
                aux = "" + code.charAt(i);
393
                if (!aux.equals(" ")) {
394
                    code2 += aux;
395
                } else {
396
                    code2 += "";
397
                }
398
            }
399
            crsWkt = new CrsWkt(code2);
400

    
401
            setName(fullCode);
402
            // setAbrev(crsWkt.getName());
403
            setAbrev(crsWkt.getAuthority()[0] + ":" + crsWkt.getAuthority()[1]);
404

    
405
        }
406
        // Asignar el datum:
407
        if (!(crsWkt.getSpheroid()[1].equals("") || crsWkt.getSpheroid()[2].equals(""))) {
408
            double eSemiMajorAxis = Double.valueOf(crsWkt.getSpheroid()[1]).doubleValue();
409
            double eIFlattening = Double.valueOf(crsWkt.getSpheroid()[2]).doubleValue();
410
            datum = new CRSDatum(eSemiMajorAxis, eIFlattening);
411

    
412
            // Crs base (en el caso de ser projectado):
413
            /*
414
             * if(this.isProjected()){
415
             * String proj4Base = "+proj=latlong +a=" + crsWkt.getSpheroid()[1]
416
             * + " +rf=" + crsWkt.getSpheroid()[2] ;
417
             * crsBase = new CrsProj(proj4Base);
418
             * }
419
             */
420
        }
421
    }
422

    
423
    /*
424
     * public Crs(CrsEpsg source) throws CrsException {
425
     * crsProj4 = source;
426
     * }
427
     */
428

    
429
    /**
430
     * @param code
431
     */
432
    public void setTrans(String code) {
433
        trans = code;
434
        changeTrans(trans);
435
    }
436

    
437
    /**
438
     *
439
     * @param code
440
     */
441
    public void changeTrans(String code) {
442
        getCrsProj().changeStrCrs(code);
443
    }
444

    
445
    /**
446
         *
447
         */
448
    public String getAbrev() {
449
        return abrev;
450
    }
451

    
452
    /**
453
     *
454
     * @param code
455
     */
456
    protected void setAbrev(String code) {
457
        abrev = code;
458
    }
459

    
460
    /**
461
     *
462
     * @param nom
463
     */
464
    public void setName(String nom) {
465
        name = nom;
466
    }
467

    
468
    /**
469
     * @return datum
470
     */
471
    public IDatum getDatum() {
472

    
473
        return datum;
474
    }
475

    
476
    /**
477
     * @return CrsWkt
478
     */
479
    public CrsWkt getCrsWkt() {
480
        return crsWkt;
481
    }
482

    
483
    /**
484
     *
485
     * @param wkt
486
     */
487
    public void setWKT(String wkt) {
488
        this.wkt = wkt;
489
    }
490

    
491
    /**
492
     * @return wkt
493
     */
494
    public String getWKT() {
495
        return this.wkt;
496
    }
497

    
498
    /**
499
     *
500
     * @param params
501
     */
502
    public void setTransformationParams(String sourceParams, String targetParams) {
503
        this.sourceTrParams = sourceParams;
504
        this.targetTrParams = targetParams;
505
    }
506

    
507
    /**
508
     * Devuelve los parametros de la transformacion del crs fuente
509
     *
510
     * @return source transformation parameters
511
     */
512
    public String getSourceTransformationParams() {
513
        return this.sourceTrParams;
514
    }
515

    
516
    /**
517
     * Devuelve los parametros de la transformacion del crs destino
518
     *
519
     * @return target transformation parameters
520
     */
521
    public String getTargetTransformationParams() {
522
        return this.targetTrParams;
523
    }
524

    
525
    /**
526
     * @return transformation parameters
527
     */
528
    public String getTransformationParams() {
529
        return this.sourceTrParams;
530
    }
531

    
532
    /**
533
     *
534
     * @return CrsProj
535
     */
536
    public CrsProj getCrsProj() {
537
        if (crsProj == null)
538
            try {
539
                crsProj = new CrsProj(getProj4String());
540
            } catch (CrsException e) {
541
                logger.error("Can't get proj4 string.", e);
542
            }
543
        return crsProj;
544
    }
545

    
546
    /**
547
     * @param x
548
     * @param y
549
     * @return a Point2D
550
     */
551
    public Point2D createPoint(double x, double y) {
552
        return new Point2D.Double(x, y);
553
    }
554

    
555
    /**
556
     * @param g
557
     * @param vp
558
     */
559
    public void drawGrid(Graphics2D g, ViewPortData vp) {
560
        // TODO Auto-generated method stub
561

    
562
    }
563

    
564
    /**
565
     * @param c
566
     */
567
    public void setGridColor(Color c) {
568
        gridColor = c;
569
    }
570

    
571
    /**
572
     * @return grid color
573
     */
574
    public Color getGridColor() {
575
        return gridColor;
576
    }
577

    
578
    /**
579
     * @param dest
580
     * @return Coordinate transformation
581
     */
582
    public ICoordTrans getCT(IProjection dest) {
583

    
584
        try {
585
            if (dest == this)
586
                return null;
587
            COperation operation = null;
588
            if (((ICrs) dest).getSourceTransformationParams() != null
589
                || ((ICrs) dest).getTargetTransformationParams() != null)
590
                operation =
591
                    new COperation(this, (ICrs) dest, ((ICrs) dest).getTargetTransformationParams(),
592
                        ((ICrs) dest).getSourceTransformationParams());
593
            else
594
                operation = new COperation(this, (ICrs) dest, sourceTrParams, targetTrParams);
595
            return operation;
596
        } catch (CrsException e) {
597
            logger.error("Can't get CoordTrans.", e);
598
            return null;
599
        }
600

    
601
        /*
602
         * try {
603
         * operation = new COperation(this, (ICrs)dest);
604
         * } catch (CrsException e) {
605
         * // TODO Auto-generated catch block
606
         * logger....
607
         * }
608
         *
609
         * if (getTransformationParams()!=null){
610
         * if (isTargetParams())
611
         * operation.setParamsCrsProj(new
612
         * CrsProj(crsDest.getProj4String()+getTransformationParams()), true);
613
         * else
614
         * operation.setParamsCrsProj(new
615
         * CrsProj(getProj4String()+getTransformationParams()), false);
616
         *
617
         * return operation;
618
         * }
619
         *
620
         * return operation;
621
         */
622
    }
623

    
624
    /**
625
     * @param pt
626
     * @return Point2D
627
     */
628
    public Point2D toGeo(Point2D pt) {
629
        if (isProjected()) {
630
            double x[] = { pt.getX() };
631
            double y[] = { pt.getY() };
632
            double z[] = { 0D };
633
            try {
634
                CrsProj.operate(x, y, z, getCrsProj(), crsBase);
635
            } catch (OperationCrsException e) {
636
                logger.error("Can't convert point to geo.", e);
637
            }
638
            return new Point2D.Double(x[0], y[0]);
639
        } else
640
            return pt;
641
    }
642

    
643
    /**
644
     * @param gPt
645
     * @param mPt
646
     * @return Point2D
647
     */
648
    public Point2D fromGeo(Point2D gPt, Point2D mPt) {
649
        // TODO Auto-generated method stub
650
        return null;
651
    }
652

    
653
    /**
654
     * @return true if is projected
655
     */
656
    public boolean isProjected() {
657
        return !getCrsProj().isLatlong();
658
    }
659

    
660
    /**
661
     * @param minX
662
     * @param maxX
663
     * @param width
664
     * @param dpi
665
     * @return scale
666
     */
667
    public double getScale(double minX, double maxX, double width, double dpi) {
668
        double scale = 0D;
669
        // Esto ahora se hace fuera
670
        // if (!isProjected()) { // Es geogr?fico; calcula la escala.
671
        // scale = ((maxX - minX) * // grados
672
        //
673
        // // 1852.0 metros x minuto de meridiano
674
        // (dpi / 2.54 * 100.0 * 1852.0 * 60.0)) / // px / metro
675
        // width; // pixels
676
        // }
677
        // else{
678
        scale = ((maxX - minX) * // metros
679
            (dpi / 2.54 * 100.0))
680
            / // px / metro
681
            width; // pixels
682
        // }
683
        return scale;
684
    }
685

    
686
    /**
687
     * @param minX
688
     * @param maxX
689
     * @param minY
690
     * @param maxY
691
     * @param width
692
     * @param dpi
693
     * @return scale
694
     */
695
    public double getScale(double minX, double maxX, double minY, double maxY, double width, double dpi) {
696

    
697
        double scale = 0D;
698
        double incX = (maxX - minX);
699

    
700
        if (!isProjected()) {
701
            double a = getDatum().getESemiMajorAxis();
702
            double invF = getDatum().getEIFlattening();
703
            double meanY = (minY + maxY) / 2.0;
704
            double radius = 0.0;
705

    
706
            if (invF == Double.POSITIVE_INFINITY) {
707
                radius = a;
708
            } else {
709
                double e2 = 2.0 / invF - Math.pow(1.0 / invF, 2.0);
710
                radius =
711
                    a / Math.sqrt(1.0 - e2 * Math.pow(Math.sin(meanY * Math.PI / 180.0), 2.0))
712
                        * Math.cos(meanY * Math.PI / 180.0);
713
            }
714
            incX *= Math.PI / 180.0 * radius;
715
        }
716

    
717
        scale = (incX * // metros
718
            (dpi / 2.54 * 100.0))
719
            / // px / metro
720
            width; // pixels
721

    
722
        return scale;
723
    }
724

    
725
    /**
726
     *
727
     * @param epsg_cod
728
     */
729
    public void setCode(int epsg_cod) {
730
        epsg_code = epsg_cod;
731
    }
732

    
733
    /**
734
     * @return espg code
735
     */
736
    public int getCode() {
737
        // TODO Auto-generated method stub
738
        return epsg_code;
739
    }
740

    
741
    public String getFullCode() {
742
        if (this.sourceTrParams == null && this.targetTrParams == null)
743
            return getAbrev();
744
        String sourceParams = "";
745
        String targetParams = "";
746
        if (sourceTrParams != null)
747
            sourceParams = sourceTrParams;
748
        if (targetTrParams != null)
749
            targetParams = targetTrParams;
750

    
751
        return getAbrev() + ":proj@" + sourceParams + "@" + targetParams;
752
    }
753

    
754
    public Rectangle2D getExtent(Rectangle2D extent, double scale, double wImage, double hImage, double mapUnits,
755
        double distanceUnits, double dpi) {
756
        double w = 0;
757
        double h = 0;
758
        double wExtent = 0;
759
        double hExtent = 0;
760
        // if (isProjected()) {
761
        w = ((wImage / dpi) * 2.54);
762
        h = ((hImage / dpi) * 2.54);
763
        wExtent = w * scale * distanceUnits / mapUnits;
764
        hExtent = h * scale * distanceUnits / mapUnits;
765

    
766
        // En las no proyectadas, ahora viene el calculo hecho
767
        // al haber incluido los grados en el array DISTANCETRANS2METER del
768
        // MapContext
769
        // }else {
770
        // w = ((wImage / dpi) * 2.54);
771
        // h = ((hImage / dpi) * 2.54);
772
        // wExtent =(w*scale*distanceUnits)/ (mapUnits*1852.0*60.0);
773
        // hExtent =(h*scale*distanceUnits)/ (mapUnits*1852.0*60.0);
774
        // }
775
        double xExtent = extent.getCenterX() - wExtent / 2;
776
        double yExtent = extent.getCenterY() - hExtent / 2;
777
        Rectangle2D rec = new Rectangle2D.Double(xExtent, yExtent, wExtent, hExtent);
778
        return rec;
779
    }
780

    
781
    private Proj4 getProj4() {
782
        if (proj4 == null)
783
            try {
784
                proj4 = new Proj4();
785
            } catch (CrsException e) {
786
                logger.error("Can't create Proj4 instance.", e);
787
            }
788
        return proj4;
789
    }
790

    
791
    /**
792
     *
793
     * @return Cadena proj4 Correspondiente al CRS.
794
     * @throws CrsException
795
     */
796
    public String getProj4String() throws CrsException {
797
        if (proj4String == null)
798
            proj4String = getProj4().exportToProj4(this);
799
        return proj4String;
800
    }
801

    
802
    public Object clone() throws CloneNotSupportedException {
803
        return CRSFactory.getCRS(this.getFullCode());
804
    }
805

    
806
    public String toString() {
807
        return MessageFormat.format("{0}({1},{2})",
808
            new Object[] { this.getClass().getName(), this.hashCode(), this.getFullCode() });
809
    }
810

    
811
    /*
812
     * (non-Javadoc)
813
     *
814
     * @see org.cresques.cts.IProjection#export(java.lang.String)
815
     */
816
    public String export(String format) {
817
        if (this.spatialReference != null) {
818
            if (format.equalsIgnoreCase(ICRSFactory.FORMAT_PROJ4)) {
819
                return spatialReference.ExportToProj4();
820
            } else if (format.equalsIgnoreCase(ICRSFactory.FORMAT_WKT_ESRI)) {
821
                if (spatialReference.MorphToESRI() == 0) {
822
                    return spatialReference.ExportToWkt();
823
                }
824
                return null;
825
            } else if (format.equalsIgnoreCase(ICRSFactory.FORMAT_WKT)) {
826
                return spatialReference.ExportToWkt();
827
            } else {
828
                return null;
829
            }
830
        } else {
831

    
832
            SpatialReference spatialReference = getCrsProj().getSpatialReference();
833
            SpatialReference auxSpatialReference = new SpatialReference();
834
            if (format.equalsIgnoreCase(ICRSFactory.FORMAT_PROJ4)) {
835
                String proj4 = spatialReference.ExportToProj4();
836
                auxSpatialReference.ImportFromProj4(proj4);
837
                if (auxSpatialReference.GetAuthorityName(null) != null) {
838
                    return proj4;
839
                }
840
                return null;
841
            } else if (format.equalsIgnoreCase(ICRSFactory.FORMAT_WKT_ESRI)) {
842
                if (spatialReference.MorphToESRI() == 0) {
843
                    String esri = spatialReference.ExportToWkt();
844
                    Vector<String> vector = new Vector<String>();
845
                    vector.add(esri);
846
                    auxSpatialReference.ImportFromESRI(vector);
847
                    auxSpatialReference.MorphFromESRI();
848
                    if (auxSpatialReference.GetAuthorityName(null) != null) {
849
                        return esri;
850
                    }
851
                    return null;
852
                }
853
                return null;
854
            } else if (format.equalsIgnoreCase(ICRSFactory.FORMAT_WKT)) {
855
                String wkt = spatialReference.ExportToWkt();
856
                auxSpatialReference.ImportFromWkt(wkt);
857
                if (auxSpatialReference.GetAuthorityName(null) != null) {
858
                    return wkt;
859
                }
860
                return null;
861
            } else {
862
                return null;
863
            }
864
        }
865
    }
866

    
867
    @Override
868
    public boolean equals(Object obj) {
869
        if( this == obj ) {
870
            return true;
871
        }
872
        if( !(obj instanceof Crs) ) {
873
            return false;
874
        }
875
        return this.getFullCode().equalsIgnoreCase(((Crs)obj).getFullCode());
876
    }
877

    
878
    @Override
879
    public int hashCode() {
880
        return this.getFullCode().hashCode();
881
    }
882
}