geo-coordinates-parser 1.5.7 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/dist/cjs/converter.d.ts +15 -0
- package/dist/cjs/converter.js +363 -0
- package/dist/cjs/merge.d.ts +2 -0
- package/dist/cjs/merge.js +12 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/regex.d.ts +4 -0
- package/dist/cjs/regex.js +16 -0
- package/dist/cjs/tests/failFormats.d.ts +2 -0
- package/dist/cjs/tests/failFormats.js +26 -0
- package/dist/cjs/tests/makeTestFormatsJSON.d.ts +1 -0
- package/dist/cjs/tests/makeTestFormatsJSON.js +14 -0
- package/dist/cjs/tests/test.d.ts +1 -0
- package/dist/cjs/tests/test.js +56 -0
- package/dist/cjs/tests/testFormatConverter.d.ts +1 -0
- package/dist/cjs/tests/testFormatConverter.js +11 -0
- package/dist/cjs/tests/testIndividual.d.ts +1 -0
- package/dist/cjs/tests/testIndividual.js +26 -0
- package/dist/cjs/tests/testformats.d.ts +2 -0
- package/dist/cjs/tests/testformats.js +359 -0
- package/dist/cjs/toCoordinateFormat.d.ts +6 -0
- package/dist/cjs/toCoordinateFormat.js +42 -0
- package/dist/mjs/converter.d.ts +15 -0
- package/dist/mjs/converter.js +358 -0
- package/dist/mjs/merge.d.ts +2 -0
- package/dist/mjs/merge.js +6 -0
- package/dist/mjs/package.json +3 -0
- package/dist/mjs/regex.d.ts +4 -0
- package/dist/mjs/regex.js +10 -0
- package/dist/mjs/tests/failFormats.d.ts +2 -0
- package/dist/mjs/tests/failFormats.js +24 -0
- package/dist/mjs/tests/makeTestFormatsJSON.d.ts +1 -0
- package/dist/mjs/tests/makeTestFormatsJSON.js +9 -0
- package/dist/mjs/tests/test.d.ts +1 -0
- package/dist/mjs/tests/test.js +51 -0
- package/dist/mjs/tests/testFormatConverter.d.ts +1 -0
- package/dist/mjs/tests/testFormatConverter.js +6 -0
- package/dist/mjs/tests/testIndividual.d.ts +1 -0
- package/dist/mjs/tests/testIndividual.js +21 -0
- package/dist/mjs/tests/testformats.d.ts +2 -0
- package/dist/mjs/tests/testformats.js +357 -0
- package/dist/mjs/toCoordinateFormat.d.ts +6 -0
- package/dist/mjs/toCoordinateFormat.js +40 -0
- package/package.json +50 -42
- package/bundle/demo.html +0 -39
- package/bundle/geocoordsparser.js +0 -1
- package/bundle/workflow.txt +0 -8
- package/conf.py +0 -3
- package/converter.js +0 -419
- package/failFormats.js +0 -17
- package/formatsOnly.json +0 -41
- package/geocoordsparser.js +0 -0
- package/makeTestFormatsJSON.js +0 -11
- package/merge.js +0 -9
- package/test.js +0 -66
- package/testFormatConverter.js +0 -8
- package/testFormats.json +0 -352
- package/testIndividual.js +0 -21
- package/testformats.js +0 -351
- package/toCoordinateFormat.js +0 -52
@@ -0,0 +1,358 @@
|
|
1
|
+
//function for converting coordinates from a string to decimal and verbatim
|
2
|
+
//this is just a comment
|
3
|
+
import { dd_re, dms_periods, dms_abbr, coords_other } from './regex.js';
|
4
|
+
import toCoordinateFormat from './toCoordinateFormat.js';
|
5
|
+
/**
|
6
|
+
* Function for converting coordinates in a variety of formats to decimal coordinates
|
7
|
+
* @param {string} coordsString The coordinates string to convert
|
8
|
+
* @param {number} decimalPlaces The number of decimal places for converted coordinates; default is 5
|
9
|
+
* @returns {object} { verbatimCoordinates, decimalCoordinates, decimalLatitude, decimalLongitude }
|
10
|
+
*/
|
11
|
+
function converter(coordsString, decimalPlaces) {
|
12
|
+
//TODO add exact match to entered string, so that it can be used to filter out superflous text around it
|
13
|
+
if (!decimalPlaces) {
|
14
|
+
decimalPlaces = 5;
|
15
|
+
}
|
16
|
+
coordsString = coordsString.replace(/\s+/g, ' ').trim(); //just to tidy up whitespaces
|
17
|
+
let ddLat = null;
|
18
|
+
let ddLng = null;
|
19
|
+
let latdir = "";
|
20
|
+
let lngdir = "";
|
21
|
+
let match = [];
|
22
|
+
let matchSuccess = false;
|
23
|
+
if (dd_re.test(coordsString)) {
|
24
|
+
match = dd_re.exec(coordsString);
|
25
|
+
matchSuccess = checkMatch(match);
|
26
|
+
if (matchSuccess) {
|
27
|
+
ddLat = match[2];
|
28
|
+
ddLng = match[6];
|
29
|
+
//need to fix if there are ','s instead of '.'
|
30
|
+
if (ddLat.includes(',')) {
|
31
|
+
ddLat = ddLat.replace(',', '.');
|
32
|
+
}
|
33
|
+
if (ddLng.includes(',')) {
|
34
|
+
ddLng = ddLng.replace(',', '.');
|
35
|
+
}
|
36
|
+
//validation, we don't want things like 23.00000
|
37
|
+
//some more validation: no zero coords or degrees only
|
38
|
+
if (Number(Math.round(ddLat)) == Number(ddLat)) {
|
39
|
+
throw new Error('integer only coordinate provided');
|
40
|
+
}
|
41
|
+
if (Number(Math.round(ddLng)) == Number(ddLng)) {
|
42
|
+
throw new Error('integer only coordinate provided');
|
43
|
+
}
|
44
|
+
//get directions
|
45
|
+
if (match[1]) {
|
46
|
+
latdir = match[1];
|
47
|
+
lngdir = match[5];
|
48
|
+
}
|
49
|
+
else if (match[4]) {
|
50
|
+
latdir = match[4];
|
51
|
+
lngdir = match[8];
|
52
|
+
}
|
53
|
+
}
|
54
|
+
else {
|
55
|
+
throw new Error("invalid decimal coordinate format");
|
56
|
+
}
|
57
|
+
}
|
58
|
+
else if (dms_periods.test(coordsString)) {
|
59
|
+
match = dms_periods.exec(coordsString);
|
60
|
+
matchSuccess = checkMatch(match);
|
61
|
+
if (matchSuccess) {
|
62
|
+
ddLat = Math.abs(parseInt(match[2]));
|
63
|
+
if (match[4]) {
|
64
|
+
ddLat += match[4] / 60;
|
65
|
+
}
|
66
|
+
if (match[6]) {
|
67
|
+
ddLat += match[6].replace(',', '.') / 3600;
|
68
|
+
}
|
69
|
+
if (parseInt(match[2]) < 0) {
|
70
|
+
ddLat = -1 * ddLat;
|
71
|
+
}
|
72
|
+
ddLng = Math.abs(parseInt(match[9]));
|
73
|
+
if (match[11]) {
|
74
|
+
ddLng += match[11] / 60;
|
75
|
+
}
|
76
|
+
if (match[13]) {
|
77
|
+
ddLng += match[13].replace(',', '.') / 3600;
|
78
|
+
}
|
79
|
+
if (parseInt(match[9]) < 0) {
|
80
|
+
ddLng = -1 * ddLng;
|
81
|
+
}
|
82
|
+
//the compass directions
|
83
|
+
if (match[1]) {
|
84
|
+
latdir = match[1];
|
85
|
+
lngdir = match[8];
|
86
|
+
}
|
87
|
+
else if (match[7]) {
|
88
|
+
latdir = match[7];
|
89
|
+
lngdir = match[14];
|
90
|
+
}
|
91
|
+
}
|
92
|
+
else {
|
93
|
+
throw new Error("invalid DMS coordinates format");
|
94
|
+
}
|
95
|
+
}
|
96
|
+
else if (dms_abbr.test(coordsString)) {
|
97
|
+
match = dms_abbr.exec(coordsString);
|
98
|
+
matchSuccess = checkMatch(match);
|
99
|
+
if (matchSuccess) {
|
100
|
+
ddLat = Math.abs(parseInt(match[2]));
|
101
|
+
if (match[4]) {
|
102
|
+
ddLat += match[4] / 60;
|
103
|
+
}
|
104
|
+
if (match[6]) {
|
105
|
+
ddLat += match[6] / 3600;
|
106
|
+
}
|
107
|
+
if (parseInt(match[2]) < 0) {
|
108
|
+
ddLat = -1 * ddLat;
|
109
|
+
}
|
110
|
+
ddLng = Math.abs(parseInt(match[10]));
|
111
|
+
if (match[12]) {
|
112
|
+
ddLng += match[12] / 60;
|
113
|
+
}
|
114
|
+
if (match[14]) {
|
115
|
+
ddLng += match[14] / 3600;
|
116
|
+
}
|
117
|
+
if (parseInt(match[10]) < 0) {
|
118
|
+
ddLng = -1 * ddLng;
|
119
|
+
}
|
120
|
+
if (match[1]) {
|
121
|
+
latdir = match[1];
|
122
|
+
lngdir = match[9];
|
123
|
+
}
|
124
|
+
else if (match[8]) {
|
125
|
+
latdir = match[8];
|
126
|
+
lngdir = match[16];
|
127
|
+
}
|
128
|
+
}
|
129
|
+
else {
|
130
|
+
throw new Error("invalid DMS coordinates format");
|
131
|
+
}
|
132
|
+
}
|
133
|
+
else if (coords_other.test(coordsString)) {
|
134
|
+
match = coords_other.exec(coordsString);
|
135
|
+
matchSuccess = checkMatch(match);
|
136
|
+
if (matchSuccess) {
|
137
|
+
ddLat = Math.abs(parseInt(match[2]));
|
138
|
+
if (match[4]) {
|
139
|
+
ddLat += match[4] / 60;
|
140
|
+
}
|
141
|
+
if (match[6]) {
|
142
|
+
ddLat += match[6] / 3600;
|
143
|
+
}
|
144
|
+
if (parseInt(match[2]) < 0) {
|
145
|
+
ddLat = -1 * ddLat;
|
146
|
+
}
|
147
|
+
ddLng = Math.abs(parseInt(match[10]));
|
148
|
+
if (match[12]) {
|
149
|
+
ddLng += match[12] / 60;
|
150
|
+
}
|
151
|
+
if (match[14]) {
|
152
|
+
ddLng += match[14] / 3600;
|
153
|
+
}
|
154
|
+
if (parseInt(match[10]) < 0) {
|
155
|
+
ddLng = -1 * ddLng;
|
156
|
+
}
|
157
|
+
if (match[1]) {
|
158
|
+
latdir = match[1];
|
159
|
+
lngdir = match[9];
|
160
|
+
}
|
161
|
+
else if (match[8]) {
|
162
|
+
latdir = match[8];
|
163
|
+
lngdir = match[16];
|
164
|
+
}
|
165
|
+
}
|
166
|
+
else {
|
167
|
+
throw new Error("invalid coordinates format");
|
168
|
+
}
|
169
|
+
}
|
170
|
+
if (matchSuccess) {
|
171
|
+
//more validation....
|
172
|
+
//check longitude value - it can be wrong!
|
173
|
+
if (Math.abs(ddLng) >= 180) {
|
174
|
+
throw new Error("invalid longitude value");
|
175
|
+
}
|
176
|
+
//just to be safe check latitude also...
|
177
|
+
if (Math.abs(ddLat) >= 90) {
|
178
|
+
throw new Error("invalid latitude value");
|
179
|
+
}
|
180
|
+
//if we have one direction we must have the other
|
181
|
+
if ((latdir || lngdir) && (!latdir || !lngdir)) {
|
182
|
+
throw new Error("invalid coordinates format");
|
183
|
+
}
|
184
|
+
//the directions can't be the same
|
185
|
+
if (latdir && latdir == lngdir) {
|
186
|
+
throw new Error("invalid coordinates format");
|
187
|
+
}
|
188
|
+
//make sure the signs and cardinal directions match
|
189
|
+
let patt = /S|SOUTH/i;
|
190
|
+
if (patt.test(latdir)) {
|
191
|
+
if (ddLat > 0) {
|
192
|
+
ddLat = -1 * ddLat;
|
193
|
+
}
|
194
|
+
}
|
195
|
+
patt = /W|WEST/i;
|
196
|
+
if (patt.test(lngdir)) {
|
197
|
+
if (ddLng > 0) {
|
198
|
+
ddLng = -1 * ddLng;
|
199
|
+
}
|
200
|
+
}
|
201
|
+
//we need to get the verbatim coords from the string
|
202
|
+
//we can't split down the middle because if there are decimals they may have different numbers on each side
|
203
|
+
//so we need to find the separating character, or if none, use the match values to split down the middle
|
204
|
+
const verbatimCoordinates = match[0].trim();
|
205
|
+
let verbatimLat;
|
206
|
+
let verbatimLng;
|
207
|
+
const sepChars = /[,/;\u0020]/g; //comma, forward slash and spacebar
|
208
|
+
const seps = verbatimCoordinates.match(sepChars);
|
209
|
+
if (seps == null) {
|
210
|
+
//split down the middle
|
211
|
+
const middle = Math.floor(coordsString.length / 2);
|
212
|
+
verbatimLat = verbatimCoordinates.substring(0, middle).trim();
|
213
|
+
verbatimLng = verbatimCoordinates.substring(middle).trim();
|
214
|
+
}
|
215
|
+
else { //if length is odd then find the index of the middle value
|
216
|
+
//get the middle index
|
217
|
+
let middle;
|
218
|
+
//easy for odd numbers
|
219
|
+
if (seps.length % 2 == 1) {
|
220
|
+
middle = Math.floor(seps.length / 2);
|
221
|
+
}
|
222
|
+
else {
|
223
|
+
middle = (seps.length / 2) - 1;
|
224
|
+
}
|
225
|
+
//walk through seps until we get to the middle
|
226
|
+
let splitIndex = 0;
|
227
|
+
//it might be only one value
|
228
|
+
if (middle == 0) {
|
229
|
+
splitIndex = verbatimCoordinates.indexOf(seps[0]);
|
230
|
+
verbatimLat = verbatimCoordinates.substring(0, splitIndex).trim();
|
231
|
+
verbatimLng = verbatimCoordinates.substring(splitIndex + 1).trim();
|
232
|
+
}
|
233
|
+
else {
|
234
|
+
let currSepIndex = 0;
|
235
|
+
let startSearchIndex = 0;
|
236
|
+
while (currSepIndex <= middle) {
|
237
|
+
splitIndex = verbatimCoordinates.indexOf(seps[currSepIndex], startSearchIndex);
|
238
|
+
startSearchIndex = splitIndex + 1;
|
239
|
+
currSepIndex++;
|
240
|
+
}
|
241
|
+
verbatimLat = verbatimCoordinates.substring(0, splitIndex).trim();
|
242
|
+
verbatimLng = verbatimCoordinates.substring(splitIndex + 1).trim();
|
243
|
+
}
|
244
|
+
}
|
245
|
+
//validation again...
|
246
|
+
//we only allow zeros after the period if its DM
|
247
|
+
const splitLat = verbatimLat.split('.');
|
248
|
+
if (splitLat.length == 2) {
|
249
|
+
if (splitLat[1] == 0 && splitLat[1].length != 2) {
|
250
|
+
throw new Error('invalid coordinates format');
|
251
|
+
}
|
252
|
+
}
|
253
|
+
const splitLon = verbatimLng.split('.');
|
254
|
+
if (splitLon.length == 2) {
|
255
|
+
if (splitLon[1] == 0 && splitLon[1].length != 2) {
|
256
|
+
throw new Error('invalid coordinates format');
|
257
|
+
}
|
258
|
+
}
|
259
|
+
//no integer coords allowed
|
260
|
+
//validation -- no integer coords
|
261
|
+
if (/^\d+$/.test(verbatimLat) || /^\d+$/.test(verbatimLng)) {
|
262
|
+
throw new Error('degree only coordinate/s provided');
|
263
|
+
}
|
264
|
+
//some tidying up...
|
265
|
+
if (isNaN(ddLat) && ddLat.includes(',')) {
|
266
|
+
ddLat = ddLat.replace(',', '.');
|
267
|
+
}
|
268
|
+
//all done!!
|
269
|
+
//just truncate the decimals appropriately
|
270
|
+
ddLat = Number(Number(ddLat).toFixed(decimalPlaces));
|
271
|
+
if (isNaN(ddLng) && ddLng.includes(',')) {
|
272
|
+
ddLng = ddLng.replace(',', '.');
|
273
|
+
}
|
274
|
+
ddLng = Number(Number(ddLng).toFixed(decimalPlaces));
|
275
|
+
return Object.freeze({
|
276
|
+
verbatimCoordinates,
|
277
|
+
verbatimLatitude: verbatimLat,
|
278
|
+
verbatimLongitude: verbatimLng,
|
279
|
+
decimalLatitude: ddLat,
|
280
|
+
decimalLongitude: ddLng,
|
281
|
+
decimalCoordinates: `${ddLat},${ddLng}`,
|
282
|
+
closeEnough: coordsCloseEnough,
|
283
|
+
toCoordinateFormat
|
284
|
+
});
|
285
|
+
}
|
286
|
+
else {
|
287
|
+
throw new Error("coordinates pattern match failed");
|
288
|
+
}
|
289
|
+
}
|
290
|
+
function checkMatch(match) {
|
291
|
+
if (!isNaN(match[0])) { //we've matched a number, not what we want....
|
292
|
+
return false;
|
293
|
+
}
|
294
|
+
//first remove the empty values from the array
|
295
|
+
const filteredMatch = [...match];
|
296
|
+
//we need to shift the array because it contains the whole coordinates string in the first item
|
297
|
+
filteredMatch.shift();
|
298
|
+
//check the array length is an even number else exit
|
299
|
+
if (filteredMatch.length % 2 > 0) {
|
300
|
+
return false;
|
301
|
+
}
|
302
|
+
//regex for testing corresponding values match
|
303
|
+
const numerictest = /^[-+]?\d+([\.,]\d+)?$/; //for testing numeric values
|
304
|
+
const stringtest = /[eastsouthnorthwest]+/i; //for testing string values (north, south, etc)
|
305
|
+
const halflen = filteredMatch.length / 2;
|
306
|
+
for (let i = 0; i < halflen; i++) {
|
307
|
+
const leftside = filteredMatch[i];
|
308
|
+
const rightside = filteredMatch[i + halflen];
|
309
|
+
const bothAreNumbers = numerictest.test(leftside) && numerictest.test(rightside);
|
310
|
+
const bothAreStrings = stringtest.test(leftside) && stringtest.test(rightside);
|
311
|
+
const valuesAreEqual = leftside == rightside;
|
312
|
+
if (leftside == undefined && rightside == undefined) { //we have to handle undefined because regex converts it to string 'undefined'!!
|
313
|
+
continue;
|
314
|
+
}
|
315
|
+
else if (leftside == undefined || rightside == undefined) { //no we need to handle the case where one is and the other not...
|
316
|
+
return false;
|
317
|
+
}
|
318
|
+
else if (bothAreNumbers || bothAreStrings || valuesAreEqual) {
|
319
|
+
continue;
|
320
|
+
}
|
321
|
+
else {
|
322
|
+
return false;
|
323
|
+
}
|
324
|
+
}
|
325
|
+
return true;
|
326
|
+
}
|
327
|
+
//functions for coordinate validation
|
328
|
+
//as decimal arithmetic is not straightforward, we approximate
|
329
|
+
function decimalsCloseEnough(dec1, dec2) {
|
330
|
+
const originaldiff = Math.abs(dec1 - dec2);
|
331
|
+
const diff = Number(originaldiff.toFixed(6));
|
332
|
+
if (diff <= 0.00001) {
|
333
|
+
return true;
|
334
|
+
}
|
335
|
+
else {
|
336
|
+
return false;
|
337
|
+
}
|
338
|
+
}
|
339
|
+
function coordsCloseEnough(coordsToTest) {
|
340
|
+
if (coordsToTest.includes(',')) {
|
341
|
+
const coords = coordsToTest.split(',');
|
342
|
+
if (Number(coords[0]) == NaN || Number(coords[1]) == NaN) {
|
343
|
+
throw new Error("coords are not valid decimals");
|
344
|
+
}
|
345
|
+
else {
|
346
|
+
return decimalsCloseEnough(this.decimalLatitude, Number(coords[0])) && decimalsCloseEnough(this.decimalLongitude, coords[1]); //this here will be the converted coordinates object
|
347
|
+
}
|
348
|
+
}
|
349
|
+
else {
|
350
|
+
throw new Error("coords being tested must be separated by a comma");
|
351
|
+
}
|
352
|
+
}
|
353
|
+
const to = Object.freeze({
|
354
|
+
DMS: 'DMS',
|
355
|
+
DM: 'DM'
|
356
|
+
});
|
357
|
+
converter.to = to;
|
358
|
+
export default converter;
|
@@ -0,0 +1,6 @@
|
|
1
|
+
//adds the formats to the convert object
|
2
|
+
//we need to use this as the source for the npm package so that the formats are not included in the bundle
|
3
|
+
import converter from './converter.js';
|
4
|
+
import testFormats from './tests/testformats.js';
|
5
|
+
converter.formats = testFormats.map(format => format.verbatimCoordinates);
|
6
|
+
export const convert = converter;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
//Coordinates pattern matching regex
|
2
|
+
//decimal degrees
|
3
|
+
const dd_re = /(NORTH|SOUTH|[NS])?[\s]*([+-]?[0-8]?[0-9](?:[\.,]\d{3,}))[\s]*([•º°]?)[\s]*(NORTH|SOUTH|[NS])?[\s]*[,/;]?[\s]*(EAST|WEST|[EW])?[\s]*([+-]?[0-1]?[0-9]?[0-9](?:[\.,]\d{3,}))[\s]*([•º°]?)[\s]*(EAST|WEST|[EW])?/i;
|
4
|
+
//degrees minutes seconds with '.' as separator - gives array with 15 values
|
5
|
+
const dms_periods = /(NORTH|SOUTH|[NS])?\s*([+-]?[0-8]?[0-9])\s*(\.)\s*([0-5]?[0-9])\s*(\.)\s*((?:[0-5]?[0-9])(?:[\.,]\d{1,3})?)?\s*(NORTH|SOUTH|[NS])?(?:\s*[,/;]\s*|\s*)(EAST|WEST|[EW])?\s*([+-]?[0-1]?[0-9]?[0-9])\s*(\.)\s*([0-5]?[0-9])\s*(\.)\s*((?:[0-5]?[0-9])(?:[\.,]\d{1,3})?)?\s*(EAST|WEST|[EW])?/i;
|
6
|
+
//degrees minutes seconds with words 'degrees, minutes, seconds' as separators (needed because the s of seconds messes with the S of SOUTH) - gives array of 17 values
|
7
|
+
const dms_abbr = /(NORTH|SOUTH|[NS])?\s*([+-]?[0-8]?[0-9])\s*(D(?:EG)?(?:REES)?)\s*([0-5]?[0-9])\s*(M(?:IN)?(?:UTES)?)\s*((?:[0-5]?[0-9])(?:[\.,]\d{1,3})?)?\s*(S(?:EC)?(?:ONDS)?)?\s*(NORTH|SOUTH|[NS])?(?:\s*[,/;]\s*|\s*)(EAST|WEST|[EW])?\s*([+-]?[0-1]?[0-9]?[0-9])\s*(D(?:EG)?(?:REES)?)\s*([0-5]?[0-9])\s*(M(?:IN)?(?:UTES)?)\s*((?:[0-5]?[0-9])(?:[\.,]\d{1,3})?)?\s*(S(?:EC)?(?:ONDS)?)\s*(EAST|WEST|[EW])?/i;
|
8
|
+
//everything else - gives array of 17 values
|
9
|
+
const coords_other = /(NORTH|SOUTH|[NS])?\s*([+-]?[0-8]?[0-9])\s*([•º°\.:]|D(?:EG)?(?:REES)?)?\s*,?([0-5]?[0-9](?:[\.,]\d{1,})?)?\s*(['′´’\.:]|M(?:IN)?(?:UTES)?)?\s*,?((?:[0-5]?[0-9])(?:[\.,]\d{1,3})?)?\s*(''|′′|’’|´´|["″”\.])?\s*(NORTH|SOUTH|[NS])?(?:\s*[,/;]\s*|\s*)(EAST|WEST|[EW])?\s*([+-]?[0-1]?[0-9]?[0-9])\s*([•º°\.:]|D(?:EG)?(?:REES)?)?\s*,?([0-5]?[0-9](?:[\.,]\d{1,})?)?\s*(['′´’\.:]|M(?:IN)?(?:UTES)?)?\s*,?((?:[0-5]?[0-9])(?:[\.,]\d{1,3})?)?\s*(''|′′|´´|’’|["″”\.])?\s*(EAST|WEST|[EW])?/i;
|
10
|
+
export { dd_re, dms_periods, dms_abbr, coords_other };
|
@@ -0,0 +1,24 @@
|
|
1
|
+
//TODO These formats should throw...
|
2
|
+
const failingFormats = [
|
3
|
+
'10,10',
|
4
|
+
'46,8',
|
5
|
+
'12.12323, 123',
|
6
|
+
'24.0, 26.0',
|
7
|
+
'33.25°S 18.25°E',
|
8
|
+
'27.0 23.0',
|
9
|
+
'10.00000S 10.000000E',
|
10
|
+
'00.00 01.00',
|
11
|
+
'50°4\'17.698"south, 24.34532',
|
12
|
+
'90°4\'17.698"south, 23°4\'17.698"east',
|
13
|
+
'89°4\'17.698"south, 183°4\'17.698"east',
|
14
|
+
'50°4\'17.698"east, 23°4\'17.698"south',
|
15
|
+
'E23.34355,S25.324234',
|
16
|
+
'23°45\'12.2\'\'S 18.33\'56.7\'\'E',
|
17
|
+
'S 27.45.34 23.23.23',
|
18
|
+
'S 27.45.34 S 23.23.23',
|
19
|
+
'S 90°4\'17.698" S 23°4\'17.698"',
|
20
|
+
'27.45.34 S S 23.23.23',
|
21
|
+
'27.45.34 23.23.23 E',
|
22
|
+
'8°83S 35°67E '
|
23
|
+
];
|
24
|
+
export default failingFormats;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import fs from 'fs';
|
2
|
+
import testFormats from './testformats.js';
|
3
|
+
fs.writeFile("testFormats.json", JSON.stringify(testFormats, null, 2), 'utf8', function (err) {
|
4
|
+
if (err) {
|
5
|
+
console.log("An error occured while writing JSON Object to File.");
|
6
|
+
return console.log(err);
|
7
|
+
}
|
8
|
+
console.log("JSON file has been saved.");
|
9
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import convert from '../converter.js';
|
2
|
+
import testFormats from '../testformats.js';
|
3
|
+
import failingFormats from './failFormats.js';
|
4
|
+
let allPassed = true;
|
5
|
+
//FORMATS THAT SHOULD BE CONVERTED
|
6
|
+
for (const t of testFormats) {
|
7
|
+
try {
|
8
|
+
const converted = convert(t.verbatimCoordinates, 8);
|
9
|
+
const testDecimalCoordsString = `${t.decimalLatitude},${t.decimalLongitude}`;
|
10
|
+
//check the calculation is correct
|
11
|
+
if (!converted.closeEnough(testDecimalCoordsString)) {
|
12
|
+
console.log("Error in decimal conversion");
|
13
|
+
console.log(t.verbatimCoordinates);
|
14
|
+
console.log(t.decimalLatitude);
|
15
|
+
console.log(t.decimalLongitude);
|
16
|
+
allPassed = false;
|
17
|
+
}
|
18
|
+
//check the verbatim coords are correct
|
19
|
+
if (converted.verbatimLatitude != t.verbatimLatitude || converted.verbatimLongitude != t.verbatimLongitude) {
|
20
|
+
console.log("Error in verbatim extraction");
|
21
|
+
console.log('For', t.verbatimCoordinates);
|
22
|
+
console.log('got', converted.verbatimLatitude, 'should be ', t.verbatimLatitude);
|
23
|
+
console.log('got', converted.verbatimLongitude, 'should be', t.verbatimLongitude);
|
24
|
+
allPassed = false;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
catch (err) {
|
28
|
+
console.log("Failed to convert the following format");
|
29
|
+
console.log(t.verbatimCoordinates);
|
30
|
+
console.log(err.message);
|
31
|
+
allPassed = false;
|
32
|
+
}
|
33
|
+
}
|
34
|
+
//FORMATS THAT SHOULD NOT BE CONVERTED
|
35
|
+
const converting = [];
|
36
|
+
for (let f of failingFormats) {
|
37
|
+
try {
|
38
|
+
const converted = convert(f);
|
39
|
+
converting.push(f);
|
40
|
+
allPassed = false;
|
41
|
+
}
|
42
|
+
catch {
|
43
|
+
//nothing here
|
44
|
+
}
|
45
|
+
}
|
46
|
+
if (converting.length) {
|
47
|
+
console.log("The following coordinates should NOT have converted successfully: " + converting.join(' | '));
|
48
|
+
}
|
49
|
+
if (allPassed) {
|
50
|
+
console.log("all formats successfully converted");
|
51
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import convert from '../converter.js';
|
2
|
+
//const test = '26°44S 29°46E'
|
3
|
+
//const test = '00.00, 01.00'
|
4
|
+
const test = `8°83S 35°67E`;
|
5
|
+
try {
|
6
|
+
let converted = convert(test);
|
7
|
+
console.log(converted);
|
8
|
+
console.log(converted.toCoordinateFormat(convert.to.DM));
|
9
|
+
//and just to make sure it's frozen
|
10
|
+
let previous = converted.decimalLatitude;
|
11
|
+
converted.decimalLatitude = 24;
|
12
|
+
if (converted.decimalLatitude === previous) {
|
13
|
+
console.log('the result is frozen');
|
14
|
+
}
|
15
|
+
else {
|
16
|
+
console.error('!!!The result is not frozen!!!!');
|
17
|
+
}
|
18
|
+
}
|
19
|
+
catch (err) {
|
20
|
+
console.log(err.message);
|
21
|
+
}
|