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",