From 2e9a16d56d66d216e24342d55ba0712cb1364beb Mon Sep 17 00:00:00 2001 From: Raul Ochoa Date: Thu, 23 Oct 2014 16:49:04 +0200 Subject: [PATCH] Don't loop twice over svg rows --- NEWS.md | 3 + app/models/formats/svg.js | 182 ++++++++++++++++++++------------------ 2 files changed, 100 insertions(+), 85 deletions(-) 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;