This repository has been archived by the owner on Aug 24, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 34
/
mapdataLoader.js
92 lines (83 loc) · 3.12 KB
/
mapdataLoader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
'use strict';
let _ = require('underscore'),
urllib = require('url'),
MWApi = require('mwapi'),
DataManager = require('@wikimedia/mapdata'),
preq = require('preq'),
Promise = require('bluebird');
/**
* Download map data from MW api
* @param {string} protocol - "http" or "https"
* @param {string} domain - "en.wikipedia.org"
* @param {string} title - title of the page - ok to be unsanitized
* @param {string|string[]} groupIds
* @returns {Promise}
*/
module.exports = function downloadMapdata(protocol, domain, title, groupIds) {
let dm = new DataManager({
createPromise: createPromise,
whenAllPromises: Promise.all,
isEmptyObject: _.isEmpty,
isPlainObject: _.isObject,
isArray: _.isArray,
extend: _.extend,
getJSON: url => {
if (url[0] === '/' && url[1] === '/') {
// Workaround: urllib does not support relative URLs
url = protocol + ':' + url;
}
let urlParts = urllib.parse(url);
if (!urlParts.protocol) urlParts.protocol = protocol;
if (!urlParts.hostname) urlParts.hostname = domain;
if (!urlParts.slashes) urlParts.slashes = true;
let request = {
uri: urllib.format(urlParts),
headers: {'User-Agent': 'kartotherian-getJSON (yurik @ wikimedia)'}
};
return preq.get(request).then(response => response.body);
},
mwApi: request => {
let mwapi = new MWApi('kartotherian (yurik @ wikimedia)', protocol + '://' + domain + '/w/api.php');
return mwapi.execute(request);
},
title: title,
});
return dm.loadGroups( groupIds ).then( dataGroups => {
let mapdata = [];
if (!dataGroups.length) {
throw new Error('GroupId not available');
}
for (let i = 0; i < dataGroups.length; i++ ) {
expandArraysAndCollections(mapdata, dataGroups[ i ].getGeoJSON());
}
if (mapdata.length === 1) return mapdata[0];
return {"type": "FeatureCollection", "features": mapdata};
} );
};
function expandArraysAndCollections(mapdata, geojson) {
if (Array.isArray(geojson)) {
for (let v of geojson) {
expandArraysAndCollections(mapdata, v);
}
} else if (_.isObject(geojson)) {
if (!geojson.type) throw new Error('Bad geojson - object has no type');
switch (geojson.type) {
case 'FeatureCollection':
expandArraysAndCollections(mapdata, geojson.features);
break;
case 'Feature':
// init empty "properties" so it doesn't fail with
// "invalid json" in geojson-mapnikify
geojson.properties = geojson.properties || {};
mapdata.push(geojson);
break;
default:
throw new Error('Bad geojson - unknown type ' + geojson.type);
}
} else {
throw new Error('Bad geojson - unknown type ' + typeof(geojson));
}
}
function createPromise(callback) {
return new Promise(callback);
}