Revision 44430

View differences:

trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/SQLLexicalAnalyzer.java
214 214
        
215 215
        case '@':
216 216
            ungetch();
217
            parseSpecialNumber();
217
            parseDMSNumber();
218 218
            return token;
219 219
        }
220 220
        
trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/test/java/org/gvsig/expresionevaluator/impl/TestInterpreter.java
94 94

  
95 95
        Code code = compiler.compileExpression(source);
96 96
        Object v = interpreter.run(code);
97
        assertEquals(-10.5003, Math.round(((Number)v).doubleValue()*10000d)/10000d);
97
        assertEquals(10.5003, Math.round(((Number)v).doubleValue()*10000d)/10000d);
98

  
99
        source = "@10 30 0.09 N";
100

  
101
        code = compiler.compileExpression(source);
102
        v = interpreter.run(code);
103
        assertEquals(10.500025, Math.round(((Number)v).doubleValue()*1000000d)/1000000d);
104

  
105
        source = "@10 30 0.09 S";
106

  
107
        code = compiler.compileExpression(source);
108
        v = interpreter.run(code);
109
        assertEquals(-10.500025, Math.round(((Number)v).doubleValue()*1000000d)/1000000d);
110

  
111
        source = "@+10 30 0.09";
112

  
113
        code = compiler.compileExpression(source);
114
        v = interpreter.run(code);
115
        assertEquals(10.500025, Math.round(((Number)v).doubleValue()*1000000d)/1000000d);
116

  
117
        source = "@-10 30 0.09";
118

  
119
        code = compiler.compileExpression(source);
120
        v = interpreter.run(code);
121
        assertEquals(-10.500025, Math.round(((Number)v).doubleValue()*1000000d)/1000000d);
122

  
98 123
    }
99 124
    
100 125
    public void testTrue() {
trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.api/src/main/java/org/gvsig/expressionevaluator/spi/AbstractLexicalAnalyzer.java
313 313
        token.set(Token.STRING_LITERAL, buffer.toString());
314 314
    }
315 315

  
316
    protected void parseSpecialNumber() {
317
        char ch = getch();
318
        if( ch!='@' ) {
319
            throw new ExpressionSyntaxException(I18N.Wrong_special_number_start(), this);
320
        }
321
        buffer.clear();
322
        ch = getch();
323
        while (true) {
324
            if (ch == EOF) {
325
                throw new ExpressionSyntaxException(I18N.End_of_string_was_expected_and_end_of_source_was_found(), this);
326
            }
327
            if( !Character.isAlphabetic(ch) ) {
328
                break;
329
            }
330
            buffer.add(ch);
331
            ch = getch();
332
        }
333
        String formatName = buffer.toString();
334
        if( StringUtils.isBlank(formatName) ) {
335
            formatName = "DMS";
336
        }
337
        formatName = formatName.toUpperCase();
338
        /*
339
        From https://es.wikipedia.org/wiki/Sistema_de_coordenadas#Coordenadas_geogr%C3%A1ficas
340
        
341
        DD --- Decimal Degree (Grados Polares)
342
        DM --- Degree:Minute (Grados:Minutos)
343
        DMS -- Degree:Minute:Second 
344
        */
345
        switch(formatName) {
346
            case "DMS":
347
                ungetch();
348
                parseDMSNumber();
349
                break;
350
            default:
351
                throw new ExpressionSyntaxException(I18N.Special_number_format_not_supported(formatName), this);
352
        }
353
    }
354

  
355
    private void parseDMSNumber() {
316
    protected void parseDMSNumber() {
356 317
        int d;
357 318
        int m;
358 319
        int s_i;
359
        int s_d;
320
        double s_d;
360 321
        double s;
361
        String ll;
362 322
        char ch;
323
        Integer sign = null;
363 324
        
325
        skipblanks();
326
        ch = getch();
327
        if( ch!='@' ) {
328
            throw new ExpressionSyntaxException(I18N.Wrong_special_number_start(), this);
329
        }
330
        
364 331
        // Parseamos los grados
365 332
        skipblanks();
366 333
        ch = getch();
334
        if( ch=='+' ) {
335
            sign = 1;
336
            ch = getch();
337
        } else if ( ch=='-' ) {
338
            sign = -1;
339
            ch = getch();
340
        }
341
        
367 342
        buffer.clear();
368 343
        if( !Character.isDigit(ch) ) {
369 344
            throw new ExpressionSyntaxException(I18N.Expected_a_number_at_position_XpositionX(this.getPosition()), this);        
......
442 417
                buffer.add(ch);
443 418
                ch = getch();
444 419
            }            
445
            s_d = Integer.parseInt(buffer.toString());
420
            String ss = buffer.toString();
421
            s_d = (double) Integer.parseInt(ss) / Math.pow(10, ss.length());
446 422
        } else {
447 423
            s_d = 0;
448 424
        }
......
450 426
            throw new ExpressionSyntaxException(I18N.Expected_XexpectedX_and_found_XfoundX(" ", String.valueOf(ch)), this);
451 427
        }
452 428
        
453
        s = Double.parseDouble(s_i+"."+s_d);
429
        s = s_i + s_d; 
454 430
        
455 431
        double dd = d + m / 60.0 + s / 3600.0;
456 432
        
457
        skipblanks();
458
        ch = getch();
459
        switch(ch) {
460
            case 'N':
461
            case 'n':
462
                if( dd>90 ) {
463
                    throw new ExpressionSyntaxException(I18N.Incorrect_value_for_latitude(dd), this);
464
                }
465
                dd = -dd;
466
                break;
467
                
468
            case 'S':
469
            case 's':
470
                if( dd>90 ) {
471
                    throw new ExpressionSyntaxException(I18N.Incorrect_value_for_latitude(dd), this);
472
                }
473
                break;
474
            case 'E':
475
            case 'e':
476
                if( dd>180 ) {
477
                    throw new ExpressionSyntaxException(I18N.Incorrect_value_for_latitude(dd), this);
478
                }
479
                break;
480
                
481
            case 'O':
482
            case 'o':
483
            case 'W':
484
            case 'w':
485
                if( dd>180 ) {
486
                    throw new ExpressionSyntaxException(I18N.Incorrect_value_for_latitude(dd), this);
487
                }
488
                dd = -dd;
489
                break;
490
                
491
            default:
492
                throw new ExpressionSyntaxException(I18N.Expected_XexpectedX_and_found_XfoundX("N/S/E/W", String.valueOf(ch)), this);
493
        }
494
        ll = String.valueOf(Character.toUpperCase(ch));
495
        
433
        if( sign==null ) {
434
            skipblanks();
435
            ch = getch();
436
            switch(ch) {
437
                case 'N':
438
                case 'n':
439
                    if( dd>90 ) {
440
                        throw new ExpressionSyntaxException(I18N.Incorrect_value_for_latitude(dd), this);
441
                    }
442
                    sign = 1;
443
                    break;
444

  
445
                case 'S':
446
                case 's':
447
                    if( dd>90 ) {
448
                        throw new ExpressionSyntaxException(I18N.Incorrect_value_for_latitude(dd), this);
449
                    }
450
                    sign = -1;
451
                    break;
452
                case 'E':
453
                case 'e':
454
                    if( dd>180 ) {
455
                        throw new ExpressionSyntaxException(I18N.Incorrect_value_for_latitude(dd), this);
456
                    }
457
                    sign = 1;
458
                    break;
459

  
460
                case 'O':
461
                case 'o':
462
                case 'W':
463
                case 'w':
464
                    if( dd>180 ) {
465
                        throw new ExpressionSyntaxException(I18N.Incorrect_value_for_longitude(dd), this);
466
                    }
467
                    sign = -1;
468
                    break;
469

  
470
                default:
471
                    throw new ExpressionSyntaxException(I18N.Expected_XexpectedX_and_found_XfoundX("N/S/E/W", String.valueOf(ch)), this);
472
            }
473
        } 
474
        dd = dd * sign;
496 475
        token.set(
497 476
                Token.FLOATING_POINT_LITERAL,
498
                String.format("@%d? %d' %f\" %s", d,m,s,ll) ,
477
                String.format("@%s%d? %d' %f\"", sign<0? "-":"+", d,m,s) ,
499 478
                dd
500 479
        );
501
        
502 480
    }
503 481
    
504 482
    protected void parseNumber() {

Also available in: Unified diff