forked from osmlab/to-fix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
prioritize.js
115 lines (98 loc) · 4.82 KB
/
prioritize.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
var fs = require('fs'),
path = require('path'),
gju = require('geojson-utils'),
key = require('./lib/key.js'),
levelup = require('levelup'),
wellknown = require('wellknown');
// adjusts skipvals based on geometry, prioritizing particular areas/markets
if (process.stdin.isTTY) {
var quickMode = true; // should we bother matching against every geometry or just quit after one hit?
if (process.argv.length < 4) {
return console.log('file arguments are required\n`node prioritize.js [task] [geojson1 geojson2 ... ]`');
}
// process command line params, load geojson files
var geojson = {};
process.argv
.forEach(function(elem, i) {
if (i <= 2) {
// skip require params -- choosing not to use .filter() to make async logic simpler below
return true;
}
// if using overlapping geojson files, this flag might be useful. otherwise, no.
if (elem === '--slow') {
quickMode = false;
} else {
var basename = path.basename(elem, '.geojson');
fs.readFile(elem, function(err, data) {
if (err) console.log('# Error loading GeoJSON file ' + elem);
var boundary = JSON.parse(data);
if ((boundary === null) || !boundary.features) {
console.log('# failed to load valid GeoJSON from ' + elem);
} else {
geojson[basename] = boundary;
console.log('- loaded GeoJSON file ' + elem);
}
// if all params have been loaded, begin main processing
if(i === process.argv.length-1) ProcessLevelDB();
});
}
});
}
function ProcessLevelDB(){
console.log('- opening leveldb database ' + process.argv[2]);
levelup('./ldb/' + process.argv[2] + '.ldb', function(err, db) {
if (err) throw(err);
var maxOverlaps = 0;
console.log('- checking for geometry overlap');
db.createReadStream()
.on('data', function(data) {
data.value = JSON.parse(data.value);
// if this task is already fixed, skip it
if (key.decompose(data.key).skipval === 0) return;
// check if point is in any geojson geometries
var overlapCount = 0;
Object.keys(geojson).forEach(function(k) {
if (!data.value.st_astext) {
console.log('# missing geometry (st_astext) for key ' + data.key);
return false;
}
if (gju.pointInPolygon(wellknown.parse(data.value.st_astext), geojson[k].features[0].geometry)) {
if (!data.value.priority) data.value.priority = [];
data.value.priority.push(k);
overlapCount++;
if (quickMode) return false;
}
});
// track maximum number of overlaps
maxOverlaps = Math.max(maxOverlaps, overlapCount);
data.value.overlapCount = overlapCount;
db.put(data.key, JSON.stringify(data.value), function(err) {
if (err) console.log('# error saving key ' + data.key + '#' + overlapCount);
});
})
.on('end', function(){
// iterate through all keys, adding (maxOverlaps - overlap) to each skipval
console.log('- reordering tasks');
var adjustmentsMade = 0;
var reordered = 0;
db.createReadStream()
.on('data', function(data) {
data.value = JSON.parse(data.value);
var keyComponents = key.decompose(data.key);
var newKey = key.compose((keyComponents.skipval + (maxOverlaps - parseInt(data.value.overlapCount))), keyComponents.hash);
if (parseInt(data.value.overlapCount) > 0) adjustmentsMade++;
delete data.value.overlapCount;
db.del(data.key, function(err){
if (err) console.log('# error deleting key ' + newKey);
db.put(newKey, JSON.stringify(data.value), function(err) {
if (err) console.log('# error saving key ' + newKey);
reordered++;
});
});
})
.on('end', function() {
console.log('- finished, reprioritized ' + adjustmentsMade + '/' + reordered + ' tasks');
});
});
});
}