Skip to content

Commit 6464cc9

Browse files
authored
Get Flutter asset path in application bundle (#608)
- Provide correct path for local asset in application bundle for url with "asset" scheme
1 parent 776f68b commit 6464cc9

33 files changed

+198
-71
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### main
2+
3+
* Support local assets for 3D puck and `ModelLayer`. To use a local assets, please specify it with `asset://` scheme in the uri.
4+
15
### 2.1.0
26

37
* Add ModelLayer API.

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/LocationComponentController.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import com.mapbox.maps.mapbox_maps.pigeons.*
88
import com.mapbox.maps.plugin.locationcomponent.createDefault2DPuck
99
import com.mapbox.maps.plugin.locationcomponent.location
1010

11-
class LocationComponentController(private val mapView: MapView, private val context: Context) :
12-
_LocationComponentSettingsInterface {
11+
class LocationComponentController(
12+
private val mapView: MapView,
13+
private val context: Context
14+
) : _LocationComponentSettingsInterface {
1315
override fun getSettings(): LocationComponentSettings = mapView.location.toFLT(context)
1416

1517
override fun updateSettings(settings: LocationComponentSettings, useDefaultPuck2DIfNeeded: Boolean) {

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/MapboxMapFactory.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ import com.mapbox.maps.Style
1818
import com.mapbox.maps.ViewportMode
1919
import com.mapbox.maps.applyDefaultParams
2020
import com.mapbox.maps.mapbox_maps.mapping.turf.PointDecoder
21+
import io.flutter.embedding.engine.plugins.FlutterPlugin
2122
import io.flutter.plugin.common.BinaryMessenger
2223
import io.flutter.plugin.common.StandardMessageCodec
2324
import io.flutter.plugin.platform.PlatformView
2425
import io.flutter.plugin.platform.PlatformViewFactory
2526

2627
class MapboxMapFactory(
2728
private val messenger: BinaryMessenger,
29+
private val flutterAssets: FlutterPlugin.FlutterAssets,
2830
private val lifecycleProvider: MapboxMapsPlugin.LifecycleProvider
2931
) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
3032

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/MapboxMapsPlugin.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.mapbox.maps.mapbox_maps.pigeons._SnapshotterInstanceManager
1212
import com.mapbox.maps.mapbox_maps.pigeons._TileStoreInstanceManager
1313
import com.mapbox.maps.mapbox_maps.snapshot.SnapshotterInstanceManager
1414
import io.flutter.embedding.engine.plugins.FlutterPlugin
15+
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterAssets
1516
import io.flutter.embedding.engine.plugins.activity.ActivityAware
1617
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
1718
import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter
@@ -28,19 +29,19 @@ class MapboxMapsPlugin : FlutterPlugin, ActivityAware {
2829
"plugins.flutter.io/mapbox_maps",
2930
MapboxMapFactory(
3031
flutterPluginBinding.binaryMessenger,
32+
flutterPluginBinding.flutterAssets,
3133
object : LifecycleProvider {
3234
override fun getLifecycle(): Lifecycle? {
3335
return lifecycle
3436
}
3537
}
3638
)
3739
)
38-
39-
setupStaticChannels(flutterPluginBinding.applicationContext, flutterPluginBinding.binaryMessenger)
40+
setupStaticChannels(flutterPluginBinding.applicationContext, flutterPluginBinding.binaryMessenger, flutterPluginBinding.flutterAssets)
4041
}
4142

42-
private fun setupStaticChannels(context: Context, binaryMessenger: BinaryMessenger) {
43-
val optionsController = MapboxOptionsController()
43+
private fun setupStaticChannels(context: Context, binaryMessenger: BinaryMessenger, flutterAssets: FlutterAssets) {
44+
val optionsController = MapboxOptionsController(flutterAssets)
4445
val snapshotterInstanceManager = SnapshotterInstanceManager(context, binaryMessenger)
4546
val offlineMapInstanceManager = OfflineMapInstanceManager(context, binaryMessenger)
4647
val offlineSwitch = OfflineSwitch()

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/MapboxOptionsController.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ import com.mapbox.common.SettingsServiceFactory
77
import com.mapbox.common.SettingsServiceStorageType
88
import com.mapbox.maps.MapboxMapsOptions
99
import com.mapbox.maps.mapbox_maps.pigeons.*
10+
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterAssets
1011

11-
class MapboxOptionsController : _MapboxMapsOptions, _MapboxOptions {
12+
class MapboxOptionsController(
13+
private val flutterAssets: FlutterAssets
14+
) : _MapboxMapsOptions, _MapboxOptions {
1215
private val settingsService = SettingsServiceFactory.getInstance(SettingsServiceStorageType.PERSISTENT)
1316

1417
override fun getAccessToken(): String {
@@ -39,6 +42,10 @@ class MapboxOptionsController : _MapboxMapsOptions, _MapboxOptions {
3942
return ""
4043
}
4144

45+
override fun getFlutterAssetPath(flutterAssetUri: String?): String? {
46+
return flutterAssetUri?.replace("""^asset://(.+)""".toRegex(), "asset://${flutterAssets.getAssetFilePathBySubpath("$1")}")
47+
}
48+
4249
override fun setAssetPath(path: String) {
4350
// ignored on Android
4451
}

android/src/main/kotlin/com/mapbox/maps/mapbox_maps/pigeons/MapInterfaces.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4332,6 +4332,7 @@ interface _MapboxMapsOptions {
43324332
fun setDataPath(path: String)
43334333
fun getAssetPath(): String
43344334
fun setAssetPath(path: String)
4335+
fun getFlutterAssetPath(flutterAssetUri: String?): String?
43354336
fun getTileStoreUsageMode(): TileStoreUsageMode
43364337
fun setTileStoreUsageMode(mode: TileStoreUsageMode)
43374338
fun getWorldview(): String?
@@ -4453,6 +4454,24 @@ interface _MapboxMapsOptions {
44534454
channel.setMessageHandler(null)
44544455
}
44554456
}
4457+
run {
4458+
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._MapboxMapsOptions.getFlutterAssetPath$separatedMessageChannelSuffix", codec)
4459+
if (api != null) {
4460+
channel.setMessageHandler { message, reply ->
4461+
val args = message as List<Any?>
4462+
val flutterAssetUriArg = args[0] as String?
4463+
var wrapped: List<Any?>
4464+
try {
4465+
wrapped = listOf<Any?>(api.getFlutterAssetPath(flutterAssetUriArg))
4466+
} catch (exception: Throwable) {
4467+
wrapped = wrapError(exception)
4468+
}
4469+
reply.reply(wrapped)
4470+
}
4471+
} else {
4472+
channel.setMessageHandler(null)
4473+
}
4474+
}
44564475
run {
44574476
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.mapbox_maps_flutter._MapboxMapsOptions.getTileStoreUsageMode$separatedMessageChannelSuffix", codec)
44584477
if (api != null) {

example/assets/sportcar.glb

1.18 MB
Binary file not shown.

example/integration_test/location_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ void main() {
115115
modelTranslation: [0.0, 1.0, 2.0],
116116
modelScaleExpression: expression)));
117117

118-
location.updateSettings(settings);
118+
await location.updateSettings(settings);
119119

120120
final updatedSettings = await location.getSettings();
121121
expect(updatedSettings.enabled, settings.enabled);

example/lib/location.dart

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:flutter/cupertino.dart';
12
import 'package:flutter/material.dart';
23
import 'package:flutter/services.dart';
34
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart';
@@ -180,9 +181,9 @@ class LocationPageBodyState extends State<LocationPageBody> {
180181
);
181182
}
182183

183-
Widget _switchLocationPuck3D() {
184+
Widget _switchLocationPuck3D_duck() {
184185
return TextButton(
185-
child: Text('switch to 3d puck'),
186+
child: Text('switch to 3d puck with duck model'),
186187
onPressed: () {
187188
mapboxMap?.location.updateSettings(LocationComponentSettings(
188189
locationPuck: LocationPuck(
@@ -194,6 +195,19 @@ class LocationPageBodyState extends State<LocationPageBody> {
194195
);
195196
}
196197

198+
Widget _switchLocationPuck3D_car() {
199+
return TextButton(
200+
child: Text('switch to 3d puck with car model'),
201+
onPressed: () {
202+
mapboxMap?.location.updateSettings(LocationComponentSettings(
203+
locationPuck: LocationPuck(
204+
locationPuck3D: LocationPuck3D(
205+
modelUri: "asset://assets/sportcar.glb",
206+
modelScale: [_puckScale, _puckScale, _puckScale]))));
207+
},
208+
);
209+
}
210+
197211
Widget _switchPuckScale() {
198212
return TextButton(
199213
child: Text('scale 3d puck'),
@@ -262,7 +276,8 @@ class LocationPageBodyState extends State<LocationPageBody> {
262276
_show(),
263277
_hide(),
264278
_switchLocationPuck2D(),
265-
_switchLocationPuck3D(),
279+
_switchLocationPuck3D_duck(),
280+
_switchLocationPuck3D_car(),
266281
_switchPuckScale(),
267282
_showBearing(),
268283
_hideBearing(),

example/lib/model_layer.dart

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,30 @@ class _ModelLayerState extends State<ModelLayerWidget> {
5858
throw Exception("MapboxMap is not ready yet");
5959
}
6060

61-
var modelId = "model-test-id";
62-
var uri =
61+
final buggyModelId = "model-test-id";
62+
final buggyModelUri =
6363
"https://github.com/KhronosGroup/glTF-Sample-Models/raw/d7a3cc8e51d7c573771ae77a57f16b0662a905c6/2.0/Buggy/glTF/Buggy.gltf";
64-
await mapboxMap?.style.addStyleModel(modelId, uri);
64+
await mapboxMap?.style.addStyleModel(buggyModelId, buggyModelUri);
65+
66+
final carModelId = "model-car-id";
67+
final carModelUri = "asset://assets/sportcar.glb";
68+
await mapboxMap?.style.addStyleModel(carModelId, carModelUri);
6569

6670
await mapboxMap?.style
6771
.addSource(GeoJsonSource(id: "sourceId", data: json.encode(value)));
6872

69-
var modelLayer = ModelLayer(id: "modelLayer", sourceId: "sourceId");
70-
modelLayer.modelId = modelId;
73+
var modelLayer = ModelLayer(id: "modelLayer-buggy", sourceId: "sourceId");
74+
modelLayer.modelId = buggyModelId;
7175
modelLayer.modelScale = [0.15, 0.15, 0.15];
7276
modelLayer.modelRotation = [0, 0, 90];
7377
modelLayer.modelType = ModelType.COMMON_3D;
7478
mapboxMap?.style.addLayer(modelLayer);
79+
80+
var modelLayer1 = ModelLayer(id: "modelLayer-car", sourceId: "sourceId");
81+
modelLayer1.modelId = carModelId;
82+
modelLayer1.modelScale = [0.15, 0.15, 0.15];
83+
modelLayer1.modelRotation = [0, 0, 90];
84+
modelLayer1.modelType = ModelType.COMMON_3D;
85+
mapboxMap?.style.addLayer(modelLayer1);
7586
}
7687
}

0 commit comments

Comments
 (0)