├── .eslintrc ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── Overpass_API.png ├── README.md ├── index.js ├── index.test.js ├── package-lock.json └── package.json /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb-base", "prettier"], 3 | "plugins": ["import"], 4 | "env": { 5 | "node": true 6 | }, 7 | "rules": { 8 | "arrow-parens": ["warn", "as-needed", { "requireForBlockBody": true }], 9 | "comma-dangle": ["error", "never"], 10 | "max-len": ["error", { "code": 100, "ignoreUrls": true }], 11 | "quotes": ["error", "single"] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.osm 2 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | dist: trusty 4 | 5 | branches: 6 | except: 7 | - /^v[0-9]/ 8 | 9 | node_js: 10 | - "8" 11 | - "10" 12 | 13 | before_install: npm i -g greenkeeper-lockfile@1 14 | 15 | before_script: greenkeeper-lockfile-update 16 | 17 | script: npm test 18 | 19 | after_script: greenkeeper-lockfile-upload 20 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | 6 | # 1.0.0 (2018-09-17) 7 | 8 | 9 | ### Features 10 | 11 | * add geocodeAndExtract ([86af2c2](https://github.com/stepankuzmin/osm-extractor/commit/86af2c2)) 12 | * add Overpass support ([7b09e45](https://github.com/stepankuzmin/osm-extractor/commit/7b09e45)) 13 | * initial commit ([a5efb1b](https://github.com/stepankuzmin/osm-extractor/commit/a5efb1b)) 14 | * switch to overpass api to extract data using bbox ([b97aac1](https://github.com/stepankuzmin/osm-extractor/commit/b97aac1)) 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Stepan Kuzmin 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 | -------------------------------------------------------------------------------- /Overpass_API.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/urbica/osm-extractor/b369cd03265a62456b963b31562dbf99cda452fe/Overpass_API.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # osm-extractor 2 | 3 | [![Build Status](https://travis-ci.org/urbica/osm-extractor.svg?branch=master)](https://travis-ci.org/urbica/osm-extractor) 4 | 5 | Extracts data from [OpenStreetMap](https://www.openstreetmap.org) using [Overpass API](https://overpass-turbo.eu/). 6 | 7 | 8 | 9 | ## Installation 10 | 11 | ```shell 12 | npm i osm-extractor 13 | ``` 14 | 15 | ## Usage 16 | 17 | Geocode and extract area using [Overpass API](https://overpass-turbo.eu/) 18 | 19 | ```js 20 | const fs = require("fs"); 21 | const { extractWithGeocode } = require("osm-extractor"); 22 | 23 | extractWithGeocode("Liechtenstein").then(data => 24 | data.pipe(fs.createWriteStream("data.osm")) 25 | ); 26 | ``` 27 | 28 | Extract OpenStreetMap data from Overpass using [BBox](https://wiki.openstreetmap.org/wiki/Bounding_Box) 29 | 30 | ```js 31 | const fs = require("fs"); 32 | const { extractWithBBox } = require("osm-extractor"); 33 | 34 | extractWithBBox([11.5, 48.1, 11.6, 48.2]).then(data => 35 | data.pipe(fs.createWriteStream("data.osm")) 36 | ); 37 | ``` 38 | 39 | Extract from [Overpass API](https://overpass-turbo.eu/) using [Overpass QL](https://wiki.openstreetmap.org/wiki/Overpass_API/Language_Guide) 40 | 41 | ```js 42 | const fs = require("fs"); 43 | const { extractWithQuery } = require("osm-extractor"); 44 | 45 | const query = "node(50.745,7.17,50.75,7.18);out;"; 46 | extractWithQuery(query).then(data => 47 | data.pipe(fs.createWriteStream("data.osm")) 48 | ); 49 | ``` 50 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | 3 | const geocode = (query, options = {}) => 4 | axios 5 | .get(options.url || 'https://nominatim.openstreetmap.org/search', { 6 | params: { q: query, format: options.format || 'json' } 7 | }) 8 | .then(response => response.data); 9 | 10 | const nominatimBBoxToOSM = bbox => [bbox[2], bbox[0], bbox[3], bbox[1]]; 11 | 12 | // https://github.com/tyrasd/overpass-turbo/blob/fcf98fd443b5372010ce45017d44d67f796d111f/js/shortcuts.js#L103 13 | const normalizeNominatimId = (result) => { 14 | let areaRef = 1 * result.osm_id; 15 | if (result.osm_type === 'way') areaRef += 2400000000; 16 | if (result.osm_type === 'relation') areaRef += 3600000000; 17 | return areaRef; 18 | }; 19 | 20 | const buildAreaQuery = nominatimResult => 21 | [ 22 | `area(${normalizeNominatimId(nominatimResult)})->.searchArea;`, 23 | '(node(area.searchArea); way(area.searchArea); relation(area.searchArea););', 24 | 'out body; >; out skel qt;' 25 | ].join(''); 26 | 27 | const buildBBoxQuery = (bbox) => { 28 | const bboxStr = bbox.join(','); 29 | return [ 30 | `(node(${bboxStr}); way(${bboxStr}); relation(${bboxStr}););`, 31 | 'out body; >; out skel qt;' 32 | ].join(''); 33 | }; 34 | 35 | const extractWithQuery = (query, options = {}) => 36 | axios 37 | .get(options.url || 'https://overpass-api.de/api/interpreter', { 38 | responseType: options.responseType || 'stream', 39 | params: { data: query } 40 | }) 41 | .then(response => response.data); 42 | 43 | const extractWithBBox = bbox => extractWithQuery(buildBBoxQuery(bbox)); 44 | 45 | const extractWithGeocode = query => 46 | geocode(query).then(results => extractWithQuery(buildAreaQuery(results[0]))); 47 | 48 | module.exports = { 49 | geocode, 50 | nominatimBBoxToOSM, 51 | buildAreaQuery, 52 | buildBBoxQuery, 53 | extractWithQuery, 54 | extractWithBBox, 55 | extractWithGeocode 56 | }; 57 | -------------------------------------------------------------------------------- /index.test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape'); 2 | const moxios = require('moxios'); 3 | const { geocode } = require('./index'); 4 | 5 | test('geocode', (t) => { 6 | moxios.install(); 7 | 8 | const nominatimResponse = []; 9 | moxios.stubRequest(/nominatim.openstreetmap.org/, { 10 | status: 200, 11 | responseText: nominatimResponse 12 | }); 13 | 14 | geocode('Moscow').then((results) => { 15 | t.deepEqual(results, nominatimResponse); 16 | moxios.uninstall(); 17 | t.end(); 18 | }); 19 | }); 20 | 21 | // TODO: write the remaining tests 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "osm-extractor", 3 | "description": "Extracts data from OpenStreetMap", 4 | "version": "1.0.0", 5 | "main": "index.js", 6 | "keywords": [ 7 | "osm", 8 | "openstreetmap", 9 | "extracts", 10 | "nominatim" 11 | ], 12 | "author": "Stepan Kuzmin (stepankuzmin.ru)", 13 | "homepage": "https://github.com/stepankuzmin/osm-extractor", 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/stepankuzmin/osm-extractor.git" 17 | }, 18 | "bugs": { 19 | "url": "https://github.com/stepankuzmin/osm-extractor/issues" 20 | }, 21 | "license": "MIT", 22 | "scripts": { 23 | "cz": "git-cz", 24 | "lint": "eslint .", 25 | "test": "node index.test.js" 26 | }, 27 | "config": { 28 | "commitizen": { 29 | "path": "./node_modules/cz-conventional-changelog" 30 | } 31 | }, 32 | "lint-staged": { 33 | "*.js": [ 34 | "prettier-eslint --write", 35 | "yarn lint", 36 | "git add" 37 | ] 38 | }, 39 | "dependencies": { 40 | "axios": "^0.21.1" 41 | }, 42 | "devDependencies": { 43 | "commitizen": "^3.0.4", 44 | "cz-conventional-changelog": "^2.1.0", 45 | "eslint": "^5.9.0", 46 | "eslint-config-airbnb-base": "^13.1.0", 47 | "eslint-config-prettier": "^3.3.0", 48 | "eslint-plugin-import": "^2.14.0", 49 | "husky": "^1.1.3", 50 | "lint-staged": "^8.0.4", 51 | "moxios": "^0.4.0", 52 | "prettier": "^1.15.2", 53 | "prettier-eslint": "^8.8.2", 54 | "prettier-eslint-cli": "^4.7.1", 55 | "tape": "^4.9.1" 56 | }, 57 | "husky": { 58 | "hooks": { 59 | "pre-commit": "lint-staged" 60 | } 61 | } 62 | } 63 | --------------------------------------------------------------------------------