CartoDB-SQL-API/lib/models/formats/pg/topojson.js

139 lines
3.7 KiB
JavaScript
Raw Normal View History

2018-10-24 21:42:33 +08:00
'use strict';
2019-12-24 01:19:08 +08:00
var Pg = require('./../pg');
2015-05-13 19:00:12 +08:00
var _ = require('underscore');
var geojson = require('./geojson');
var TopoJSON = require('topojson');
2013-05-16 17:24:52 +08:00
2019-12-24 01:19:08 +08:00
function TopoJsonFormat () {
this.features = [];
}
2013-05-16 17:24:52 +08:00
2019-01-16 22:58:11 +08:00
TopoJsonFormat.prototype = new Pg('topojson');
2013-05-16 17:24:52 +08:00
2019-12-24 01:19:08 +08:00
TopoJsonFormat.prototype.getQuery = function (sql, options) {
return geojson.prototype.getQuery(sql, options) + ' where ' + options.gn + ' is not null';
};
2013-05-16 17:24:52 +08:00
2019-12-24 01:19:08 +08:00
TopoJsonFormat.prototype.handleQueryRow = function (row) {
var _geojson = {
2019-12-24 01:19:08 +08:00
type: 'Feature'
};
_geojson.geometry = JSON.parse(row[this.opts.gn]);
delete row[this.opts.gn];
2015-05-13 19:00:12 +08:00
delete row.the_geom_webmercator;
_geojson.properties = row;
this.features.push(_geojson);
};
2013-05-16 17:24:52 +08:00
2019-12-24 01:19:08 +08:00
TopoJsonFormat.prototype.handleQueryEnd = function () {
if (this.error) {
this.callback(this.error);
return;
2013-05-16 17:24:52 +08:00
}
2019-12-24 01:19:08 +08:00
if (this.opts.profiler) {
2015-05-13 19:00:12 +08:00
this.opts.profiler.done('gotRows');
}
var topology = TopoJSON.topology(this.features, {
2019-12-24 01:19:08 +08:00
quantization: 1e4,
'force-clockwise': true,
'property-filter': function (d) {
return d;
}
2013-05-16 17:24:52 +08:00
});
this.features = [];
var stream = this.opts.sink;
var jsonpCallback = this.opts.callback;
var bufferedRows = this.opts.bufferedRows;
var buffer = '';
var immediately = global.setImmediate || process.nextTick;
2019-12-27 00:46:27 +08:00
/* eslint-disable */
2019-12-24 01:19:08 +08:00
function streamObjectSubtree (obj, key, done) {
buffer += '"' + key + '":';
2019-12-24 01:19:08 +08:00
var isObject = _.isObject(obj[key]);
var isArray = _.isArray(obj[key]);
var isIterable = isArray || isObject;
if (isIterable) {
buffer += isArray ? '[' : '{';
var subtreeKeys = Object.keys(obj[key]);
var pos = 0;
2019-12-24 01:19:08 +08:00
function streamNext () {
immediately(function () {
var subtreeKey = subtreeKeys.shift();
if (!isArray) {
buffer += '"' + subtreeKey + '":';
}
buffer += JSON.stringify(obj[key][subtreeKey]);
if (pos++ % (bufferedRows || 1000)) {
stream.write(buffer);
buffer = '';
}
if (subtreeKeys.length > 0) {
delete obj[key][subtreeKey];
buffer += ',';
streamNext();
} else {
buffer += isArray ? ']' : '}';
stream.write(buffer);
buffer = '';
done();
}
});
}
streamNext();
} else {
buffer += JSON.stringify(obj[key]);
done();
}
}
2019-12-27 00:46:27 +08:00
/* eslint-enable */
if (jsonpCallback) {
buffer += jsonpCallback + '(';
}
buffer += '{';
var keys = Object.keys(topology);
2019-12-24 01:19:08 +08:00
function sendResponse () {
immediately(function () {
var key = keys.shift();
2019-12-24 01:19:08 +08:00
function done () {
if (keys.length > 0) {
delete topology[key];
buffer += ',';
sendResponse();
} else {
buffer += '}';
if (jsonpCallback) {
buffer += ')';
}
stream.write(buffer);
stream.end();
topology = null;
}
}
streamObjectSubtree(topology, key, done);
});
}
sendResponse();
this.callback();
};
2019-12-24 01:19:08 +08:00
TopoJsonFormat.prototype.cancel = function () {
if (this.queryCanceller) {
this.queryCanceller.call();
}
};
2014-08-03 02:27:05 +08:00
module.exports = TopoJsonFormat;