2021-04-19 18:17:26 +02:00
import { AllKnownLayouts } from "../Customizations/AllKnownLayouts" ;
import Locale from "../UI/i18n/Locale" ;
import { Translation } from "../UI/i18n/Translation" ;
2021-05-05 11:30:44 +02:00
import { readFileSync , writeFileSync } from "fs" ;
2021-08-07 23:11:34 +02:00
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig" ;
import LayerConfig from "../Models/ThemeConfig/LayerConfig" ;
2021-04-19 18:17:26 +02:00
2021-05-04 17:46:45 +02:00
/ * *
* Generates all the files in "Docs/TagInfo" . These are picked up by the taginfo project , showing a link to the mapcomplete theme if the key is used
* /
2021-04-19 18:17:26 +02:00
const outputDirectory = "Docs/TagInfo"
2021-09-09 00:05:51 +02:00
function generateTagOverview ( kv : { k : string , v : string } , description : string ) : {
2021-06-24 14:02:18 +02:00
key : string ,
description : string ,
value? : string
} {
2021-04-20 11:54:45 +02:00
const overview = {
// OSM tag key (required)
key : kv.k ,
2021-06-24 14:02:18 +02:00
description : description ,
2021-09-09 00:05:51 +02:00
value : undefined
2021-04-20 11:54:45 +02:00
} ;
if ( kv . v !== undefined ) {
// OSM tag value (optional, if not supplied it means "all values")
2021-06-24 14:02:18 +02:00
overview . value = kv . v
2021-04-20 11:54:45 +02:00
}
return overview
}
2021-04-19 18:17:26 +02:00
function generateLayerUsage ( layer : LayerConfig , layout : LayoutConfig ) : any [ ] {
2021-05-04 17:46:45 +02:00
2021-09-09 00:05:51 +02:00
if ( layer . name === undefined ) {
2021-07-28 00:12:14 +02:00
return [ ] // Probably a duplicate or irrelevant layer
}
2021-09-09 00:05:51 +02:00
2021-04-19 18:17:26 +02:00
const usedTags = layer . source . osmTags . asChange ( { } )
2021-09-09 00:05:51 +02:00
const result : {
2021-06-24 14:02:18 +02:00
key : string ,
description : string ,
value? : string
} [ ] = [ ]
2021-04-19 18:17:26 +02:00
for ( const kv of usedTags ) {
2021-04-20 11:54:45 +02:00
const description = "The MapComplete theme " + layout . title . txt + " has a layer " + layer . name . txt + " showing features with this tag"
result . push ( generateTagOverview ( kv , description ) )
}
for ( const tr of layer . tagRenderings ) {
2021-05-04 17:46:45 +02:00
{
2021-07-03 22:00:36 +02:00
const usesImageCarousel = ( tr . render ? . txt ? . indexOf ( "image_carousel" ) ? ? - 2 ) > 0
const usesImageUpload = ( tr . render ? . txt ? . indexOf ( "image_upload" ) ? ? - 2 ) > 0
2021-05-04 17:46:45 +02:00
if ( usesImageCarousel || usesImageUpload ) {
2021-05-07 12:39:37 +02:00
2021-05-04 17:46:45 +02:00
const descrNoUpload = ` The layer ' ${ layer . name . txt } shows images based on the keys image, image:0, image:1,... and wikidata, wikipedia, wikimedia_commons and mapillary ` ;
const descrUpload = ` The layer ' ${ layer . name . txt } allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary ` ;
const descr = usesImageUpload ? descrUpload : descrNoUpload ;
result . push ( generateTagOverview ( { k : "image" , v : undefined } , descr ) ) ;
result . push ( generateTagOverview ( { k : "mapillary" , v : undefined } , descr ) ) ;
result . push ( generateTagOverview ( { k : "wikidata" , v : undefined } , descr ) ) ;
result . push ( generateTagOverview ( { k : "wikipedia" , v : undefined } , descr ) ) ;
}
}
2021-04-20 11:54:45 +02:00
const q = tr . question ? . txt ;
const key = tr . freeform ? . key ;
if ( key != undefined ) {
2021-04-21 18:51:12 +02:00
let descr = ` Layer ' ${ layer . name . txt } ' ` ;
2021-04-20 11:54:45 +02:00
if ( q == undefined ) {
descr += " shows values with" ;
} else {
descr += " shows and asks freeform values for"
}
2021-04-21 18:51:12 +02:00
descr += ` key ' ${ key } ' (in the MapComplete.osm.be theme ' ${ layout . title . txt } ') `
2021-04-20 11:54:45 +02:00
result . push ( generateTagOverview ( { k : key , v : undefined } , descr ) )
}
const mappings = tr . mappings ? ? [ ]
for ( const mapping of mappings ) {
2021-04-21 18:51:12 +02:00
let descr = "Layer '" + layer . name . txt + "'" ;
2021-04-20 11:54:45 +02:00
descr += " shows " + mapping . if . asHumanString ( false , false , { } ) + " with a fixed text, namely '" + mapping . then . txt + "'" ;
if ( q != undefined
&& mapping . hideInAnswer != true // != true will also match if a
) {
2021-04-21 18:51:12 +02:00
descr += " and allows to pick this as a default answer"
2021-04-20 11:54:45 +02:00
}
2021-04-21 18:51:12 +02:00
descr += ` (in the MapComplete.osm.be theme ' ${ layout . title . txt } ') `
2021-04-20 11:54:45 +02:00
for ( const kv of mapping . if . asChange ( { } ) ) {
let d = descr ;
2021-05-04 17:46:45 +02:00
if ( q != undefined && kv . v == "" ) {
2021-04-20 11:54:45 +02:00
d = ` ${ descr } Picking this answer will delete the key ${ kv . k } . `
}
result . push ( generateTagOverview ( kv , d ) )
}
2021-04-19 18:17:26 +02:00
}
}
2021-09-09 00:05:51 +02:00
2021-06-24 14:02:18 +02:00
return result . filter ( result = > ! result . key . startsWith ( "_" ) )
2021-04-19 18:17:26 +02:00
}
/ * *
* Generates the JSON - object representing the theme for inclusion on taginfo
* @param layout
* /
function generateTagInfoEntry ( layout : LayoutConfig ) : any {
const usedTags = [ ]
for ( const layer of layout . layers ) {
usedTags . push ( . . . generateLayerUsage ( layer , layout ) )
}
let icon = layout . icon ;
if ( icon . startsWith ( "./" ) ) {
icon = icon . substring ( 2 )
}
2021-05-04 17:46:45 +02:00
/ *
const t = new Date ( ) ;
const generationTime = t . getUTCFullYear ( ) + Utils . TwoDigits ( t . getUTCMonth ( ) ) + Utils . TwoDigits ( t . getUTCDate ( ) ) + "T" + Utils . TwoDigits ( t . getUTCHours ( ) ) + Utils . TwoDigits ( t . getUTCMinutes ( ) ) + Utils . TwoDigits ( t . getSeconds ( ) ) + "Z"
* /
2021-04-19 18:17:26 +02:00
const themeInfo = {
// data format version, currently always 1, will get updated if there are incompatible changes to the format (required)
"data_format" : 1 ,
// "data_url": "...", # this should be the URL under which this project file can be accessed (optional)
// timestamp when project file was updated (optional, will use HTTP header date if not available)
2021-04-21 18:46:35 +02:00
// Not marked as not to pollute the github history
//"data_updated": generationTime,
2021-04-19 18:17:26 +02:00
"project" : {
"name" : "MapComplete " + layout . title . txt , // name of the project (required)
"description" : layout . shortDescription . txt , // short description of the project (required)
"project_url" : "https://mapcomplete.osm.be/" + layout . id , // home page of the project with general information (required)
"doc_url" : "https://github.com/pietervdvn/MapComplete/tree/master/assets/themes/" , // documentation of the project and especially the tags used (optional)
2021-05-04 17:46:45 +02:00
"icon_url" : "https://mapcomplete.osm.be/" + icon , // project logo, should work in 16x16 pixels on white and light gray backgrounds (optional)
2021-04-19 18:17:26 +02:00
"contact_name" : "Pieter Vander Vennet, " + layout . maintainer , // contact name, needed for taginfo maintainer (required)
"contact_email" : "pietervdvn@posteo.net" // contact email, needed for taginfo maintainer (required)
} ,
tags : usedTags
}
const filename = "mapcomplete_" + layout . id
console . log ( "Writing info about " + layout . id )
2021-09-09 00:30:48 +02:00
writeFileSync ( ` ${ outputDirectory } / ${ filename } .json ` , JSON . stringify ( themeInfo , null , 2 ) )
2021-04-19 18:17:26 +02:00
return filename
}
2021-05-07 12:39:37 +02:00
// Write the URLS to the taginfo repository. Might fail if the repository is not checked ou
function generateProjectsOverview() {
try {
const tagInfoList = "../taginfo-projects/project_list.txt"
let projectList = readFileSync ( tagInfoList , "UTF8" )
. split ( "\n" )
. filter ( entry = > entry . indexOf ( "mapcomplete_" ) < 0 )
. concat ( files . map ( f = > ` ${ f } https://raw.githubusercontent.com/pietervdvn/MapComplete/master/Docs/TagInfo/ ${ f } .json ` ) )
. sort ( )
. filter ( entry = > entry != "" )
console . log ( "Writing taginfo project filelist" ) ;
writeFileSync ( tagInfoList , projectList . join ( "\n" ) + "\n" ) ;
} catch ( e ) {
console . warn ( "Could not write the taginfo-projects list - the repository is probably not checked out. Are you creating a fork? Ignore this message then." )
}
}
2021-04-19 18:17:26 +02:00
console . log ( "Creating taginfo project files" )
Locale . language . setData ( "en" )
Translation . forcedLanguage = "en"
const files = [ ]
for ( const layout of AllKnownLayouts . layoutsList ) {
if ( layout . hideFromOverview ) {
continue ;
}
files . push ( generateTagInfoEntry ( layout ) ) ;
}
2021-05-07 12:39:37 +02:00
generateProjectsOverview ( ) ;