GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 92a5c1...70b115 )
by Florian
01:14
created

Coordinates.fromStringDMS   B

Complexity

Conditions 9
Paths 31

Size

Total Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
c 1
b 0
f 0
nc 31
nop 1
dl 0
loc 54
rs 7.255

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/*jslint
2
  nomen: false,
3
  indent: 4
4
*/
5
6
/*global
7
  GeographicLib, google
8
*/
9
10
var Coordinates = {};
11
Coordinates.m_format = "DM";
12
Coordinates.m_geod = GeographicLib.Geodesic.WGS84;
13
14
15
Coordinates.setFormat = function (format) {
16
    'use strict';
17
18
    if (format === "DM" || format === "DMS" || format === "D") {
19
        this.m_format = format;
20
    }
21
};
22
23
24
Coordinates.validLat = function (lat) {
25
    'use strict';
26
27
    return lat !== null && lat !== undefined && !isNaN(lat) && -90.0 <= lat && lat <= 90.0;
28
};
29
30
31
Coordinates.validLng = function (lng) {
32
    'use strict';
33
34
    return lng !== null && lng !== undefined && !isNaN(lng) && -180.0 <= lng && lng <= 180.0;
35
};
36
37
38
Coordinates.valid = function (lat, lng) {
39
    'use strict';
40
41
    return this.validLat(lat) && this.validLng(lng);
42
};
43
44
45
Coordinates.toLatLng = function (lat, lng) {
46
    'use strict';
47
48
    if (this.valid(lat, lng)) {
49
        return new google.maps.LatLng(lat, lng);
50
    }
51
52
    return null;
53
};
54
55
56
Coordinates.fromString = function (coordsString) {
57
    'use strict';
58
59
    var coords;
60
61
    coords = this.fromStringDM(coordsString);
62
    if (coords) {
63
        return coords;
64
    }
65
66
    coords = this.fromStringDMS(coordsString);
67
    if (coords) {
68
        return coords;
69
    }
70
71
    coords = this.fromStringD(coordsString);
72
    if (coords) {
73
        return coords;
74
    }
75
76
    return null;
77
};
78
79
80
Coordinates.sanitize = function (s) {
81
    'use strict';
82
83
    var sanitized = "",
84
        commas = 0,
85
        periods = 0,
86
        i;
87
88
    for (i = 0; i < s.length; i = i + 1) {
89
        if ((s[i] === 'o') || (s[i] === 'O')) {
90
            // map 'O'/'o' to 'E' (German 'Ost' = 'East')
91
            sanitized += 'E';
92
        } else if (s[i].match(/[a-z0-9\-]/i)) {
93
            sanitized += s[i].toUpperCase();
94
        } else if (s[i] === '.') {
95
            periods += 1;
96
            sanitized += s[i];
97
        } else if (s[i] === ',') {
98
            commas += 1;
99
            sanitized += s[i];
100
        } else {
101
            sanitized += ' ';
102
        }
103
    }
104
105
    // try to map commas to spaces or periods
106
    if ((commas === 1) && ((periods === 0) || (periods >= 2))) {
107
        return sanitized.replace(/,/g, ' ');
108
    }
109
110
    if ((commas >= 1) && (periods === 0)) {
111
        return sanitized.replace(/,/g, '.');
112
    }
113
114
    return sanitized;
115
};
116
117
118
Coordinates.create = function (h1, d1, m1, s1, h2, d2, m2, s2) {
119
    'use strict';
120
121
    var c1, c2, lat, lng;
122
123
    if (h1 && d1 < 0) {
124
        return null;
125
    }
126
    if (m1 < 0 || m1 >= 60) {
127
        return null;
128
    }
129
    if (s1 < 0 || s1 >= 60) {
130
        return null;
131
    }
132
133
    if (h2 && d2 < 0) {
134
        return null;
135
    }
136
    if (m2 < 0 || m2 >= 60) {
137
        return null;
138
    }
139
    if (s2 < 0 || s2 >= 60) {
140
        return null;
141
    }
142
143
    c1 = d1 + (m1 / 60.0) + (s1 / 3600.0);
144
    c2 = d2 + (m2 / 60.0) + (s2 / 3600.0);
145
146
    if (!h1 && !h2) {
147
        lat = c1;
148
        lng = c2;
149
    } else if ((h1 === 'N' || h1 === 'S') && (h2 === 'E' || h2 === 'W')) {
150
        lat = c1;
151
        lng = c2;
152
        if (h1 === 'S') {
153
            lat = -lat;
154
        }
155
        if (h2 === 'W') {
156
            lng = -lng;
157
        }
158
    } else if ((h2 === 'N' || h2 === 'S') && (h1 === 'E' || h1 === 'W')) {
159
        lat = c2;
160
        lng = c1;
161
        if (h2 === 'S') {
162
            lat = -lat;
163
        }
164
        if (h1 === 'W') {
165
            lng = -lng;
166
        }
167
    } else {
168
        return null;
169
    }
170
171
    if (!this.valid(lat, lng)) {
172
        return null;
173
    }
174
175
    return Coordinates.toLatLng(lat, lng);
176
};
177
178
179
Coordinates.fromStringDMS = function (coordsString) {
180
    'use strict';
181
182
    var s = this.sanitize(coordsString),
183
        pattern,
184
        m,
185
        coords;
186
187
    // H D M S.S
188
    pattern = /^\s*([NEWS])\s*(\d+)\s+(\d+)\s+(\d+\.?\d*)\s*([NEWS])\s*(\d+)\s+(\d+)\s+(\d+\.?\d*)\s*$/;
189
    m = s.match(pattern);
190
    if (m) {
191
        coords = Coordinates.create(m[1], parseFloat(m[2]), parseFloat(m[3]), parseFloat(m[4]),
192
                                    m[5], parseFloat(m[6]), parseFloat(m[7]), parseFloat(m[8]));
193
        if (coords) {
194
            return coords;
195
        }
196
    }
197
198
    // D H M S.S
199
    pattern = /^\s*(\d+)\s*([NEWS])\s*(\d+)\s+(\d+\.?\d*)\s+(\d+)\s*([NEWS])\s*(\d+)\s+(\d+\.?\d*)\s*$/;
200
    m = s.match(pattern);
201
    if (m) {
202
        coords = Coordinates.create(m[2], parseFloat(m[1]), parseFloat(m[3]), parseFloat(m[4]),
203
                                    m[6], parseFloat(m[5]), parseFloat(m[7]), parseFloat(m[8]));
204
        if (coords) {
205
            return coords;
206
        }
207
    }
208
209
    // D M S.S H
210
    pattern = /^\s*(\d+)\s+(\d+)\s+(\d+\.?\d*)\s*([NEWS])\s*(\d+)\s+(\d+)\s+(\d+\.?\d*)\s*([NEWS])\s*$/;
211
    m = s.match(pattern);
212
    if (m) {
213
        coords = Coordinates.create(m[4], parseFloat(m[1]), parseFloat(m[2]), parseFloat(m[3]),
214
                                    m[8], parseFloat(m[5]), parseFloat(m[6]), parseFloat(m[7]));
215
        if (coords) {
216
            return coords;
217
        }
218
    }
219
220
    // D M S.S
221
    pattern = /^\s*(\d+)\s+(\d+)\s+(\d+\.?\d*)\s+(\d+)\s+(\d+)\s+(\d+\.?\d*)\s*$/;
222
    m = s.match(pattern);
223
    if (m) {
224
        coords = Coordinates.create('N', parseFloat(m[1]), parseFloat(m[2]), parseFloat(m[3]),
225
                                    'E', parseFloat(m[4]), parseFloat(m[5]), parseFloat(m[6]));
226
        if (coords) {
227
            return coords;
228
        }
229
    }
230
231
    return null;
232
};
233
234
235
Coordinates.fromStringDM = function (coordsString) {
236
    'use strict';
237
238
    var s = this.sanitize(coordsString),
239
        pattern,
240
        m,
241
        coords;
242
243
    // H D M.M
244
    pattern = /^\s*([NEWS])\s*(\d+)\s+(\d+\.?\d*)\s*([NEWS])\s*(\d+)\s+(\d+\.?\d*)\s*$/;
245
    m = s.match(pattern);
246
    if (m) {
247
        coords = Coordinates.create(m[1], parseFloat(m[2]), parseFloat(m[3]), 0,
248
                                    m[4], parseFloat(m[5]), parseFloat(m[6]), 0);
249
        if (coords) {
250
            return coords;
251
        }
252
    }
253
254
    // D H M.M
255
    pattern = /^\s*(\d+)\s*([NEWS])\s*(\d+\.?\d*)\s+(\d+)\s*([NEWS])\s*(\d+\.?\d*)\s*$/;
256
    m = s.match(pattern);
257
    if (m) {
258
        coords = Coordinates.create(m[2], parseFloat(m[1]), parseFloat(m[3]), 0,
259
                                    m[5], parseFloat(m[4]), parseFloat(m[6]), 0);
260
        if (coords) {
261
            return coords;
262
        }
263
    }
264
265
    // D M.M H
266
    pattern = /^\s*(\d+)\s+(\d+\.?\d*)\s*([NEWS])\s*(\d+)\s+(\d+\.?\d*)\s*([NEWS])\s*$/;
267
    m = s.match(pattern);
268
    if (m) {
269
        coords = Coordinates.create(m[3], parseFloat(m[1]), parseFloat(m[2]), 0,
270
                                    m[6], parseFloat(m[4]), parseFloat(m[5]), 0);
271
        if (coords) {
272
            return coords;
273
        }
274
    }
275
276
    // D M.M
277
    pattern = /^\s*(\d+)\s+(\d+\.?\d*)\s+(\d+)\s+(\d+\.?\d*)\s*$/;
278
    m = s.match(pattern);
279
    if (m) {
280
        coords = Coordinates.create('N', parseFloat(m[1]), parseFloat(m[2]), 0,
281
                                    'E', parseFloat(m[3]), parseFloat(m[4]), 0);
282
        if (coords) {
283
            return coords;
284
        }
285
    }
286
287
    return null;
288
};
289
290
291
Coordinates.fromStringD = function (coordsString) {
292
    'use strict';
293
294
    var s = this.sanitize(coordsString),
295
        pattern,
296
        m,
297
        coords;
298
299
    // H D.D
300
    pattern = /^\s*([NEWS])\s*(\d+\.?\d*)\s*([NEWS])\s*(\d+\.?\d*)\s*$/;
301
    m = s.match(pattern);
302
    if (m) {
303
        coords = Coordinates.create(m[1], parseFloat(m[2]), 0, 0,
304
                                     m[3], parseFloat(m[4]), 0, 0);
305
        if (coords) {
306
            return coords;
307
        }
308
    }
309
310
    // D.D H
311
    pattern = /^\s*(\d+\.?\d*)\s*([NEWS])\s*(\d+\.?\d*)\s*([NEWS])\s*$/;
312
    m = s.match(pattern);
313
    if (m) {
314
        coords = Coordinates.create(m[2], parseFloat(m[1]), 0, 0,
315
                                     m[4], parseFloat(m[3]), 0, 0);
316
        if (coords) {
317
            return coords;
318
        }
319
    }
320
321
    // D.D
322
    pattern = /^\s*(-?\d+\.?\d*)\s+(-?\d+\.?\d*)\s*$/;
323
    m = s.match(pattern);
324
    if (m) {
325
        coords = Coordinates.create(null, parseFloat(m[1]), 0, 0,
326
                                     null, parseFloat(m[2]), 0, 0);
327
        if (coords) {
328
            return coords;
329
        }
330
    }
331
332
    return null;
333
};
334
335
336
Coordinates.toStringDM = function (coords) {
337
    'use strict';
338
339
    var lat = Math.abs(coords.lat()),
340
        lat_h = (coords.lat() >= 0) ? "N" : "S",
341
        lat_deg,
342
        lat_min,
343
        lat_mmin,
344
        lng = Math.abs(coords.lng()),
345
        lng_h = (coords.lng() >= 0) ? "E" : "W",
346
        lng_deg,
347
        lng_min,
348
        lng_mmin,
349
        s;
350
351
    lat_deg = Math.floor(lat);
352
    lat = lat - lat_deg;
353
    lat_min = Math.floor(lat * 60);
354
    lat = lat * 60 - lat_min;
355
    lat_mmin = Math.floor(Math.round(lat * 1000));
356
    while (lat_mmin >= 1000) {
357
        lat_mmin -= 1000;
358
        lat_min += 1;
359
    }
360
361
    lng_deg = Math.floor(lng);
362
    lng = lng - lng_deg;
363
    lng_min = Math.floor(lng * 60);
364
    lng = lng * 60 - lng_min;
365
    lng_mmin = Math.floor(Math.round(lng * 1000));
366
    while (lng_mmin >= 1000) {
367
        lng_mmin -= 1000;
368
        lng_min += 1;
369
    }
370
371
    s = lat_h +
372
        " " +
373
        this.zeropad(lat_deg, 2) +
374
        " " +
375
        this.zeropad(lat_min, 2) +
376
        "." +
377
        this.zeropad(lat_mmin, 3) +
378
        " " +
379
        lng_h +
380
        " " +
381
        this.zeropad(lng_deg, 3) +
382
        " " +
383
        this.zeropad(lng_min, 2) +
384
        "." +
385
        this.zeropad(lng_mmin, 3);
386
    return s;
387
};
388
389
390
Coordinates.toStringDMS = function (coords) {
391
    'use strict';
392
393
    var lat = Math.abs(coords.lat()),
394
        lat_h = ((coords.lat() >= 0) ? "N" : "S"),
395
        lat_deg,
396
        lat_min,
397
        lat_sec,
398
        lng = Math.abs(coords.lng()),
399
        lng_h = ((coords.lng() >= 0) ? "E" : "W"),
400
        lng_deg,
401
        lng_min,
402
        lng_sec,
403
        s;
404
405
    lat_deg = Math.floor(lat);
406
    lat = lat - lat_deg;
407
    lat_min = Math.floor(lat * 60);
408
    lat = lat * 60 - lat_min;
409
    lat_sec = lat * 60.0;
410
411
    lng_deg = Math.floor(lng);
412
    lng = lng - lng_deg;
413
    lng_min = Math.floor(lng * 60);
414
    lng = lng * 60 - lng_min;
415
    lng_sec = lng * 60.0;
416
417
    s = lat_h +
418
        " " +
419
        this.zeropad(lat_deg, 2) +
420
        " " +
421
        this.zeropad(lat_min, 2) +
422
        " " +
423
        this.zeropad(lat_sec.toFixed(2), 5) +
424
        " " +
425
        lng_h +
426
        " " +
427
        this.zeropad(lng_deg, 3) +
428
        " " +
429
        this.zeropad(lng_min, 2) +
430
        " " +
431
        this.zeropad(lng_sec.toFixed(2), 5);
432
433
    return s;
434
};
435
436
437
Coordinates.toStringD = function (coords) {
438
    'use strict';
439
440
    var lat = Math.abs(coords.lat()),
441
        lat_h = ((coords.lat() >= 0) ? "N" : "S"),
442
        lng = Math.abs(coords.lng()),
443
        lng_h = ((coords.lng() >= 0) ? "E" : "W");
444
445
    return lat_h + " " + lat.toFixed(6) + " " + lng_h + " " + lng.toFixed(6);
446
};
447
448
449
Coordinates.toString = function (coords) {
450
    'use strict';
451
452
    if (this.m_format === "DM") {
453
        return this.toStringDM(coords);
454
    }
455
456
    if (this.m_format === "DMS") {
457
        return this.toStringDMS(coords);
458
    }
459
460
    if (this.m_format === "D") {
461
        return this.toStringD(coords);
462
    }
463
464
    return this.toStringDM(coords);
465
};
466
467
468
Coordinates.dist_angle_geodesic = function (startpos, endpos) {
469
    'use strict';
470
471
    var t = this.m_geod.Inverse(startpos.lat(), startpos.lng(), endpos.lat(), endpos.lng()),
472
        a = t.azi1;
473
    if (a < 0) {
474
        a += 360.0;
475
    }
476
477
    return {dist: t.s12, angle: a};
478
};
479
480
481
Coordinates.projection_geodesic = function (startpos, angle, distance) {
482
    'use strict';
483
484
    var t = this.m_geod.Direct(startpos.lat(), startpos.lng(), angle, distance);
485
    return new google.maps.LatLng(t.lat2, t.lon2);
486
};
487
488
489
Coordinates.zeropad = function (num, width) {
490
    'use strict';
491
492
    var s = String(num);
493
    while (s.length < width) {
494
        s = "0" + s;
495
    }
496
    return s;
497
};
498