diff --git a/NEWS.md b/NEWS.md
index 7f6785ed..785f7812 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,6 +1,9 @@
1.18.1 - 2014-mm-dd
-------------------
+Enhancements:
+ * Don't loop twice over svg rows
+
1.18.0 - 2014-10-14
-------------------
diff --git a/app/models/formats/svg.js b/app/models/formats/svg.js
index d1d92b1b..3bad9e85 100644
--- a/app/models/formats/svg.js
+++ b/app/models/formats/svg.js
@@ -1,13 +1,31 @@
-var pg = require('./pg');
-var _ = require('underscore')
+var pg = require('./pg'),
+ _ = require('underscore');
var svg_width = 1024.0;
var svg_height = 768.0;
var svg_ratio = svg_width/svg_height;
-function SvgFormat() {}
+var radius = 5; // in pixels (based on svg_width and svg_height)
+
+var stroke_width = 1; // in pixels (based on svg_width and svg_height)
+var stroke_color = 'black';
+// fill settings affect polygons and points (circles)
+var fill_opacity = 0.5; // 0.0 is fully transparent, 1.0 is fully opaque
+// unused if fill_color='none'
+var fill_color = 'none'; // affects polygons and circles
+
+function SvgFormat() {
+ this.totalRows = 0;
+
+ this.bbox = null; // will be computed during the results scan
+
+ this.polys = [];
+ this.lines = [];
+ this.points = [];
+}
SvgFormat.prototype = new pg('svg');
+SvgFormat.prototype._contentType = "image/svg+xml; charset=utf-8";
SvgFormat.prototype.getQuery = function(sql, options) {
var gn = options.gn;
@@ -33,106 +51,100 @@ SvgFormat.prototype.getQuery = function(sql, options) {
+ ' FROM trans, extent_info, source';
};
-SvgFormat.prototype._contentType = "image/svg+xml; charset=utf-8";
+SvgFormat.prototype.handleQueryRow = function(row) {
+ this.totalRows++;
-SvgFormat.prototype.transform = function(result, options, callback) {
- toSVG(result.rows, options.gn, callback);
-};
+ if ( ! row.hasOwnProperty(this.opts.gn) ) {
+ this.error = new Error('column "' + this.opts.gn + '" does not exist');
+ }
+ var g = row[this.opts.gn];
+ if ( ! g ) return; // null or empty
-function toSVG(rows, gn, callback) {
+ var gdims = row[this.opts.gn + '_dimension'];
+ // TODO: add an identifier, if any of "cartodb_id", "oid", "id", "gid" are found
+ // TODO: add "class" attribute to help with styling ?
+ if ( gdims == '0' ) {
+ this.points.push('');
+ } else if ( gdims == '1' ) {
+ // Avoid filling closed linestrings
+ this.lines.push('');
+ } else if ( gdims == '2' ) {
+ this.polys.push('');
+ }
- var radius = 5; // in pixels (based on svg_width and svg_height)
- var stroke_width = 1; // in pixels (based on svg_width and svg_height)
- var stroke_color = 'black';
- // fill settings affect polygons and points (circles)
- var fill_opacity = 0.5; // 0.0 is fully transparent, 1.0 is fully opaque
- // unused if fill_color='none'
- var fill_color = 'none'; // affects polygons and circles
-
- var bbox; // will be computed during the results scan
- var polys = [];
- var lines = [];
- var points = [];
- _.each(rows, function(ele){
- if ( ! ele.hasOwnProperty(gn) ) {
- throw new Error('column "' + gn + '" does not exist');
- }
- var g = ele[gn];
- if ( ! g ) return; // null or empty
- var gdims = ele[gn + '_dimension'];
-
- // TODO: add an identifier, if any of "cartodb_id", "oid", "id", "gid" are found
- // TODO: add "class" attribute to help with styling ?
- if ( gdims == '0' ) {
- points.push('');
- } else if ( gdims == '1' ) {
- // Avoid filling closed linestrings
- var linetag = '';
- lines.push(linetag);
- } else if ( gdims == '2' ) {
- polys.push('');
- }
-
- if ( ! bbox ) {
- // Parse layer extent: "BOX(x y, X Y)"
- // NOTE: the name of the extent field is
- // determined by the same code adding the
- // ST_AsSVG call (in queryResult)
- //
- bbox = ele[gn + '_box'];
- bbox = bbox.match(/BOX\(([^ ]*) ([^ ,]*),([^ ]*) ([^)]*)\)/);
- bbox = {
+ if ( ! this.bbox ) {
+ // Parse layer extent: "BOX(x y, X Y)"
+ // NOTE: the name of the extent field is
+ // determined by the same code adding the
+ // ST_AsSVG call (in queryResult)
+ //
+ var bbox = row[this.opts.gn + '_box'];
+ bbox = bbox.match(/BOX\(([^ ]*) ([^ ,]*),([^ ]*) ([^)]*)\)/);
+ this.bbox = {
xmin: parseFloat(bbox[1]),
ymin: parseFloat(bbox[2]),
xmax: parseFloat(bbox[3]),
ymax: parseFloat(bbox[4])
- };
- }
- });
+ };
+ }
+};
- // Set point radius
- for (var i=0; i',
- '',
+ ''
];
- var root_tag = '');
+ this.opts.sink.write(this.points.join('\n'));
+ this.points = [];
+ this.opts.sink.write(this.lines.join('\n'));
+ this.lines = [];
+ this.opts.sink.write(this.polys.join('\n'));
+ this.polys = [];
+ // rootTag close
+ this.opts.sink.write('');
+ this.opts.sink.end();
- // return payload
- callback(null, out.join("\n"));
-}
+ this.callback();
+};
module.exports = SvgFormat;