Skip to content

Commit 1e3d478

Browse files
RD-1146: Add MTLineLayer Bridge (#55)
1 parent 734ab4d commit 1e3d478

File tree

23 files changed

+312
-60
lines changed

23 files changed

+312
-60
lines changed

.github/copilot-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ MUST wait for `ON_READY` before mutating style or layers. Changing the reference
300300
- Commands (MUST run):
301301
- `./gradlew ktlintFormat`
302302
- `./gradlew ktlintCheck`
303+
- `./gradlew test`
303304
- Add or update unit tests as required (encoding, clamping, `toJS()` contract), but leave full execution to the user/CI.
304305
- Prefer small, focused tests near the code you change; avoid introducing unrelated tests.
305306

Examples/MapTilerMobileDemo/.idea/deploymentTargetSelector.xml

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Examples/MapTilerMobileDemo/app/src/main/java/com/maptilerdemo/maptilermobiledemo/HomeScreen.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import com.maptiler.maptilersdk.map.style.MTMapReferenceStyle
3434
import com.maptiler.maptilersdk.map.style.MTStyleError
3535
import com.maptiler.maptilersdk.map.style.layer.MTLayerType
3636
import com.maptiler.maptilersdk.map.style.layer.fill.MTFillLayer
37+
import com.maptiler.maptilersdk.map.style.layer.line.MTLineLayer
3738
import com.maptiler.maptilersdk.map.style.layer.symbol.MTSymbolLayer
3839
import com.maptiler.maptilersdk.map.style.source.MTVectorTileSource
3940
import com.maptiler.maptilersdk.map.types.MTData
@@ -85,6 +86,15 @@ fun HomeScreen(
8586
} catch (error: MTStyleError) {
8687
Log.e("MTStyleError", "Fill Layer already exists.")
8788
}
89+
} else if (type == MTLayerType.LINE) {
90+
try {
91+
val layer = MTLineLayer("lineLayer", "openmapsource")
92+
layer.color = Color.BLUE
93+
layer.sourceLayer = "water"
94+
mapController.controller.style?.addLayer(layer)
95+
} catch (error: MTStyleError) {
96+
Log.e("MTStyleError", "Line Layer already exists.")
97+
}
8898
}
8999
},
90100
modifier =

Examples/MapTilerMobileDemo/app/src/main/java/com/maptilerdemo/maptilermobiledemo/LayerControl.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,16 @@ fun LayerControl(
6464
text = { Text("Symbol") },
6565
onClick = { onSelect(MTLayerType.SYMBOL) },
6666
)
67+
6768
DropdownMenuItem(
6869
text = { Text("Fill") },
6970
onClick = { onSelect(MTLayerType.FILL) },
7071
)
72+
73+
DropdownMenuItem(
74+
text = { Text("Line") },
75+
onClick = { onSelect(MTLayerType.LINE) },
76+
)
7177
}
7278
}
7379
}

MapTilerSDK/src/main/java/com/maptiler/maptilersdk/MTConfig.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ object MTConfig {
4949
* Boolean indicating whether telemetry is enabled.
5050
*
5151
* The telemetry is very valuable to the team at MapTiler because it shares information about
52-
* where to add the extra effort. It also helps spotting some incompatibility issues that may
53-
* arise between the SDK and a specific version of a module. It consist in sending the SDK version,
52+
* where to add extra effort. It also helps spot some incompatibility issues that may
53+
* arise between the SDK and a specific version of a module. It consists of sending the SDK version,
5454
* API Key, MapTiler session ID, if tile caching is enabled, if language specified at initialization,
5555
* if terrain is activated at initialization, if globe projection is activated at initialization.
5656
* Defaults to true.

MapTilerSDK/src/main/java/com/maptiler/maptilersdk/MTUnit.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ package com.maptiler.maptilersdk
1111
*/
1212
enum class MTUnit {
1313
/**
14-
* Imperical units.
14+
* Imperial units.
1515
*/
1616
IMPERIAL,
1717

MapTilerSDK/src/main/java/com/maptiler/maptilersdk/commands/annotations/AddMarker.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,31 @@ internal data class AddMarker(
6464
}
6565

6666
if (marker.icon != null) {
67+
val encoded = ImageHelper.encodeImageWithMime(marker.icon!!)
6768
iconInit = """
6869
var icon${marker.identifier} = new Image();
69-
icon${marker.identifier}.src = 'data:image/png;base64,${ImageHelper.encodeImage(marker.icon!!)}';
70+
icon${marker.identifier}.src = 'data:${encoded.mimeType};base64,${encoded.base64}';
7071
"""
7172

7273
iconData = "element: icon${marker.identifier}"
7374
}
7475

76+
val markerOptions =
77+
buildString {
78+
append("color: '$color'")
79+
append(",\n draggable: $draggable")
80+
if (iconData.isNotBlank()) {
81+
append(",\n $iconData")
82+
}
83+
}
84+
7585
return """
7686
$popupAttachment
7787
7888
$iconInit
7989
8090
const ${marker.identifier} = new maptilersdk.Marker({
81-
color: '$color',
82-
draggable: $draggable,
83-
$iconData
91+
$markerOptions
8492
});
8593
8694
$popupString

MapTilerSDK/src/main/java/com/maptiler/maptilersdk/commands/navigation/PanBy.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,22 @@ import com.maptiler.maptilersdk.bridge.MTBridge
1111
import com.maptiler.maptilersdk.bridge.MTCommand
1212
import com.maptiler.maptilersdk.helpers.JsonConfig
1313
import com.maptiler.maptilersdk.map.types.MTPoint
14+
import kotlinx.serialization.json.Json
1415

1516
internal data class PanBy(
1617
val offset: MTPoint,
1718
) : MTCommand {
1819
override val isPrimitiveReturnType: Boolean = false
1920

2021
override fun toJS(): String {
21-
val offsetString: JSString = JsonConfig.json.encodeToString(offset)
22+
// Pretty-printed JSON to match expected JS contract in tests
23+
val prettyJson =
24+
Json {
25+
prettyPrint = true
26+
encodeDefaults = JsonConfig.json.configuration.encodeDefaults
27+
explicitNulls = JsonConfig.json.configuration.explicitNulls
28+
}
29+
val offsetString: JSString = prettyJson.encodeToString(offset)
2230

2331
return "${MTBridge.MAP_OBJECT}.panBy($offsetString);"
2432
}

MapTilerSDK/src/main/java/com/maptiler/maptilersdk/commands/navigation/PanTo.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,22 @@ import com.maptiler.maptilersdk.bridge.MTBridge
1111
import com.maptiler.maptilersdk.bridge.MTCommand
1212
import com.maptiler.maptilersdk.helpers.JsonConfig
1313
import com.maptiler.maptilersdk.map.LngLat
14+
import kotlinx.serialization.json.Json
1415

1516
internal data class PanTo(
1617
val coordinates: LngLat,
1718
) : MTCommand {
1819
override val isPrimitiveReturnType: Boolean = false
1920

2021
override fun toJS(): String {
21-
val coordinatesString: JSString = JsonConfig.json.encodeToString(coordinates)
22+
// Pretty-printed JSON to match expected JS contract in tests
23+
val prettyJson =
24+
Json {
25+
prettyPrint = true
26+
encodeDefaults = JsonConfig.json.configuration.encodeDefaults
27+
explicitNulls = JsonConfig.json.configuration.explicitNulls
28+
}
29+
val coordinatesString: JSString = prettyJson.encodeToString(coordinates)
2230

2331
return "${MTBridge.MAP_OBJECT}.panTo($coordinatesString);"
2432
}

MapTilerSDK/src/main/java/com/maptiler/maptilersdk/commands/style/AddLayer.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.maptiler.maptilersdk.helpers.ImageHelper
1313
import com.maptiler.maptilersdk.helpers.JsonConfig
1414
import com.maptiler.maptilersdk.map.style.layer.MTLayer
1515
import com.maptiler.maptilersdk.map.style.layer.fill.MTFillLayer
16+
import com.maptiler.maptilersdk.map.style.layer.line.MTLineLayer
1617
import com.maptiler.maptilersdk.map.style.layer.symbol.MTSymbolLayer
1718

1819
internal data class AddLayer(
@@ -25,19 +26,23 @@ internal data class AddLayer(
2526
handleSymbolLayer(layer)
2627
} else if (layer is MTFillLayer) {
2728
handleFillLayer(layer)
29+
} else if (layer is MTLineLayer) {
30+
handleLineLayer(layer)
2831
} else {
29-
""
32+
// Fallback to a generic addLayer for any future-supported layer types
33+
val layerString: JSString = JsonConfig.json.encodeToString(layer)
34+
"${MTBridge.MAP_OBJECT}.addLayer($layerString);"
3035
}
3136

3237
private fun handleSymbolLayer(layer: MTSymbolLayer): JSString {
3338
val layerString: JSString = JsonConfig.json.encodeToString(layer)
3439

3540
if (layer.icon != null) {
36-
val encodedImageString = ImageHelper.encodeImage(layer.icon!!)
41+
val encoded = ImageHelper.encodeImageWithMime(layer.icon!!)
3742

3843
val iconString = """
3944
var icon${layer.identifier} = new Image();
40-
icon${layer.identifier}.src = 'data:image/png;base64,$encodedImageString';
45+
icon${layer.identifier}.src = 'data:${encoded.mimeType};base64,${encoded.base64}';
4146
icon${layer.identifier}.onload = function() {
4247
map.addImage('icon${layer.identifier}', icon${layer.identifier})
4348
"""
@@ -50,13 +55,20 @@ internal data class AddLayer(
5055
5156
""".trimIndent()
5257
} else {
53-
return ""
58+
// No icon to register; add the layer directly
59+
return "${MTBridge.MAP_OBJECT}.addLayer($layerString);"
5460
}
5561
}
5662

5763
private fun handleFillLayer(layer: MTFillLayer): JSString {
5864
val layerString: JSString = JsonConfig.json.encodeToString(layer)
5965

60-
return "${MTBridge.MAP_OBJECT}.addLayer($layerString)"
66+
return "${MTBridge.MAP_OBJECT}.addLayer($layerString);"
67+
}
68+
69+
private fun handleLineLayer(layer: MTLineLayer): JSString {
70+
val layerString: JSString = JsonConfig.json.encodeToString(layer)
71+
72+
return "${MTBridge.MAP_OBJECT}.addLayer($layerString);"
6173
}
6274
}

0 commit comments

Comments
 (0)