2022-01-14 03:14:56 +01:00
import { LayoutConfigJson } from "../Json/LayoutConfigJson"
import { Utils } from "../../../Utils"
import LineRenderingConfigJson from "../Json/LineRenderingConfigJson"
import { LayerConfigJson } from "../Json/LayerConfigJson"
2023-10-11 04:16:52 +02:00
import { ConversionContext , DesugaringStep , Each , Fuse , On } from "./Conversion"
2023-06-20 02:02:45 +02:00
import PointRenderingConfigJson from "../Json/PointRenderingConfigJson"
2022-09-08 21:40:48 +02:00
2021-12-21 18:35:31 +01:00
export class UpdateLegacyLayer extends DesugaringStep <
LayerConfigJson | string | { builtin ; override }
> {
constructor ( ) {
super (
"Updates various attributes from the old data format to the new to provide backwards compatibility with the formats" ,
2022-02-14 02:26:03 +01:00
[ "overpassTags" , "source.osmtags" , "tagRenderings[*].id" , "mapRendering" ] ,
"UpdateLegacyLayer"
2022-09-08 21:40:48 +02:00
)
2021-12-21 18:35:31 +01:00
}
2023-10-11 04:16:52 +02:00
convert ( json : LayerConfigJson , context : ConversionContext ) : LayerConfigJson {
2022-01-27 01:30:54 +01:00
if ( typeof json === "string" || json [ "builtin" ] !== undefined ) {
// Reuse of an already existing layer; return as-is
2023-10-11 04:16:52 +02:00
return json
2021-12-21 18:35:31 +01:00
}
2023-10-11 04:16:52 +02:00
context = context . enter ( json . id )
2022-08-22 14:46:55 +02:00
let config = { . . . json }
2021-10-29 01:41:37 +02:00
if ( config [ "overpassTags" ] ) {
2022-06-19 22:37:31 +02:00
config . source = config . source ? ? {
osmTags : config [ "overpassTags" ] ,
}
2023-04-27 02:24:38 +02:00
config . source [ "osmTags" ] = config [ "overpassTags" ]
2021-10-29 01:41:37 +02:00
delete config [ "overpassTags" ]
}
2023-06-20 01:52:15 +02:00
for ( const preset of config . presets ? ? [ ] ) {
const preciseInput = preset [ "preciseInput" ]
if ( typeof preciseInput === "boolean" ) {
delete preset [ "preciseInput" ]
} else if ( preciseInput !== undefined ) {
delete preciseInput [ "preferredBackground" ]
preset . snapToLayer = preciseInput . snapToLayer
delete preciseInput . snapToLayer
if ( preciseInput . maxSnapDistance ) {
preset . maxSnapDistance = preciseInput . maxSnapDistance
delete preciseInput . maxSnapDistance
}
if ( Object . keys ( preciseInput ) . length == 0 ) {
delete preset [ "preciseInput" ]
}
}
2023-06-23 16:14:43 +02:00
if ( typeof preset . snapToLayer === "string" ) {
preset . snapToLayer = [ preset . snapToLayer ]
}
2023-06-20 01:52:15 +02:00
}
2021-10-29 01:41:37 +02:00
if ( config . tagRenderings !== undefined ) {
2022-01-17 21:33:03 +01:00
let i = 0
2021-10-29 01:41:37 +02:00
for ( const tagRendering of config . tagRenderings ) {
2021-12-21 19:56:04 +01:00
i ++
2022-01-27 01:30:54 +01:00
if (
typeof tagRendering === "string" ||
tagRendering [ "builtin" ] !== undefined ||
tagRendering [ "rewrite" ] !== undefined
) {
2021-12-21 19:56:04 +01:00
continue
}
2021-10-29 01:41:37 +02:00
if ( tagRendering [ "id" ] === undefined ) {
2021-11-04 22:31:14 +01:00
if ( tagRendering [ "#" ] !== undefined ) {
tagRendering [ "id" ] = tagRendering [ "#" ]
delete tagRendering [ "#" ]
} else if ( tagRendering [ "freeform" ] ? . key !== undefined ) {
2021-10-29 01:41:37 +02:00
tagRendering [ "id" ] = config . id + "-" + tagRendering [ "freeform" ] [ "key" ]
2022-01-17 21:33:03 +01:00
} else {
tagRendering [ "id" ] = "tr-" + i
2021-10-29 01:41:37 +02:00
}
}
}
}
2023-10-06 23:56:50 +02:00
if (
config [ "mapRendering" ] === undefined &&
config . pointRendering === undefined &&
config . lineRendering === undefined
) {
2023-09-19 14:04:13 +02:00
config [ "mapRendering" ] = [ ]
2021-10-29 01:41:37 +02:00
// This is a legacy format, lets create a pointRendering
let location : ( "point" | "centroid" ) [ ] = [ "point" ]
let wayHandling : number = config [ "wayHandling" ] ? ? 0
2021-11-11 17:35:24 +01:00
if ( wayHandling !== 0 ) {
2021-10-29 01:41:37 +02:00
location = [ "point" , "centroid" ]
}
2021-12-21 18:35:31 +01:00
if ( config [ "icon" ] ? ? config [ "label" ] !== undefined ) {
const pointConfig = {
icon : config [ "icon" ] ,
iconBadges : config [ "iconOverlays" ] ,
label : config [ "label" ] ,
iconSize : config [ "iconSize" ] ,
location ,
rotation : config [ "rotation" ] ,
}
2023-09-19 14:04:13 +02:00
config [ "mapRendering" ] . push ( pointConfig )
2021-12-21 18:35:31 +01:00
}
2021-10-29 01:41:37 +02:00
if ( wayHandling !== 1 ) {
const lineRenderConfig = < LineRenderingConfigJson > {
color : config [ "color" ] ,
width : config [ "width" ] ,
dashArray : config [ "dashArray" ] ,
}
if ( Object . keys ( lineRenderConfig ) . length > 0 ) {
2023-09-19 14:04:13 +02:00
config [ "mapRendering" ] . push ( lineRenderConfig )
2021-10-29 01:41:37 +02:00
}
}
2023-09-19 14:04:13 +02:00
if ( config [ "mapRendering" ] . length === 0 ) {
2021-12-21 18:35:31 +01:00
throw (
"Could not convert the legacy theme into a new theme: no renderings defined for layer " +
config . id
2022-09-08 21:40:48 +02:00
)
2021-11-14 16:57:14 +01:00
}
2021-10-29 01:41:37 +02:00
}
2021-11-07 21:20:05 +01:00
delete config [ "color" ]
delete config [ "width" ]
delete config [ "dashArray" ]
delete config [ "icon" ]
delete config [ "iconOverlays" ]
delete config [ "label" ]
delete config [ "iconSize" ]
delete config [ "rotation" ]
delete config [ "wayHandling" ]
2021-12-03 02:29:25 +01:00
delete config [ "hideUnderlayingFeaturesMinPercentage" ]
2021-12-21 18:35:31 +01:00
2023-09-19 14:04:13 +02:00
for ( const mapRenderingElement of config [ "mapRendering" ] ? ? [ ] ) {
2021-10-29 01:41:37 +02:00
if ( mapRenderingElement [ "iconOverlays" ] !== undefined ) {
mapRenderingElement [ "iconBadges" ] = mapRenderingElement [ "iconOverlays" ]
}
for ( const overlay of mapRenderingElement [ "iconBadges" ] ? ? [ ] ) {
if ( overlay [ "badge" ] !== true ) {
2023-10-11 04:16:52 +02:00
context . enters ( "iconBadges" , "badge" ) . warn ( "Non-overlay element" )
2021-10-29 01:41:37 +02:00
}
delete overlay [ "badge" ]
}
}
2023-09-19 14:04:13 +02:00
if ( config [ "mapRendering" ] ) {
2023-10-06 23:56:50 +02:00
console . log ( "MapRendering is" , config [ "mapRendering" ] , json . id )
2023-09-19 14:04:13 +02:00
const pointRenderings : PointRenderingConfigJson [ ] = [ ]
const lineRenderings : LineRenderingConfigJson [ ] = [ ]
for ( const mapRenderingElement of config [ "mapRendering" ] ) {
if ( mapRenderingElement [ "location" ] ) {
// This is a pointRendering
pointRenderings . push ( < any > mapRenderingElement )
} else {
lineRenderings . push ( < any > mapRenderingElement )
}
2023-06-20 02:02:45 +02:00
}
2023-09-19 14:04:13 +02:00
config [ "pointRendering" ] = pointRenderings
config [ "lineRendering" ] = lineRenderings
delete config [ "mapRendering" ]
}
for ( const rendering of config . pointRendering ? ? [ ] ) {
const pr = rendering
2023-10-06 23:56:50 +02:00
if ( pr [ "icon" ] ) {
try {
const icon = Utils . NoEmpty ( pr [ "icon" ] . split ( ";" ) )
pr . marker = icon . map ( ( i ) = > {
const [ iconPath , color ] = i . split ( ":" )
return { icon : iconPath , color }
} )
delete pr [ "icon" ]
} catch ( e ) {
console . error ( "Could not handle icon in" , json . id )
pr . marker = [ { icon : pr [ "icon" ] } ]
delete pr [ "icon" ]
}
}
2023-07-08 01:09:46 +02:00
let iconSize = pr . iconSize
2023-09-19 14:04:13 +02:00
if ( ! iconSize ) {
continue
}
2023-07-08 01:09:46 +02:00
if ( Object . keys ( pr . iconSize ) . length === 1 && pr . iconSize [ "render" ] !== undefined ) {
iconSize = pr . iconSize [ "render" ]
}
2023-06-20 02:02:45 +02:00
if ( typeof iconSize === "string" )
2023-06-20 03:14:18 +02:00
if ( [ "bottom" , "center" , "top" ] . some ( ( a ) = > ( < string > iconSize ) . endsWith ( a ) ) ) {
2023-06-20 02:02:45 +02:00
const parts = iconSize . split ( "," ) . map ( ( parts ) = > parts . toLowerCase ( ) . trim ( ) )
pr . anchor = parts . pop ( )
pr . iconSize = parts . join ( "," )
}
}
2023-10-06 23:56:50 +02:00
if ( config . pointRendering )
for ( const rendering of config . pointRendering ) {
for ( const key in rendering ) {
if ( ! rendering [ key ] ) {
continue
}
if (
typeof rendering [ key ] [ "render" ] === "string" &&
Object . keys ( rendering [ key ] ) . length === 1
) {
console . log ( "Rewrite: " , rendering [ key ] )
rendering [ key ] = rendering [ key ] [ "render" ]
}
2023-09-19 14:04:13 +02:00
}
}
2023-10-06 23:56:50 +02:00
if ( config . lineRendering )
for ( const rendering of config . lineRendering ) {
for ( const key in rendering ) {
if ( ! rendering [ key ] ) {
continue
}
if (
typeof rendering [ key ] [ "render" ] === "string" &&
Object . keys ( rendering [ key ] ) . length === 1
) {
console . log ( "Rewrite: " , rendering [ key ] )
rendering [ key ] = rendering [ key ] [ "render" ]
}
2023-06-20 03:14:18 +02:00
}
}
2023-10-11 04:16:52 +02:00
return config
2021-12-21 18:35:31 +01:00
}
}
class UpdateLegacyTheme extends DesugaringStep < LayoutConfigJson > {
constructor ( ) {
2022-08-22 14:46:55 +02:00
super ( "Small fixes in the theme config" , [ "roamingRenderings" ] , "UpdateLegacyTheme" )
2021-12-21 18:35:31 +01:00
}
2023-10-11 04:16:52 +02:00
convert ( json : LayoutConfigJson , context : ConversionContext ) : LayoutConfigJson {
2021-12-21 18:35:31 +01:00
const oldThemeConfig = { . . . json }
2022-08-22 14:46:55 +02:00
if ( oldThemeConfig . socialImage === "" ) {
2022-02-19 17:40:51 +01:00
delete oldThemeConfig . socialImage
}
2022-08-22 14:46:55 +02:00
2023-09-28 23:50:27 +02:00
if ( oldThemeConfig . defaultBackgroundId === "osm" ) {
2023-09-24 18:24:10 +02:00
console . log ( "Removing old background in" , json . id )
}
2023-10-30 13:45:44 +01:00
if ( typeof oldThemeConfig . credits === "string" ) {
oldThemeConfig . credits = [ oldThemeConfig . credits ]
}
2021-12-21 18:35:31 +01:00
if ( oldThemeConfig [ "roamingRenderings" ] !== undefined ) {
if ( oldThemeConfig [ "roamingRenderings" ] . length == 0 ) {
delete oldThemeConfig [ "roamingRenderings" ]
} else {
2023-10-11 04:16:52 +02:00
context . err ( "The theme contains roamingRenderings. These are not supported anymore" )
return null
2021-12-21 18:35:31 +01:00
}
}
2022-01-24 16:43:50 +01:00
oldThemeConfig . layers = Utils . NoNull ( oldThemeConfig . layers )
2022-01-27 01:30:54 +01:00
delete oldThemeConfig [ "language" ]
2022-08-22 14:46:55 +02:00
delete oldThemeConfig [ "version" ]
if ( oldThemeConfig [ "maintainer" ] !== undefined ) {
console . log (
"Maintainer: " ,
oldThemeConfig [ "maintainer" ] ,
"credits: " ,
oldThemeConfig [ "credits" ]
)
if ( oldThemeConfig . credits === undefined ) {
oldThemeConfig [ "credits" ] = oldThemeConfig [ "maintainer" ]
delete oldThemeConfig [ "maintainer" ]
} else if ( oldThemeConfig [ "maintainer" ] . toLowerCase ( ) . trim ( ) === "mapcomplete" ) {
delete oldThemeConfig [ "maintainer" ]
} else if ( oldThemeConfig [ "maintainer" ] . toLowerCase ( ) . trim ( ) === "" ) {
delete oldThemeConfig [ "maintainer" ]
}
}
2023-10-11 04:16:52 +02:00
return oldThemeConfig
2021-10-29 01:41:37 +02:00
}
2021-12-21 18:35:31 +01:00
}
2021-10-29 01:41:37 +02:00
2021-12-21 18:35:31 +01:00
export class FixLegacyTheme extends Fuse < LayoutConfigJson > {
constructor ( ) {
super (
"Fixes a legacy theme to the modern JSON format geared to humans. Syntactic sugars are kept (i.e. no tagRenderings are expandend, no dependencies are automatically gathered)" ,
new UpdateLegacyTheme ( ) ,
2022-08-22 14:46:55 +02:00
new On ( "layers" , new Each ( new UpdateLegacyLayer ( ) ) )
2021-12-21 18:35:31 +01:00
)
}
}