basic zoom filters are working
This commit is contained in:
parent
37f0b8c121
commit
509c260ac5
@ -4,7 +4,8 @@ var path = require('path'),
|
|||||||
Step = require('step'),
|
Step = require('step'),
|
||||||
_ = require('underscore')._,
|
_ = require('underscore')._,
|
||||||
sys = require('sys'),
|
sys = require('sys'),
|
||||||
mess = require('mess');
|
mess = require('mess'),
|
||||||
|
tree = require('mess/tree');
|
||||||
|
|
||||||
require.paths.unshift(path.join(__dirname, '..', 'lib'));
|
require.paths.unshift(path.join(__dirname, '..', 'lib'));
|
||||||
|
|
||||||
@ -211,7 +212,7 @@ mess.Renderer = function Renderer(env) {
|
|||||||
// definitions are ordered in specificity,
|
// definitions are ordered in specificity,
|
||||||
// high to low
|
// high to low
|
||||||
//
|
//
|
||||||
// basically if 'this level' has
|
// basically if 'this level' has
|
||||||
// a filter, then keep going, otherwise
|
// a filter, then keep going, otherwise
|
||||||
// this is the final selector.
|
// this is the final selector.
|
||||||
var winners = [];
|
var winners = [];
|
||||||
@ -244,21 +245,34 @@ mess.Renderer = function Renderer(env) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
resolve_filters: function(definitions) {
|
resolve_filters: function(definitions) {
|
||||||
var negated_filters = [];
|
var negatedFilters = [];
|
||||||
|
var negatedZoom = new tree.ZoomFilter('zoom', { value: '>=' }, '0');
|
||||||
|
|
||||||
for (var i = 0; i < definitions.length; i++) {
|
for (var i = 0; i < definitions.length; i++) {
|
||||||
if (definitions[i].selector.filters.length) {
|
var filters = definitions[i].selector.filters;
|
||||||
// array of the negation of this definition's filters
|
var normal = filters.filter(function(f) { return f instanceof tree.Filter; });
|
||||||
var negation = definitions[i].selector.filters.map(
|
var zoom = filters.filter(function(f) { return f instanceof tree.ZoomFilter; });
|
||||||
function(f) { return f.negate(); });
|
|
||||||
|
|
||||||
// add in existing negations
|
var negation = normal.map(function(f) { return f.negate(); });
|
||||||
// TODO: run uniq on this.
|
|
||||||
definitions[i].selector.filters =
|
|
||||||
definitions[i].selector.filters.concat(negated_filters);
|
|
||||||
|
|
||||||
// add this definition's filter's negations to the list
|
// add in existing negations
|
||||||
negated_filters = negated_filters.concat(negation);
|
// TODO: run uniq on this.
|
||||||
}
|
normal.push.apply(normal, negatedFilters);
|
||||||
|
|
||||||
|
// add this definition's filter's negations to the list
|
||||||
|
negatedFilters.push.apply(negatedFilters, negation);
|
||||||
|
|
||||||
|
// Merge all zoom filters without overwriting existing zoom
|
||||||
|
// filters; they might be referenced in other selectors.
|
||||||
|
var currentZoom = new tree.ZoomFilter('zoom', { value: '>=' }, '0');
|
||||||
|
zoom.forEach(function(f) { currentZoom.intersection(f); });
|
||||||
|
|
||||||
|
// Only add the negated current zoom when there actually are zoom filters.
|
||||||
|
var negation = zoom.length ? currentZoom.negated() : false;
|
||||||
|
currentZoom.intersection(negatedZoom);
|
||||||
|
if (negation) negatedZoom.intersection(negation);
|
||||||
|
|
||||||
|
definitions[i].selector.filters = normal.concat([currentZoom]);
|
||||||
}
|
}
|
||||||
return definitions;
|
return definitions;
|
||||||
},
|
},
|
||||||
@ -348,14 +362,14 @@ mess.Renderer = function Renderer(env) {
|
|||||||
* @param {Array} stylesheets the results of ruleHash().
|
* @param {Array} stylesheets the results of ruleHash().
|
||||||
* @return Formalized layer definition with .styles = [].
|
* @return Formalized layer definition with .styles = [].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var rulesets = _.flatten(stylesheets.map(function(rulesets) {
|
var rulesets = _.flatten(stylesheets.map(function(rulesets) {
|
||||||
return rulesets[2].toMSS();
|
return rulesets[2].toMSS();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
var output = [entities(entity_list)];
|
var output = [entities(entity_list)];
|
||||||
// TODO: must change when background colors are available
|
// TODO: must change when background colors are available
|
||||||
output.push('<Map background-color="'
|
output.push('<Map background-color="'
|
||||||
+ "#ffffff"
|
+ "#ffffff"
|
||||||
// findBackground(stylesheets)
|
// findBackground(stylesheets)
|
||||||
+ '" srs="+proj=merc +a=6378137 +b=6378137 '
|
+ '" srs="+proj=merc +a=6378137 +b=6378137 '
|
||||||
@ -369,7 +383,7 @@ mess.Renderer = function Renderer(env) {
|
|||||||
var matching = rulesets.filter(function(ruleset) {
|
var matching = rulesets.filter(function(ruleset) {
|
||||||
return ruleset.selector.matches(l.id, classes);
|
return ruleset.selector.matches(l.id, classes);
|
||||||
});
|
});
|
||||||
|
|
||||||
// matching is an array of matching selectors,
|
// matching is an array of matching selectors,
|
||||||
// in order from high specificity to low.
|
// in order from high specificity to low.
|
||||||
var by_symbolizer = that.split_symbolizers(matching);
|
var by_symbolizer = that.split_symbolizers(matching);
|
||||||
@ -391,7 +405,7 @@ mess.Renderer = function Renderer(env) {
|
|||||||
// output.push(references(entity_list));
|
// output.push(references(entity_list));
|
||||||
// output.push(stylesheet_tmpl(m));
|
// output.push(stylesheet_tmpl(m));
|
||||||
output.push('</Map>');
|
output.push('</Map>');
|
||||||
|
|
||||||
callback(null, output.join('\n'));
|
callback(null, output.join('\n'));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -58,11 +58,25 @@ tree.Selector.prototype.combinedFilter = function() {
|
|||||||
return f instanceof tree.ZoomFilter;
|
return f instanceof tree.ZoomFilter;
|
||||||
});
|
});
|
||||||
|
|
||||||
return normal_filters.length ?
|
var filters = [];
|
||||||
'<Filter>' + normal_filters.map(function(f) {
|
if (normal_filters.length) {
|
||||||
|
filters.push('<Filter>' + normal_filters.map(function(f) {
|
||||||
return '(' + f.toXML().trim() + ')';
|
return '(' + f.toXML().trim() + ')';
|
||||||
}).join(' and ') + '</Filter>'
|
}).join(' and ') + '</Filter>');
|
||||||
: '<ElseFilter/>';
|
}
|
||||||
|
|
||||||
|
if (zoom_filters.length) {
|
||||||
|
filters.push(zoom_filters.map(function(f) {
|
||||||
|
return f.toXML();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filters.length) {
|
||||||
|
return '<ElseFilter/>';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return filters.join('');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
})(require('mess/tree'));
|
})(require('mess/tree'));
|
||||||
|
@ -1,11 +1,41 @@
|
|||||||
(function(tree) {
|
(function(tree) {
|
||||||
|
|
||||||
tree.ZoomFilter = function(key, op, val, index) {
|
tree.ZoomFilter = function(key, op, value, index) {
|
||||||
this.key = key;
|
value = parseInt(value);
|
||||||
this.op = op;
|
if (value > tree.ZoomFilter.maxZoom || value < 0) {
|
||||||
this.val = parseInt(val);
|
throw {
|
||||||
this.index = index;
|
message: 'Only zoom levels between 0 and ' + tree.ZoomFilter.maxZoom + ' supported.',
|
||||||
this.zoom_range = tree.ZoomFilter.create_range(this.op.value, this.val);
|
index: index
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.range = tree.ZoomFilter.createRange(op.value, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
tree.ZoomFilter.maxZoom = 22;
|
||||||
|
|
||||||
|
tree.ZoomFilter.ranges = {
|
||||||
|
1: 500000000,
|
||||||
|
2: 200000000,
|
||||||
|
3: 100000000,
|
||||||
|
4: 50000000,
|
||||||
|
5: 25000000,
|
||||||
|
6: 12500000,
|
||||||
|
7: 6500000,
|
||||||
|
8: 3000000,
|
||||||
|
9: 1500000,
|
||||||
|
10: 750000,
|
||||||
|
11: 400000,
|
||||||
|
12: 200000,
|
||||||
|
13: 100000,
|
||||||
|
14: 50000,
|
||||||
|
15: 25000,
|
||||||
|
16: 12500,
|
||||||
|
17: 5000,
|
||||||
|
18: 2500,
|
||||||
|
19: 1000,
|
||||||
|
20: 500,
|
||||||
|
21: 250,
|
||||||
|
22: 100
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,30 +43,46 @@ tree.ZoomFilter = function(key, op, val, index) {
|
|||||||
* which denotes whether this filter should apply
|
* which denotes whether this filter should apply
|
||||||
* to each of the zoom levels from 0-22.
|
* to each of the zoom levels from 0-22.
|
||||||
*/
|
*/
|
||||||
tree.ZoomFilter.create_range = function(op, value) {
|
tree.ZoomFilter.createRange = function(op, value) {
|
||||||
var max_zoom = 22;
|
var range = [];
|
||||||
var zoom_range = [];
|
|
||||||
if (op === '>' || op === '>=') {
|
if (op === '>' || op === '>=') {
|
||||||
if (op === '>') value++;
|
if (op === '>') value++;
|
||||||
for (var i = 0; i < max_zoom; i++) {
|
for (var i = 0; i < tree.ZoomFilter.maxZoom; i++) {
|
||||||
zoom_range[i] = (i >= value);
|
range[i] = (i >= value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (op === '<') value--;
|
if (op === '<') value--;
|
||||||
for (var i = 0; i < max_zoom; i++) {
|
for (var i = 0; i < tree.ZoomFilter.maxZoom; i++) {
|
||||||
zoom_range[i] = (i <= value);
|
range[i] = (i <= value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return zoom_range;
|
return range;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of ranges that are set.
|
||||||
|
*/
|
||||||
|
tree.ZoomFilter.getRanges = function(range) {
|
||||||
|
var ranges = [], start = null;
|
||||||
|
for (var i = 0; i < range.length; i++) {
|
||||||
|
if (start == null && range[i]) {
|
||||||
|
start = i;
|
||||||
|
} else if (start != null && !range[i]) {
|
||||||
|
ranges.push([start, i - 1]);
|
||||||
|
start = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (start != null) ranges.push([start, 22]);
|
||||||
|
return ranges;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the overlap of this and another set
|
* Find the overlap of this and another set
|
||||||
*/
|
*/
|
||||||
tree.ZoomFilter.prototype.intersection = function(filter) {
|
tree.ZoomFilter.prototype.intersection = function(filter) {
|
||||||
if (filter.zoom_range) {
|
if (filter.range) {
|
||||||
for (var i = 0; i < this.max_zoom; i++) {
|
for (var i = 0; i < this.range.length; i++) {
|
||||||
this.zoom_range[i] = this.zoom_range[i] && filter.zoom_range[i];
|
this.range[i] = this.range[i] && filter.range[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -45,9 +91,9 @@ tree.ZoomFilter.prototype.intersection = function(filter) {
|
|||||||
* Find the union of this and another set
|
* Find the union of this and another set
|
||||||
*/
|
*/
|
||||||
tree.ZoomFilter.prototype.union = function(filter) {
|
tree.ZoomFilter.prototype.union = function(filter) {
|
||||||
if (filter.zoom_range) {
|
if (filter.range) {
|
||||||
for (var i = 0; i < this.max_zoom; i++) {
|
for (var i = 0; i < this.range.length; i++) {
|
||||||
this.zoom_range[i] = this.zoom_range[i] || filter.zoom_range[i];
|
this.range[i] = this.range[i] || filter.range[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -60,58 +106,26 @@ tree.ZoomFilter.prototype.union = function(filter) {
|
|||||||
* Usage is for doing the equivalent of an ElseFilter
|
* Usage is for doing the equivalent of an ElseFilter
|
||||||
* for defaulting to non-zoom-filtered rules
|
* for defaulting to non-zoom-filtered rules
|
||||||
*/
|
*/
|
||||||
tree.ZoomFilter.prototype.negate = function() {
|
tree.ZoomFilter.prototype.negated = function() {
|
||||||
this.zoom_range = this.zoom_range.map(function(i) {
|
var negated = this.clone();
|
||||||
|
negated.range = this.range.map(function(i) {
|
||||||
return !i;
|
return !i;
|
||||||
});
|
});
|
||||||
return this;
|
return negated;
|
||||||
};
|
};
|
||||||
|
|
||||||
tree.ZoomFilter.prototype.toXML = function(env) {
|
tree.ZoomFilter.prototype.toXML = function(env) {
|
||||||
if (this.val > 22 || this.val < 0) {
|
var ranges = tree.ZoomFilter.getRanges(this.range);
|
||||||
throw {
|
return ranges.map(function(range) {
|
||||||
message: 'Only zoom levels between 0 and 22 supported.',
|
return (range[0] > 0 ? '<MinScaleDenominator>' + /*tree.ZoomFilter.ranges[*/range[0]/*]*/ + '</MinScaleDenominator>' : '') +
|
||||||
index: this.index
|
(range[1] < 22 ? '<MaxScaleDenominator>' + /*tree.ZoomFilter.ranges[*/range[1]/*]*/ + '</MaxScaleDenominator>' : '');
|
||||||
};
|
});
|
||||||
}
|
|
||||||
|
|
||||||
var zooms = {
|
|
||||||
'1': [200000000, 500000000],
|
|
||||||
'2': [100000000, 200000000],
|
|
||||||
'3': [50000000, 100000000],
|
|
||||||
'4': [25000000, 50000000],
|
|
||||||
'5': [12500000, 25000000],
|
|
||||||
'6': [6500000, 12500000],
|
|
||||||
'7': [3000000, 6500000],
|
|
||||||
'8': [1500000, 3000000],
|
|
||||||
'9': [750000, 1500000],
|
|
||||||
'10': [400000, 750000],
|
|
||||||
'11': [200000, 400000],
|
|
||||||
'12': [100000, 200000],
|
|
||||||
'13': [50000, 100000],
|
|
||||||
'14': [25000, 50000],
|
|
||||||
'15': [12500, 25000],
|
|
||||||
'16': [5000, 12500],
|
|
||||||
'17': [2500, 5000],
|
|
||||||
'18': [1000, 2500],
|
|
||||||
'19': [500, 1000],
|
|
||||||
'20': [250, 500],
|
|
||||||
'21': [100, 250],
|
|
||||||
'22': [50, 100]};
|
|
||||||
|
|
||||||
switch (this.op.value) {
|
|
||||||
case '>':
|
|
||||||
return '<MaxScaleDenominator>' + zooms[this.val][0] +
|
|
||||||
'</MaxScaleDenominator>';
|
|
||||||
case '>=':
|
|
||||||
return '<MaxScaleDenominator>' + zooms[this.val][1] +
|
|
||||||
'</MaxScaleDenominator>';
|
|
||||||
case '<':
|
|
||||||
return '<MinScaleDenominator>' + zooms[this.val][1] +
|
|
||||||
'</MinScaleDenominator>';
|
|
||||||
case '<=':
|
|
||||||
return '<MinScaleDenominator>' + zooms[this.val][0] +
|
|
||||||
'</MinScaleDenominator>';
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
tree.ZoomFilter.prototype.clone = function() {
|
||||||
|
var obj = Object.create(Object.getPrototypeOf(this));
|
||||||
|
obj.range = this.range.slice();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
})(require('mess/tree'));
|
})(require('mess/tree'));
|
||||||
|
Loading…
Reference in New Issue
Block a user