diff --git a/bin/carto b/bin/carto index 6d719f7..4ca598f 100755 --- a/bin/carto +++ b/bin/carto @@ -4,7 +4,7 @@ var path = require('path'), fs = require('fs'), carto = require('carto'), url = require('url'), - _ = require('lodash'); + _ = require('underscore'); var existsSync = require('fs').existsSync || require('path').existsSync diff --git a/lib/carto/index.js b/lib/carto/index.js index 64ed5b4..a0265d8 100644 --- a/lib/carto/index.js +++ b/lib/carto/index.js @@ -2,6 +2,7 @@ var util = require('util'), fs = require('fs'), path = require('path'); + function getVersion() { if (parseInt(process.version.split('.')[1], 10) > 4) { return require('../../package.json').version.split('.'); diff --git a/lib/carto/parser.js b/lib/carto/parser.js index 81b1e64..f5f160d 100644 --- a/lib/carto/parser.js +++ b/lib/carto/parser.js @@ -3,7 +3,7 @@ var carto, tree, _; if (typeof(process) !== 'undefined') { carto = exports; tree = require('./tree'); - _ = require('lodash'); + _ = require('underscore'); } else { if (typeof(window.carto) === 'undefined') { window.carto = {}; } carto = window.carto; diff --git a/lib/carto/renderer.js b/lib/carto/renderer.js index 1b16508..2fe5c9b 100644 --- a/lib/carto/renderer.js +++ b/lib/carto/renderer.js @@ -1,4 +1,4 @@ -var _ = require('lodash'); +var _ = require('underscore'); var carto = require('./index'); var tree = require('./tree'); @@ -29,7 +29,7 @@ carto.Renderer.prototype.render = function render(m, callback) { var output = []; // Transform stylesheets into rulesets. - var rulesets = _(m.Stylesheet) + var rulesets = _(m.Stylesheet).chain() .map(function(s) { if (typeof s == 'string') { throw new Error("Stylesheet object is expected not a string: '" + s + "'"); @@ -50,31 +50,36 @@ carto.Renderer.prototype.render = function render(m, callback) { // Iterate through layers and create styles custom-built // for each of them, and apply those styles to the layers. - m.Layer.forEach(function(l) { + var styles, l, classIndex, rules, sorted, matching; + for (var i = 0; i < m.Layer.length; i++) { + l = m.Layer[i]; + styles = []; + classIndex = {}; + if (env.benchmark) console.warn('processing layer: ' + l.id); - l.styles = []; // Classes are given as space-separated alphanumeric strings. var classes = (l['class'] || '').split(/\s+/g); - var matching = rulesets.filter(function(definition) { - return definition.appliesTo(l.name, classes); + for (var j = 0; j < classes.length; j++) { + classIndex[classes[j]] = true; + } + matching = rulesets.filter(function(definition) { + return definition.appliesTo(l.name, classIndex); }); - var rules = inheritRules(matching, env); - var sorted = sortStyles(rules, env); + rules = inheritRules(matching, env); + sorted = sortStyles(rules, env); - _(sorted).each(function(rule) { - var style = new tree.Style(l.name, rule.attachment, rule); - if (style) { - l.styles.push(style.name); + for (var k = 0, rule, style_name; k < sorted.length; k++) { + rule = sorted[k]; + style_name = l.name + (rule.attachment !== '__default__' ? '-' + rule.attachment : ''); + styles.push(style_name); - var xml = style.toXML(env); - // env.effects can be modified by this call - output.push(xml); - } - }); - if (l.styles.length) { - output.push((new carto.tree.Layer(l)).toXML()); + // env.effects can be modified by this call + output.push(tree.Style.toXML(style_name, rule.attachment, rule, env)); } - }); + if (styles.length) { + output.push(carto.tree.Layer.toXML(l, styles)); + } + } output.unshift(env.effects.map(function(e) { return e.toXML(env); diff --git a/lib/carto/tree/definition.js b/lib/carto/tree/definition.js index c1a1899..9f3c2bf 100644 --- a/lib/carto/tree/definition.js +++ b/lib/carto/tree/definition.js @@ -11,11 +11,11 @@ tree.Definition = function Definition(selector, rules) { this.elements = selector.elements; assert.ok(selector.filters instanceof tree.Filterset); this.rules = rules; - this.ruleIndex = []; + this.ruleIndex = {}; for (var i = 0; i < this.rules.length; i++) { if ('zoom' in this.rules[i]) this.rules[i] = this.rules[i].clone(); this.rules[i].zoom = selector.zoom; - this.ruleIndex.push(this.rules[i].updateID()); + this.ruleIndex[this.rules[i].updateID()] = true; } this.filters = selector.filters; this.zoom = selector.zoom; @@ -35,7 +35,7 @@ tree.Definition.prototype.clone = function(filters) { if (filters) assert.ok(filters instanceof tree.Filterset); var clone = Object.create(tree.Definition.prototype); clone.rules = this.rules.slice(); - clone.ruleIndex = this.ruleIndex.slice(); + clone.ruleIndex = Object.create(this.ruleIndex); clone.filters = filters ? filters : this.filters.clone(); clone.attachment = this.attachment; return clone; @@ -46,9 +46,9 @@ tree.Definition.prototype.addRules = function(rules) { // Add only unique rules. for (var i = 0; i < rules.length; i++) { - if (this.ruleIndex.indexOf(rules[i].id) < 0) { + if (!this.ruleIndex[rules[i].id]) { this.rules.push(rules[i]); - this.ruleIndex.push(rules[i].id); + this.ruleIndex[rules[i].id] = true; added++; } } @@ -60,7 +60,7 @@ tree.Definition.prototype.addRules = function(rules) { // and array of classes, by determining whether // all elements it contains match. tree.Definition.prototype.appliesTo = function(id, classes) { - for (var i = 0; i < this.elements.length; i++) { + for (var i = 0, l = this.elements.length; i < l; i++) { if (!this.elements[i].matches(id, classes)) { return false; } diff --git a/lib/carto/tree/dimension.js b/lib/carto/tree/dimension.js index aa631da..8db423e 100644 --- a/lib/carto/tree/dimension.js +++ b/lib/carto/tree/dimension.js @@ -12,7 +12,7 @@ tree.Dimension = function Dimension(value, unit, index) { tree.Dimension.prototype = { is: 'float', 'eval': function (env) { - if (this.unit && ['px', '%'].indexOf(this.unit) === -1) { + if (this.unit && (this.unit !== 'px' && this.unit !== '%')) { env.error({ message: "Invalid unit: '" + this.unit + "'", index: this.index diff --git a/lib/carto/tree/element.js b/lib/carto/tree/element.js index 1b06c5a..412e794 100644 --- a/lib/carto/tree/element.js +++ b/lib/carto/tree/element.js @@ -25,7 +25,7 @@ tree.Element.prototype.toString = function() { // Takes a plain string for id and plain strings in the array of // classes. tree.Element.prototype.matches = function(id, classes) { - return (classes.indexOf(this.value.replace(/^\./, '')) !== -1) || + return (classes[this.value.replace(/^\./, '')]) || (this.value.replace(/^#/, '') === id) || (this.value === '*'); }; diff --git a/lib/carto/tree/filterset.js b/lib/carto/tree/filterset.js index 6e02605..889cbfd 100644 --- a/lib/carto/tree/filterset.js +++ b/lib/carto/tree/filterset.js @@ -65,9 +65,7 @@ tree.Filterset.prototype.cloneWith = function(other) { // We can add the rules that are already present without going through the // add function as a Filterset is always in it's simplest canonical form. - for (id in this.filters) { - clone.filters[id] = this.filters[id]; - } + clone.filters = Object.create(this.filters); // Only add new filters that actually change the filter. while (id = additions.shift()) { diff --git a/lib/carto/tree/layer.js b/lib/carto/tree/layer.js index f36cfcf..dc2c9d9 100644 --- a/lib/carto/tree/layer.js +++ b/lib/carto/tree/layer.js @@ -1,32 +1,26 @@ (function(tree) { -tree.Layer = function Layer(obj) { - this.name = obj.name; - this.status = obj.status; - this.styles = obj.styles; - this.properties = obj.properties || {}; - this.srs = obj.srs; - this.datasource = obj.Datasource; +tree.Layer = function Layer(obj, styles) { }; -tree.Layer.prototype.toXML = function() { +tree.Layer.toXML = function(obj, styles) { var dsoptions = []; - for (var i in this.datasource) { + for (var i in obj.Datasource) { dsoptions.push(''); + obj.Datasource[i] + ']]>'); } var prop_string = ''; - for (var prop in this.properties) { - prop_string += ' ' + prop + '="' + this.properties[prop] + '"\n'; + for (var prop in obj.properties) { + prop_string += ' ' + prop + '="' + obj.properties[prop] + '"\n'; } return '\n ' + - this.styles.reverse().map(function(s) { + ((typeof obj.status === 'undefined') ? '' : ' status="' + obj.status + '"\n') + + ' srs="' + obj.srs + '">\n ' + + styles.reverse().map(function(s) { return '' + s + ''; }).join('\n ') + '\n \n ' + diff --git a/lib/carto/tree/reference.js b/lib/carto/tree/reference.js index 5e7a25f..27716d4 100644 --- a/lib/carto/tree/reference.js +++ b/lib/carto/tree/reference.js @@ -4,7 +4,7 @@ // combinations. (function(tree) { -var _ = require('lodash'); +var _ = require('underscore'); var mapnik_reference = require('mapnik-reference'); tree.Reference = { diff --git a/lib/carto/tree/style.js b/lib/carto/tree/style.js index d05551d..9bf0d46 100644 --- a/lib/carto/tree/style.js +++ b/lib/carto/tree/style.js @@ -1,16 +1,12 @@ (function(tree) { -var _ = require('lodash'); +var _ = require('underscore'); tree.Style = function Style(name, attachment, definitions) { - this.attachment = attachment; - this.definitions = definitions; - this.name = name + (attachment !== '__default__' ? '-' + attachment : ''); }; -tree.Style.prototype.toXML = function(env) { +tree.Style.toXML = function(name, attachment, definitions, env) { var existing = {}; - var definitions = this.definitions; function byName(name) { return _.flatten(definitions.map(function(definition) { return definition.rules.filter(function(rule) { @@ -23,7 +19,7 @@ tree.Style.prototype.toXML = function(env) { var comp_op = byName('comp-op'); var opacity = byName('opacity'); - var rules = this.definitions.map(function(definition) { + var rules = definitions.map(function(definition) { return definition.toXML(env, existing); }); @@ -43,7 +39,7 @@ tree.Style.prototype.toXML = function(env) { attrs_xml += ' opacity="' + opacity[0].value.eval(env).toString() + '" '; } - return ''; + return ''; }; })(require('../tree')); diff --git a/package.json b/package.json index 28c2456..42a433e 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,7 @@ "dependencies": { "underscore": "~1.3.3", "mapnik-reference": "~5.0.0", - "xml2js": "~0.1.13", - "lodash": "~1.0.0-rc.3" + "xml2js": "~0.1.13" }, "devDependencies": { "mocha": "1.3.x",