Workflow funktioniert nun wieder. Es gab Probleme nach Aenderungen.
Build and Publish Site / docker (push) Successful in 23s
Build and Publish Site / docker (push) Successful in 23s
ABER: Die Applikation funktioniert nur lokal. Die deployte Version geht noch nicht.
This commit is contained in:
+3
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "4.2"
|
||||
script:
|
||||
- make test && (make test-ci-coverage || true)
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Natural Atlas, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
.PHONY: test test-ci-coverage release
|
||||
|
||||
_MOCHA=node_modules/.bin/_mocha
|
||||
ISTANBUL=node_modules/.bin/istanbul
|
||||
CODECOV=node_modules/.bin/codecov
|
||||
|
||||
test:
|
||||
npm run test
|
||||
|
||||
test-ci-coverage:
|
||||
npm install codecov.io
|
||||
npm install istanbul
|
||||
@rm -rf coverage
|
||||
$(ISTANBUL) cover $(_MOCHA) --report lcovonly -- -R tap
|
||||
|
||||
@echo
|
||||
@echo Sending report to codecov...
|
||||
@cat ./coverage/lcov.info | $(CODECOV)
|
||||
@rm -rf ./coverage
|
||||
@echo Done
|
||||
|
||||
release:
|
||||
ifeq ($(strip $(version)),)
|
||||
@echo "\033[31mERROR:\033[0;39m No version provided."
|
||||
@echo "\033[1;30mmake release version=1.0.0\033[0;39m"
|
||||
else
|
||||
rm -rf node_modules
|
||||
npm install
|
||||
make test
|
||||
sed -i.bak 's/"version": "[^"]*"/"version": "$(version)"/' package.json
|
||||
rm *.bak
|
||||
git add .
|
||||
git commit -a -m "Released $(version)."
|
||||
git tag v$(version)
|
||||
git push origin master
|
||||
git push origin --tags
|
||||
npm publish
|
||||
@echo "\033[32mv${version} released\033[0;39m"
|
||||
endif
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
# coord-parser
|
||||
[](https://www.npmjs.org/package/coord-parser)
|
||||
[](https://travis-ci.org/naturalatlas/coord-parser)
|
||||
[](https://codecov.io/github/naturalatlas/coord-parser)
|
||||
|
||||
`coord-parser` is a DMS coordinate parsing library designed to handle very rough / mangled user input. It's a re-write of Gregor MacLennan's [`parse-dms`](https://github.com/gmaclennan/parse-dms). If you notice something it can't parse, open an issue or pull request.
|
||||
|
||||
```sh
|
||||
$ npm install coord-parser --save
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```js
|
||||
var parse = require('coord-parser');
|
||||
|
||||
parse('59°12\'7.7“N 02°15\'39.6“W');
|
||||
parse('N59°12\'7.7" W02°15\'39.6"');
|
||||
parse('-2.1S-1.1E');
|
||||
parse('2N,1');
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Before submitting pull requests, please update the [tests](test) and make sure they all pass.
|
||||
|
||||
```sh
|
||||
$ npm test
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2015 Natural Atlas, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
var TOKEN_WHITESPACE = '\\s*';
|
||||
var TOKEN_SEPARATOR = '[,;\\s]*';
|
||||
var TOKEN_FLOAT = '(-?\\d+(?:\\.\\d+)?)';
|
||||
var TOKEN_DEG = TOKEN_FLOAT + TOKEN_WHITESPACE + '[°º:d]?';
|
||||
var TOKEN_MIN = TOKEN_FLOAT + TOKEN_WHITESPACE + '[\'’‘′:]';
|
||||
var TOKEN_SEC = TOKEN_FLOAT + TOKEN_WHITESPACE + '(?:"|″|’’|\'\'|”|“)?';
|
||||
var TOKEN_DMS = TOKEN_DEG + optional(TOKEN_WHITESPACE + TOKEN_MIN) + optional(TOKEN_WHITESPACE + TOKEN_SEC);
|
||||
var TOKEN_DIR = '([NSEW]?)';
|
||||
|
||||
function optional(re) {
|
||||
return '(?:' + re + ')?';
|
||||
}
|
||||
function inRange(value, a, b) {
|
||||
return value >= a && value <= b;
|
||||
}
|
||||
|
||||
function dmsToDec(deg, min, sec) {
|
||||
deg = parseFloat(deg);
|
||||
min = parseFloat(min) || 0;
|
||||
sec = parseFloat(sec) || 0;
|
||||
var sign = deg < 0 ? -1 : 1;
|
||||
if (!inRange(min, 0, 60)) throw new Error('Minutes out of range');
|
||||
if (!inRange(sec, 0, 60)) throw new Error('Seconds out of range');
|
||||
return (deg + sign * min / 60 + sign * sec / 3600);
|
||||
}
|
||||
|
||||
function apply(deg, min, sec, cardinality, result) {
|
||||
if (typeof deg === 'undefined') return;
|
||||
var prop = 'lat', coeff = 1;
|
||||
if (cardinality === 'e' || cardinality === 'w') {
|
||||
prop = 'lon';
|
||||
}
|
||||
|
||||
// 1E -> 1.0, 1W -> -1.0
|
||||
// 1N -> 1.0, 1S -> -1.0
|
||||
if (cardinality === 's') coeff = -1;
|
||||
if (cardinality === 'w') coeff = -1;
|
||||
result[prop] = coeff * dmsToDec(deg, min, sec);
|
||||
}
|
||||
|
||||
function normalizeCardinality(a, b) {
|
||||
a = (a || '').toLowerCase();
|
||||
b = (b || '').toLowerCase();
|
||||
// +n, +e
|
||||
if (!a && !b) return ['n', 'e'];
|
||||
if (a && !b) return [a, a === 'n' || a === 's' ? 'e' : 'n'];
|
||||
if (!a && b) return [b === 'n' || b === 's' ? 'e' : 'n', b];
|
||||
return [a, b];
|
||||
}
|
||||
|
||||
|
||||
module.exports = function(input) {
|
||||
input = input.trim();
|
||||
|
||||
var regExpA = new RegExp('^' + TOKEN_FLOAT + '$', 'ig');
|
||||
var regExpB = new RegExp('^' + TOKEN_FLOAT + TOKEN_SEPARATOR + TOKEN_FLOAT + '$', 'ig');
|
||||
var regExpC = new RegExp('^' + TOKEN_DMS + TOKEN_WHITESPACE + TOKEN_DIR + '(?:' + TOKEN_SEPARATOR + TOKEN_DMS + TOKEN_WHITESPACE + TOKEN_DIR + ')?$', 'ig'); // 0°W, O°N
|
||||
var regExpD = new RegExp('^' + TOKEN_DIR + TOKEN_WHITESPACE + TOKEN_DMS + '(?:' + TOKEN_SEPARATOR + TOKEN_DIR + TOKEN_WHITESPACE + TOKEN_DMS + ')?$', 'ig'); // N0, WO
|
||||
|
||||
var match, cardinality;
|
||||
var result = {};
|
||||
if (match = regExpA.exec(input)) {
|
||||
return parseFloat(match[1]);
|
||||
} else if (match = regExpB.exec(input)) {
|
||||
return {
|
||||
lat: parseFloat(match[1]),
|
||||
lon: parseFloat(match[2])
|
||||
};
|
||||
} else if (match = regExpC.exec(input)) {
|
||||
cardinality = normalizeCardinality(match[4], match[8]);
|
||||
if (!match[4] && !match[5]) return dmsToDec(match[1], match[2], match[3]);
|
||||
apply(match[1], match[2], match[3], cardinality[0], result);
|
||||
apply(match[5], match[6], match[7], cardinality[1], result);
|
||||
} else if (match = regExpD.exec(input)) {
|
||||
cardinality = normalizeCardinality(match[1], match[5]);
|
||||
apply(match[2], match[3], match[4], cardinality[0], result);
|
||||
apply(match[6], match[7], match[8], cardinality[1], result);
|
||||
} else {
|
||||
throw new Error('Could not parse string: ' + input);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "coord-parser",
|
||||
"version": "1.0.0",
|
||||
"description": "Loose geographic coordinate parsing library (designed for user input)",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "mocha -R tap"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/gmaclennan/coord-parser.git"
|
||||
},
|
||||
"author": "Brian Reavis <brian@naturalatlas.com>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/naturalatlas/coord-parser/issues"
|
||||
},
|
||||
"homepage": "https://github.com/naturalatlas/coord-parser",
|
||||
"devDependencies": {
|
||||
"chai": "^3.4.1",
|
||||
"mocha": "^2.3.4"
|
||||
}
|
||||
}
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
var parse = require('../index');
|
||||
var assert = require('chai').assert;
|
||||
|
||||
function parseTest(input, expected) {
|
||||
describe('"' + input + '"', function() {
|
||||
it('should parse', function() {
|
||||
assert.deepEqual(parse(input), expected);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('DMS pairs with different separators, hemisphere at end', function() {
|
||||
var testData = [
|
||||
'59°12\'7.7"N 02°15\'39.6"W',
|
||||
'59°12\'7.7”N 02°15\'39.6”W',
|
||||
'59°12\'7.7“N 02°15\'39.6“W',
|
||||
'59º12\'7.7"N 02º15\'39.6"W',
|
||||
'59 12\' 7.7" N 02 15\' 39.6" W',
|
||||
'59 12\'7.7\'\'N 02 15\'39.6\'\' W',
|
||||
'59:12:7.7"N 2:15:39.6W',
|
||||
'59 12’7.7’’N 02 15’39.6’’W'
|
||||
];
|
||||
|
||||
var expected = {
|
||||
lat: 59 + 12 / 60 + 7.7 / 3600,
|
||||
lon: -1 * (2 + 15 / 60 + 39.6 / 3600)
|
||||
};
|
||||
|
||||
testData.forEach(function(input) {
|
||||
parseTest(input, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Simple DMS pairs (rough user-input style)', function() {
|
||||
parseTest('1W2N', {lat: 2, lon: -1});
|
||||
parseTest('1E2N', {lat: 2, lon: 1});
|
||||
parseTest('1W2S', {lat: -2, lon: -1});
|
||||
parseTest('1E2S', {lat: -2, lon: 1});
|
||||
parseTest('-1.1W-2.1N', {lat: -2.1, lon: 1.1});
|
||||
parseTest('-1.1E-2.1N', {lat: -2.1, lon: -1.1});
|
||||
parseTest('-1.1W-2.1S', {lat: 2.1, lon: 1.1});
|
||||
parseTest('-1.1E-2.1S', {lat: 2.1, lon: -1.1});
|
||||
parseTest('-2.1N-1.1W', {lat: -2.1, lon: 1.1});
|
||||
parseTest('-2.1N-1.1E', {lat: -2.1, lon: -1.1});
|
||||
parseTest('-2.1S-1.1W', {lat: 2.1, lon: 1.1});
|
||||
parseTest('-2.1S-1.1E', {lat: 2.1, lon: -1.1});
|
||||
parseTest('12.34,56.78', {lat: 12.34, lon: 56.78});
|
||||
parseTest('-12.34,-56.78', {lat: -12.34, lon: -56.78});
|
||||
});
|
||||
|
||||
describe('Hemisphere inference from other coordinate', function() {
|
||||
parseTest('1,2N', {lat: 2, lon: 1});
|
||||
parseTest('1,2N', {lat: 2, lon: 1});
|
||||
parseTest('1,2S', {lat: -2, lon: 1});
|
||||
parseTest('1,2S', {lat: -2, lon: 1});
|
||||
parseTest('2N,1', {lat: 2, lon: 1});
|
||||
parseTest('2N,1', {lat: 2, lon: 1});
|
||||
parseTest('2S,1', {lat: -2, lon: 1});
|
||||
parseTest('2S,1', {lat: -2, lon: 1});
|
||||
|
||||
parseTest('1,2E', {lat: 1, lon: 2});
|
||||
parseTest('1,2E', {lat: 1, lon: 2});
|
||||
parseTest('1,2W', {lat: 1, lon: -2});
|
||||
parseTest('1,2W', {lat: 1, lon: -2});
|
||||
parseTest('2E,1', {lat: 1, lon: 2});
|
||||
parseTest('2E,1', {lat: 1, lon: 2});
|
||||
parseTest('2W,1', {lat: 1, lon: -2});
|
||||
parseTest('2W,1', {lat: 1, lon: -2});
|
||||
});
|
||||
|
||||
describe('DMS pairs with hemisphere at beginning', function() {
|
||||
var testData = [
|
||||
'N59°12\'7.7" W02°15\'39.6"',
|
||||
'W02°15\'39.6" N59°12\'7.7"'
|
||||
];
|
||||
|
||||
var expected = {
|
||||
lat: 59 + 12 / 60 + 7.7 / 3600,
|
||||
lon: -1 * (2 + 15 / 60 + 39.6 / 3600)
|
||||
};
|
||||
|
||||
testData.forEach(function(input) {
|
||||
parseTest(input, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Various separators between lat / lon pairs', function() {
|
||||
var testData = [
|
||||
'59°12\'7.7"N 02°15\'39.6"W',
|
||||
'59°12\'7.7"N , 02°15\'39.6"W',
|
||||
'59°12\'7.7"N,02°15\'39.6"W'
|
||||
];
|
||||
|
||||
var expected = {
|
||||
lat: 59 + 12 / 60 + 7.7 / 3600,
|
||||
lon: -1 * (2 + 15 / 60 + 39.6 / 3600)
|
||||
};
|
||||
|
||||
testData.forEach(function(input) {
|
||||
parseTest(input, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('single coordinate with hemisphere', function() {
|
||||
var testData = [
|
||||
'59°12\'7.7"N',
|
||||
'02°15\'39.6"W'
|
||||
];
|
||||
|
||||
var expected = [
|
||||
{lat: 59 + 12 / 60 + 7.7 / 3600},
|
||||
{lon: -1 * (2 + 15 / 60 + 39.6 / 3600)}
|
||||
];
|
||||
|
||||
testData.forEach(function(input, i) {
|
||||
parseTest(input, expected[i]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Single coordinate with no hemisphere', function() {
|
||||
var testData = [
|
||||
'12.123',
|
||||
'59°12\'7.7"',
|
||||
'02°15\'39.6"',
|
||||
'-02°15\'39.6"'
|
||||
];
|
||||
|
||||
var expected = [
|
||||
12.123,
|
||||
59 + 12 / 60 + 7.7 / 3600,
|
||||
2 + 15 / 60 + 39.6 / 3600,
|
||||
-1 * (2 + 15 / 60 + 39.6 / 3600)
|
||||
];
|
||||
|
||||
testData.forEach(function(input, i) {
|
||||
parseTest(input, expected[i]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Infer first coordinate is lat, second lon, if no hemisphere letter is included', function() {
|
||||
var testData = [
|
||||
'59°12\'7.7" -02°15\'39.6"',
|
||||
'59°12\'7.7", -02°15\'39.6"',
|
||||
];
|
||||
|
||||
var expected = {
|
||||
lat: 59 + 12 / 60 + 7.7 / 3600,
|
||||
lon: -1 * (2 + 15 / 60 + 39.6 / 3600)
|
||||
};
|
||||
|
||||
testData.forEach(function(input, i) {
|
||||
parseTest(input, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Throws when input invalid', function() {
|
||||
assert.throws(function() { parse('Not DMS string'); }, /Could not parse string/);
|
||||
assert.throws(function() { parse('59°65\'7.7" -02°15\'39.6"'); }, /Minutes out of range/);
|
||||
assert.throws(function() { parse('59°12\'65.5" -02°15\'39.6"'); }, /Seconds out of range/);
|
||||
});
|
||||
|
||||
describe('DMS with decimal minutes', function() {
|
||||
var testData = [
|
||||
'N59°12.105\' W02°15.66\''
|
||||
];
|
||||
|
||||
var expected = {
|
||||
lat: 59 + 12.105 / 60,
|
||||
lon: -1 * (2 + 15.66 / 60)
|
||||
};
|
||||
|
||||
testData.forEach(function(input) {
|
||||
parseTest(input, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Parse DMS with no minutes or seconds', function() {
|
||||
var testData = [
|
||||
'59°N 02°W'
|
||||
];
|
||||
|
||||
var expected = {
|
||||
lat: 59,
|
||||
lon: -2
|
||||
};
|
||||
|
||||
testData.forEach(function(input) {
|
||||
parseTest(input, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Parse decimal degrees as decimal degrees', function() {
|
||||
var testData = [
|
||||
'51.5, -0.126',
|
||||
'51.5,-0.126',
|
||||
'51.5 -0.126'
|
||||
];
|
||||
|
||||
var expected = {
|
||||
lat: 51.5,
|
||||
lon: -0.126
|
||||
};
|
||||
|
||||
testData.forEach(function(input) {
|
||||
parseTest(input, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Parse DMS with separators and spaces', function() {
|
||||
var testData = [
|
||||
'59° 12\' 7.7" N 02° 15\' 39.6" W',
|
||||
'59º 12\' 7.7" N 02º 15\' 39.6" W',
|
||||
'59 12’ 7.7’’N 02 15’ 39.6’’W'
|
||||
];
|
||||
|
||||
var expected = {
|
||||
lat: 59 + 12 / 60 + 7.7 / 3600,
|
||||
lon: -1 * (2 + 15 / 60 + 39.6 / 3600)
|
||||
};
|
||||
|
||||
testData.forEach(function(input) {
|
||||
parseTest(input, expected);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user