Statistics
| Revision:

svn-gvsig-desktop / branches / F2 / libraries / libJCRS / src / org / gvsig / crs / ogr / CrsEPSG.java @ 12609

History | View | Annotate | Download (15.4 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.ogr;
42

    
43
import java.sql.ResultSet;
44
import java.sql.SQLException;
45

    
46

    
47
import es.idr.teledeteccion.connection.EpsgConnection;
48
import es.idr.teledeteccion.connection.Query;
49

    
50
/**
51
 * Clase que consigue los par?metros necesarios de la base de
52
 * datos de la EPSG una vez escogido un CRS, y que ser?n
53
 * los que se utilicen para la generaci?n de la cadena wkt
54
 * correcta para generar el CRS.
55
 * 
56
 * @author Jos? Luis G?mez Mart?nez (jolugomar@gmail.com)
57
 *
58
 */
59
public class CrsEPSG {
60
        
61
        int epsg_code;
62
        boolean crs_source;
63
        int source_code;
64
        int projection_code;        
65
        int coord_op_code;        
66
        
67
                
68
        int datum_code;
69
        int ellipsoid_code, prime_meridian_code;
70
        
71
        String PROJCS = null;
72
        String GEOGCS = null;
73
        String DATUM = null;
74
        String[] SPHEROID = null;
75
        String[] PRIMEM = null;
76
        String UNIT_A = "degree";
77
        String UNIT_B = "Meter";
78
        String PROJECTION = null;
79
        //ArrayList PARAMETER = null;
80
        String[] param_name = null;
81
        String[] param_value = null;
82
        String[] AUTHORITY = null;
83
        EpsgConnection connect;
84
        
85
        public CrsEPSG(){                
86
        }        
87
        
88
        public CrsEPSG(int code, boolean source_yn, int source_cod, int coord_op_cod, EpsgConnection conn){
89
                epsg_code = code;
90
                crs_source = source_yn;
91
                source_code = source_cod;                
92
                coord_op_code = coord_op_cod;
93
                connect = conn;
94
                SPHEROID = new String[3];
95
                PRIMEM = new String[2];
96
                AUTHORITY = new String[2];
97
                initialize();
98
        }
99
        
100
        public void initialize(){
101
                ResultSet result;
102
                ResultSet result2;
103
                /*
104
                 * Si es base solamente realizamos una consulta, y ya tenemos el Datum
105
                 * (ver en caso de ser fuente que PROJCS no tiene que estar definido)
106
                 */
107
                if (crs_source){
108
                        String sentence = "SELECT coord_ref_sys_name, datum_code " +
109
                                                          "FROM epsg_coordinatereferencesystem " +                                      
110
                                                          "WHERE coord_ref_sys_code = " + epsg_code;
111
                        result = Query.select(sentence,connect.getConnection());
112
                        try {
113
                                while (result.next()){
114
                                        GEOGCS = result.getString("coord_ref_sys_name");
115
                                        datum_code = Integer.parseInt(result.getString("datum_code"));                                        
116
                                }
117
                        } catch (SQLException e) {
118
                                e.printStackTrace();
119
                        }                        
120
                }
121
                else{
122
                        String sentence = "SELECT coord_ref_sys_name " +
123
                                                          "FROM epsg_coordinatereferencesystem " +                                      
124
                                                          "WHERE coord_ref_sys_code = " + epsg_code;
125
                        result = Query.select(sentence,connect.getConnection());
126
                        
127
                        String sentence2 = "SELECT coord_ref_sys_name, datum_code " +
128
                                                          "FROM epsg_coordinatereferencesystem " +                                      
129
                                                          "WHERE coord_ref_sys_code = " + source_code;
130
                        result2 = Query.select(sentence2,connect.getConnection());
131
                        
132
                        try {
133
                                while (result.next()){
134
                                        PROJCS = result.getString("coord_ref_sys_name");                                        
135
                                }
136
                                while (result2.next()){
137
                                        datum_code = Integer.parseInt(result2.getString("datum_code"));
138
                                        GEOGCS = result2.getString("coord_ref_sys_name");
139
                                }
140
                        } catch (SQLException e) {
141
                                e.printStackTrace();
142
                        }
143
                }
144
                /*
145
                 * hasta aqui hemos rellenado projcs, geocs y tenemos el codigo de datum
146
                 * vamos a obtener los c?digos del elipsoide y el prime_meridian
147
                 */
148
                String sentence = "SELECT datum_name, ellipsoid_code, prime_meridian_code " +
149
                                                  "FROM epsg_datum " +                                      
150
                                                  "WHERE datum_code = " + datum_code;
151
                result = Query.select(sentence,connect.getConnection());
152
                try {
153
                        while (result.next()){
154
                                DATUM = result.getString("datum_name");
155
                                ellipsoid_code = Integer.parseInt(result.getString("ellipsoid_code"));        
156
                                prime_meridian_code = Integer.parseInt(result.getString("prime_meridian_code"));
157
                        }                        
158
                } catch (SQLException e) {
159
                        e.printStackTrace();
160
                }
161
                
162
                /*
163
                 * Ahora vamos a coger varios campos del elipsoide y operaremos con ellos, si la
164
                 * informaci?n de los mismos no esta en las unidades de medida que utilizaremos.
165
                 */
166
                sentence = "SELECT ellipsoid_name, semi_major_axis, inv_flattening, uom_code, " +
167
                                        "semi_minor_axis, ellipsoid_shape " +
168
                                          "FROM epsg_ellipsoid " +                                      
169
                                          "WHERE ellipsoid_code = " + ellipsoid_code;
170
                result = Query.select(sentence,connect.getConnection());
171
                
172
                SPHEROID = getEllipsoid(result);
173
                
174
                sentence = "SELECT prime_meridian_name, greenwich_longitude, uom_code " +
175
                                          "FROM epsg_primemeridian " +                                      
176
                                          "WHERE prime_meridian_code = " + prime_meridian_code;
177
                result = Query.select(sentence,connect.getConnection());
178
                
179
                PRIMEM = getPrimeMeridian(result);
180
                AUTHORITY = getAuthority(epsg_code);
181
                /*
182
                 * si tiene proyecci?n porque es proyectado, la buscamos
183
                 */
184
                if (!crs_source){                        
185
                        sentence = "SELECT coord_op_method_code " +
186
                                                "FROM epsg_coordoperation " +
187
                                                "WHERE coord_op_code = " + coord_op_code;
188
                        result = Query.select(sentence,connect.getConnection());
189
                        try {
190
                                while (result.next()){
191
                                        projection_code = result.getInt("coord_op_method_code");
192
                                }
193
                        } catch (SQLException e) {
194
                                e.printStackTrace();
195
                        }
196
                        
197
                        
198
                        sentence = "SELECT coord_op_method_name " +
199
                                                  "FROM epsg_coordoperationmethod " +                                      
200
                                                  "WHERE coord_op_method_code = " + projection_code;
201
                        result = Query.select(sentence,connect.getConnection());
202
                        try {
203
                                while (result.next()){
204
                                        PROJECTION = result.getString("coord_op_method_name");                                
205
                                }                        
206
                        } catch (SQLException e) {
207
                                e.printStackTrace();
208
                        }
209
                        
210
                        parameters(projection_code);
211
                }
212
                /*
213
                 * Una vez que tengo todo, hago la llamada al constructor de Epsg2wkt para pasarle los
214
                 * parametros y realizar la cadena
215
                 * CAMBIARLO Y PONER METODOS getXXX para todos los parametros para hacerlo mas generico
216
                         
217
                if (crs_source){
218
                        cadwkt = new Epsg2wkt(0);
219
                }
220
                else{
221
                        cadwkt = new Epsg2wkt();
222
                }
223
                */
224
        }
225
        
226
        /**
227
         * Cuando recuperamos el elipsoide del CRS que hemos seleccionado,
228
         * buscamos sus par?metros, los pasamos a las unidades correctas
229
         * y devolvemos un array de string con el nombre y los valores
230
         * del esferoide.
231
         * @param result
232
         * @return
233
         */
234
        private String[] getEllipsoid(ResultSet result) {
235
                String[] spheroid = new String[3];                
236
                double semi_major_axis = 0;
237
                double semi_minor_axis = 0;
238
                double inv_flattening = 0;
239
                int uom_code = 0;
240
                int ellipsoid_shape = 0;
241
                
242
                try {
243
                        while (result.next()){
244
                                spheroid[0] = result.getString("ellipsoid_name");
245
                                semi_major_axis = result.getDouble("semi_major_axis");
246
                                semi_minor_axis = result.getDouble("semi_minor_axis");
247
                                inv_flattening = result.getDouble("inv_flattening");
248
                                uom_code = result.getInt("uom_code");
249
                                ellipsoid_shape = result.getInt("ellipsoid_shape");
250
                        }                        
251
                } catch (SQLException e) {
252
                        e.printStackTrace();
253
                }
254
                
255
                /*
256
                 * pasaremos a metros las unidades del semi_major_axis, semi_minor_axis
257
                 */
258
                String sentence = "SELECT factor_b, factor_c " +
259
                                                  "FROM epsg_unitofmeasure " +                                      
260
                                                  "WHERE uom_code = " + uom_code;
261
                ResultSet result2 = Query.select(sentence,connect.getConnection());
262
                
263
                double factor_b = 0;
264
                double factor_c = 0;
265
                try{                        
266
                        while (result2.next()){
267
                                factor_b = result2.getDouble("factor_b");
268
                                factor_c = result2.getDouble("factor_c");                                
269
                        }
270
                } catch (SQLException e) {
271
                        e.printStackTrace();
272
                }
273
                if (factor_b != 0 && factor_c != 0 ){
274
                        semi_major_axis = (semi_major_axis * factor_b)/ factor_c;
275
                        if (semi_minor_axis != 0){
276
                                semi_minor_axis = (semi_minor_axis * factor_b) / factor_c;
277
                        }
278
                }
279
                /*
280
                 * calculamos inv_flattening en caso de que sea nulo
281
                 */
282
                if (inv_flattening == 0){
283
                        if (ellipsoid_shape == 0){
284
                                inv_flattening = 0;
285
                        }
286
                        else{
287
                                inv_flattening = (semi_major_axis) / (semi_major_axis - semi_minor_axis);
288
                        }
289
                }                
290
                spheroid[1] = ""+semi_major_axis;
291
                spheroid[2] = ""+inv_flattening;
292
                
293
                return spheroid;
294
        }
295

    
296
        /**
297
         * Este m?todo acepta un result en el que tenemos los par?metros
298
         * del PrimeMeridian, se hace la conversi?n a las unidades correctas
299
         * y se devuelve un array de String con el nombre y los par?metros 
300
         * pertenecientes a PrimeMeridian.
301
         * @param result
302
         * @return
303
         */
304
        private String[] getPrimeMeridian(ResultSet result) {
305
                String[] primem = new String[2];
306
                double greenwich_longitude = 0;
307
                
308
                try {
309
                        while (result.next()){
310
                                primem[0] = result.getString("prime_meridian_name");
311
                                greenwich_longitude = result.getDouble("greenwich_longitude");
312
                                int co= Integer.parseInt((String)result.getString("uom_code"));
313
                                /*
314
                                 * Realizamos este cambio de meridiano origen de la unidad de la epsg
315
                                 * a degrees, para insertarlo en este formato en wkt
316
                                 */
317
                                ResultSet result2 = null;
318
                                if (co != 9110){
319
                                        String sentence = "SELECT factor_b, factor_c " +
320
                                          "FROM epsg_unitofmeasure " +                                      
321
                                          "WHERE uom_code = " + co;
322
                                        result2 = Query.select(sentence,connect.getConnection());
323
                                        
324
                                        while(result.next()){                                                
325
                                                greenwich_longitude = ((greenwich_longitude * result2.getDouble("factor_b") )/ result2.getDouble("factor_c")) * (180.0 / Math.PI);
326
                                        }                                        
327
                                }
328
                        }
329
                } catch (SQLException e) {
330
                        e.printStackTrace();
331
                }
332
                
333
                primem[1] = ""+greenwich_longitude;
334
                return primem;
335
        }
336
        
337
        /**
338
         * M?todo para bucar los par?metros de la proyecci?n que
339
         * se est? utilizando. Se rellenan las variables param_name y
340
         * param_value con los datos de la proyecci?n utilizada.
341
         * @param proj
342
         */
343
        private void parameters(int proj) {
344
                /*
345
                 * para la consecucion de los parametros se tiene que ir buscando dependiendo de la
346
                 * proyeccion que se utilice, hay que ver que parametros exactos tiene cada uno de ellos
347
                 * y si hay mas de 17, que son los que se utilizan en WKT, como vamos a tratarlos, mensaje
348
                 * de error, intentar no mostrarlos, o simplemente pasar de ellos
349
                 */                
350
                                        
351
                ResultSet result;
352
                ResultSet result2;
353
                ResultSet result3;
354
                
355
                /*
356
                 * Conseguimos la lista de parametros y valores, ordenados segun sort_order de manera
357
                 * ascendente por lo que coincidiram siempre param_name[i] y param_value[i]
358
                 */
359
                String sentence = "SELECT COUNT(*) " +
360
                                "FROM epsg_coordoperationparamusage " +
361
                                "WHERE coord_op_method_code = " + proj;
362
                result = Query.select(sentence,connect.getConnection());
363
                
364
                int count = 0;
365
                try {
366
                        result.next();
367
                        count = result.getInt(1);
368
                } catch (SQLException e1) {
369
                        e1.printStackTrace();
370
                }                
371
                param_name = new String[count];
372
                param_value = new String[count];
373
                
374
                sentence = "SELECT parameter_code " +
375
                "FROM epsg_coordoperationparamusage " +
376
                "WHERE coord_op_method_code = " + proj + " " +
377
                                "ORDER BY sort_order ASC";
378
                result = Query.select(sentence,connect.getConnection());
379
                
380
                int i = 0;
381
                try {
382
                        while (result.next()) {
383
                                
384
                                int cod = result.getInt("parameter_code");
385
                                /*
386
                                 * con el codigo del parametro, obtenemos tanto su nombre como su valor
387
                                 */
388
                                sentence = "SELECT parameter_name " +
389
                                                "FROM epsg_coordoperationparam " +
390
                                                "WHERE parameter_code = " + cod;
391
                                result2 = Query.select(sentence,connect.getConnection());
392
                                
393
                                result2.next();
394
                                param_name[i] = result2.getString("parameter_name");
395
                                
396
                                sentence = "SELECT parameter_value, uom_code " +
397
                                                "FROM epsg_coordoperationparamvalue " +
398
                                                "WHERE parameter_code = " + cod + " AND coord_op_code = " + coord_op_code;
399
                                result3 = Query.select(sentence,connect.getConnection());
400
                                
401
                                result3.next();
402
                                double param_val = result3.getDouble("parameter_value");
403
                                int uom_code = result3.getInt("uom_code");
404
                                
405
                                sentence = "SELECT factor_b, factor_c, unit_of_meas_type " +
406
                                                  "FROM epsg_unitofmeasure " +                                      
407
                                                  "WHERE uom_code = " + uom_code;
408
                                ResultSet result4 = Query.select(sentence,connect.getConnection());
409
                                
410
                                double factor_b = 0;
411
                                double factor_c = 0;                                
412
                                result4.next();
413
                                String type = result4.getString("unit_of_meas_type");
414
                                factor_b = result4.getDouble("factor_b");
415
                                factor_c = result4.getDouble("factor_c");                                
416
                                                                
417
                                if (factor_b != 0 && factor_c != 0 && !type.equals("angle")){
418
                                        param_val = (param_val * factor_b) / factor_c;
419
                                }
420
                                else if(factor_b != 0 && factor_c != 0 && type.equals("angle")){
421
                                        param_val = ((param_val * factor_b) / factor_c) * (180.0 / Math.PI);;
422
                                }else if (uom_code == 9110){
423
                                        param_val = especialDegree(param_val);
424
                                        param_val = Math.toDegrees(param_val);
425
                                }else {
426
                                        System.out.println("C?digo de medida no v?lido...");                                        
427
                                }                                
428
                                param_value[i] = ""+param_val;
429
                                
430
                                i++;
431
                        }
432
                } catch (SQLException e) {
433
                        e.printStackTrace();
434
                }
435
                        
436
        }        
437
        
438
        /**
439
         * M?todo para pasar a las unidades correctas el valor de los distintos
440
         * par?metros de la proyecci?n.
441
         * @param val
442
         * @return
443
         */
444
        private double especialDegree(double val){
445
                if(val==0)
446
                        return val;
447
                int signo = 1;
448
                if (val < 0){
449
                        signo = -1;
450
                        val = Math.abs(val);
451
                }                
452
                String strValue=String.valueOf(val);
453
                int posPto=strValue.indexOf('.');
454
                double grad=Double.parseDouble(strValue.substring(0,posPto));
455
                String strFraction=strValue.substring(posPto+1);
456
                double min=0;
457
                double sec=0;
458
                if(strFraction.length()==1)
459
                {
460
                        min=Double.parseDouble(strFraction);
461
                        min*=10;
462
                }
463
                if(strFraction.length()==2)
464
                {
465
                        min=Double.parseDouble(strFraction);
466
                }
467
                if(strFraction.length()>2)
468
                {
469
                        min=Double.parseDouble(strFraction.substring(0,2));
470
                        sec=Double.parseDouble(strFraction.substring(2));
471
                        if(strFraction.length()==3)
472
                                sec*=10;
473
                        if(strFraction.length()>4){
474
                                for(int i=0;i<strFraction.length()-4;i++)
475
                                        sec=sec/10.0;
476
                        }
477
                        
478
                }
479
                
480
                
481
/*                grad = Math.floor(val);
482
                val=(val-grad)*100.0;
483
                min=Math.floor(val);
484
                sec=(val-min)*100.0;
485
*/                
486
                val = ((grad + (min/60.0) + (sec/3600.0)) * (Math.PI/180.0)) * signo;
487
                
488
                return val;
489
        }        
490
        
491
        /**
492
         * Genera el authority del CRS
493
         * @param epsg_cod
494
         * @return
495
         */        
496
        private String[] getAuthority(int epsg_cod) {
497
                String[] aut = new String[2];
498
                aut[0] = "EPSG";
499
                aut[1] = ""+epsg_cod;
500
                return aut;
501
        }
502
        
503
        public String getPROJCS(){
504
                return PROJCS;
505
        }
506
        
507
        public String getGEOGCS(){
508
                return GEOGCS;
509
        }
510
        
511
        public String getDATUM(){
512
                return DATUM;
513
        }
514
        
515
        public String[] getSPHEROID(){
516
                return SPHEROID;
517
        }
518
        
519
        public String[] getPRIMEM(){
520
                return PRIMEM;
521
        }
522
        
523
        public String getUNIT_A(){
524
                return UNIT_A;
525
        }
526
        
527
        public String getPROJECTION(){
528
                return PROJECTION;
529
        }
530
        
531
        public String[] getParam_name(){
532
                return param_name;
533
        }
534
        
535
        public String[] getParam_value(){
536
                return param_value;
537
        }
538
        
539
        public String getUNIT_B(){
540
                return UNIT_B;
541
        }        
542
        
543
        public String[] getAUTHORITY(){
544
                return AUTHORITY;
545
        }
546
}