Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion maplibre_gl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ constructor. The following formats are supported:
3. Passing the style as a local file. create an JSON file in app directory (e.g.
ApplicationDocumentsDirectory). Set the style string to the absolute path of
this JSON file.
4. Passing the raw JSON of the map style. This is only supported on Android.
4. Passing the raw JSON of the map style.

### Tile sources requiring an API key

Expand Down
1 change: 1 addition & 0 deletions maplibre_gl/ios/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ Icon?

Package.resolved
.swiftpm
.build
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,49 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
return mapView
}

private static func createMapView(
args: Any?,
frame: CGRect,
registrar: FlutterPluginRegistrar
) -> MLNMapView {
if let args = args as? [String: Any],
let styleString = args["styleString"] as? String
{
if Self.styleStringIsJSON(styleString) {
return MLNMapView(frame: frame, styleJSON: styleString)
}

if let url = Self.styleStringAsURL(
styleString,
registrar: registrar
) {
return MLNMapView(frame: frame, styleURL: url)
}
}

// Fallback to default if neither JSON nor valid URL
NSLog(
"""
Warning: MapLibreMapController - Initializing map view with \
default style. This capability will be removed in a future release.
"""
)
// https://github.com/maplibre/maplibre-native/issues/709
return MLNMapView(frame: frame)
}

init(
withFrame frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?,
registrar: FlutterPluginRegistrar
) {
mapView = MLNMapView(frame: frame)
mapView = Self.createMapView(
args: args,
frame: frame,
registrar: registrar
)

mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.logoView.isHidden = true
self.registrar = registrar
Expand Down Expand Up @@ -1778,34 +1814,54 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
mapView.maximumZoomLevel = max
}

func setStyleString(styleString: String) {
// Check if json, url, absolute path or asset path:
private static func styleStringIsJSON(_ styleString: String) -> Bool {
return styleString.hasPrefix("{") || styleString.hasPrefix("[")
}

private static func styleStringAsURL(
_ styleString: String,
registrar: FlutterPluginRegistrar
) -> URL? {
if styleString.isEmpty {
NSLog("setStyleString - string empty")
} else if styleString.hasPrefix("{") || styleString.hasPrefix("[") {
// Currently the iOS MapLibre SDK does not have a builder for json.
NSLog("setStyleString - JSON style currently not supported")
NSLog("styleStringAsURL - style string is empty, ignoring")
return nil
} else if styleStringIsJSON(styleString) {
return nil
} else if styleString.hasPrefix("/") {
// Absolute path
mapView.styleURL = URL(fileURLWithPath: styleString, isDirectory: false)
} else if
!styleString.hasPrefix("http://"),
return URL(fileURLWithPath: styleString, isDirectory: false)
} 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)

return URL(string: assetPath, relativeTo: Bundle.main.resourceURL)
} else if (styleString.hasPrefix("file://")) {
if let path = Bundle.main.path(forResource: styleString.deletingPrefix("file://"), ofType: "json") {
let url = URL(fileURLWithPath: path)
mapView.styleURL = url
if let path = Bundle.main.path(
forResource: styleString.deletingPrefix("file://"),
ofType: "json"
) {
return URL(fileURLWithPath: path)
} else {
NSLog("setStyleString - Path not found")
NSLog(
"styleStringAsURL - path not found: \(styleString), ignoring"
)
return nil
}
} else {
mapView.styleURL = URL(string: styleString)
return URL(string: styleString)
}
}

func setStyleString(styleString: String) {
if Self.styleStringIsJSON(styleString) {
mapView.styleJSON = styleString;
} else if let url = Self.styleStringAsURL(
styleString,
registrar: registrar
) {
mapView.styleURL = url;
}
}

Expand Down
2 changes: 1 addition & 1 deletion maplibre_gl/lib/src/maplibre_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class MapLibreMap extends StatefulWidget {
/// 1. Passing the URL of the map style. This should be a custom map style served remotely using a URL that start with 'http(s)://'
/// 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 style as a local file. create an JSON file in app directory (e.g. ApplicationDocumentsDirectory). Set the style string to the absolute path of this JSON file.
/// 4. Passing the raw JSON of the map style. This is only supported on Android.
/// 4. Passing the raw JSON of the map style.
final String styleString;

/// Preferred bounds for the camera zoom level.
Expand Down
1 change: 1 addition & 0 deletions maplibre_gl_web/lib/maplibre_gl_web.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
library maplibre_gl_web;

import 'dart:async';
import 'dart:convert';

// FIXED HERE: https://github.com/dart-lang/linter/pull/1985
// ignore_for_file: avoid_web_libraries_in_flutter
Expand Down
8 changes: 7 additions & 1 deletion maplibre_gl_web/lib/src/convert.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ class Convert {
sink.setCompassEnabled(options['compassEnabled']);
}
if (options.containsKey('styleString')) {
sink.setStyleString(options['styleString']);
final styleString = options['styleString'];
if (styleString is String &&
(styleString.startsWith('{') || styleString.startsWith('['))) {
sink.setStyle(jsonDecode(styleString));
} else {
sink.setStyle(styleString);
}
}
if (options.containsKey('minMaxZoomPreference')) {
sink.setMinMaxZoomPreference(options['minMaxZoomPreference'][0],
Expand Down
5 changes: 2 additions & 3 deletions maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ class MapLibreMapController extends MapLibrePlatform
_map = MapLibreMap(
MapOptions(
container: _mapElement,
style: _creationParams['styleString'],
center: LngLat(camera['target'][1], camera['target'][0]),
zoom: camera['zoom'],
bearing: camera['bearing'],
Expand Down Expand Up @@ -697,7 +696,7 @@ class MapLibreMapController extends MapLibrePlatform
}

@override
void setStyleString(String? styleString) {
void setStyle(dynamic styleObject) {
//remove old mouseenter callbacks to avoid multicalling
for (final layerId in _interactiveFeatureLayerIds) {
_map.off('mouseenter', layerId, _onMouseEnterFeature);
Expand All @@ -707,7 +706,7 @@ class MapLibreMapController extends MapLibrePlatform
}
_interactiveFeatureLayerIds.clear();

_map.setStyle(styleString, {'diff': false});
_map.setStyle(styleObject, {'diff': false});
}

@override
Expand Down
2 changes: 1 addition & 1 deletion maplibre_gl_web/lib/src/options_sink.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ abstract class MapLibreMapOptionsSink {
void setCompassEnabled(bool compassEnabled);

// TODO: styleString is not actually a part of options. consider moving
void setStyleString(String? styleString);
void setStyle(dynamic styleObject);

void setMinMaxZoomPreference(num? min, num? max);

Expand Down
2 changes: 1 addition & 1 deletion maplibre_gl_web/lib/src/ui/map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ class MapLibreMap extends Camera {
/// @returns {MapLibreMap} `this`
/// @see [Change a map's style](https://maplibre.org/maplibre-gl-js/docs/examples/setstyle/)
MapLibreMap setStyle(dynamic style, [dynamic options]) =>
MapLibreMap.fromJsObject(jsObject.setStyle(style, jsify(options)));
MapLibreMap.fromJsObject(jsObject.setStyle(jsify(style), jsify(options)));

/// Returns the map's MapLibre style object, which can be used to recreate the map's style.
///
Expand Down