Adding zoomfilter type to alleviate filter complexity
This commit is contained in:
parent
1860ded45e
commit
6571489ef9
@ -82,7 +82,7 @@ var mess = {
|
||||
'selector', 'quoted', 'expression', 'rule',
|
||||
'call', 'url', 'alpha', 'import',
|
||||
'mixin', 'comment', 'anonymous', 'value', 'javascript',
|
||||
'comparison', 'reference', 'filter'
|
||||
'comparison', 'reference', 'filter', 'zoomfilter'
|
||||
].forEach(function (n) {
|
||||
require(path.join('mess', 'tree', n));
|
||||
});
|
||||
|
@ -858,7 +858,11 @@ mess.Parser = function Parser(env) {
|
||||
if ((op = $(this.entities.comparison)) &&
|
||||
(val = $(this.entities.quoted) || $(/^[\w-]+/))) {
|
||||
if (! $(']')) return;
|
||||
return new(tree.Filter)(key, op, val, memo);
|
||||
if (key == 'zoom') {
|
||||
return new(tree.ZoomFilter)(key, op, val, memo);
|
||||
} else {
|
||||
return new(tree.Filter)(key, op, val, memo);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -6,126 +6,17 @@ tree.Filter = function(key, op, val, index) {
|
||||
this.op = op;
|
||||
this.val = val;
|
||||
this.index = index;
|
||||
|
||||
/**
|
||||
* Create an array of true, false values
|
||||
* which denotes whether this filter should apply
|
||||
* to each of the zoom levels from 0-22.
|
||||
*/
|
||||
if (this.key === 'zoom') {
|
||||
var val = parseInt(this.val, 10);
|
||||
this.zoom_range = [];
|
||||
|
||||
if (this.op.value === '>' || this.op.value === '>=') {
|
||||
if (this.op.value === '>') val++;
|
||||
for (var i = 0; i < this.max_zoom; i++) {
|
||||
this.zoom_range[i] = (i <= val);
|
||||
}
|
||||
} else {
|
||||
// TODO: non-correct ops will fail here
|
||||
if (this.op.value === '<') val--;
|
||||
for (var i = 0; i < this.max_zoom; i++) {
|
||||
this.zoom_range[i] = (i >= val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.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]
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the overlap of this and another set
|
||||
*/
|
||||
tree.Filter.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];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the union of this and another set
|
||||
*/
|
||||
tree.Filter.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];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Invert this style rule. Apply to all zoom levels
|
||||
* that the rule previously did not apply to and
|
||||
* vice versa.
|
||||
*
|
||||
* Usage is for doing the equivalent of an ElseFilter
|
||||
* for defaulting to non-zoom-filtered rules
|
||||
*/
|
||||
tree.Filter.prototype.inverse = function() {
|
||||
for (var i = 0; i < this.max_zoom; i++) {
|
||||
this.zoom_range[i] = !this.zoom_range[i];
|
||||
}
|
||||
};
|
||||
|
||||
tree.Filter.prototype.toCSS = function(env) {
|
||||
if (this.key === 'zoom') {
|
||||
if (parseInt(this.val) > 22 || parseInt(this.val) < 0) {
|
||||
throw {
|
||||
message: 'Only zoom levels between 0 and 22 supported.',
|
||||
index: this.index
|
||||
}
|
||||
}
|
||||
if (this.op.toCSS() == '>') {
|
||||
return '<MaxScaleDenominator>' + this.zooms[this.val][0] +
|
||||
'</MaxScaleDenominator>';
|
||||
}
|
||||
if (this.op.toCSS() == '> =') {
|
||||
return '<MaxScaleDenominator>' + this.zooms[this.val][1] +
|
||||
'</MaxScaleDenominator>';
|
||||
}
|
||||
if (this.op.toCSS() == '<') {
|
||||
return '<MinScaleDenominator>' + this.zooms[this.val][1] +
|
||||
'</MinScaleDenominator>';
|
||||
}
|
||||
if (this.op.toCSS() == '< =') {
|
||||
return '<MinScaleDenominator>' + this.zooms[this.val][0] +
|
||||
'</MinScaleDenominator>';
|
||||
}
|
||||
} else {
|
||||
if (this.val.is) {
|
||||
this.val = this.val.toCSS((this.val.is == 'string'));
|
||||
}
|
||||
return '<Filter>[' + this.key + '] ' +
|
||||
this.op.toCSS() +
|
||||
' ' +
|
||||
this.val +
|
||||
'</Filter>';
|
||||
if (this.val.is) {
|
||||
this.val = this.val.toCSS((this.val.is == 'string'));
|
||||
}
|
||||
return '<Filter>[' + this.key + '] ' +
|
||||
this.op.toCSS() +
|
||||
' ' +
|
||||
this.val +
|
||||
'</Filter>';
|
||||
};
|
||||
|
||||
})(require('mess/tree'));
|
||||
|
120
lib/mess/tree/zoomfilter.js
Normal file
120
lib/mess/tree/zoomfilter.js
Normal file
@ -0,0 +1,120 @@
|
||||
(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 = this.create_range(this.op.value, this.val);
|
||||
|
||||
this.zooms = {
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an array of true, false values
|
||||
* which denotes whether this filter should apply
|
||||
* to each of the zoom levels from 0-22.
|
||||
*/
|
||||
tree.ZoomFilter.prototype.create_range = function(op, value) {
|
||||
var max_zoom = 22;
|
||||
var zoom_range = [];
|
||||
if (op === '>' || op === '>=') {
|
||||
if (op === '>') val++;
|
||||
for (var i = 0; i < max_zoom; i++) {
|
||||
zoom_range[i] = (i >= val);
|
||||
}
|
||||
} else {
|
||||
if (op === '<') val--;
|
||||
for (var i = 0; i < max_zoom; i++) {
|
||||
zoom_range[i] = (i <= val);
|
||||
}
|
||||
}
|
||||
return zoom_range;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Invert this style rule. Apply to all zoom levels
|
||||
* that the rule previously did not apply to and
|
||||
* vice versa.
|
||||
*
|
||||
* Usage is for doing the equivalent of an ElseFilter
|
||||
* for defaulting to non-zoom-filtered rules
|
||||
*/
|
||||
tree.ZoomFilter.prototype.inverse = function() {
|
||||
for (var i = 0; i < this.max_zoom; i++) {
|
||||
this.zoom_range[i] = !this.zoom_range[i];
|
||||
}
|
||||
};
|
||||
|
||||
tree.ZoomFilter.prototype.toCSS = 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>';
|
||||
}
|
||||
};
|
||||
})(require('mess/tree'));
|
Loading…
Reference in New Issue
Block a user