Skip to content

Commit

Permalink
Set the map style to a local asset in iOS (#306)
Browse files Browse the repository at this point in the history
* Try to load a style from a local asset if styleString does not start with http(s):// or mapbox://

* Add style.json asset for testing.

* Update map_ui so that we can toggle through different map styles.

* Added similar implementation on Android for parity.

* Added some documentation on the usage of map styles.
  • Loading branch information
TimothySealy authored Jun 9, 2020
1 parent e97051b commit d2a4b37
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 4 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ This project is available on [pub.dev](https://pub.dev/packages/mapbox_gl), foll
| Line | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Fill | | | |

## Map Styles

Map styles can be supplied by setting the `styleString` in the `MapOptions`. The following formats are supported:

1. Passing the URL of the map style. This can be one of the built-in map styles, also see `MapboxStyles` or a custom map style served remotely using a URL that start with 'http(s)://' or 'mapbox://'
2. Passing the style as a local asset. Create a JSON file in the `assets` and add a reference in `pubspec.yml`. Set the style string to the relative path for this asset in order to load it into the map.
3. Passing the raw JSON of the map style. This is only supported on Android.

## Offline Sideloading

Support for offline maps is available by *"side loading"* the required map tiles and including them in your `assets` folder.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,14 @@ public void setStyleString(String styleString) {
Log.e(TAG, "setStyleString - string empty or null");
} else if (styleString.startsWith("{") || styleString.startsWith("[")) {
mapboxMap.setStyle(new Style.Builder().fromJson(styleString), onStyleLoadedCallback);
} else if (
!styleString.startsWith("http://") &&
!styleString.startsWith("https://")&&
!styleString.startsWith("mapbox://")) {
// We are assuming that the style will be loaded from an asset here.
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset(styleString);
mapboxMap.setStyle(new Style.Builder().fromUri("asset://" + key), onStyleLoadedCallback);
} else {
mapboxMap.setStyle(new Style.Builder().fromUrl(styleString), onStyleLoadedCallback);
}
Expand Down
36 changes: 36 additions & 0 deletions example/assets/style.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"version": 8,
"name": "Example taken from https://docs.mapbox.com/ios/maps/examples/source-custom-vector/",
"sources": {
"mapillary": {
"type": "vector",
"tiles": [
"https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt"
],
"attribution": "<a href=\"https://www.mapillary.com\" target=\"_blank\">© Mapillary, CC BY</a>",
"maxzoom": 14
}
},
"layers": [{
"id": "background",
"type": "background",
"paint": {
"background-color": "#485E77"
}
},
{
"id": "mapillary-sequences",
"type": "line",
"source": "mapillary",
"source-layer": "mapillary-sequences",
"filter": [
"==",
"$type",
"LineString"
],
"paint": {
"line-color": "#F56745"
}
}
]
}
12 changes: 8 additions & 4 deletions example/lib/map_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ class MapUiBodyState extends State<MapUiBody> {
bool _compassEnabled = true;
CameraTargetBounds _cameraTargetBounds = CameraTargetBounds.unbounded;
MinMaxZoomPreference _minMaxZoomPreference = MinMaxZoomPreference.unbounded;
String _styleString = MapboxStyles.MAPBOX_STREETS;
int _styleStringIndex = 0;
// Style string can a reference to a local or remote resources.
// On Android the raw JSON can also be passed via a styleString, on iOS this is not supported.
List<String> _styleStrings = [MapboxStyles.MAPBOX_STREETS, MapboxStyles.SATELLITE, "assets/style.json"];
List<String> _styleStringLabels = ["MAPBOX_STREETS", "SATELLITE", "LOCAL_ASSET"];
bool _rotateGesturesEnabled = true;
bool _scrollGesturesEnabled = true;
bool _tiltGesturesEnabled = true;
Expand Down Expand Up @@ -131,10 +135,10 @@ class MapUiBodyState extends State<MapUiBody> {

Widget _setStyleToSatellite() {
return FlatButton(
child: Text('change map style to Satellite'),
child: Text('change map style to ${_styleStringLabels[(_styleStringIndex + 1) % _styleStringLabels.length]}'),
onPressed: () {
setState(() {
_styleString = MapboxStyles.SATELLITE;
_styleStringIndex = (_styleStringIndex + 1) % _styleStrings.length;
});
},
);
Expand Down Expand Up @@ -226,7 +230,7 @@ class MapUiBodyState extends State<MapUiBody> {
compassEnabled: _compassEnabled,
cameraTargetBounds: _cameraTargetBounds,
minMaxZoomPreference: _minMaxZoomPreference,
styleString: _styleString,
styleString: _styleStrings[_styleStringIndex],
rotateGesturesEnabled: _rotateGesturesEnabled,
scrollGesturesEnabled: _scrollGesturesEnabled,
tiltGesturesEnabled: _tiltGesturesEnabled,
Expand Down
1 change: 1 addition & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ flutter:
- assets/symbols/custom-icon.png
- assets/symbols/2.0x/custom-icon.png
- assets/symbols/3.0x/custom-icon.png
- assets/style.json

# For details regarding adding assets from package dependencies, see
# https://flutter.io/assets-and-images/#from-packages
Expand Down
7 changes: 7 additions & 0 deletions ios/Classes/MapboxMapController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,13 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma
} else if (styleString.hasPrefix("{") || styleString.hasPrefix("[")) {
// Currently the iOS Mapbox SDK does not have a builder for json.
NSLog("setStyleString - JSON style currently not supported")
} else if (
!styleString.hasPrefix("http://") &&
!styleString.hasPrefix("https://") &&
!styleString.hasPrefix("mapbox://")) {
// We are assuming that the style will be loaded from an asset here.
let assetPath = registrar.lookupKey(forAsset: styleString)
mapView.styleURL = URL(string: assetPath, relativeTo: Bundle.main.resourceURL)
} else {
mapView.styleURL = URL(string: styleString)
}
Expand Down

0 comments on commit d2a4b37

Please sign in to comment.