11package com.mapbox.maps.extension.localization
22
3- import com.mapbox.maps.StyleObjectInfo
3+ import com.mapbox.bindgen.Value
4+ import com.mapbox.maps.StylePropertyValueKind
45import com.mapbox.maps.extension.style.StyleInterface
56import com.mapbox.maps.extension.style.expressions.dsl.generated.get
6- import com.mapbox.maps.extension.style.expressions.generated.Expression
7- import com.mapbox.maps.extension.style.layers.generated.SymbolLayer
8- import com.mapbox.maps.extension.style.layers.getLayerAs
9- import com.mapbox.maps.extension.style.sources.generated.VectorSource
10- import com.mapbox.maps.extension.style.sources.getSourceAs
117import com.mapbox.maps.logE
128import com.mapbox.maps.logI
139import java.util.*
@@ -20,70 +16,98 @@ import java.util.*
2016 * `["format",["coalesce",["get","name_de"],["get","name"]],{}]`
2117 */
2218internal fun setMapLanguage (locale : Locale , style : StyleInterface , layerIds : List <String >? ) {
23- var convertedLocale = " name_${locale.language} "
19+ val convertedLocale = " name_${locale.language} "
2420 if (! isSupportedLanguage(convertedLocale)) {
2521 logE(TAG , " Locale: $locale is not supported." )
2622 return
2723 }
2824
29- style.styleSources
30- .forEach { source ->
31- style.styleLayers
32- .filter { it.type == LAYER_TYPE_SYMBOL }
33- .filter { layer ->
34- layerIds?.contains(layer.id) ? : true
35- }
36- .forEach { layer ->
37- val symbolLayer = style.getLayerAs<SymbolLayer >(layer.id)
38- symbolLayer?.let {
39- it.textFieldAsExpression?.let { textFieldExpression ->
40- if (BuildConfig .DEBUG ) {
41- logI(TAG , " Localize layer id: ${it.layerId} " )
42- }
43-
44- if (sourceIsStreetsV8(style, source)) {
45- convertedLocale = getLanguageNameV8(locale)
46- } else if (sourceIsStreetsV7(style, source)) {
47- convertedLocale = getLanguageNameV7(locale)
48- }
49- convertExpression(convertedLocale, it, textFieldExpression)
50- }
51- }
52- }
25+ layerIds?.forEach { id ->
26+ localizeTextFieldExpression(
27+ style = style,
28+ layerId = id,
29+ locale = locale,
30+ convertedLocale = convertedLocale,
31+ filterSymbolLayers = true ,
32+ )
33+ } ? : style.styleLayers.forEach { layer ->
34+ if (layer.type == SYMBOL ) {
35+ localizeTextFieldExpression(
36+ style = style,
37+ layerId = layer.id,
38+ locale = locale,
39+ convertedLocale = convertedLocale,
40+ filterSymbolLayers = false ,
41+ )
5342 }
43+ }
5444}
5545
56- private fun convertExpression (language : String , layer : SymbolLayer , textField : Expression ? ) {
57- textField?.let {
58- val stringExpression: String = it.toJson().replace(
59- EXPRESSION_REGEX ,
60- get(language).toJson()
61- ).replace(EXPRESSION_ABBR_REGEX , get(language).toJson())
62- if (BuildConfig .DEBUG ) {
63- logI(TAG , " Localize layer with expression: $stringExpression " )
46+ private fun localizeTextFieldExpression (
47+ style : StyleInterface ,
48+ layerId : String ,
49+ locale : Locale ,
50+ convertedLocale : String ,
51+ filterSymbolLayers : Boolean ,
52+ ) {
53+ if (filterSymbolLayers) {
54+ val type = style.getStyleLayerProperty(layerId, TYPE ).value.contents as ? String
55+ if (type != SYMBOL ) {
56+ return
6457 }
65- layer.textField(Expression .fromRaw(stringExpression))
58+ }
59+ val textFieldProperty = style.getStyleLayerProperty(layerId, TEXT_FIELD )
60+ if (textFieldProperty.kind != StylePropertyValueKind .EXPRESSION ) {
61+ return
62+ }
63+ val textField = textFieldProperty.value.toJson()
64+ val adaptedLocale = adaptLocaleToV8orV7IfNeeded(
65+ style,
66+ style.getStyleLayerProperty(layerId, SOURCE ).value.contents as ? String ? : " " ,
67+ locale
68+ ) ? : convertedLocale
69+ val getExpression = get(adaptedLocale).toJson()
70+ val localizedTextFieldExpressionAsJson = textField.replace(
71+ EXPRESSION_REGEX ,
72+ getExpression
73+ ).replace(EXPRESSION_ABBR_REGEX , getExpression)
74+ if (BuildConfig .DEBUG ) {
75+ logI(TAG , " Localize layer with expression: $localizedTextFieldExpressionAsJson " )
76+ }
77+ val expected = Value .fromJson(localizedTextFieldExpressionAsJson)
78+ expected.value?.let { value ->
79+ style.setStyleLayerProperty(
80+ layerId,
81+ TEXT_FIELD ,
82+ value
83+ )
84+ } ? : run {
85+ logE(TAG , " An error ${expected.error} occurred when converting $localizedTextFieldExpressionAsJson to a Value!" )
6686 }
6787}
6888
69- private fun sourceIsStreetsV8 (style : StyleInterface , source : StyleObjectInfo ): Boolean =
70- sourceIsType( style, source, STREET_V8 )
71-
72- private fun sourceIsStreetsV7 ( style : StyleInterface , source : StyleObjectInfo ): Boolean =
73- sourceIsType(style, source, STREET_V7 )
74-
75- private fun sourceIsType ( style : StyleInterface , source : StyleObjectInfo , type : String ): Boolean {
76- if (source.type == SOURCE_TYPE_VECTOR ) {
77- style.getSourceAs< VectorSource >(source.id)?.url?. let {
78- return it.contains(type)
89+ private fun adaptLocaleToV8orV7IfNeeded (style : StyleInterface , sourceId : String , locale : Locale ): String? {
90+ if (( style.getStyleSourceProperty(sourceId, TYPE ).value.contents as ? String ) == VECTOR ) {
91+ (style.getStyleSourceProperty(sourceId, URL ).value.contents as ? String )?. let { url ->
92+ return if (url.contains( STREET_V8 )) {
93+ getLanguageNameV8(locale )
94+ } else if (url.contains( STREET_V7 )) {
95+ getLanguageNameV7(locale)
96+ } else {
97+ null
98+ }
7999 }
80100 }
81- return false
101+ return null
82102}
83103
84104private const val TAG = " LocalizationPluginImpl"
85- private const val SOURCE_TYPE_VECTOR = " vector"
86- private const val LAYER_TYPE_SYMBOL = " symbol"
105+ private const val TYPE = " type"
106+ private const val SOURCE = " source"
107+ private const val SYMBOL = " symbol"
108+ private const val URL = " url"
109+ private const val VECTOR = " vector"
110+ private const val TEXT_FIELD = " text-field"
87111private const val STREET_V7 = " mapbox.mapbox-streets-v7"
88112private const val STREET_V8 = " mapbox.mapbox-streets-v8"
89113private val EXPRESSION_REGEX = Regex (" \\ [\" get\" ,\\ s*\" (name_.{2,7})\"\\ ]" )
0 commit comments