Last commit of week 2
This commit is contained in:
parent
2289827a9d
commit
2ba01713ef
7 changed files with 167 additions and 2462 deletions
|
@ -1,17 +1,3 @@
|
|||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"node": "current"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"env": {
|
||||
"test": {
|
||||
"plugins": ["@babel/plugin-transform-modules-commonjs"]
|
||||
}
|
||||
}
|
||||
"presets": ["@babel/preset-env"]
|
||||
}
|
||||
|
|
|
@ -3,15 +3,13 @@
|
|||
* Constructor
|
||||
* @param name {string} Name of RuleSet
|
||||
* @param defaultValue {number} Default score value
|
||||
* @param unit {string} Meta field with some info // !TODO: Decide if I'm going to keep this or remove it from the class
|
||||
* @param values {object} Main data object
|
||||
*/
|
||||
class RuleSet {
|
||||
constructor(name, defaultValue = 1, unit, values) {
|
||||
constructor(name, defaultValue = 1, values) {
|
||||
this.name = name;
|
||||
this.defaultValue = defaultValue;
|
||||
this.values = values;
|
||||
this.unit = unit;
|
||||
this.score = this.defaultValue;
|
||||
this.scoreValues = null;
|
||||
this.order = null;
|
||||
|
@ -20,25 +18,30 @@ class RuleSet {
|
|||
* toString
|
||||
* Returns constructor values in string for display in the console
|
||||
*/
|
||||
toString() {
|
||||
return `${this.name} | ${this.unit} | ${this.defaultValue} | ${this.values}`;
|
||||
toString () {
|
||||
return `${this.name} | ${this.defaultValue} | ${this.values}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* getScore calculates a score for the RuleSet
|
||||
* @param tags {object} Active tags to compare against
|
||||
*/
|
||||
getScore(tags) {
|
||||
const [[program,keys], values] = Object.entries(this.values);
|
||||
|
||||
runProgram (tags, initValues = this.values) {
|
||||
const [
|
||||
[program, keys], values
|
||||
] = Object.entries(initValues);
|
||||
|
||||
if (program === '$multiply') {
|
||||
this.scoreValues = keys;
|
||||
this.score *= this.multiplyScore(tags);
|
||||
console.log(`${this.name}: ${this.score}`)
|
||||
this.score = this.multiplyScore(tags);
|
||||
return `"${this.name.slice(8)}":"${this.score}"`;
|
||||
|
||||
} else if (program === '$firstMatchOf') {
|
||||
this.scoreValues = values;
|
||||
this.order = keys;
|
||||
this.getFirstMatchScore(tags);
|
||||
const match = this.getFirstMatchScore(tags);
|
||||
return `"${this.name.slice(8)}":"${match}"`;
|
||||
|
||||
} else {
|
||||
console.error(`Error: Program ${program} is not implemented yet. ${JSON.stringify(keys)}`);
|
||||
}
|
||||
|
@ -48,43 +51,68 @@ class RuleSet {
|
|||
* @param tags {object} the active tags to check against
|
||||
* @returns score after multiplication
|
||||
*/
|
||||
multiplyScore(tags) {
|
||||
multiplyScore (tags) {
|
||||
let number = this.defaultValue;
|
||||
|
||||
Object.entries(tags).forEach(tag => {
|
||||
const [key, value] = tag;
|
||||
|
||||
Object.entries(this.scoreValues).forEach(property => {
|
||||
const [propKey, propValues] = property;
|
||||
// console.log(propKey, key)
|
||||
|
||||
if (key === propKey) {
|
||||
for (let propEntry of Object.entries(propValues)) {
|
||||
const [propValueKey, propValue] = propEntry;
|
||||
if (value === propValueKey) number = propValue;
|
||||
|
||||
if (value === propValueKey) number *= propValue;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
return number;
|
||||
return number.toFixed(2);
|
||||
}
|
||||
getFirstMatchScore(tags) {
|
||||
const [[tagKey, tagValue]] = Object.entries(tags);
|
||||
for (let item of this.order) {
|
||||
if (item === tagKey) {
|
||||
const options = Object.entries(this.scoreValues[1]);
|
||||
// console.log(tagKey)
|
||||
for (let optGroup of options) {
|
||||
if (tagKey === optGroup[0]) {
|
||||
for (let prop of Object.entries(optGroup[1])) {
|
||||
const [propKey, propValue] = prop;
|
||||
if (tagValue === propKey) {
|
||||
console.log(`${this.name}: ${propValue}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
getFirstMatchScore (tags) {
|
||||
let matchFound = false;
|
||||
let match = "";
|
||||
|
||||
for (let key of this.order) {
|
||||
for (let entry of Object.entries(tags)) {
|
||||
const [tagKey, tagValue] = entry;
|
||||
|
||||
if (key === tagKey) {
|
||||
const valueReply = this.checkValues(entry);
|
||||
|
||||
if (!!valueReply) {
|
||||
match = valueReply;
|
||||
matchFound = true;
|
||||
return match;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!matchFound) {
|
||||
match = this.defaultValue;
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
checkValues (tag) {
|
||||
const [tagKey, tagValue] = tag;
|
||||
const options = Object.entries(this.scoreValues[1])
|
||||
|
||||
for (let option of options) {
|
||||
const [optKey, optValues] = option;
|
||||
|
||||
if (optKey === tagKey) {
|
||||
return optValues[`${tagValue}`];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default RuleSet;
|
|
@ -1 +1,68 @@
|
|||
const RuleSet = require('../RuleSet.mjs');
|
||||
import { expect, jest } from '@jest/globals';
|
||||
import RuleSet from '../RuleSet.js';
|
||||
|
||||
describe('RuleSet', () => {
|
||||
const exampleJSON = {
|
||||
"name": "real.name",
|
||||
"$default": "1",
|
||||
"value": {
|
||||
"$multiply": {
|
||||
"example": {
|
||||
"score": "1.2"
|
||||
},
|
||||
"other": {
|
||||
"thing": "1",
|
||||
"something": "1.2",
|
||||
"other_thing": "1.4"
|
||||
}
|
||||
},
|
||||
"$firstMatchOf": [
|
||||
"area",
|
||||
"empty",
|
||||
"things"
|
||||
],
|
||||
"value": {
|
||||
"area": {
|
||||
"yes": "no"
|
||||
},
|
||||
"access:": {
|
||||
"no": "no",
|
||||
"customers": "private"
|
||||
},
|
||||
"$multiply": {
|
||||
"access": {
|
||||
"dismount": 0.15
|
||||
},
|
||||
"highway": {
|
||||
"path": 0.5
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
const tags = {
|
||||
"example": "score",
|
||||
"other": "something",
|
||||
"highway": "track",
|
||||
"surface": "sett",
|
||||
"cycleway": "lane"
|
||||
}
|
||||
test('it should resolve', () => {
|
||||
const ruleSet = exampleJSON;
|
||||
const { name, $default, $multiply, value} = ruleSet;
|
||||
|
||||
if (!!value) {
|
||||
const currentSet = new RuleSet(name, $default, value);
|
||||
currentSet.runProgram(tags);
|
||||
expect(currentSet.runProgram).resolves;
|
||||
expect(currentSet.toString).resolves;
|
||||
} else {
|
||||
const currentSet = new RuleSet(name, $default, {$multiply});
|
||||
currentSet.toString();
|
||||
currentSet.runProgram(tags);
|
||||
}
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
import interpret from "./interpret.mjs";
|
||||
import RuleSet from "./RuleSet.mjs";
|
||||
import interpret from './interpret.js';
|
||||
import RuleSet from './RuleSet.js';
|
||||
|
||||
export { interpret, RuleSet };
|
||||
const printMsg = () => {
|
||||
console.log("BE-StressMap has been installed successfully!")
|
||||
}
|
||||
|
||||
export {
|
||||
interpret,
|
||||
RuleSet,
|
||||
printMsg,
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Import packages
|
||||
*/
|
||||
import fs from 'fs';
|
||||
import RuleSet from './RuleSet.mjs';
|
||||
import RuleSet from './RuleSet.js';
|
||||
|
||||
|
||||
/**
|
||||
|
@ -22,9 +22,9 @@ const tags2 = {
|
|||
|
||||
const tags3 = {
|
||||
"cyclestreet": "yes",
|
||||
"highway":"residential",
|
||||
"maxspeed":"30",
|
||||
"surface":"asphalt"
|
||||
"highway": "residential",
|
||||
"maxspeed": "30",
|
||||
"surface": "asphalt"
|
||||
}
|
||||
|
||||
const tags4 = {
|
||||
|
@ -33,6 +33,12 @@ const tags4 = {
|
|||
"incline": "10%"
|
||||
}
|
||||
|
||||
const tags5 = {
|
||||
"access": "no",
|
||||
"bicycle": "official",
|
||||
"area": "yes"
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret JsonFile w/ Tags
|
||||
* @param definitionFile {any} JSON input defining the score distribution
|
||||
|
@ -42,18 +48,18 @@ const interpret = (definitionFile, tags) => {
|
|||
const rawData = fs.readFileSync(definitionFile);
|
||||
const ruleSet = JSON.parse(rawData);
|
||||
|
||||
const { name, unit, $default, $multiply, value} = ruleSet;
|
||||
const { name, $default, $multiply, value} = ruleSet;
|
||||
|
||||
if (!!value) {
|
||||
const currentSet = new RuleSet(name, $default, unit, value);
|
||||
currentSet.getScore(tags);
|
||||
const currentSet = new RuleSet(name, $default, value);
|
||||
console.log(currentSet.runProgram(tags));
|
||||
} else {
|
||||
const currentSet = new RuleSet(name, $default, unit, {$multiply});
|
||||
currentSet.toString();
|
||||
currentSet.getScore(tags);
|
||||
const currentSet = new RuleSet(name, $default, {$multiply});
|
||||
// currentSet.toString();
|
||||
console.log(currentSet.runProgram(tags));
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
console.info('Comfort')
|
||||
interpret("../Examples/bicycle/aspects/bicycle.comfort.json", tags1);
|
||||
interpret("../Examples/bicycle/aspects/bicycle.comfort.json", tags2);
|
||||
|
@ -66,23 +72,24 @@ interpret("../Examples/bicycle/aspects/bicycle.safety.json", tags1);
|
|||
interpret("../Examples/bicycle/aspects/bicycle.safety.json", tags2);
|
||||
interpret("../Examples/bicycle/aspects/bicycle.safety.json", tags3);
|
||||
interpret("../Examples/bicycle/aspects/bicycle.safety.json", tags4);
|
||||
console.log('*******************')
|
||||
console.log('*******************') */
|
||||
|
||||
console.info('Legal Access')
|
||||
interpret("../Examples/bicycle/aspects/bicycle.legal_access.json", tags1);
|
||||
interpret("../Examples/bicycle/aspects/bicycle.legal_access.json", tags2);
|
||||
interpret("../Examples/bicycle/aspects/bicycle.legal_access.json", tags3);
|
||||
interpret("../Examples/bicycle/aspects/bicycle.legal_access.json", tags4);
|
||||
interpret("../Examples/bicycle/aspects/bicycle.legal_access.json", tags5);
|
||||
|
||||
// !TODO: Add default value = "no" as a fallback. Fix logic
|
||||
|
||||
console.log('*******************')
|
||||
|
||||
console.info('Speed Factor')
|
||||
/* console.info('Speed Factor')
|
||||
interpret("./.routeExamples/bicycle.speed_factor.json", tags1);
|
||||
interpret("./.routeExamples/bicycle.speed_factor.json", tags2);
|
||||
interpret("./.routeExamples/bicycle.speed_factor.json", tags3);
|
||||
interpret("./.routeExamples/bicycle.speed_factor.json", tags4);
|
||||
console.log('*******************')
|
||||
console.log('*******************') */
|
||||
|
||||
export default interpret;
|
||||
export default interpret;
|
2382
javascript/package-lock.json
generated
2382
javascript/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -3,33 +3,24 @@
|
|||
"version": "1.0.0",
|
||||
"description": "Calculate bicycle route stress score to display on MapComplete/OSM.",
|
||||
"main": "index.js",
|
||||
"jest": {
|
||||
"transform": {
|
||||
"\\.[jt]sx?$": "babel-jest"
|
||||
}
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"babel": "./node_modules/.bin/babel src -d dist",
|
||||
"test": "jest"
|
||||
},
|
||||
"jest": {
|
||||
"transform": {
|
||||
"^.+\\.jsx?$": "babel-jest"
|
||||
}
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Pieter Vander Vennet, Charlotte Delvaux",
|
||||
"author": "Charlotte Delvaux",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.6",
|
||||
"@babel/node": "^7.14.7",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.14.5",
|
||||
"@babel/preset-env": "^7.14.7",
|
||||
"@babel/preset-typescript": "^7.14.5",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/node": "^16.3.1",
|
||||
"babel-jest": "^27.0.6",
|
||||
"babel-plugin-add-module-exports": "^1.0.4",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"jest": "^27.0.6",
|
||||
"ts-node": "^10.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.26.0"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue