admin管理员组

文章数量:1388805

I'm having trouble converting DMS to DD in javascript using regular expressions. I took this code from geoserver but it does not seem to work. I want it to be able to convert all my test cases with the correct or VERY close answer.

I really don't care if the function is pletely javascript or heavy regular expressions, i just need it to work.

You can test it on JSFIDDLE /

Here are my test cases: dmsToDeg(' N 03 01’ 37”'); dmsToDeg('03 01 37'); dmsToDeg('03 01’ 37” N'); dmsToDeg('076 40’ 35” W'); dmsToDeg('W 076 40’ 35”'); dmsToDeg('N 05 11’ 17”');

Here is my code:

function dmsToDeg (dms) {
    if (!dms) {
        return Number.NaN;
    }
    var neg = dms.match(/(^\s?-)|(\s?[SW]\s?$)/) != null ? -1.0 : 1.0;
    dms = dms.replace(/(^\s?-)|(\s?[NSEW]\s?)$/, '');
    dms = dms.replace(/\s/g, '');
    var parts = dms.match(/(\d{1,3})[.,°d ]?\s*(\d{0,2})[']?(\d{0,2})[.,]?(\d{0,})(?:["]|[']{2})?/);
    if (parts == null) {
        return Number.NaN;
    }
    // parts: 
    // 0 : degree 
    // 1 : degree 
    // 2 : minutes 
    // 3 : secondes 
    // 4 : fractions of seconde 
    var d = (parts[1] ? parts[1] : '0.0') * 1.0;
    var m = (parts[2] ? parts[2] : '0.0') * 1.0;
    var s = (parts[3] ? parts[3] : '0.0') * 1.0;
    var r = (parts[4] ? ('0.' + parts[4]) : '0.0') * 1.0;
    var dec = (d + (m / 60.0) + (s / 3600.0) + (r / 3600.0)) * neg;
    return dec;
}

I'm having trouble converting DMS to DD in javascript using regular expressions. I took this code from geoserver but it does not seem to work. I want it to be able to convert all my test cases with the correct or VERY close answer.

I really don't care if the function is pletely javascript or heavy regular expressions, i just need it to work.

You can test it on JSFIDDLE http://jsfiddle/NJDp4/13/

Here are my test cases: dmsToDeg(' N 03 01’ 37”'); dmsToDeg('03 01 37'); dmsToDeg('03 01’ 37” N'); dmsToDeg('076 40’ 35” W'); dmsToDeg('W 076 40’ 35”'); dmsToDeg('N 05 11’ 17”');

Here is my code:

function dmsToDeg (dms) {
    if (!dms) {
        return Number.NaN;
    }
    var neg = dms.match(/(^\s?-)|(\s?[SW]\s?$)/) != null ? -1.0 : 1.0;
    dms = dms.replace(/(^\s?-)|(\s?[NSEW]\s?)$/, '');
    dms = dms.replace(/\s/g, '');
    var parts = dms.match(/(\d{1,3})[.,°d ]?\s*(\d{0,2})[']?(\d{0,2})[.,]?(\d{0,})(?:["]|[']{2})?/);
    if (parts == null) {
        return Number.NaN;
    }
    // parts: 
    // 0 : degree 
    // 1 : degree 
    // 2 : minutes 
    // 3 : secondes 
    // 4 : fractions of seconde 
    var d = (parts[1] ? parts[1] : '0.0') * 1.0;
    var m = (parts[2] ? parts[2] : '0.0') * 1.0;
    var s = (parts[3] ? parts[3] : '0.0') * 1.0;
    var r = (parts[4] ? ('0.' + parts[4]) : '0.0') * 1.0;
    var dec = (d + (m / 60.0) + (s / 3600.0) + (r / 3600.0)) * neg;
    return dec;
}
Share Improve this question asked May 11, 2011 at 21:41 capdragoncapdragon 14.9k24 gold badges110 silver badges155 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

It's not that tough, the following assumes that the correct format is passed in, you might want to do some validation of that. It also doesn't format the output, use a generic formatting function if you need that (again, not hard to write, about 5 lines of code max).

Likely you are feeding this into another calculation (degrees to radians conversion?) so formatting is probably unnecessary. Note that javascript numbers can't accurately represent all decimal numbers, so be careful with rounding. The precision is sufficient for most purposes though.

function dms2deg(s) {

  // Determine if south latitude or west longitude
  var sw = /[sw]/i.test(s);

  // Determine sign based on sw (south or west is -ve) 
  var f = sw? -1 : 1;

  // Get into numeric parts
  var bits = s.match(/[\d.]+/g);

  var result = 0;

  // Convert to decimal degrees
  for (var i=0, iLen=bits.length; i<iLen; i++) {

    // String conversion to number is done by division
    // To be explicit (not necessary), use 
    //   result += Number(bits[i])/f
    result += bits[i]/f;

    // Divide degrees by +/- 1, min by +/- 60, sec by +/-3600
    f *= 60;
  }

  return result;
}

alert( 
  dms2deg('S 023 30\'') + '\n' +      // -23.5
  dms2deg('N 023 00\' 00\"') + '\n' + //  23
  dms2deg('W 117 23\' 23.32\"')       // -117.3898111111111
);

The problem is that you're removing all the spaces, so that '03 01 37' bees '030137'. Then, the regex \d{1,3} matches three digits, '030'. You should add optional separators to the regex rather than stripping them from the input.

There may be other things, but that's the first one I see.

Parsing lat/lon values is, as you have found, harder than it might seem. If you can just re-use someone else's code, you should.

本文标签: regexRegular ExpressionJavascript Convert Degrees Minutes Seconds to Decimal DegreesStack Overflow