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'),
|
||||
_ = require('underscore')._,
|
||||
sys = require('sys'),
|
||||
mess = require('mess');
|
||||
mess = require('mess'),
|
||||
tree = require('mess/tree');
|
||||
|
||||
require.paths.unshift(path.join(__dirname, '..', 'lib'));
|
||||
|
||||
@ -211,7 +212,7 @@ mess.Renderer = function Renderer(env) {
|
||||
// definitions are ordered in specificity,
|
||||
// high to low
|
||||
//
|
||||
// basically if 'this level' has
|
||||
// basically if 'this level' has
|
||||
// a filter, then keep going, otherwise
|
||||
// this is the final selector.
|
||||
var winners = [];
|
||||
@ -244,21 +245,34 @@ mess.Renderer = function Renderer(env) {
|
||||
},
|
||||
|
||||
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++) {
|
||||
if (definitions[i].selector.filters.length) {
|
||||
// array of the negation of this definition's filters
|
||||
var negation = definitions[i].selector.filters.map(
|
||||
function(f) { return f.negate(); });
|
||||
var filters = definitions[i].selector.filters;
|
||||
var normal = filters.filter(function(f) { return f instanceof tree.Filter; });
|
||||
var zoom = filters.filter(function(f) { return f instanceof tree.ZoomFilter; });
|
||||
|
||||
// add in existing negations
|
||||
// TODO: run uniq on this.
|
||||
definitions[i].selector.filters =
|
||||
definitions[i].selector.filters.concat(negated_filters);
|
||||
var negation = normal.map(function(f) { return f.negate(); });
|
||||
|
||||
// add this definition's filter's negations to the list
|
||||
negated_filters = negated_filters.concat(negation);
|
||||
}
|
||||
// add in existing negations
|
||||
// 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;
|
||||
},
|
||||
@ -348,14 +362,14 @@ mess.Renderer = function Renderer(env) {
|
||||
* @param {Array} stylesheets the results of ruleHash().
|
||||
* @return Formalized layer definition with .styles = [].
|
||||
*/
|
||||
|
||||
|
||||
var rulesets = _.flatten(stylesheets.map(function(rulesets) {
|
||||
return rulesets[2].toMSS();
|
||||
}));
|
||||
|
||||
var output = [entities(entity_list)];
|
||||
// TODO: must change when background colors are available
|
||||
output.push('<Map background-color="'
|
||||
output.push('<Map background-color="'
|
||||
+ "#ffffff"
|
||||
// findBackground(stylesheets)
|
||||
+ '" srs="+proj=merc +a=6378137 +b=6378137 '
|
||||
@ -369,7 +383,7 @@ mess.Renderer = function Renderer(env) {
|
||||
var matching = rulesets.filter(function(ruleset) {
|
||||
return ruleset.selector.matches(l.id, classes);
|
||||
});
|
||||
|
||||
|
||||
// matching is an array of matching selectors,
|
||||
// in order from high specificity to low.
|
||||
var by_symbolizer = that.split_symbolizers(matching);
|
||||
@ -391,7 +405,7 @@ mess.Renderer = function Renderer(env) {
|
||||
// output.push(references(entity_list));
|
||||
// output.push(stylesheet_tmpl(m));
|
||||
output.push('</Map>');
|
||||
|
||||
|
||||
callback(null, output.join('\n'));
|
||||
},
|
||||
|
||||
|
@ -58,11 +58,25 @@ tree.Selector.prototype.combinedFilter = function() {
|
||||
return f instanceof tree.ZoomFilter;
|
||||
});
|
||||
|
||||
return normal_filters.length ?
|
||||
'<Filter>' + normal_filters.map(function(f) {
|
||||
var filters = [];
|
||||
if (normal_filters.length) {
|
||||
filters.push('<Filter>' + normal_filters.map(function(f) {
|
||||
return '(' + f.toXML().trim() + ')';
|
||||
}).join(' and ') + '</Filter>'
|
||||
: '<ElseFilter/>';
|
||||
}).join(' and ') + '</Filter>');
|
||||
}
|
||||
|
||||
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'));
|
||||
|
@ -1,11 +1,41 @@
|
||||
(function(tree) {
|
||||
|
||||
tree.ZoomFilter = function(key, op, val, index) {
|
||||
this.key = key;
|
||||
this.op = op;
|
||||
this.val = parseInt(val);
|
||||
this.index = index;
|
||||
this.zoom_range = tree.ZoomFilter.create_range(this.op.value, this.val);
|
||||
tree.ZoomFilter = function(key, op, value, index) {
|
||||
value = parseInt(value);
|
||||
if (value > tree.ZoomFilter.maxZoom || value < 0) {
|
||||
throw {
|
||||
message: 'Only zoom levels between 0 and ' + tree.ZoomFilter.maxZoom + ' supported.',
|
||||
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
|
||||
* to each of the zoom levels from 0-22.
|
||||
*/
|
||||
tree.ZoomFilter.create_range = function(op, value) {
|
||||
var max_zoom = 22;
|
||||
var zoom_range = [];
|
||||
tree.ZoomFilter.createRange = function(op, value) {
|
||||
var range = [];
|
||||
if (op === '>' || op === '>=') {
|
||||
if (op === '>') value++;
|
||||
for (var i = 0; i < max_zoom; i++) {
|
||||
zoom_range[i] = (i >= value);
|
||||
for (var i = 0; i < tree.ZoomFilter.maxZoom; i++) {
|
||||
range[i] = (i >= value);
|
||||
}
|
||||
} else {
|
||||
if (op === '<') value--;
|
||||
for (var i = 0; i < max_zoom; i++) {
|
||||
zoom_range[i] = (i <= value);
|
||||
for (var i = 0; i < tree.ZoomFilter.maxZoom; i++) {
|
||||
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
|
||||
*/
|
||||
tree.ZoomFilter.prototype.intersection = function(filter) {
|
||||
if (filter.zoom_range) {
|
||||
for (var i = 0; i < this.max_zoom; i++) {
|
||||
this.zoom_range[i] = this.zoom_range[i] && filter.zoom_range[i];
|
||||
if (filter.range) {
|
||||
for (var i = 0; i < this.range.length; 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
|
||||
*/
|
||||
tree.ZoomFilter.prototype.union = function(filter) {
|
||||
if (filter.zoom_range) {
|
||||
for (var i = 0; i < this.max_zoom; i++) {
|
||||
this.zoom_range[i] = this.zoom_range[i] || filter.zoom_range[i];
|
||||
if (filter.range) {
|
||||
for (var i = 0; i < this.range.length; 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
|
||||
* for defaulting to non-zoom-filtered rules
|
||||
*/
|
||||
tree.ZoomFilter.prototype.negate = function() {
|
||||
this.zoom_range = this.zoom_range.map(function(i) {
|
||||
tree.ZoomFilter.prototype.negated = function() {
|
||||
var negated = this.clone();
|
||||
negated.range = this.range.map(function(i) {
|
||||
return !i;
|
||||
});
|
||||
return this;
|
||||
return negated;
|
||||
};
|
||||
|
||||
tree.ZoomFilter.prototype.toXML = function(env) {
|
||||
if (this.val > 22 || this.val < 0) {
|
||||
throw {
|
||||
message: 'Only zoom levels between 0 and 22 supported.',
|
||||
index: this.index
|
||||
};
|
||||
}
|
||||
|
||||
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>';
|
||||
}
|
||||
var ranges = tree.ZoomFilter.getRanges(this.range);
|
||||
return ranges.map(function(range) {
|
||||
return (range[0] > 0 ? '<MinScaleDenominator>' + /*tree.ZoomFilter.ranges[*/range[0]/*]*/ + '</MinScaleDenominator>' : '') +
|
||||
(range[1] < 22 ? '<MaxScaleDenominator>' + /*tree.ZoomFilter.ranges[*/range[1]/*]*/ + '</MaxScaleDenominator>' : '');
|
||||
});
|
||||
};
|
||||
|
||||
tree.ZoomFilter.prototype.clone = function() {
|
||||
var obj = Object.create(Object.getPrototypeOf(this));
|
||||
obj.range = this.range.slice();
|
||||
return obj;
|
||||
}
|
||||
|
||||
})(require('mess/tree'));
|
||||
|
Loading…
Reference in New Issue
Block a user