blob: 43ba4d1b88a2a25cab5ded7749069524891001ca [file] [log] [blame]
evansirokyd401c892016-06-16 00:05:14 -07001var fs = require('fs'),
2 http = require('http')
3
4var async = require('async'),
evansiroky63d35e12016-06-16 10:08:15 -07005 jsts = require('jsts'),
evansirokyd401c892016-06-16 00:05:14 -07006 overpass = require('query-overpass'),
7 shp = require('shpjs')
8
9
evansiroky63d35e12016-06-16 10:08:15 -070010var osmBoundarySources = require('./osmBoundarySources.json'),
11 geoJsonReader = new jsts.io.GeoJSONReader(),
12 geoJsonWriter = new jsts.io.GeoJSONWriter()
13
14
evansirokyd401c892016-06-16 00:05:14 -070015var toArrayBuffer = function(buffer) {
16 var ab = new ArrayBuffer(buffer.length)
17 var view = new Uint8Array(ab)
18 for (var i = 0; i < buffer.length; ++i) {
19 view[i] = buffer[i]
20 }
21 return view
22}
23
24var extractToGeoJson = function(callback) {
25 shp(toArrayBuffer(fs.readFileSync('./downloads/tz_world_mp.zip')))
26 .then(function(geojson) { console.log('extract success'); callback(null, geojson) })
27 .catch(function(e){ console.log('extract err', e); callback(e) })
28}
29
evansiroky63d35e12016-06-16 10:08:15 -070030var union = function(a, b) {
31 var _a = geoJsonReader.read(JSON.stringify(a)),
32 _b = geoJsonReader.read(JSON.stringify(b))
33
34 var result = _a.union(_b)
35
36 return geoJsonWriter.write(result)
37
38}
39
40var downloadOsmBoundary = function(boundaryId, boundaryCallback) {
41 var cfg = osmBoundarySources[boundaryId],
42 query = '[out:json][timeout:60];',
43 boundaryFilename = './downloads/' + cfg.type,
44 debug = 'getting data for '
45
46 if(cfg.type === 'ISO3166-1') {
47 query += '(relation["boundary"="administrative"]' +
48 '["admin_level"="2"]' +
49 '["ISO3166-1"="' + cfg.code + '"]);' +
50 'out body;>;out meta qt;'
51 boundaryFilename += '_' + cfg.code
52 debug += 'country: ' + cfg.code
53 }
54
55 console.log(debug)
56
57 async.auto({
58 checkForAlreadyDownloadedFile: function(cb) {
59 fs.stat(boundaryFilename, function(err) {
60 if(!err) { return boundaryCallback() }
61 cb()
62 })
63 },
64 downloadFromOverpass: ['checkForAlreadyDownloadedFile', function(results, cb) {
65 console.log('downloading from overpass')
66 overpass(query, cb, { flatProperties: true })
67 }],
68 validateOverpassResult: ['downloadFromOverpass', function(results, cb) {
69 var data = results.downloadFromOverpass
70 if(!data.features || data.features.length == 0) {
71 err = new Error('Invalid geojson for boundary: ' + boundaryId)
72 return cb(err)
73 }
74 cb()
75 }],
76 saveSingleMultiPolygon: ['validateOverpassResult', function(results, cb) {
77 var data = results.downloadFromOverpass,
78 combined
79
80 // union all multi-polygons / polygons into one
81 for (var i = data.features.length - 1; i >= 0; i--) {
82 var curGeom = data.features[i].geometry
83 if(curGeom.type === 'Polygon' || curGeom.type === 'MultiPolygon') {
84 console.log('combining border')
85 if(!combined) {
86 combined = curGeom
87 } else {
88 combined = union(curGeom, combined)
89 }
90 }
91 }
92 fs.writeFile(boundaryFilename, JSON.stringify(combined, null, 2), cb)
93 }]
94 }, boundaryCallback)
95}
evansirokyd401c892016-06-16 00:05:14 -070096
97async.auto({
98 makeDownloadsDir: function(cb) {
99 console.log('creating downloads dir')
100 fs.mkdir('./downloads', function(err) {
101 if(err && err.code === 'EEXIST') {
102 cb()
103 } else {
104 cb(err)
105 }
106 })
107 },
108 getEfeleShapefile: ['makeDownloadsDir', function(results, cb) {
109 console.log('downloads efele.net shapefile')
110 return cb()
111 var file = fs.createWriteStream('./downloads/tz_world_mp.zip')
112 http.get('http://efele.net/maps/tz/world/tz_world_mp.zip', function(response) {
113 response.pipe(file)
114 file
115 .on('finish', function() {
116 file.close(cb)
117 })
118 .on('error', cb)
119 })
120 }],
evansirokyd401c892016-06-16 00:05:14 -0700121 getOsmBoundaries: ['makeDownloadsDir', function(results, cb) {
122 console.log('downloading osm boundaries')
evansiroky63d35e12016-06-16 10:08:15 -0700123 async.eachSeries(Object.keys(osmBoundarySources), downloadOsmBoundary, cb)
124 }],
125 extractEfeleNetShapefile: ['getOsmBoundaries', function(results, cb) {
126 return cb()
127 console.log('extracting efele.net shapefile')
128 extractToGeoJson(cb)
evansirokyd401c892016-06-16 00:05:14 -0700129 }]
130}, function(err) {
131 console.log('done')
132 if(err) {
133 console.log('error!', err)
134 return
135 }
136
137 //console.log(osmBoundarySources)
138})