CartoDB-SQL-API/app/models/formats/pg/geojson.js

120 lines
2.8 KiB
JavaScript
Raw Normal View History

2015-05-13 19:00:01 +08:00
var _ = require('underscore');
var pg = require('./../pg');
var PgErrorHandler = require('../../../postgresql/error_handler');
2013-05-16 17:24:52 +08:00
2014-07-31 09:17:14 +08:00
function GeoJsonFormat() {
this.buffer = '';
}
2013-05-16 17:24:52 +08:00
2014-07-31 09:17:14 +08:00
GeoJsonFormat.prototype = new pg('geojson');
2013-05-16 17:24:52 +08:00
2014-07-31 09:17:14 +08:00
GeoJsonFormat.prototype._contentType = "application/json; charset=utf-8";
2013-05-16 17:24:52 +08:00
2014-07-31 09:17:14 +08:00
GeoJsonFormat.prototype.getQuery = function(sql, options) {
2013-05-16 17:24:52 +08:00
var gn = options.gn;
var dp = options.dp;
return 'SELECT *, ST_AsGeoJSON(' + gn + ',' + dp + ') as the_geom FROM (' + sql + ') as foo';
};
2013-05-16 17:24:52 +08:00
2014-07-31 09:17:14 +08:00
GeoJsonFormat.prototype.startStreaming = function() {
this.total_rows = 0;
if (this.opts.beforeSink) {
this.opts.beforeSink();
}
if (this.opts.callback) {
this.buffer += this.opts.callback + '(';
}
this.buffer += '{"type": "FeatureCollection", "features": [';
this._streamingStarted = true;
};
GeoJsonFormat.prototype.handleQueryRow = function(row) {
if ( ! this._streamingStarted ) {
this.startStreaming();
}
var geojson = [
'{',
'"type":"Feature",',
'"geometry":' + row[this.opts.gn] + ',',
'"properties":'
];
delete row[this.opts.gn];
2015-05-13 19:00:01 +08:00
delete row.the_geom_webmercator;
2014-07-31 09:17:14 +08:00
geojson.push(JSON.stringify(row));
geojson.push('}');
this.buffer += (this.total_rows++ ? ',' : '') + geojson.join('');
if (this.total_rows % (this.opts.bufferedRows || 1000)) {
this.opts.sink.write(this.buffer);
this.buffer = '';
}
};
2015-05-13 19:00:01 +08:00
GeoJsonFormat.prototype.handleQueryEnd = function(/*result*/) {
if (this.error && !this._streamingStarted) {
this.callback(this.error);
return;
}
2015-05-13 19:00:01 +08:00
if ( this.opts.profiler ) {
this.opts.profiler.done('gotRows');
}
if ( ! this._streamingStarted ) {
this.startStreaming();
}
this.buffer += ']'; // end of features
if (this.error) {
var pgErrorHandler = new PgErrorHandler(this.error);
this.buffer += ',"error":' + JSON.stringify([pgErrorHandler.getMessage()]);
}
this.buffer += '}'; // end of root object
2014-07-31 09:17:14 +08:00
if (this.opts.callback) {
this.buffer += ')';
}
this.opts.sink.write(this.buffer);
this.opts.sink.end();
this.buffer = '';
this.callback();
2013-05-16 17:24:52 +08:00
};
function _toGeoJSON(data, gn, callback){
try {
var out = {
type: "FeatureCollection",
features: []
};
_.each(data.rows, function(ele){
var _geojson = {
type: "Feature",
properties: { },
geometry: { }
};
_geojson.geometry = JSON.parse(ele[gn]);
delete ele[gn];
2015-05-13 19:00:01 +08:00
delete ele.the_geom_webmercator; // TODO: use skipfields
2013-05-16 17:24:52 +08:00
_geojson.properties = ele;
out.features.push(_geojson);
});
// return payload
callback(null, out);
} catch (err) {
callback(err,null);
}
}
2014-07-31 09:17:14 +08:00
module.exports = GeoJsonFormat;
module.exports.toGeoJSON = _toGeoJSON;