Skip to content
Permalink
Newer
Older
100644 93 lines (79 sloc) 3.13 KB
Aug 18, 2015
1
var util = require("util");
2
3
var Promise = require("bluebird"),
4
Map = require("collections/map"),
5
_ = require("underscore");
6
7
// Used to build up a set of hierarchical VRTs.
8
// The problem with VRTs that have many, many files is...they are sloooow.
9
// This uses a technique of building VRTs up so that they do not contain
10
// more images than some threshold. If the original set of images
11
// is greater than the the threshold, then we build VRTs in a grid based
12
// on the min/max col and row of the grid coordinates.
13
// Then those VRTs that we built up are contructed into another VRT.
14
// This is recursive, so if it ends up that the generated set of VRTs in the first
15
// level make up more images then the threshold, those images will be partitioned
16
// into another level's VRT, and so one, until the last VRT has no more images
17
// then the threshold.
18
// Requires that you set "this" to a swfr DeciderContext.
19
module.exports = function buildHierarchicalVrt(initialCoordsAndFiles, vrtPath, options) {
20
var threshold = options.vrtThreshold | 256;
21
var t = Math.sqrt(threshold) | 0;
22
23
var levelUpHierarchy = function(level, desc) {
24
var minCol = desc.minCol,
25
minRow = desc.minRow;
26
27
var coordsAndFiles = desc.coordsAndFiles;
28
29
var newMinCol = -1,
30
newMinRow = -1;
31
32
var m = new Map();
33
for(var i = 0; i < coordsAndFiles.length; i += 1) {
34
var caf = coordsAndFiles[i];
35
var coord = caf.coord;
36
37
if(coord[0] < newMinCol || newMinCol < 0) { newMinCol = coord[0]; }
38
if(coord[1] < newMinRow || newMinRow < 0) { newMinRow = coord[1]; }
39
40
var file = caf.file;
41
var x = (coord[0] - minCol) / t | 0;
42
var y = (coord[1] - minRow) / t | 0;
43
var s = x + "-" + y;
44
if(!m.has(s)) { m.set(s, { coord: [x, y], componentFiles: [], file: util.format("%s-%d-%s.vrt", vrtPath, level,s) }); }
45
m.get(s).componentFiles.push(file);
46
}
47
48
return {
49
minCol: newMinCol,
50
minRow: newMinRow,
51
coordsAndFiles: m.values()
52
};
53
};
54
55
var minCol = -1,
56
minRow = -1;
57
_.forEach(_.map(initialCoordsAndFiles, function(caf) { return caf.coord; }), function(coord) {
58
if(coord[0] < minCol || minCol < 0) { minCol = coord[0]; }
59
if(coord[1] < minRow || minRow < 0) { minRow = coord[1]; }
60
});
61
62
var desc = {
63
minCol: minCol,
64
minRow: minRow,
65
coordsAndFiles: initialCoordsAndFiles
66
};
67
68
var level = 1;
69
var vrtSteps = [];
70
while(desc.coordsAndFiles.length > threshold) {
71
desc = levelUpHierarchy(level, desc);
72
var vrtStep = _.map(desc.coordsAndFiles, function(caf) { return { vrtPath: caf.file, componentFiles: caf.componentFiles } });
73
vrtSteps.push(vrtStep);
74
level += 1;
75
}
76
77
vrtSteps.push([{ vrtPath: vrtPath, componentFiles: _.map(desc.coordsAndFiles, function(caf) { return caf.file; }) }]);
78
79
return Promise
80
.resolve(vrtSteps)
81
.bind(this)
82
.each(function(vrtStep) {
83
return Promise
84
.resolve(vrtStep)
85
.bind(this)
86
.map(function(vrtBuildDesc) {
87
return this.activity("buildVRT", "1.0", vrtBuildDesc.componentFiles, vrtBuildDesc.vrtPath, { nodata: 0 });
88
});
89
})
90
.then(function() {
91
return vrtPath;
92
});
93
};