From 27480de3147d7d8889b2263bddbabf9a9759bf6d Mon Sep 17 00:00:00 2001 From: Gabriel Palmisano Date: Sat, 13 Jul 2024 17:26:20 +0200 Subject: [PATCH 1/6] Aligned example and maplibre_dl_web pubspec versions. --- example/pubspec.yaml | 3 ++- maplibre_gl_web/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 71b4a0c82..90737f5da 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: sdk: flutter http: ^1.1.0 location: ^5.0.3 - maplibre_gl: ^0.19.0 + maplibre_gl: ^0.20.0 path_provider: ^2.0.15 dev_dependencies: @@ -36,3 +36,4 @@ flutter: - assets/osm_style.json - assets/sydney0.png - assets/sydney1.png + - assets/features.json diff --git a/maplibre_gl_web/pubspec.yaml b/maplibre_gl_web/pubspec.yaml index 2f320e9e3..1c72fbee1 100644 --- a/maplibre_gl_web/pubspec.yaml +++ b/maplibre_gl_web/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: sdk: flutter image: ^4.0.17 js: ">=0.6.7 <0.8.0" - maplibre_gl_platform_interface: ^0.19.0+2 + maplibre_gl_platform_interface: ^0.20.0 meta: ^1.3.0 dev_dependencies: From 876c4858969828355b6617fb05f64d676b3bda17 Mon Sep 17 00:00:00 2001 From: Gabriel Palmisano Date: Sat, 13 Jul 2024 17:55:51 +0200 Subject: [PATCH 2/6] fix: remove unused custom asset from example pubspec.yaml (caused an error) --- example/pubspec.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 90737f5da..907af722e 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -36,4 +36,3 @@ flutter: - assets/osm_style.json - assets/sydney0.png - assets/sydney1.png - - assets/features.json From 232c0c13c713da1a9275a9c5a57da23388844175 Mon Sep 17 00:00:00 2001 From: Gabriel Palmisano Date: Fri, 26 Jul 2024 00:54:38 +0200 Subject: [PATCH 3/6] refactor: Updated and fixed outdated generate.dart and template files. Added checks in LayerPropertyConverter.swift to correct property values, in cases of arrays and expressions. --- .../maplibre_gl/LayerPropertyConverter.swift | 24 +++++++++++++--- scripts/lib/generate.dart | 17 +++++++---- .../LayerPropertyConverter.java.template | 10 +++---- .../LayerPropertyConverter.swift.template | 28 +++++++++++++++---- .../templates/layer_expressions.dart.template | 4 +-- .../templates/layer_properties.dart.template | 5 ++-- scripts/templates/layer_tools.dart.template | 8 +++--- .../templates/source_properties.dart.template | 5 ++-- 8 files changed, 70 insertions(+), 31 deletions(-) diff --git a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift index 8e4fbc4a1..dbbe8e616 100644 --- a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift +++ b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift @@ -354,6 +354,8 @@ class LayerPropertyConverter { private class func interpretExpression(propertyName: String, expression: String) -> NSExpression? { let isColor = propertyName.contains("color"); + let isOffset = propertyName.contains("offset"); + let isTranslate = propertyName.contains("translate"); do { let json = try JSONSerialization.jsonObject(with: expression.data(using: .utf8)!, options: .fragmentsAllowed) @@ -364,20 +366,34 @@ class LayerPropertyConverter { return NSExpression(forConstantValue: UIColor(hexString: color)) } } - // this is required because NSExpression.init(mglJSONObject: json) fails to create - // a proper Expression if the data of a literal is an array + if let offset = json as? [Any]{ + // checks on the value of property that are literal expressions if offset.count == 2 && offset.first is String && offset.first as? String == "literal" { if let vector = offset.last as? [Any]{ if(vector.count == 2) { - if let x = vector.first as? Double, let y = vector.last as? Double { + if isOffset || isTranslate { + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data of a literal is an array destined for a CGVector + if let x = vector.first as? Double, let y = vector.last as? Double { + return NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: x, dy: y))) + } + } + return NSExpression.init(mglJSONObject: json) + } else if vector.count == 2, let x = vector.first as? Double, let y = vector.last as? Double { + if isOffset || isTranslate { + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data of an array is destined for a CGVector return NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: x, dy: y))) } - + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data is an array of double + return NSExpression(forConstantValue: [NSNumber(value: x), NSNumber(value: y)]) } } } } + return NSExpression.init(mglJSONObject: json) } catch { } diff --git a/scripts/lib/generate.dart b/scripts/lib/generate.dart index 9d6f8b0cb..9879f102c 100644 --- a/scripts/lib/generate.dart +++ b/scripts/lib/generate.dart @@ -7,8 +7,9 @@ import 'package:recase/recase.dart'; import 'conversions.dart'; main() async { - final styleJson = - jsonDecode(await File('scripts/input/style.json').readAsString()); + final currentPath = Directory.current.path; + final styleFilePath = '$currentPath/input/style.json'; + final styleJson = jsonDecode(await File(styleFilePath).readAsString()); final layerTypes = [ "symbol", @@ -20,6 +21,7 @@ main() async { "hillshade", "heatmap", ]; + final sourceTypes = [ "vector", "raster", @@ -58,8 +60,8 @@ main() async { }.map((p) => {"property": p}).toList(); const templates = [ - "maplibre_gl/android/src/main/java/com/mapbox/mapboxgl/LayerPropertyConverter.java", - "maplibre_gl/ios/Classes/LayerPropertyConverter.swift", + "maplibre_gl/android/src/main/java/org/maplibre/maplibregl/LayerPropertyConverter.java", + "maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift", "maplibre_gl/lib/src/layer_expressions.dart", "maplibre_gl/lib/src/layer_properties.dart", "maplibre_gl_web/lib/src/layer_tools.dart", @@ -75,13 +77,16 @@ Future render( Map renderContext, String path, ) async { + final currentParentPath = Directory.current.parent.path; + final pathItems = path.split("/"); final filename = pathItems.removeLast(); - final outputPath = pathItems.join("/"); + final outputPath = '$currentParentPath/${pathItems.join("/")}'; print("Rendering $filename"); final templateFile = - await File('./scripts/templates/$filename.template').readAsString(); + await File('$currentParentPath/scripts/templates/$filename.template') + .readAsString(); final template = Template(templateFile); final outputFile = File('$outputPath/$filename'); diff --git a/scripts/templates/LayerPropertyConverter.java.template b/scripts/templates/LayerPropertyConverter.java.template index 044517237..4c8eaad8a 100644 --- a/scripts/templates/LayerPropertyConverter.java.template +++ b/scripts/templates/LayerPropertyConverter.java.template @@ -1,11 +1,11 @@ // This file is generated by // ./scripts/lib/generate.dart -package com.mapbox.mapboxgl; +package org.maplibre.maplibregl; -import com.mapbox.mapboxsdk.style.expressions.Expression; -import com.mapbox.mapboxsdk.style.layers.PropertyFactory; -import com.mapbox.mapboxsdk.style.layers.PropertyValue; +import org.maplibre.android.style.expressions.Expression; +import org.maplibre.android.style.layers.PropertyFactory; +import org.maplibre.android.style.layers.PropertyValue; import java.util.LinkedList; import java.util.List; @@ -16,7 +16,7 @@ import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; -import static com.mapbox.mapboxgl.Convert.toMap; +import static org.maplibre.maplibregl.Convert.toMap; class LayerPropertyConverter { {{#layerTypes}} diff --git a/scripts/templates/LayerPropertyConverter.swift.template b/scripts/templates/LayerPropertyConverter.swift.template index 59d40d80f..ae000533e 100644 --- a/scripts/templates/LayerPropertyConverter.swift.template +++ b/scripts/templates/LayerPropertyConverter.swift.template @@ -1,11 +1,11 @@ // This file is generated by // ./scripts/lib/generate.dart -import Mapbox +import MapLibre class LayerPropertyConverter { {{#layerTypes}} - class func add{{typePascal}}Properties({{typeCamel}}Layer: MGL{{typePascal}}StyleLayer, properties: [String: String]) { + class func add{{typePascal}}Properties({{typeCamel}}Layer: MLN{{typePascal}}StyleLayer, properties: [String: String]) { for (propertyName, propertyValue) in properties { let expression = interpretExpression(propertyName: propertyName, expression: propertyValue) switch propertyName { @@ -43,6 +43,8 @@ class LayerPropertyConverter { {{/layerTypes}} private class func interpretExpression(propertyName: String, expression: String) -> NSExpression? { let isColor = propertyName.contains("color"); + let isOffset = propertyName.contains("offset"); + let isTranslate = propertyName.contains("translate"); do { let json = try JSONSerialization.jsonObject(with: expression.data(using: .utf8)!, options: .fragmentsAllowed) @@ -53,20 +55,34 @@ class LayerPropertyConverter { return NSExpression(forConstantValue: UIColor(hexString: color)) } } - // this is required because NSExpression.init(mglJSONObject: json) fails to create - // a proper Expression if the data of a literal is an array + if let offset = json as? [Any]{ + // checks on the value of property that are literal expressions if offset.count == 2 && offset.first is String && offset.first as? String == "literal" { if let vector = offset.last as? [Any]{ if(vector.count == 2) { - if let x = vector.first as? Double, let y = vector.last as? Double { + if isOffset || isTranslate { + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data of a literal is an array destined for a CGVector + if let x = vector.first as? Double, let y = vector.last as? Double { + return NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: x, dy: y))) + } + } + return NSExpression.init(mglJSONObject: json) + } else if vector.count == 2, let x = vector.first as? Double, let y = vector.last as? Double { + if isOffset || isTranslate { + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data of an array is destined for a CGVector return NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: x, dy: y))) } - + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data is an array of double + return NSExpression(forConstantValue: [NSNumber(value: x), NSNumber(value: y)]) } } } } + return NSExpression.init(mglJSONObject: json) } catch { } diff --git a/scripts/templates/layer_expressions.dart.template b/scripts/templates/layer_expressions.dart.template index 24e47f9dc..d4351bc93 100644 --- a/scripts/templates/layer_expressions.dart.template +++ b/scripts/templates/layer_expressions.dart.template @@ -1,9 +1,9 @@ // This file is generated by // ./scripts/lib/generate.dart -part of maplibre_gl; +part of '../maplibre_gl.dart'; -class Expressions{ +class Expressions { {{#expressions}} {{#docSplit}} /// {{{part}}} diff --git a/scripts/templates/layer_properties.dart.template b/scripts/templates/layer_properties.dart.template index 3fa45c06c..bef01c502 100644 --- a/scripts/templates/layer_properties.dart.template +++ b/scripts/templates/layer_properties.dart.template @@ -1,7 +1,7 @@ // This file is generated by // ./scripts/lib/generate.dart -part of maplibre_gl; +part of '../maplibre_gl.dart'; abstract class LayerProperties { Map toJson(); @@ -45,8 +45,9 @@ class {{typePascal}}LayerProperties implements LayerProperties { ); } + @override Map toJson() { - final Map json = {}; + final json = {}; void addIfPresent(String fieldName, dynamic value) { if (value != null) { diff --git a/scripts/templates/layer_tools.dart.template b/scripts/templates/layer_tools.dart.template index b5e28b1ab..0cdf78332 100644 --- a/scripts/templates/layer_tools.dart.template +++ b/scripts/templates/layer_tools.dart.template @@ -3,10 +3,10 @@ const _layoutProperties = { {{#all_layout_properties}} - "{{{property}}}", + "{{{property}}}", {{/all_layout_properties}} }; -bool isLayoutProperty(String property){ - return _layoutProperties.contains(property); -} \ No newline at end of file +bool isLayoutProperty(String property) { + return _layoutProperties.contains(property); +} diff --git a/scripts/templates/source_properties.dart.template b/scripts/templates/source_properties.dart.template index f0e45b00b..9314d00b3 100644 --- a/scripts/templates/source_properties.dart.template +++ b/scripts/templates/source_properties.dart.template @@ -1,7 +1,7 @@ // This file is generated by // ./scripts/lib/generate.dart -part of maplibre_gl_platform_interface; +part of '../maplibre_gl_platform_interface.dart'; abstract class SourceProperties { Map toJson(); @@ -39,8 +39,9 @@ class {{typePascal}}SourceProperties implements SourceProperties { ); } + @override Map toJson() { - final Map json = {}; + final json = {}; void addIfPresent(String fieldName, dynamic value) { if (value != null) { From 3c029611dd911e058a56008b92280ffeda44485b Mon Sep 17 00:00:00 2001 From: Gabriel Palmisano Date: Fri, 26 Jul 2024 01:17:02 +0200 Subject: [PATCH 4/6] fix: Minor fix on literal expressions and arrays checks. --- .../maplibre_gl/LayerPropertyConverter.swift | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift index dbbe8e616..9bca921a3 100644 --- a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift +++ b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift @@ -380,17 +380,18 @@ class LayerPropertyConverter { } } return NSExpression.init(mglJSONObject: json) - } else if vector.count == 2, let x = vector.first as? Double, let y = vector.last as? Double { - if isOffset || isTranslate { - // this is required because NSExpression.init(mglJSONObject: json) fails to create - // a proper Expression if the data of an array is destined for a CGVector - return NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: x, dy: y))) - } - // this is required because NSExpression.init(mglJSONObject: json) fails to create - // a proper Expression if the data is an array of double - return NSExpression(forConstantValue: [NSNumber(value: x), NSNumber(value: y)]) } } + // checks on the value of properties that are arrays + } else if vector.count == 2, let x = vector.first as? Double, let y = vector.last as? Double { + if isOffset || isTranslate { + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data of an array is destined for a CGVector + return NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: x, dy: y))) + } + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data is an array of double + return NSExpression(forConstantValue: [NSNumber(value: x), NSNumber(value: y)]) } } From ca44645272d03aaa2bab31e9484fc3bee7b9504a Mon Sep 17 00:00:00 2001 From: Gabriel Palmisano Date: Fri, 26 Jul 2024 01:23:02 +0200 Subject: [PATCH 5/6] fix: Minor correction of a typo --- .../Sources/maplibre_gl/LayerPropertyConverter.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift index 9bca921a3..992ba230d 100644 --- a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift +++ b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/LayerPropertyConverter.swift @@ -383,7 +383,7 @@ class LayerPropertyConverter { } } // checks on the value of properties that are arrays - } else if vector.count == 2, let x = vector.first as? Double, let y = vector.last as? Double { + } else if offset.count == 2, let x = offset.first as? Double, let y = offset.last as? Double { if isOffset || isTranslate { // this is required because NSExpression.init(mglJSONObject: json) fails to create // a proper Expression if the data of an array is destined for a CGVector From 9321b788429c8f8d8b55ce47a03a72f51f75b921 Mon Sep 17 00:00:00 2001 From: Gabriel Palmisano Date: Mon, 29 Jul 2024 16:01:42 +0200 Subject: [PATCH 6/6] fix: Added translate, offset and others arrays expressions handling on Android. Minor fix on iOS template and generate.dart. --- .../maplibregl/LayerPropertyConverter.java | 133 ++++++++++++++++-- scripts/lib/generate.dart | 5 + .../LayerPropertyConverter.java.template | 53 ++++++- .../LayerPropertyConverter.swift.template | 19 +-- 4 files changed, 185 insertions(+), 25 deletions(-) diff --git a/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/LayerPropertyConverter.java b/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/LayerPropertyConverter.java index 832e7705f..b4b08ddce 100644 --- a/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/LayerPropertyConverter.java +++ b/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/LayerPropertyConverter.java @@ -11,11 +11,11 @@ import java.util.List; import java.util.Map; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; - import static org.maplibre.maplibregl.Convert.toMap; class LayerPropertyConverter { @@ -44,7 +44,16 @@ static PropertyValue[] interpretSymbolLayerProperties(Object o) { properties.add(PropertyFactory.iconHaloBlur(expression)); break; case "icon-translate": - properties.add(PropertyFactory.iconTranslate(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.iconTranslate(floatArray)); + } else { + properties.add(PropertyFactory.iconTranslate(expression)); + } + } else { + properties.add(PropertyFactory.iconTranslate(expression)); + } break; case "icon-translate-anchor": properties.add(PropertyFactory.iconTranslateAnchor(expression)); @@ -65,7 +74,16 @@ static PropertyValue[] interpretSymbolLayerProperties(Object o) { properties.add(PropertyFactory.textHaloBlur(expression)); break; case "text-translate": - properties.add(PropertyFactory.textTranslate(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.textTranslate(floatArray)); + } else { + properties.add(PropertyFactory.textTranslate(expression)); + } + } else { + properties.add(PropertyFactory.textTranslate(expression)); + } break; case "text-translate-anchor": properties.add(PropertyFactory.textTranslateAnchor(expression)); @@ -104,12 +122,21 @@ static PropertyValue[] interpretSymbolLayerProperties(Object o) { properties.add(PropertyFactory.iconTextFit(expression)); break; case "icon-text-fit-padding": - properties.add(PropertyFactory.iconTextFitPadding(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.iconTextFitPadding(floatArray)); + } else { + properties.add(PropertyFactory.iconTextFitPadding(expression)); + } + } else { + properties.add(PropertyFactory.iconTextFitPadding(expression)); + } break; case "icon-image": - if(jsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()){ + if (jsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()) { properties.add(PropertyFactory.iconImage(jsonElement.getAsString())); - }else{ + } else { properties.add(PropertyFactory.iconImage(expression)); } break; @@ -123,7 +150,16 @@ static PropertyValue[] interpretSymbolLayerProperties(Object o) { properties.add(PropertyFactory.iconKeepUpright(expression)); break; case "icon-offset": - properties.add(PropertyFactory.iconOffset(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.iconOffset(floatArray)); + } else { + properties.add(PropertyFactory.iconOffset(expression)); + } + } else { + properties.add(PropertyFactory.iconOffset(expression)); + } break; case "icon-anchor": properties.add(PropertyFactory.iconAnchor(expression)); @@ -186,7 +222,16 @@ static PropertyValue[] interpretSymbolLayerProperties(Object o) { properties.add(PropertyFactory.textTransform(expression)); break; case "text-offset": - properties.add(PropertyFactory.textOffset(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.textOffset(floatArray)); + } else { + properties.add(PropertyFactory.textOffset(expression)); + } + } else { + properties.add(PropertyFactory.textOffset(expression)); + } break; case "text-allow-overlap": properties.add(PropertyFactory.textAllowOverlap(expression)); @@ -230,7 +275,16 @@ static PropertyValue[] interpretCircleLayerProperties(Object o) { properties.add(PropertyFactory.circleOpacity(expression)); break; case "circle-translate": - properties.add(PropertyFactory.circleTranslate(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.circleTranslate(floatArray)); + } else { + properties.add(PropertyFactory.circleTranslate(expression)); + } + } else { + properties.add(PropertyFactory.circleTranslate(expression)); + } break; case "circle-translate-anchor": properties.add(PropertyFactory.circleTranslateAnchor(expression)); @@ -280,7 +334,16 @@ static PropertyValue[] interpretLineLayerProperties(Object o) { properties.add(PropertyFactory.lineColor(expression)); break; case "line-translate": - properties.add(PropertyFactory.lineTranslate(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.lineTranslate(floatArray)); + } else { + properties.add(PropertyFactory.lineTranslate(expression)); + } + } else { + properties.add(PropertyFactory.lineTranslate(expression)); + } break; case "line-translate-anchor": properties.add(PropertyFactory.lineTranslateAnchor(expression)); @@ -298,7 +361,16 @@ static PropertyValue[] interpretLineLayerProperties(Object o) { properties.add(PropertyFactory.lineBlur(expression)); break; case "line-dasharray": - properties.add(PropertyFactory.lineDasharray(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.lineDasharray(floatArray)); + } else { + properties.add(PropertyFactory.lineDasharray(expression)); + } + } else { + properties.add(PropertyFactory.lineDasharray(expression)); + } break; case "line-pattern": properties.add(PropertyFactory.linePattern(expression)); @@ -354,7 +426,16 @@ static PropertyValue[] interpretFillLayerProperties(Object o) { properties.add(PropertyFactory.fillOutlineColor(expression)); break; case "fill-translate": - properties.add(PropertyFactory.fillTranslate(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.fillTranslate(floatArray)); + } else { + properties.add(PropertyFactory.fillTranslate(expression)); + } + } else { + properties.add(PropertyFactory.fillTranslate(expression)); + } break; case "fill-translate-anchor": properties.add(PropertyFactory.fillTranslateAnchor(expression)); @@ -392,7 +473,16 @@ static PropertyValue[] interpretFillExtrusionLayerProperties(Object o) { properties.add(PropertyFactory.fillExtrusionColor(expression)); break; case "fill-extrusion-translate": - properties.add(PropertyFactory.fillExtrusionTranslate(expression)); + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.fillExtrusionTranslate(floatArray)); + } else { + properties.add(PropertyFactory.fillExtrusionTranslate(expression)); + } + } else { + properties.add(PropertyFactory.fillExtrusionTranslate(expression)); + } break; case "fill-extrusion-translate-anchor": properties.add(PropertyFactory.fillExtrusionTranslateAnchor(expression)); @@ -537,4 +627,21 @@ static PropertyValue[] interpretHeatmapLayerProperties(Object o) { return properties.toArray(new PropertyValue[properties.size()]); } + private static boolean isNumber(JsonElement element) { + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber(); + } + + private static Float[] convertJsonToFloatArray(JsonElement jsonElement) { + final JsonArray jsonArray = jsonElement.getAsJsonArray(); + Float[] floatArray = new Float[jsonArray.size()]; + + for (int i = 0; i < jsonArray.size(); i++) { + if (jsonArray.get(i).isJsonPrimitive() && jsonArray.get(i).getAsJsonPrimitive().isNumber()) { + floatArray[i] = jsonArray.get(i).getAsFloat(); + } else { + return null; + } + } + return floatArray; + } } \ No newline at end of file diff --git a/scripts/lib/generate.dart b/scripts/lib/generate.dart index 9879f102c..bb7c895b5 100644 --- a/scripts/lib/generate.dart +++ b/scripts/lib/generate.dart @@ -103,9 +103,14 @@ List> buildStyleProperties( Map buildStyleProperty( String key, Map value) { + final typeDart = dartTypeMappingTable[value["type"]]; + final nestedTypeDart = dartTypeMappingTable[value["value"]] ?? + dartTypeMappingTable[value["value"]?["type"]]; final camelCase = ReCase(key).camelCase; + return { 'value': key, + 'isFloatArrayProperty': typeDart == "List" && nestedTypeDart == "double", 'isVisibilityProperty': key == "visibility", 'requiresLiteral': key == "icon-image", 'isIosAsCamelCase': renamedIosProperties.containsKey(camelCase), diff --git a/scripts/templates/LayerPropertyConverter.java.template b/scripts/templates/LayerPropertyConverter.java.template index 4c8eaad8a..8b0c1236d 100644 --- a/scripts/templates/LayerPropertyConverter.java.template +++ b/scripts/templates/LayerPropertyConverter.java.template @@ -11,11 +11,11 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; - import static org.maplibre.maplibregl.Convert.toMap; class LayerPropertyConverter { @@ -30,22 +30,39 @@ class LayerPropertyConverter { Expression expression = Expression.Converter.convert(jsonElement); switch (entry.getKey()) { {{#paint_properties}} + {{^isFloatArrayProperty}} case "{{value}}": properties.add(PropertyFactory.{{valueAsCamelCase}}(expression)); + {{/isFloatArrayProperty}} + {{#isFloatArrayProperty}} + case "{{value}}": + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.{{valueAsCamelCase}}(floatArray)); + } else { + properties.add(PropertyFactory.{{valueAsCamelCase}}(expression)); + } + } else { + properties.add(PropertyFactory.{{valueAsCamelCase}}(expression)); + } + {{/isFloatArrayProperty}} break; {{/paint_properties}} {{#layout_properties}} + {{^isFloatArrayProperty}} {{^isVisibilityProperty}} {{^requiresLiteral}} case "{{value}}": properties.add(PropertyFactory.{{valueAsCamelCase}}(expression)); {{/requiresLiteral}} {{/isVisibilityProperty}} + {{/isFloatArrayProperty}} {{#requiresLiteral}} case "{{value}}": - if(jsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()){ + if (jsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()) { properties.add(PropertyFactory.iconImage(jsonElement.getAsString())); - }else{ + } else { properties.add(PropertyFactory.iconImage(expression)); } {{/requiresLiteral}} @@ -53,6 +70,19 @@ class LayerPropertyConverter { case "{{value}}": properties.add(PropertyFactory.{{valueAsCamelCase}}(entry.getValue().substring(1, entry.getValue().length() - 1))); {{/isVisibilityProperty}} + {{#isFloatArrayProperty}} + case "{{value}}": + if (jsonElement.isJsonArray()) { + final Float[] floatArray = convertJsonToFloatArray(jsonElement); + if (floatArray != null) { + properties.add(PropertyFactory.{{valueAsCamelCase}}(floatArray)); + } else { + properties.add(PropertyFactory.{{valueAsCamelCase}}(expression)); + } + } else { + properties.add(PropertyFactory.{{valueAsCamelCase}}(expression)); + } + {{/isFloatArrayProperty}} break; {{/layout_properties}} default: @@ -64,4 +94,21 @@ class LayerPropertyConverter { } {{/layerTypes}} + private static boolean isNumber(JsonElement element) { + return element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber(); + } + + private static Float[] convertJsonToFloatArray(JsonElement jsonElement) { + final JsonArray jsonArray = jsonElement.getAsJsonArray(); + Float[] floatArray = new Float[jsonArray.size()]; + + for (int i = 0; i < jsonArray.size(); i++) { + if (jsonArray.get(i).isJsonPrimitive() && jsonArray.get(i).getAsJsonPrimitive().isNumber()) { + floatArray[i] = jsonArray.get(i).getAsFloat(); + } else { + return null; + } + } + return floatArray; + } } \ No newline at end of file diff --git a/scripts/templates/LayerPropertyConverter.swift.template b/scripts/templates/LayerPropertyConverter.swift.template index ae000533e..b452b0e47 100644 --- a/scripts/templates/LayerPropertyConverter.swift.template +++ b/scripts/templates/LayerPropertyConverter.swift.template @@ -69,17 +69,18 @@ class LayerPropertyConverter { } } return NSExpression.init(mglJSONObject: json) - } else if vector.count == 2, let x = vector.first as? Double, let y = vector.last as? Double { - if isOffset || isTranslate { - // this is required because NSExpression.init(mglJSONObject: json) fails to create - // a proper Expression if the data of an array is destined for a CGVector - return NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: x, dy: y))) - } - // this is required because NSExpression.init(mglJSONObject: json) fails to create - // a proper Expression if the data is an array of double - return NSExpression(forConstantValue: [NSNumber(value: x), NSNumber(value: y)]) } } + // checks on the value of properties that are arrays + } else if offset.count == 2, let x = offset.first as? Double, let y = offset.last as? Double { + if isOffset || isTranslate { + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data of an array is destined for a CGVector + return NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: x, dy: y))) + } + // this is required because NSExpression.init(mglJSONObject: json) fails to create + // a proper Expression if the data is an array of double + return NSExpression(forConstantValue: [NSNumber(value: x), NSNumber(value: y)]) } }