Skip to content

Commit c035f71

Browse files
committed
first commit
0 parents  commit c035f71

12 files changed

+300
-0
lines changed

.editorconfig

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false

.gitignore

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Logs
2+
logs
3+
*.log
4+
5+
# Runtime data
6+
pids
7+
*.pid
8+
*.seed
9+
10+
# Directory for instrumented libs generated by jscoverage/JSCover
11+
lib-cov
12+
13+
# Coverage directory used by tools like istanbul
14+
coverage
15+
16+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17+
.grunt
18+
19+
# node-waf configuration
20+
.lock-wscript
21+
22+
# Compiled binary addons (http://nodejs.org/api/addons.html)
23+
build/Release
24+
25+
# Dependency directory
26+
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
27+
node_modules
28+
lib

.node-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v5

.npmignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
src
3+
.*

.nvmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v5

.travis.yml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
language: node_js
2+
node_js:
3+
- "0.12"
4+
- "4"
5+
- "5"
6+
notifications:
7+
email: false

LICENSE

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015 Leonardo Gatica
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

README.md

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# simple-reverse-geocoder
2+
3+
[![npm version](https://img.shields.io/npm/v/simple-reverse-geocoder.svg?style=flat-square)](https://www.npmjs.com/package/simple-reverse-geocoder)
4+
[![npm downloads](https://img.shields.io/npm/dm/simple-reverse-geocoder.svg?style=flat-square)](https://www.npmjs.com/package/simple-reverse-geocoder)
5+
[![dependency Status](https://img.shields.io/david/lgaticaq/simple-reverse-geocoder.svg?style=flat-square)](https://david-dm.org/lgaticaq/simple-reverse-geocoder#info=dependencies)
6+
[![Build Status](https://img.shields.io/travis/lgaticaq/simple-reverse-geocoder.svg?style=flat-square)](https://travis-ci.org/lgaticaq/simple-reverse-geocoder)
7+
[![devDependency Status](https://img.shields.io/david/dev/lgaticaq/simple-reverse-geocoder.svg?style=flat-square)](https://david-dm.org/lgaticaq/simple-reverse-geocoder#info=devDependencies)
8+
[![Join the chat at https://gitter.im/lgaticaq/simple-reverse-geocoder](https://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg?style=flat-square)](https://gitter.im/lgaticaq/simple-reverse-geocoder?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
9+
10+
Get address from a point
11+
12+
## Installation
13+
14+
```bash
15+
npm i -S simple-reverse-geocoder
16+
```
17+
18+
## Use
19+
20+
[Try on Tonic](https://tonicdev.com/npm/simple-reverse-geocoder)
21+
```js
22+
import meitrack from 'simple-reverse-geocoder'
23+
24+
const rg = require('simple-reverse-geocoder');
25+
26+
const loc = {type: 'Point', coordinates: [-70.5171743, -33.3608387]};
27+
rg.getAddress(loc).then(console.log); // 'Del Candil 665-701, Lo Barnechea'
28+
```

example.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const rg = require('simple-reverse-geocoder');
2+
3+
const loc = {type: 'Point', coordinates: [-70.5171743, -33.3608387]};
4+
const address = await rg.getAddress(loc);

package.json

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{
2+
"name": "simple-reverse-geocoder",
3+
"version": "1.0.0",
4+
"description": "Get address from a point",
5+
"main": "lib",
6+
"scripts": {
7+
"prepublish": "npm run build -s",
8+
"prebuild": "npm run lint -s && npm run clean -s",
9+
"build": "babel src --out-dir lib --source-maps",
10+
"lint": "eslint src",
11+
"clean": "rimraf lib",
12+
"pretest": "npm run build -s",
13+
"test": "mocha --compilers js:babel-core/register"
14+
},
15+
"engines": {
16+
"node": ">=0.12"
17+
},
18+
"repository": {
19+
"type": "git",
20+
"url": "https://github.com/lgaticaq/simple-reverse-geocoder.git"
21+
},
22+
"keywords": [
23+
"reverse",
24+
"geocoder"
25+
],
26+
"author": "Leonardo Gatica <lgatica@protonmail.com> (https://about.me/lgatica)",
27+
"license": "MIT",
28+
"bugs": {
29+
"url": "https://github.com/lgaticaq/simple-reverse-geocoder/issues"
30+
},
31+
"homepage": "https://github.com/lgaticaq/simple-reverse-geocoder#readme",
32+
"dependencies": {
33+
"bluebird": "^3.3.1",
34+
"hiredis": "^0.4.1",
35+
"node-geocoder": "^3.7.0",
36+
"redis-url": "^1.2.1"
37+
},
38+
"devDependencies": {
39+
"babel-cli": "^6.5.1",
40+
"babel-core": "^6.5.2",
41+
"babel-preset-es2015": "^6.5.0",
42+
"chai": "^3.5.0",
43+
"eslint": "1.10.3",
44+
"mocha": "^2.4.5",
45+
"rimraf": "^2.5.2"
46+
},
47+
"eslintConfig": {
48+
"rules": {
49+
"strict": 0,
50+
"indent": [
51+
2,
52+
2
53+
],
54+
"quotes": [
55+
2,
56+
"single"
57+
],
58+
"linebreak-style": [
59+
2,
60+
"unix"
61+
],
62+
"semi": [
63+
2,
64+
"always"
65+
]
66+
},
67+
"ecmaFeatures": {
68+
"modules": true
69+
},
70+
"env": {
71+
"es6": true,
72+
"node": true,
73+
"mocha": true
74+
},
75+
"extends": "eslint:recommended"
76+
},
77+
"babel": {
78+
"presets": [
79+
"es2015"
80+
]
81+
},
82+
"tonicExampleFilename": "example.js"
83+
}

src/index.js

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'use strict';
2+
3+
import redisUrl from 'redis-url';
4+
import nodeGeocoder from 'node-geocoder';
5+
import Promise from 'bluebird';
6+
7+
let client;
8+
9+
const setCache = (uri) => {
10+
try {
11+
client = redisUrl.connect(uri);
12+
Promise.promisifyAll(Object.getPrototypeOf(client));
13+
} catch (err) {
14+
throw err;
15+
}
16+
};
17+
18+
const getReverse = (lat, lng) => {
19+
return new Promise((resolve, reject) => {
20+
const geocoderProvider = 'google';
21+
const httpAdapter = 'http';
22+
const geocoder = nodeGeocoder(geocoderProvider, httpAdapter);
23+
geocoder.reverse({lat: lat, lon: lng}).then(res => {
24+
if (res.length === 0) resolve(null);
25+
resolve(res[0].formattedAddress.split(',').map(x => x.trim()).slice(0, 2).join(', '));
26+
}).catch(reject);
27+
});
28+
};
29+
30+
const getCoordinates = (loc) => {
31+
return new Promise((resolve, reject) => {
32+
try {
33+
const [lng, lat] = loc.coordinates;
34+
resolve({lng: lng, lat: lat});
35+
} catch (err) {
36+
reject(err);
37+
}
38+
});
39+
};
40+
41+
const getFromCache = (lat, lng) => {
42+
return new Promise((resolve, reject) => {
43+
client.getAsync(`geocoder:${lat}:${lng}`).then(resolve).catch(reject);
44+
});
45+
};
46+
47+
const getAddress = (loc) => {
48+
return new Promise((resolve, reject) => {
49+
getCoordinates(loc).then(({lng, lat}) => {
50+
if (client) {
51+
getFromCache(lat, lng).then(reply => {
52+
if (reply) resolve(reply);
53+
getReverse(lat, lng).then(address => {
54+
if (!address) resolve(null);
55+
client.set(`geocoder:${lat}:${lng}`, address);
56+
resolve(address);
57+
}).catch(reject);
58+
}).catch(reject);
59+
} else {
60+
getReverse(lat, lng).then(resolve).catch(reject);
61+
}
62+
}).catch(reject);
63+
});
64+
};
65+
66+
const clearCache = (lat, lng) => {
67+
if (client) {
68+
client.del(`geocoder:${lat}:${lng}`);
69+
}
70+
};
71+
72+
module.exports = {
73+
setCache: setCache,
74+
getAddress: getAddress,
75+
getFromCache: getFromCache,
76+
clearCache: clearCache
77+
};

test/test.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
import lib from '../lib';
4+
import {expect} from 'chai';
5+
6+
describe('simple-reverse-geocoder', () => {
7+
describe('getAddress', () => {
8+
it('should return a valid address', (done) => {
9+
const loc = {type: 'Point', coordinates: [-70.5171743, -33.3608387]};
10+
lib.setCache();
11+
lib.getAddress(loc).then(data => {
12+
expect(data).to.eql('Del Candil 665-701, Lo Barnechea');
13+
done();
14+
}).catch(err => {
15+
expect(err).to.be.undefined;
16+
done();
17+
});
18+
});
19+
20+
it('should return a valid address', (done) => {
21+
lib.getFromCache(-33.3608387, -70.5171743).then(reply => {
22+
expect(reply).to.eql('Del Candil 665-701, Lo Barnechea');
23+
done();
24+
}).catch(err => {
25+
expect(err).to.be.undefined;
26+
done();
27+
});
28+
});
29+
});
30+
31+
after(() => {
32+
lib.clearCache(-33.3608387, -70.5171743);
33+
});
34+
});

0 commit comments

Comments
 (0)