Compare commits

...

83 Commits

Author SHA1 Message Date
Raul Ochoa
bd3fdb7f16 Release 2.78.0 2016-09-29 11:35:03 +02:00
Raul Ochoa
775af6feee Merge pull request #575 from CartoDB/cartocss-meta
Add metadata about processed turbo-carto rules
2016-09-28 19:44:52 +02:00
Raul Ochoa
adf5c17e0d Use context from adapters as provider context 2016-09-28 19:22:03 +02:00
Raul Ochoa
beb2d96a32 Upgrades turbo-carto to 0.17.1 2016-09-28 19:21:43 +02:00
Raul Ochoa
2a4ae88bc0 Merge remote-tracking branch 'origin/master' into cartocss-meta 2016-09-28 17:06:36 +02:00
Raul Ochoa
b76098ba45 Upgrades turbo-carto to 0.17.0 2016-09-28 16:57:04 +02:00
Raul Ochoa
c095027f8e Regenerate npm-shrinkwrap.json 2016-09-28 14:45:33 +02:00
Raul Ochoa
9d1db19907 Regenerate npm-shrinkwrap.json for turbo-carto dep 2016-09-28 11:39:58 +02:00
Daniel García Aubert
260e321537 Stub next version 2016-09-28 11:04:03 +02:00
Daniel García Aubert
073603b527 Release 2.77.1 2016-09-28 10:55:50 +02:00
Daniel García Aubert
17b259cf31 Upgrade camshaft to version 0.44.1 2016-09-28 10:54:27 +02:00
Daniel García Aubert
8f0f0026e9 Stubs next version 2016-09-27 12:28:44 +02:00
Daniel García Aubert
59dae2b545 Release 2.77.0 2016-09-26 19:11:12 +02:00
Daniel García Aubert
4670f69ead Upgrade camshaft to version 0.44.0 2016-09-26 19:05:16 +02:00
Daniel
16fbd25a34 Merge pull request #576 from CartoDB/conf-analysis-logger
Pass logger configuration to analysis backend and create a stream
2016-09-26 18:14:52 +02:00
Daniel García Aubert
2d75985cb3 Recreate stream on SIGHUP event 2016-09-26 17:39:27 +02:00
Daniel García Aubert
f963fb321e Set default config of analysis logger for test env 2016-09-23 17:35:46 +02:00
Daniel García Aubert
10feea0d48 Pass logger configuration to analysis backend and create a stream based on config 2016-09-23 17:11:04 +02:00
Raul Ochoa
b6b9b0ac36 Regenerate npm-shrinkwrap 2016-09-21 17:13:59 +02:00
Raul Ochoa
5551e85853 Update news and bump version 2016-09-21 16:06:43 +02:00
Raul Ochoa
1f0fa5031b Rely on turbo-carto metadata branch 2016-09-20 16:19:46 +02:00
Raul Ochoa
263294a3f5 Add metadata only for existing layers in turbocarto context 2016-09-20 16:19:22 +02:00
Raul Ochoa
f9df30f70b Append turbo-carto metadata per layer 2016-09-20 16:09:21 +02:00
Raul Ochoa
61d31ec054 Handle metadata from turbo-carto 2016-09-20 16:08:53 +02:00
Raul Ochoa
c8917bfc4c Return stats in callback 2016-09-20 16:00:33 +02:00
Raul Ochoa
36b69a05e5 Compute some stats in queries 2016-09-20 16:00:06 +02:00
Raul Ochoa
c8d2f66467 Stubs next version 2016-09-15 12:14:12 +02:00
Raul Ochoa
7416bb0e56 Release 2.76.0 2016-09-15 12:13:36 +02:00
Raul Ochoa
9182d0132d Merge pull request #574 from CartoDB/travis-addon
Travis' pg 9.5 addon
2016-09-15 11:17:51 +02:00
Raul Ochoa
9be9357ade Add libpango 2016-09-15 01:57:49 +02:00
Raul Ochoa
7f414f8adf Attempt to use travis' pg 9.5 addon 2016-09-15 01:51:36 +02:00
Raul Ochoa
3af9549939 Merge pull request #573 from CartoDB/external-config
Allow to use `--config /path/to/config.js` to specify configuration file
2016-09-15 01:49:43 +02:00
Raul Ochoa
41f248d731 Use logError 2016-09-15 01:35:38 +02:00
Raul Ochoa
18a517b7bf Allow to use --config /path/to/config.js to specify configuration file 2016-09-15 01:25:33 +02:00
Raul Ochoa
5150204389 Travis' Node.js 0.10 already uses npm 2.x 2016-09-14 21:22:40 +02:00
Raul Ochoa
3b16e7729d Merge pull request #572 from CartoDB/logs-conf
Allow to use absolute paths for log files
2016-09-14 21:04:19 +02:00
Raul Ochoa
76d27c9fce Allow to use absolute paths for log files
Fixes #570
2016-09-14 20:15:38 +02:00
Raul Ochoa
4ce6e41000 Stubs next version 2016-09-14 20:06:05 +02:00
Daniel García Aubert
33260cdbd9 Release 2.75.0 2016-09-14 09:48:20 +02:00
Raul Ochoa
85d81ba7fd Upgrades camshaft to 0.42.2 2016-09-09 13:40:31 +02:00
Raul Ochoa
7e8a3ca21f Stubs next version 2016-09-07 17:01:39 +02:00
Raul Ochoa
e9e4dc1f5c Release 2.74.1 2016-09-07 17:00:23 +02:00
Raul Ochoa
17c30e165a Upgrades camshaft to 0.42.1
Test fixture updated as it no longers generate bounds based on
table estimated bounds
2016-09-07 16:43:18 +02:00
Daniel García Aubert
c45c6ceb15 Stubs next version 2016-09-06 19:10:58 +02:00
Daniel García Aubert
d73c2c465f Release 2.74.0 2016-09-06 19:03:50 +02:00
Daniel
d4fc53939b Merge pull request #568 from CartoDB/567-show-hide-named-maps
Show & hide support in named maps
2016-09-06 18:53:23 +02:00
Daniel García Aubert
4becb65bec Stubs next version 2016-09-06 16:33:21 +02:00
Daniel García Aubert
f64e16c790 Release 2.73.1 2016-09-06 16:27:12 +02:00
Daniel García Aubert
1772011627 Add missinng column in fixture table cdb_analysis_catalog 2016-09-06 16:19:06 +02:00
Raul Ochoa
5b8f785e2b Regenerate npm-shrinkwrap.json 2016-09-06 16:01:05 +02:00
Daniel García Aubert
a0e3b77006 Release 2.73.0 2016-09-06 15:51:03 +02:00
Daniel García Aubert
908070ecd7 Fix jshint issue 2016-09-01 16:53:10 +02:00
Daniel García Aubert
7c6a58cd30 Made explicit to recreate named-map-provider 2016-09-01 16:42:06 +02:00
Daniel García Aubert
b0990a1132 Removed template-maps backend from named-maps controller 2016-09-01 16:31:30 +02:00
Daniel García Aubert
c6988cdb88 Improved and implemented new test for layer visibility suite 2016-09-01 12:37:56 +02:00
Daniel García Aubert
e0d304b033 Applied approach similar to static image options 2016-09-01 12:37:04 +02:00
Daniel García Aubert
e4a9f2d64c Added template map as dependency of named maps controller 2016-09-01 12:35:35 +02:00
Daniel García Aubert
0236fe3ca9 Implemented new scenario 2016-08-31 20:41:07 +02:00
Daniel García Aubert
1bed8623a2 Overwrites rendererparams instead of layergroup in mapconfig 2016-08-31 20:40:55 +02:00
Daniel García Aubert
df7d957914 Implemented acceptance test for layer visibility in previews 2016-08-31 19:41:23 +02:00
Daniel García Aubert
30c4b00f33 New approach: decorates named_map_provider to return the with visible layers 2016-08-31 19:40:00 +02:00
Daniel García Aubert
ab27886460 Renamed option by for name maps template 2016-08-31 19:37:48 +02:00
Daniel García Aubert
31e18d04d7 Undo unneeded optimization 2016-08-31 13:57:28 +02:00
Daniel García Aubert
8155484510 Improved test visibility layer with layerId 2016-08-29 10:46:55 +02:00
Daniel García Aubert
b61f1d2b53 Attached layer_visibility property to the named template 2016-08-26 17:30:03 +02:00
Daniel García Aubert
2e274b936a Improved test to check all possible values of visibility in named maps templates 2016-08-26 15:07:06 +02:00
Daniel García Aubert
bf3e311b57 Avoid unnecessary complexity 2016-08-26 14:46:23 +02:00
Daniel García Aubert
6a7613de6b Improved layergroup instantiation to filter non visible layers 2016-08-26 14:42:33 +02:00
Daniel García Aubert
ee46549e04 First approach 2016-08-25 20:04:23 +02:00
Raul Ochoa
377f3d4aff Removes constraint on filtered mapnik layers 2016-08-25 18:34:19 +02:00
Daniel García Aubert
752d47d71e Stubs next version 2016-08-23 11:25:39 +02:00
Daniel García Aubert
367157b80c Release 2.72.0 2016-08-23 11:19:48 +02:00
Daniel García Aubert
53542f1cd6 Stubs next version 2016-08-17 15:15:18 +02:00
Daniel García Aubert
7a8f156abf Release 2.71.0 2016-08-17 15:12:42 +02:00
Daniel García Aubert
c60cc57a0d Upgrades Windshaft to version 2.5.0 2016-08-17 15:07:29 +02:00
Raul Ochoa
8de6ec9a21 Stubs next version 2016-08-16 12:25:12 +02:00
Raul Ochoa
44b6f4be7e Release 2.70.0 2016-08-16 12:24:23 +02:00
Raul Ochoa
280be1751c Merge pull request #565 from CartoDB/update-camshaft
Upgrade camshaft to 0.40.0
2016-08-16 12:19:25 +02:00
Raul Ochoa
701a73a2c5 Upgrade camshaft to 0.40.0 2016-08-16 11:33:32 +02:00
Raul Ochoa
b578eada07 Stubs next version 2016-08-12 10:34:33 +02:00
Raul Ochoa
8100f155dc Release 2.69.1 2016-08-12 10:33:10 +02:00
Raul Ochoa
9f1a014004 Upgrades windshaft to 2.4.2 2016-08-12 10:24:06 +02:00
Raul Ochoa
e35e0e157c Stubs next version 2016-08-11 12:06:33 +02:00
32 changed files with 1187 additions and 233 deletions

View File

@@ -1,22 +1,17 @@
dist: trusty # only environment that supports Postgres 9.5 at this time
sudo: required
addons:
postgresql: "9.5"
apt:
packages:
- postgresql-plpython-9.5
- pkg-config
- libcairo2-dev
- libjpeg8-dev
- libgif-dev
- libpango1.0-dev
before_install:
- npm install -g npm@2
- lsb_release -a
- sudo apt-get -qq purge postgis* postgresql*
- sudo rm -Rf /var/lib/postgresql /etc/postgresql
- sudo apt-add-repository --yes ppa:cartodb/postgresql-9.5
- sudo apt-add-repository --yes ppa:cartodb/gis
- sudo apt-get update
- sudo apt-get install -q --force-yes postgresql-9.5-postgis-2.2 postgresql-plpython-9.5
- echo -e "local\tall\tall\ttrust\nhost\tall\tall\t127.0.0.1/32\ttrust\nhost\tall\tall\t::1/128\ttrust" |sudo tee /etc/postgresql/9.5/main/pg_hba.conf
- sudo service postgresql restart
- createdb template_postgis
- createuser publicuser
- psql -c "CREATE EXTENSION postgis" template_postgis

View File

@@ -1,5 +1,5 @@
1. Test (make clean all check), fix if broken before proceeding
2. Ensure proper version in package.json
2. Ensure proper version in package.json
3. Ensure NEWS section exists for the new version, review it, add release date
4. Recreate npm-shrinkwrap.json with: `npm install --no-shrinkwrap && npm shrinkwrap`
5. Commit package.json, npm-shrinwrap.json, NEWS

111
NEWS.md
View File

@@ -1,5 +1,116 @@
# Changelog
## 2.78.0
Released 2016-09-29
New features:
- Add metadata about processed turbo-carto rules.
Announcements:
- Upgrades turbo-carto to [0.17.1](https://github.com/CartoDB/turbo-carto/releases/tag/0.17.1).
## 2.77.1
Released 2016-09-28
Announcements:
- Upgrades camshaft to [0.44.1](https://github.com/CartoDB/camshaft/releases/tag/0.44.1).
## 2.77.0
Released 2016-09-26
Announcements:
- Upgrades camshaft to [0.44.0](https://github.com/CartoDB/camshaft/releases/tag/0.44.0).
- Adds a new configuration for camshaft: logger stream.
## 2.76.0
Released 2016-09-15
New features:
- Allow to use `--config /path/to/config.js` to specify configuration file.
- Environment will be loaded from config file if `environment` key is present, otherwise it keeps current behaviour.
Bug fixes:
- Allow to use absolute paths for log files #570.
## 2.75.0
Released 2016-09-14
Announcements:
- Upgrades camshaft to [0.43.0](https://github.com/CartoDB/camshaft/releases/tag/0.43.0).
## 2.74.1
Released 2016-09-07
Announcements:
- Upgrades camshaft to [0.42.1](https://github.com/CartoDB/camshaft/releases/tag/0.42.1).
## 2.74.0
Released 2016-09-06
Enhancements:
- Layers in previews can be shown or hidden using `preview_layers` property in template map
## 2.73.1
Released 2016-09-06
Bug fixes:
- Fixes missing column in fixture table `cdb_analysis_catalog`.
## 2.73.0
Released 2016-09-06
Announcements:
- Upgrades camshaft to [0.42.0](https://github.com/CartoDB/camshaft/releases/tag/0.42.0).
## 2.72.0
Released 2016-08-23
Announcements:
- Upgrades camshaft to [0.41.0](https://github.com/CartoDB/camshaft/releases/tag/0.41.0).
## 2.71.0
Released 2016-08-17
Announcements:
- Upgrades windshaft to [2.5.0](https://github.com/CartoDB/windshaft/releases/tag/2.5.0).
## 2.70.0
Released 2016-08-16
Announcements:
- Upgrades camshaft to [0.40.0](https://github.com/CartoDB/camshaft/releases/tag/0.40.0).
## 2.69.1
Released 2016-08-12
Announcements:
- Upgrades windshaft to [2.4.2](https://github.com/CartoDB/windshaft/releases/tag/2.4.2).
## 2.69.0
Released 2016-08-11

82
app.js
View File

@@ -5,20 +5,35 @@ var fs = require('fs');
var _ = require('underscore');
var ENVIRONMENT;
if ( process.argv[2] ) {
ENVIRONMENT = process.argv[2];
} else if ( process.env.NODE_ENV ) {
ENVIRONMENT = process.env.NODE_ENV;
} else {
ENVIRONMENT = 'development';
}
// jshint undef:false
var log = console.log.bind(console);
var logError = console.error.bind(console);
// jshint undef:true
var argv = require('yargs')
.usage('Usage: $0 <environment> [options]')
.help('h')
.example(
'$0 production -c /etc/sql-api/config.js',
'start server in production environment with /etc/sql-api/config.js as config file'
)
.alias('h', 'help')
.alias('c', 'config')
.nargs('c', 1)
.describe('c', 'Load configuration from path')
.argv;
var environmentArg = argv._[0] || process.env.NODE_ENV || 'development';
var configurationFile = path.resolve(argv.config || './config/environments/' + environmentArg + '.js');
if (!fs.existsSync(configurationFile)) {
logError('Configuration file "%s" does not exist', configurationFile);
process.exit(1);
}
global.environment = require(configurationFile);
var ENVIRONMENT = argv._[0] || process.env.NODE_ENV || global.environment.environment;
process.env.NODE_ENV = ENVIRONMENT;
var availableEnvironments = {
production: true,
staging: true,
@@ -33,16 +48,6 @@ if (!availableEnvironments[ENVIRONMENT]){
}
process.env.NODE_ENV = ENVIRONMENT;
// set environment specific variables
global.environment = require('./config/environments/' + ENVIRONMENT);
global.log4js = require('log4js');
var log4js_config = {
appenders: [],
replaceConsole: true
};
if (global.environment.uv_threadpool_size) {
process.env.UV_THREADPOOL_SIZE = global.environment.uv_threadpool_size;
}
@@ -58,25 +63,31 @@ var agentOptions = _.defaults(global.environment.httpAgent || {}, {
http.globalAgent = new http.Agent(agentOptions);
https.globalAgent = new https.Agent(agentOptions);
global.log4js = require('log4js');
var log4jsConfig = {
appenders: [],
replaceConsole: true
};
if ( global.environment.log_filename ) {
var logdir = path.dirname(global.environment.log_filename);
// See cwd inlog4js.configure call below
logdir = path.resolve(__dirname, logdir);
if ( ! fs.existsSync(logdir) ) {
logError("Log filename directory does not exist: " + logdir);
process.exit(1);
}
log("Logs will be written to " + global.environment.log_filename);
log4js_config.appenders.push(
{ type: "file", filename: global.environment.log_filename }
);
var logFilename = path.resolve(global.environment.log_filename);
var logDirectory = path.dirname(logFilename);
if (!fs.existsSync(logDirectory)) {
logError("Log filename directory does not exist: " + logDirectory);
process.exit(1);
}
log("Logs will be written to " + logFilename);
log4jsConfig.appenders.push(
{ type: "file", absolute: true, filename: logFilename }
);
} else {
log4js_config.appenders.push(
{ type: "console", layout: { type:'basic' } }
);
log4jsConfig.appenders.push(
{ type: "console", layout: { type:'basic' } }
);
}
global.log4js.configure(log4js_config, { cwd: __dirname });
global.log4js.configure(log4jsConfig);
global.logger = global.log4js.getLogger();
global.environment.api_hostname = require('os').hostname().split('.')[0];
@@ -99,6 +110,7 @@ var listener = server.listen(serverOptions.bind.port, serverOptions.bind.host, b
var version = require("./package").version;
listener.on('listening', function() {
log('Using configuration file "%s"', configurationFile);
log(
"Windshaft tileserver %s started on %s:%s PID=%d (%s)",
version, serverOptions.bind.host, serverOptions.bind.port, process.pid, ENVIRONMENT
@@ -114,7 +126,7 @@ setInterval(function() {
process.on('SIGHUP', function() {
global.log4js.clearAndShutdownAppenders(function() {
global.log4js.configure(log4js_config);
global.log4js.configure(log4jsConfig);
global.logger = global.log4js.getLogger();
log('Log files reloaded');
});

View File

@@ -210,6 +210,12 @@ var config = {
endpoint: 'http://127.0.0.1:8080/api/v2/sql/job',
// the template to use for adding the host header in the batch api requests
hostHeaderTemplate: '{{=it.username}}.localhost.lan'
},
logger: {
// If filename is given logs comming from analysis client will be written
// there, in append mode. Otherwise 'log_filename' is used. Otherwise stdout is used (default).
// Log file will be re-opened on receiving the HUP signal
filename: '/tmp/analysis.log'
}
}
,millstone: {

View File

@@ -204,6 +204,12 @@ var config = {
endpoint: 'http://127.0.0.1:8080/api/v2/sql/job',
// the template to use for adding the host header in the batch api requests
hostHeaderTemplate: '{{=it.username}}.localhost.lan'
},
logger: {
// If filename is given logs comming from analysis client will be written
// there, in append mode. Otherwise 'log_filename' is used. Otherwise stdout is used (default).
// Log file will be re-opened on receiving the HUP signal
filename: 'logs/analysis.log'
}
}
,millstone: {

View File

@@ -204,6 +204,12 @@ var config = {
endpoint: 'http://127.0.0.1:8080/api/v2/sql/job',
// the template to use for adding the host header in the batch api requests
hostHeaderTemplate: '{{=it.username}}.localhost.lan'
},
logger: {
// If filename is given logs comming from analysis client will be written
// there, in append mode. Otherwise 'log_filename' is used. Otherwise stdout is used (default).
// Log file will be re-opened on receiving the HUP signal
filename: 'logs/analysis.log'
}
}
,millstone: {

View File

@@ -205,6 +205,12 @@ var config = {
endpoint: 'http://127.0.0.1:8080/api/v2/sql/job',
// the template to use for adding the host header in the batch api requests
hostHeaderTemplate: '{{=it.username}}.localhost.lan'
},
logger: {
// If filename is given logs comming from analysis client will be written
// there, in append mode. Otherwise 'log_filename' is used. Otherwise stdout is used (default).
// Log file will be re-opened on receiving the HUP signal
filename: 'node-windshaft.log'
}
}
,millstone: {

View File

@@ -141,9 +141,6 @@ https://{username}.carto.com/api/v1/map/{layergroupid}/0,3,4/{z}/{x}/{y}.png
Some notes about filtering:
- Invalid index values or out of bounds indexes will end in `Invalid layer filtering` errors.
- Once a Mapnik layer is selected, all Mapnik layers will get blended. As this may change in the future **it is
recommended** to always select all Mapnik layers if you want to select at least one so you will get a consistent
behavior in the future.
- Ordering is not considered. So right now filtering layers 0,3,4 is the very same thing as filtering 3,4,0. As this
may change in the future **it is recommended** to always select the layers in ascending order so you will get a
consistent behavior in the future.

View File

@@ -1,10 +1,10 @@
# Named Maps
Named Maps are essentially the same as Anonymous Maps except the MapConfig is stored on the server, and the map is given a unique name. You can create Named Maps from private data, and users without an API Key can view your Named Map (while keeping your data private).
Named Maps are essentially the same as Anonymous Maps except the MapConfig is stored on the server, and the map is given a unique name. You can create Named Maps from private data, and users without an API Key can view your Named Map (while keeping your data private).
The Named Map workflow consists of uploading a MapConfig file to CARTO servers, to select data from your CARTO user database by using SQL, and specifying the CartoCSS for your map.
The Named Map workflow consists of uploading a MapConfig file to CARTO servers, to select data from your CARTO user database by using SQL, and specifying the CartoCSS for your map.
The response back from the API provides the template_id of your Named Map as the `name` (the identifier of your Named Map), which is the name that you specified in the MapConfig. You can which you can then use to create your Named Map details, or [fetch XYZ tiles](#fetching-xyz-tiles-for-named-maps) directly for Named Maps.
The response back from the API provides the template_id of your Named Map as the `name` (the identifier of your Named Map), which is the name that you specified in the MapConfig. You can which you can then use to create your Named Map details, or [fetch XYZ tiles](#fetching-xyz-tiles-for-named-maps) directly for Named Maps.
**Tip:** You can also use a Named Map that you created (which is defined by its `name`), to create a map using CARTO.js. This is achieved by adding the [`namedmap` type](http://docs.carto.com/carto-engine/carto-js/layer-source-object/#named-maps-layer-source-object-type-namedmap) layer source object to draw the Named Map.
@@ -73,6 +73,10 @@ The `name` argument defines how to name this "template_name".json. Note that the
}
]
},
"preview_layers": {
"0": true,
"layer1": false
},
"view": {
"zoom": 4,
"center": {
@@ -95,7 +99,7 @@ Params | Description
--- | ---
name | There can only be _one_ template with the same name for any user. Valid names start with a letter or a number, and only contain letters, numbers, dashes (-), or underscores (_). _This is specific to the name of your Named Map that is specified in the `name` property of the template file_.
auth |
auth |
--- | ---
&#124;_ method | `"token"` or `"open"` (`"open"` is the default if no method is specified. Use `"token"` to password-protect your map)
&#124;_ valid_tokens | when `"method"` is set to `"token"`, the values listed here allow you to instantiate the Named Map. See this [example](http://docs.carto.com/faqs/manipulating-your-data/#how-to-create-a-password-protected-named-map) for how to create a password-protected map.
@@ -105,12 +109,12 @@ view (optional) | extra keys to specify the view area for the map. It can be use
--- | ---
&#124;_ zoom | The zoom level to use
&#124;_ center |
&#124;_ center |
--- | ---
&#124;_ &#124;_ lng | The longitude to use for the center
&#124;_ &#124;_ lat | The latitude to use for the center
&#124;_ bounds |
&#124;_ bounds |
--- | ---
&#124;_ &#124;_ west | LowerCorner longitude for the bounding box, in decimal degrees (aka most western)
&#124;_ &#124;_ south | LowerCorner latitude for the bounding box, in decimal degrees (aka most southern)
@@ -160,7 +164,7 @@ curl -X POST \
#### Response
The response back from the API provides the name of your MapConfig as a template, enabling you to edit the Named Map details by inserting your variables into the template where placeholders are defined, and create custom queries using SQL.
The response back from the API provides the name of your MapConfig as a template, enabling you to edit the Named Map details by inserting your variables into the template where placeholders are defined, and create custom queries using SQL.
```javascript
{
@@ -516,7 +520,7 @@ If you are creating a Torque layer in a Named Map without using the Torque.js li
})
.addTo(map)
.done(function(layer) {
});
}
```
@@ -535,7 +539,7 @@ Optionally, authenticated users can fetch projected tiles (XYZ tiles or Mapnik R
### Fetch XYZ Tiles Directly with a URL
Authenticated users, with an auth token, can use XYZ-based URLs to fetch tiles directly, and instantiate the Named Map as part of the request to your application. You do not have to do any other steps to initialize your map.
Authenticated users, with an auth token, can use XYZ-based URLs to fetch tiles directly, and instantiate the Named Map as part of the request to your application. You do not have to do any other steps to initialize your map.
To call a template_id in a URL:

View File

@@ -1,19 +1,50 @@
var camshaft = require('camshaft');
var fs = require('fs');
function AnalysisBackend(options) {
var batchConfig = options.batch || {};
function AnalysisBackend (options) {
options = options || {};
this.setBatchConfig(options.batch);
this.setLoggerConfig(options.logger);
}
module.exports = AnalysisBackend;
AnalysisBackend.prototype.setBatchConfig = function (options) {
var batchConfig = options || {};
batchConfig.endpoint = batchConfig.endpoint || 'http://127.0.0.1:8080/api/v1/sql/job';
batchConfig.inlineExecution = batchConfig.inlineExecution || false;
batchConfig.hostHeaderTemplate = batchConfig.hostHeaderTemplate || '{{=it.username}}.localhost.lan';
this.batchConfig = batchConfig;
}
};
module.exports = AnalysisBackend;
AnalysisBackend.prototype.setLoggerConfig = function (options) {
var loggerConfig = options || {};
loggerConfig.filename = loggerConfig.filename;
this.loggerConfig = loggerConfig;
if (this.loggerConfig.filename) {
this.stream = fs.createWriteStream(this.loggerConfig.filename, { flags: 'a', encoding: 'utf8' });
process.on('SIGHUP', function () {
if (this.stream) {
this.stream.destroy();
}
this.stream = fs.createWriteStream(this.loggerConfig.filename, { flags: 'a', encoding: 'utf8' });
}.bind(this));
}
};
AnalysisBackend.prototype.create = function(analysisConfiguration, analysisDefinition, callback) {
analysisConfiguration.batch.endpoint = this.batchConfig.endpoint;
analysisConfiguration.batch.inlineExecution = this.batchConfig.inlineExecution;
analysisConfiguration.batch.hostHeaderTemplate = this.batchConfig.hostHeaderTemplate;
analysisConfiguration.logger = {
stream: this.stream ? this.stream : process.stdout
};
camshaft.create(analysisConfiguration, analysisDefinition, callback);
};

View File

@@ -6,6 +6,9 @@ dot.templateSettings.strip = false;
function createTemplate(method) {
return dot.template([
'SELECT',
'min({{=it._column}}) min_val,',
'max({{=it._column}}) max_val,',
'avg({{=it._column}}) avg_val,',
method,
'FROM ({{=it._sql}}) _table_sql WHERE {{=it._column}} IS NOT NULL'
].join('\n'));
@@ -74,11 +77,14 @@ PostgresDatasource.prototype.getRamp = function (column, buckets, method, callba
return callback(err);
}
resultSet = resultSet || {};
var result = resultSet.rows || [];
var result = getResult(resultSet);
var strategy = method2strategy[methodName];
var ramp = result[0][methodName] || [];
var ramp = result[methodName] || [];
var stats = {
min_val: result.min_val,
max_val: result.max_val,
avg_val: result.avg_val
};
// Skip null values from ramp
// Generated turbo-carto won't be correct, but better to keep it working than failing
// TODO fix cartodb-postgres extension quantification functions
@@ -89,8 +95,16 @@ PostgresDatasource.prototype.getRamp = function (column, buckets, method, callba
});
}
return callback(null, { ramp: ramp, strategy: strategy });
return callback(null, { ramp: ramp, strategy: strategy, stats: stats });
}, true); // use read-only transaction
};
function getResult(resultSet) {
resultSet = resultSet || {};
var result = resultSet.rows || [];
result = result[0] || {};
return result;
}
module.exports = PostgresDatasource;

View File

@@ -171,6 +171,7 @@ MapController.prototype.create = function(req, res, prepareConfigFn) {
var analysesResults = context.analysesResults || [];
addDataviewsAndWidgetsUrls(req.context.user, layergroup, mapConfig.obj());
addAnalysesMetadata(req.context.user, layergroup, analysesResults, true);
addContextMetadata(layergroup, mapConfig.obj(), context);
res.set('X-Layergroup-Id', layergroup.layergroupid);
self.send(req, res, layergroup, 200);
}
@@ -178,6 +179,17 @@ MapController.prototype.create = function(req, res, prepareConfigFn) {
);
};
function addContextMetadata(layergroup, mapConfig, context) {
if (layergroup.metadata && Array.isArray(layergroup.metadata.layers) && Array.isArray(mapConfig.layers)) {
layergroup.metadata.layers = layergroup.metadata.layers.map(function(layer, layerIndex) {
if (context.turboCarto && Array.isArray(context.turboCarto.layers)) {
layer.meta.cartocss_meta = context.turboCarto.layers[layerIndex];
}
return layer;
});
}
}
MapController.prototype.instantiateTemplate = function(req, res, prepareParamsFn) {
var self = this;
@@ -229,8 +241,10 @@ MapController.prototype.instantiateTemplate = function(req, res, prepareParamsFn
var templateHash = self.templateMaps.fingerPrint(mapConfigProvider.template).substring(0, 8);
layergroup.layergroupid = cdbuser + '@' + templateHash + '@' + layergroup.layergroupid;
addDataviewsAndWidgetsUrls(cdbuser, layergroup, mapConfig.obj());
var _mapConfig = mapConfig.obj();
addDataviewsAndWidgetsUrls(cdbuser, layergroup, _mapConfig);
addAnalysesMetadata(cdbuser, layergroup, mapConfigProvider.analysesResults);
addContextMetadata(layergroup, _mapConfig, mapConfigProvider.context);
res.set('X-Layergroup-Id', layergroup.layergroupid);
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbuser, mapConfigProvider.getTemplateName()));

View File

@@ -137,9 +137,15 @@ NamedMapsController.prototype.staticMap = function(req, res) {
this
);
},
function prepareImageOptions(err, _namedMapProvider) {
function prepareLayerVisibility(err, _namedMapProvider) {
assert.ifError(err);
namedMapProvider = _namedMapProvider;
self.prepareLayerFilterFromPreviewLayers(cdbUser, req, namedMapProvider, this);
},
function prepareImageOptions(err) {
assert.ifError(err);
self.getStaticImageOptions(cdbUser, req.params, namedMapProvider, this);
},
function getImage(err, imageOpts) {
@@ -184,6 +190,45 @@ NamedMapsController.prototype.staticMap = function(req, res) {
);
};
NamedMapsController.prototype.prepareLayerFilterFromPreviewLayers = function (user, req, namedMapProvider, callback) {
var self = this;
namedMapProvider.getTemplate(function (err, template) {
if (err) {
return callback(err);
}
if (!template || !template.view || !template.view.preview_layers) {
return callback();
}
var previewLayers = template.view.preview_layers;
var layerVisibilityFilter = [];
template.layergroup.layers.forEach(function (layer, index) {
if (previewLayers[''+index] !== false && previewLayers[layer.id] !== false) {
layerVisibilityFilter.push(''+index);
}
});
if (!layerVisibilityFilter.length) {
return callback();
}
// overwrites 'all' default filter
req.params.layer = layerVisibilityFilter.join(',');
// recreates the provider
self.namedMapProviderCache.get(
user,
req.params.template_id,
req.query.config,
req.query.auth_token,
req.params,
callback
);
});
};
var DEFAULT_ZOOM_CENTER = {
zoom: 1,
center: {

View File

@@ -48,6 +48,11 @@ TurboCartoAdapter.prototype.getMapConfig = function (user, requestMapConfig, par
}
requestMapConfig.layers = results.map(function(result) { return result.layer; });
context.turboCarto = {
layers: results.map(function(result) {
return result.meta;
})
};
return callback(null, requestMapConfig);
});
@@ -84,7 +89,7 @@ TurboCartoAdapter.prototype._parseCartoCss = function (username, params, layer,
}
var pg = new PSQL(dbParamsFromReqParams(params));
function processCallback(err, cartocss) {
function processCallback(err, cartocss, meta) {
// Only return turbo-carto errors
if (err && err.name === 'TurboCartoError') {
var error = new Error(err.message);
@@ -105,7 +110,7 @@ TurboCartoAdapter.prototype._parseCartoCss = function (username, params, layer,
if (cartocss) {
layer.options.cartocss = cartocss;
}
return callback(null, { layer: layer });
return callback(null, { layer: layer, meta: meta });
}
var layerSql = layer.options.sql;

View File

@@ -120,6 +120,7 @@ NamedMapMapConfigProvider.prototype.getMapConfig = function(callback) {
self.mapConfig = (mapConfig === null) ? null : new MapConfig(mapConfig, context.datasource);
self.analysesResults = context.analysesResults || [];
self.rendererParams = rendererParams;
self.context = context;
self.context.limits = renderLimits || {};
return callback(self.err, self.mapConfig, self.rendererParams, self.context);
}

View File

@@ -147,6 +147,7 @@ module.exports = function(serverOptions) {
var tileBackend = new windshaft.backend.Tile(rendererCache);
var mapValidatorBackend = new windshaft.backend.MapValidator(tileBackend, attributesBackend);
var mapBackend = new windshaft.backend.Map(rendererCache, mapStore, mapValidatorBackend);
var analysisBackend = new AnalysisBackend(serverOptions.analysis);
var layergroupAffectedTablesCache = new LayergroupAffectedTablesCache();

View File

@@ -36,6 +36,9 @@ var analysisConfig = _.defaults(global.environment.analysis || {}, {
inlineExecution: false,
endpoint: 'http://127.0.0.1:8080/api/v2/sql/job',
hostHeaderTemplate: '{{=it.username}}.localhost.lan'
},
logger: {
filename: undefined
}
});
@@ -95,6 +98,9 @@ module.exports = {
inlineExecution: analysisConfig.batch.inlineExecution,
endpoint: analysisConfig.batch.endpoint,
hostHeaderTemplate: analysisConfig.batch.hostHeaderTemplate
},
logger: {
filename: analysisConfig.logger.filename
}
},
// Do not send unwatch on release. See http://github.com/CartoDB/Windshaft-cartodb/issues/161

795
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "windshaft-cartodb",
"version": "2.69.0",
"version": "2.78.0",
"description": "A map tile server for CartoDB",
"keywords": [
"cartodb"
@@ -20,7 +20,7 @@
],
"dependencies": {
"body-parser": "~1.14.0",
"camshaft": "0.39.0",
"camshaft": "0.44.1",
"cartodb-psql": "~0.6.1",
"cartodb-query-tables": "~0.1.0",
"cartodb-redis": "0.13.1",
@@ -37,9 +37,10 @@
"request": "~2.62.0",
"step": "~0.0.6",
"step-profiler": "~0.3.0",
"turbo-carto": "0.16.0",
"turbo-carto": "0.17.1",
"underscore": "~1.6.0",
"windshaft": "2.4.0"
"windshaft": "2.5.0",
"yargs": "~5.0.0"
},
"devDependencies": {
"istanbul": "~0.4.3",

View File

@@ -0,0 +1,210 @@
var step = require('step');
var test_helper = require('../support/test_helper');
var assert = require('../support/assert');
var CartodbWindshaft = require(__dirname + '/../../lib/cartodb/server');
var serverOptions = require(__dirname + '/../../lib/cartodb/server_options');
var server = new CartodbWindshaft(serverOptions);
var RedisPool = require('redis-mpool');
var TemplateMaps = require('../../lib/cartodb/backends/template_maps.js');
var mapnik = require('windshaft').mapnik;
var IMAGE_TOLERANCE = 20;
describe('layers visibility for previews', function() {
// configure redis pool instance to use in tests
var redisPool = new RedisPool(global.environment.redis);
var templateMaps = new TemplateMaps(redisPool, {
max_user_templates: global.environment.maxUserTemplates
});
var username = 'localhost';
function createLayer (color, layerId) {
var mod;
if (color === 'red') {
mod = 0;
} else if (color === 'orange') {
mod = 1;
} else if (color === 'blue') {
mod = 2;
} else {
mod = 0;
}
return {
type: 'mapnik',
id: layerId,
options: {
sql: 'select * from populated_places_simple_reduced where cartodb_id % 3 = ' + mod,
cartocss: '#layer { marker-fill: ' + color + '; }',
cartocss_version: '2.3.0'
}
};
}
function createTemplate(scenario) {
return {
version: '0.0.1',
name: scenario.name,
auth: {
method: 'open'
},
view: {
bounds: {
west: 0,
south: 0,
east: 45,
north: 45
},
zoom: 4,
center: {
lng: 40,
lat: 20
},
preview_layers: scenario.layerPerview
},
layergroup: {
layers: scenario.layers
}
};
}
afterEach(function (done) {
test_helper.deleteRedisKeys({
'user:localhost:mapviews:global': 5
}, done);
});
function previewFixture(version) {
return './test/fixtures/previews/populated_places_simple_reduced-' + version + '.png';
}
var threeLayerPointDistintColor = [
createLayer('red'),
createLayer('orange'),
createLayer('blue', 'layer2')
];
var scenarios = [{
name: 'preview_layers_red',
layerPerview: {
'0': true,
'1': false,
'layer2': false
},
layers: threeLayerPointDistintColor
}, {
name: 'preview_layers_orange',
layerPerview: {
'0': false,
'1': true,
'layer2': false
},
layers: threeLayerPointDistintColor
}, {
name: 'preview_layers_blue',
layerPerview: {
'0': false,
'1': false,
'layer2': true
},
layers: threeLayerPointDistintColor
}, {
name: 'preview_layers_red_orange',
layerPerview: {
'0': true,
'1': true,
'layer2': false
},
layers: threeLayerPointDistintColor
}, {
name: 'preview_layers_red_blue',
layerPerview: {
'0': true,
'1': false,
'layer2': true
},
layers: threeLayerPointDistintColor
}, {
name: 'preview_layers_orange_blue',
layerPerview: {
'0': false,
'1': true,
'layer2': true
},
layers: threeLayerPointDistintColor
}, {
name: 'preview_layers_red_orange_blue',
layerPerview: {
'0': true,
'1': true,
'layer2': true
},
layers: threeLayerPointDistintColor
}, {
name: 'preview_layers_all',
layerPerview: {},
layers: threeLayerPointDistintColor
}, {
name: 'preview_layers_undefined',
layerPerview: undefined,
layers: threeLayerPointDistintColor
}];
scenarios.forEach(function (scenario) {
it('should filter layers for template: ' + scenario.name, function (done) {
step(
function addTemplate () {
var next = this;
var template = createTemplate(scenario);
templateMaps.addTemplate(username, template, next);
},
function requestPreview (err) {
assert.ifError(err);
var next = this;
assert.response(server, {
url: '/api/v1/map/static/named/' + scenario.name + '/640/480.png',
method: 'GET',
headers: {
host: 'localhost'
},
encoding: 'binary'
}, {
status: 200,
headers: {
'content-type': 'image/png'
}
}, function (res, err) {
next(err, res);
});
},
function checkPreview (err, res) {
assert.ifError(err);
var next = this;
var img = mapnik.Image.fromBytes(new Buffer(res.body, 'binary'));
var previewFixturePath = previewFixture(scenario.name);
assert.imageIsSimilarToFile(img, previewFixturePath, IMAGE_TOLERANCE, next);
},
function deleteTemplate(err) {
assert.ifError(err);
var next = this;
templateMaps.delTemplate(username, scenario.name, next);
},
function finish (err) {
done(err);
}
);
});
});
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -26,5 +26,7 @@ CREATE TABLE IF NOT EXISTS
-- last job modifying the node
last_modified_by uuid,
-- store error message for failures
last_error_message text
last_error_message text,
-- cached tables involved in the analysis
cache_tables regclass[] NOT NULL DEFAULT '{}'
);