Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1012 / libraries / libJCRS / src / org / gvsig / crs / ogr / GetCRSepsg.java @ 12987

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

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

    
46
import org.gvsig.crs.EpsgConnection;
47
import org.gvsig.crs.Query;
48

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

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