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" ;
2022-03-12 16:30:43 +01:00
import Constants from "../Models/Constants" ;
2022-03-12 16:35:27 +01:00
import { Utils } from "../Utils" ;
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 ) {
2022-03-12 16:30:43 +01:00
if ( Constants . priviliged_layers . indexOf ( layer . id ) >= 0 ) {
continue
}
if ( layer . source . geojsonSource !== undefined && layer . source . isOsmCacheLayer !== true ) {
continue
}
2021-04-19 18:17:26 +02:00
usedTags . push ( . . . generateLayerUsage ( layer , layout ) )
}
2022-03-12 16:35:27 +01:00
if ( usedTags . length == 0 ) {
return undefined
}
2021-04-19 18:17:26 +02:00
let icon = layout . icon ;
if ( icon . startsWith ( "./" ) ) {
icon = icon . substring ( 2 )
}
const themeInfo = {
// data format version, currently always 1, will get updated if there are incompatible changes to the format (required)
"data_format" : 1 ,
2022-03-12 16:30:43 +01:00
// timestamp when project file was updated is not given as it pollutes the github history
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)
2022-08-24 14:48:33 +02:00
"contact_name" : "Pieter Vander Vennet" , // contact name, needed for taginfo maintainer (required)
2021-04-19 18:17:26 +02:00
"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
2022-03-12 16:35:27 +01:00
function generateProjectsOverview ( files : string [ ] ) {
2021-05-07 12:39:37 +02:00
try {
const tagInfoList = "../taginfo-projects/project_list.txt"
let projectList = readFileSync ( tagInfoList , "UTF8" )
. split ( "\n" )
. filter ( entry = > entry . indexOf ( "mapcomplete_" ) < 0 )
2022-03-12 16:42:14 +01:00
. concat ( files . map ( f = > ` ${ f } https://raw.githubusercontent.com/pietervdvn/MapComplete/develop/Docs/TagInfo/ ${ f } .json ` ) )
2021-05-07 12:39:37 +02:00
. 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." )
}
}
2022-03-12 16:35:27 +01:00
function main ( ) {
2021-04-19 18:17:26 +02:00
console . log ( "Creating taginfo project files" )
Locale . language . setData ( "en" )
Translation . forcedLanguage = "en"
2022-03-12 16:35:27 +01:00
const files = [ ]
for ( const layout of AllKnownLayouts . layoutsList ) {
if ( layout . hideFromOverview ) {
continue ;
}
files . push ( generateTagInfoEntry ( layout ) ) ;
2021-04-19 18:17:26 +02:00
}
2022-03-12 16:35:27 +01:00
generateProjectsOverview ( Utils . NoNull ( files ) ) ;
2021-04-19 18:17:26 +02:00
}
2022-03-12 16:35:27 +01:00
main ( )