170 lines
5.4 KiB
JavaScript
Executable File
170 lines
5.4 KiB
JavaScript
Executable File
var _ = require('underscore');
|
|
var camshaftReference = require('camshaft-reference').getVersion('latest');
|
|
var DefaultCartography = require('./default-cartography.json');
|
|
|
|
var SOURCE_NAMES_MAP = {}; // string -> array, e.g. {'intersection': ['source', 'target']}
|
|
var DEFAULT_MISSING_PARAM_VALUES = [undefined, null, '', NaN];
|
|
|
|
module.exports = {
|
|
hasType: function (type) {
|
|
return !!camshaftReference.analyses[type];
|
|
},
|
|
|
|
paramsForType: function (type) {
|
|
if (!this.hasType(type)) throw new Error('no analysis params found for type: ' + type);
|
|
|
|
return _.clone(camshaftReference.analyses[type].params);
|
|
},
|
|
|
|
/**
|
|
* Validate raw form attrs
|
|
* @param {Object} formAttrs - e.g. {type: 'buffer', source: 'a0', radius: 'meh'}
|
|
* @return {Object, undefined} returns an object with keys as faulty input, e.g. {radius: 'invalid-value'} for above
|
|
*/
|
|
validate: function (formAttrs) {
|
|
var errors = {};
|
|
|
|
var parsedAttrs = this.parse(formAttrs);
|
|
var params = this.paramsForType(formAttrs.type);
|
|
|
|
for (var name in params) {
|
|
var param = params[name];
|
|
var val = parsedAttrs[name];
|
|
|
|
if (!param.optional || val !== undefined) {
|
|
switch (param.type) {
|
|
case 'node':
|
|
if (!val) {
|
|
errors[name] = _t('data.analysis-definition-node-model.validation.invalid-source');
|
|
}
|
|
break;
|
|
case 'number':
|
|
if (isNaN(val)) {
|
|
errors[name] = _t('data.analysis-definition-node-model.validation.invalid-value');
|
|
}
|
|
break;
|
|
case 'enum':
|
|
if (!_.contains(param.values, val)) {
|
|
errors[name] = _t('data.analysis-definition-node-model.validation.invalid-enum', {expectedValues: JSON.stringify(param.values)});
|
|
}
|
|
break;
|
|
default:
|
|
if (val === null) {
|
|
errors[name] = _t('data.analysis-definition-node-model.validation.missing-required');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!_.isEmpty(errors)) {
|
|
return errors;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get type-parsed attrs from the raw form attrs
|
|
* @param {Object} formAttrs - e.g. {type: 'buffer', source: 'a0 ', radius: '123', dissolved: 'false'}
|
|
* @return {Object} e.g. {type: 'buffer', source: 'a0', radius: 123, dissolved: false}
|
|
*/
|
|
parse: function (formAttrs) {
|
|
var parsedAttrs = _.extend({}, formAttrs);
|
|
var params = this.paramsForType(formAttrs.type);
|
|
|
|
for (var name in params) {
|
|
var param = params[name];
|
|
var val = parsedAttrs[name];
|
|
|
|
if (param.optional && _.contains(DEFAULT_MISSING_PARAM_VALUES, val)) {
|
|
delete parsedAttrs[name];
|
|
} else {
|
|
switch (param.type) {
|
|
case 'node':
|
|
parsedAttrs[name] = (val || '').trim();
|
|
break;
|
|
case 'number':
|
|
parsedAttrs[name] = parseFloat(val, 10);
|
|
break;
|
|
case 'boolean':
|
|
parsedAttrs[name] = val === 'true' || val === true;
|
|
break;
|
|
default:
|
|
if (_.contains(DEFAULT_MISSING_PARAM_VALUES, val)) {
|
|
parsedAttrs[name] = null;
|
|
} else if (_.isString(val)) {
|
|
parsedAttrs[name] = val.trim();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return parsedAttrs;
|
|
},
|
|
|
|
getSourceNamesForAnalysisType: function (type) {
|
|
if (!SOURCE_NAMES_MAP[type]) {
|
|
var sourceNames = [];
|
|
var params = this.paramsForType(type);
|
|
|
|
for (var name in params) {
|
|
var param = params[name];
|
|
if (param.type === 'node') {
|
|
sourceNames.push(name);
|
|
}
|
|
}
|
|
|
|
SOURCE_NAMES_MAP[type] = sourceNames;
|
|
}
|
|
|
|
return SOURCE_NAMES_MAP[type];
|
|
},
|
|
|
|
getDefaultCartoCSSForType: function () {
|
|
return _.template([
|
|
"#layer['mapnik::geometry_type'=1] {",
|
|
' marker-width: <%= point.fill.size.fixed %>;',
|
|
' marker-fill: <%= point.fill.color.fixed %>;',
|
|
' marker-fill-opacity: <%= point.fill.color.opacity %>;',
|
|
' marker-line-color: <%= point.stroke.color.fixed %>;',
|
|
' marker-line-width: <%= point.stroke.size.fixed %>;',
|
|
' marker-line-opacity: <%= point.stroke.color.opacity %>;',
|
|
' marker-type: ellipse;',
|
|
' marker-allow-overlap: true;',
|
|
'}',
|
|
"#layer['mapnik::geometry_type'=2] {",
|
|
' line-color: <%= line.stroke.color.fixed %>;',
|
|
' line-width: <%= line.stroke.size.fixed %>;',
|
|
' line-opacity: 1;',
|
|
'}',
|
|
"#layer['mapnik::geometry_type'=3] {",
|
|
' polygon-fill: <%= polygon.fill.color.fixed %>;',
|
|
' polygon-opacity: <%= polygon.fill.color.opacity %>;',
|
|
' ::outline {',
|
|
' line-color: <%= polygon.stroke.color.fixed%>;',
|
|
' line-width: <%= polygon.stroke.size.fixed %>;',
|
|
' line-opacity: <%= polygon.stroke.color.opacity %>;',
|
|
' }',
|
|
'}'
|
|
].join('\n'))(DefaultCartography.simple);
|
|
},
|
|
|
|
isValidInputGeometryForType: function (simpleGeometryType, analysisType) {
|
|
var validGeometries = this.getValidInputGeometriesForType(analysisType);
|
|
return _.contains(validGeometries, simpleGeometryType) || _.contains(validGeometries, '*');
|
|
},
|
|
|
|
getValidInputGeometriesForType: function (analysisType) {
|
|
var params = this.paramsForType(analysisType);
|
|
|
|
var geometries = [];
|
|
|
|
for (var name in params) {
|
|
var param = params[name];
|
|
if (param.type === 'node') {
|
|
geometries = _.union(geometries, param.geometry);
|
|
}
|
|
}
|
|
|
|
return geometries;
|
|
}
|
|
};
|