forked from MapComplete/MapComplete
More improvements to the charging station theme
This commit is contained in:
parent
bd37cc812f
commit
3492b5d403
4 changed files with 1611 additions and 98 deletions
File diff suppressed because it is too large
Load diff
|
@ -129,10 +129,12 @@
|
|||
{
|
||||
"#": "capacity",
|
||||
"render": {
|
||||
"en": "{capacity} vehicles can be charged here at the same time"
|
||||
"en": "{capacity} vehicles can be charged here at the same time",
|
||||
"nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden"
|
||||
},
|
||||
"question": {
|
||||
"en": "How much vehicles can be charged here at the same time?"
|
||||
"en": "How much vehicles can be charged here at the same time?",
|
||||
"nl": "Hoeveel voertuigen kunnen hier opgeladen worden?"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "capacity",
|
||||
|
@ -277,6 +279,58 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"#": "fee/charge",
|
||||
"question": {
|
||||
"en": "How much does one have to pay to use this charging station?",
|
||||
"nl": "Hoeveel kost het gebruik van dit oplaadpunt?"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "charge",
|
||||
"addExtraTags": [
|
||||
"fee=yes"
|
||||
]
|
||||
},
|
||||
"render": {
|
||||
"en": "Using this charging station costs <b>{charge}</b>",
|
||||
"nl": "Dit oplaadpunt gebruiken kost <b>{charge}</b>"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": {
|
||||
"and": [
|
||||
"fee=no",
|
||||
"charge="
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"nl": "Gratis te gebruiken",
|
||||
"en": "Free to use"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"builtin": "payment-options",
|
||||
"override": {
|
||||
"condition": {
|
||||
"or": [
|
||||
"fee=yes",
|
||||
"charge~*"
|
||||
]
|
||||
},
|
||||
"mappings+": [
|
||||
{
|
||||
"if": "payment:app=yes",
|
||||
"ifnot": "payment:app=no",
|
||||
"then": {
|
||||
"en": "Payment is done using a dedicated app",
|
||||
"nl": "Betalen via een app van het netwerk"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"#": "Network",
|
||||
"render": {
|
||||
|
@ -518,6 +572,9 @@
|
|||
],
|
||||
"title": {
|
||||
"en": "Charging station"
|
||||
},
|
||||
"preciseInput": {
|
||||
"preferredBackground": "map"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -1,34 +1,80 @@
|
|||
import {readFileSync, writeFileSync} from "fs";
|
||||
import {Utils} from "../../../Utils";
|
||||
import {TagRenderingConfigJson} from "../../../Models/ThemeConfig/Json/TagRenderingConfigJson";
|
||||
import ScriptUtils from "../../../scripts/ScriptUtils";
|
||||
|
||||
|
||||
function colonSplit(value: string): string[] {
|
||||
return value.split(";").map(v => v.replace(/"/g, '').trim().toLowerCase()).filter(s => s !== "");
|
||||
}
|
||||
|
||||
function loadCsv(file): {
|
||||
key: string,
|
||||
image: string,
|
||||
description: Map<string, string>,
|
||||
countryWhiteList?: string[],
|
||||
commonVoltages?: number[],
|
||||
commonCurrents?: number[],
|
||||
commonOutputs?: string[]
|
||||
}[] {
|
||||
const entries: string[] = Utils.NoNull(readFileSync(file, "utf8").split("\n").map(str => str.trim()))
|
||||
const header = entries.shift().split(",")
|
||||
|
||||
return Utils.NoNull(entries.map(entry => {
|
||||
const values = entry.split(",").map(str => str.trim())
|
||||
if (values[0] === undefined || values[0] === "") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const v = {}
|
||||
const colonSeperated = ["commonVoltages", "commonOutputs", "commonCurrents", "countryWhiteList"]
|
||||
const descriptionTranslations = new Map<string, string>()
|
||||
for (let j = 0; j < header.length; j++) {
|
||||
const key = header[j];
|
||||
if (key.startsWith("description")) {
|
||||
const language = key.substring("description:".length)
|
||||
descriptionTranslations.set(language, values[j])
|
||||
}
|
||||
|
||||
if (colonSeperated.indexOf(key) >= 0) {
|
||||
v[key] = colonSplit(values[j])
|
||||
} else {
|
||||
v[key] = values[j]
|
||||
}
|
||||
}
|
||||
v["description"] = descriptionTranslations
|
||||
return <any>v;
|
||||
}))
|
||||
}
|
||||
|
||||
// SMall script to output the properties of the types.csv as json to add in the tagRenderingGroup. Should be copied manually
|
||||
function run(file, protojson) {
|
||||
const entries: string[] = Utils.NoNull(readFileSync(file, "utf8").split("\n").map(str => str.trim()))
|
||||
entries.shift()
|
||||
|
||||
const overview_question_answers = []
|
||||
const questions = []
|
||||
const filterOptions: { question: string, osmTags?: string } [] = [
|
||||
const questions: TagRenderingConfigJson[] = []
|
||||
const filterOptions: { question: any, osmTags?: string } [] = [
|
||||
{
|
||||
question: "All connectors"
|
||||
question: {
|
||||
en: "All connectors",
|
||||
nl: "Alle types"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
for (const entry of entries) {
|
||||
const [key, image, description, whitelist] = entry.split(",").map(str => str.trim())
|
||||
if (key === "") {
|
||||
continue;
|
||||
const entries = loadCsv(file)
|
||||
for (const e of entries) {
|
||||
const txt = {
|
||||
en: `<img style='width:3rem; margin-left: 1rem; margin-right: 1rem' src='./assets/layers/charging_station/${e.image}'/> ${e.description.get("en")}`,
|
||||
nl: `<img style='width:3rem; margin-left: 1rem; margin-right: 1rem' src='./assets/layers/charging_station/${e.image}'/> ${e.description.get("nl")}`
|
||||
}
|
||||
|
||||
const txt = `<img style='width:3rem; margin-left: 1rem; margin-right: 1rem' src='./assets/layers/charging_station/${image}'/> ${description}`
|
||||
const json = {
|
||||
if: `${key}=1`,
|
||||
ifnot: `${key}=`,
|
||||
if: `${e.key}=1`,
|
||||
ifnot: `${e.key}=`,
|
||||
then: txt,
|
||||
}
|
||||
|
||||
if (whitelist) {
|
||||
const countries = whitelist.replace(/"/g, '').split(",").map(country => "_country!=" + country) //HideInAnswer if it is in the wrong country
|
||||
if (e.countryWhiteList !== undefined && e.countryWhiteList.length > 0) {
|
||||
const countries = e.countryWhiteList.map(country => "_country!=" + country) //HideInAnswer if it is in the wrong country
|
||||
json["hideInAnswer"] = {or: countries}
|
||||
}
|
||||
|
||||
|
@ -37,32 +83,123 @@ function run(file, protojson) {
|
|||
// We add a second time for any amount to trigger a visualisation; but this is not an answer option
|
||||
const no_ask_json = {
|
||||
if: {
|
||||
and: [`${key}~*`, `${key}!=1`]
|
||||
and: [`${e.key}~*`, `${e.key}!=1`]
|
||||
},
|
||||
then: txt,
|
||||
hideInAnswer: true
|
||||
}
|
||||
overview_question_answers.push(no_ask_json)
|
||||
|
||||
const indivQ = {
|
||||
const descrWithImage_en = `<b>${e.description.get("en")}</b> <img style='width:1rem;' src='./assets/layers/charging_station/${e.image}'/>`
|
||||
const descrWithImage_nl = `<b>${e.description.get("nl")}</b> <img style='width:1rem;' src='./assets/layers/charging_station/${e.image}'/>`
|
||||
|
||||
questions.push({
|
||||
question: {
|
||||
en: `How much plugs of type ${description} <img style='width:1rem; margin-left: 1rem; margin-right: 1rem' src='./assets/layers/charging_station/${image}'/> are available here?`
|
||||
en: `How much plugs of type ${descrWithImage_en} are available here?`,
|
||||
nl: `Hoeveel stekkers van type ${descrWithImage_nl} heeft dit oplaadpunt?`,
|
||||
},
|
||||
render: {
|
||||
en: `There are ${descrWithImage_en} plugs of type ${e.description.get("en")} available here`,
|
||||
nl: `Hier zijn ${descrWithImage_nl} stekkers van het type ${e.description.get("nl")}`
|
||||
},
|
||||
render: `There are <b>{${key}}</b> <img style='width:1rem' src='./assets/layers/charging_station/${image}'/> plugs of type ${description} available here`,
|
||||
freeform: {
|
||||
key: key,
|
||||
key: e.key,
|
||||
type: "pnat"
|
||||
},
|
||||
condition: `${key}~*`
|
||||
condition: {
|
||||
and: [`${e.key}~*`, `${e.key}!=0`]
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
questions.push({
|
||||
question: {
|
||||
en: `What voltage do the plugs with ${descrWithImage_en} offer?`,
|
||||
nl: `Welke spanning levert de stekker van type ${descrWithImage_nl}`
|
||||
},
|
||||
render: {
|
||||
en: `${descrWithImage_en} outputs {${e.key}:voltage} volt`,
|
||||
nl: `${descrWithImage_nl} heeft een spanning van {${e.key}:voltage} volt`
|
||||
},
|
||||
freeform: {
|
||||
key: `${e.key}:voltage`,
|
||||
type: "pfloat"
|
||||
},
|
||||
mappings: e.commonVoltages.map(voltage => {
|
||||
return {
|
||||
if: `socket:${e.key}:voltage=${voltage} V`,
|
||||
then: {
|
||||
en: `${descrWithImage_en} outputs ${voltage} volt`,
|
||||
nl: `${descrWithImage_nl} heeft een spanning van ${voltage} volt`
|
||||
}
|
||||
}
|
||||
}),
|
||||
condition: {
|
||||
and: [`${e.key}~*`, `${e.key}!=0`]
|
||||
}
|
||||
})
|
||||
|
||||
questions.push(indivQ)
|
||||
|
||||
questions.push({
|
||||
question: {
|
||||
en: `What current do the plugs with ${descrWithImage_en} offer?`,
|
||||
nl: `Welke stroom levert de stekker van type ${descrWithImage_nl}?`,
|
||||
},
|
||||
render: {
|
||||
en: `${descrWithImage_en} outputs at most {${e.key}:current}A`,
|
||||
nl: `${descrWithImage_nl} levert een stroom van maximaal {${e.key}:current}A`
|
||||
},
|
||||
freeform: {
|
||||
key: `${e.key}:current`,
|
||||
type: "pfloat"
|
||||
},
|
||||
mappings: e.commonCurrents.map(current => {
|
||||
return {
|
||||
if: `socket:${e.key}:current=${current} A`,
|
||||
then: {
|
||||
en: `${descrWithImage_en} outputs at most ${current} A`,
|
||||
nl: `${descrWithImage_nl} levert een stroom van maximaal ${current} A`
|
||||
}
|
||||
}
|
||||
}),
|
||||
condition: {
|
||||
and: [`${e.key}~*`, `${e.key}!=0`]
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
questions.push({
|
||||
question: {
|
||||
en: `What power output does a single plug of type ${descrWithImage_en} offer?`,
|
||||
nl: `Welk vermogen levert een enkele stekker van type ${descrWithImage_nl}?`,
|
||||
},
|
||||
render: {
|
||||
en: `${descrWithImage_en} outputs at most {${e.key}:output}`,
|
||||
nl: `${descrWithImage_nl} levert een vermogen van maximaal {${e.key}:output}`
|
||||
},
|
||||
freeform: {
|
||||
key: `${e.key}:output`,
|
||||
type: "pfloat"
|
||||
},
|
||||
mappings: e.commonOutputs.map(output => {
|
||||
return {
|
||||
if: `socket:${e.key}:output=${output}`,
|
||||
then: {
|
||||
en: `${descrWithImage_en} outputs at most ${output}`,
|
||||
nl: `${descrWithImage_nl} levert een vermogen van maximaal ${output}`
|
||||
}
|
||||
}
|
||||
}),
|
||||
condition: {
|
||||
and: [`${e.key}~*`, `${e.key}!=0`]
|
||||
}
|
||||
})
|
||||
|
||||
filterOptions.push({
|
||||
question: `Has a ${description} <img style='width:1rem' src='./assets/layers/charging_station/${image}'/> connector`,
|
||||
osmTags: `${key}~*`
|
||||
question: {
|
||||
en: `Has a ${descrWithImage_en} connector`,
|
||||
nl: `Heeft een ${descrWithImage_nl}`
|
||||
},
|
||||
osmTags: `${e.key}~*`
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -82,11 +219,99 @@ function run(file, protojson) {
|
|||
proto["filter"].push({
|
||||
options: filterOptions
|
||||
})
|
||||
|
||||
proto["units"] = [
|
||||
{
|
||||
appliesToKey: entries.map(e => e.key + ":voltage"),
|
||||
applicableUnits: [{
|
||||
canonicalDenomination: 'V',
|
||||
alternativeDenomination: ["v", "volt", "voltage",'V','Volt'],
|
||||
human: {
|
||||
en: "Volts",
|
||||
nl: "volt"
|
||||
}
|
||||
}],
|
||||
eraseInvalidValues: true
|
||||
},
|
||||
{
|
||||
appliesToKey: entries.map(e => e.key + ":current"),
|
||||
applicableUnits: [{
|
||||
canonicalDenomination: 'A',
|
||||
alternativeDenomination: ["a", "amp", "amperage",'A'],
|
||||
human: {
|
||||
en: "A",
|
||||
nl: "A"
|
||||
}
|
||||
}],
|
||||
eraseInvalidValues: true
|
||||
},
|
||||
{
|
||||
appliesToKey: entries.map(e => e.key + ":output"),
|
||||
applicableUnits: [{
|
||||
canonicalDenomination: 'kW',
|
||||
alternativeDenomination: ["kilowatt"],
|
||||
human: {
|
||||
en: "kilowatt",
|
||||
nl: "kilowatt"
|
||||
}
|
||||
},
|
||||
{
|
||||
canonicalDenomination: 'mW',
|
||||
alternativeDenomination: ["megawatt"],
|
||||
human: {
|
||||
en: "megawatt",
|
||||
nl: "megawatt"
|
||||
}
|
||||
}],
|
||||
eraseInvalidValues: true
|
||||
},
|
||||
];
|
||||
|
||||
writeFileSync("charging_station.json", JSON.stringify(proto, undefined, " "))
|
||||
}
|
||||
|
||||
|
||||
async function queryTagInfo(file, type, clean: ((s: string) => string)) {
|
||||
for (const e of loadCsv(file)) {
|
||||
const value = await ScriptUtils.TagInfoHistogram(e.key + ":" + type)
|
||||
const result = value.data
|
||||
const counts = new Map<string, number>()
|
||||
// console.log(result)
|
||||
for (const r of result) {
|
||||
let key = r.value;
|
||||
key = clean(key)
|
||||
key.trim();
|
||||
if (key.indexOf('-') >= 0) {
|
||||
continue
|
||||
}
|
||||
if (r.fraction < 0.05) {
|
||||
continue
|
||||
}
|
||||
if (counts.has(key)) {
|
||||
counts.set(key, counts.get(key) + r.count)
|
||||
} else {
|
||||
counts.set(key, r.count)
|
||||
}
|
||||
}
|
||||
const countsArray = Array.from(counts.keys())
|
||||
countsArray.sort()
|
||||
// console.log(`${e.key}:${type} = ${countsArray.join(";")}`)
|
||||
console.log(`${countsArray.join(";")}`)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
run("types.csv", "charging_station.protojson")
|
||||
// queryTagInfo("types.csv","voltage", true)
|
||||
// queryTagInfo("types.csv", "current", true)
|
||||
/* queryTagInfo("types.csv", "output", s => {
|
||||
if(s.endsWith("kW")){
|
||||
s = s.substring(0, s.length - 2)
|
||||
}
|
||||
s = s.trim()
|
||||
return s + " kW"
|
||||
})*/
|
||||
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
Key in OSM,image,Description,Country-whitelist,,,,,,,
|
||||
socket:schuko,CEE7_4F.svg,<b>Schuko wall plug</b> without ground pin (CEE7/4 type F),"be,fr,ma,tn,pl,cs,sk,mo"
|
||||
socket:typee,TypeE.svg,<b>European wall plug</b> with ground pin (CEE7/4 type E),,,,,,,,
|
||||
socket:chademo,Chademo_type4.svg,<b>Chademo</b>,,,,,,,,
|
||||
socket:type1_cable,Type1_J1772.svg,<b>Type 1 with cable</b> (J1772),,,,,,,,
|
||||
socket:type1,Type1_J1772.svg,<b>Type 1 <i>without</i> cable</b> (J1772),,,,,,,,
|
||||
socket:type1_combo,Type1-ccs.svg,<b>Type 1 CCS</b> (aka Type 1 Combo),,,,,,,,
|
||||
socket:tesla_supercharger,Tesla-hpwc-model-s.svg,<b>Tesla Supercharger</b>,,,,,,,,
|
||||
socket:type2,Type2_socket.svg,<b>Type 2</b> (mennekes),,,,,,,,
|
||||
socket:type2_combo,Type2_CCS.svg,<b>Type 2 CCS</b> (mennekes),,,,,,,,
|
||||
key,image,description:en,countryWhitelist,commonVoltages,commonCurrents,commonOutputs,description:nl
|
||||
socket:schuko,CEE7_4F.svg,<b>Schuko wall plug</b> without ground pin (CEE7/4 type F),be;fr;ma;tn;pl;cs;sk;mo,230,16,3.6 kW,<b>Schuko stekker</b> zonder aardingspin (CEE7/4 type F)
|
||||
socket:typee,TypeE.svg,<b>European wall plug</b> with ground pin (CEE7/4 type E),,230,16,3 kW;22 kW;,<b>Europese stekker</b> met aardingspin (CEE7/4 type E)
|
||||
socket:chademo,Chademo_type4.svg,<b>Chademo</b>,,500,120,50 kW,
|
||||
socket:type1_cable,Type1_J1772.svg,<b>Type 1 with cable</b> (J1772),,200;240,32,3.7 kW;7 kW,<b>Type 1 met kabel</b> (J1772)
|
||||
socket:type1,Type1_J1772.svg,<b>Type 1 <i>without</i> cable</b> (J1772),,200;240,32,3.7 kW;6.6 kW;7 kW;7.2 kW,<b>Type 1 <i>zonder</i> kabel</b> (J1772)
|
||||
socket:type1_combo,Type1-ccs.svg,<b>Type 1 CCS</b> (aka Type 1 Combo),,400;1000,50;125,50 kW;62.5 kW;150 kW;350 kW;,
|
||||
socket:tesla_supercharger,Tesla-hpwc-model-s.svg,<b>Tesla Supercharger</b>,,480,125;350,120 kW;150 kW;250 kW,
|
||||
socket:type2,Type2_socket.svg,<b>Type 2</b> (mennekes),,230;400,16;32,11 kW;22 kW,
|
||||
socket:type2_combo,Type2_CCS.svg,<b>Type 2 CCS</b> (mennekes),,500;920,125;350,50 kW,
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 2.
|
Loading…
Add table
Add a link
Reference in a new issue