├── .circleci └── config.yml ├── .fastlane ├── Appfile ├── Fastfile └── Matchfile ├── .gitattributes ├── .github ├── CODEOWNERS ├── PULL_REQUEST_TEMPLATE.md └── dependabot.yml ├── .gitignore ├── .gitmodules ├── .metadata ├── .pubignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── .editorconfig ├── .gitignore ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── kotlin │ └── com │ └── mapbox │ └── maps │ └── mapbox_maps │ ├── Accessors.kt │ ├── AnimationController.kt │ ├── AttributionController.kt │ ├── CameraController.kt │ ├── CompassController.kt │ ├── EventHandler.kt │ ├── Extentions.kt │ ├── GestureController.kt │ ├── InteractionsController.kt │ ├── LocationComponentController.kt │ ├── LoggingController.kt │ ├── LogoController.kt │ ├── MapInterfaceController.kt │ ├── MapProjectionController.kt │ ├── MapboxMapController.kt │ ├── MapboxMapFactory.kt │ ├── MapboxMapsPlugin.kt │ ├── MapboxOptionsController.kt │ ├── PerformanceStatisticsController.kt │ ├── ScaleBarController.kt │ ├── StyleController.kt │ ├── ViewportController.kt │ ├── annotation │ ├── AnnotationController.kt │ ├── CircleAnnotationController.kt │ ├── CircleAnnotationEnumsExtensions.kt │ ├── ControllerDelegate.kt │ ├── PointAnnotationController.kt │ ├── PointAnnotationEnumsExtensions.kt │ ├── PolygonAnnotationController.kt │ ├── PolygonAnnotationEnumsExtensions.kt │ ├── PolylineAnnotationController.kt │ └── PolylineAnnotationEnumsExtensions.kt │ ├── http │ └── CustomHttpServiceInterceptor.kt │ ├── mapping │ ├── AttributionMappings.kt │ ├── CompassMappings.kt │ ├── GesturesMappings.kt │ ├── LocationComponentMappings.kt │ ├── LogoMappings.kt │ ├── OrnamentPositionMapping.kt │ ├── ScaleBarMappings.kt │ └── turf │ │ └── TurfAdapters.kt │ ├── offline │ ├── OfflineController.kt │ ├── OfflineMapInstanceManager.kt │ ├── OfflineSwitch.kt │ └── TileStoreController.kt │ ├── pigeons │ ├── CircleAnnotationMessenger.kt │ ├── GestureListeners.kt │ ├── LogBackend.kt │ ├── MapInterfaces.kt │ ├── OfflineMessenger.kt │ ├── PerformaceStatistics.kt │ ├── PointAnnotationMessenger.kt │ ├── PolygonAnnotationMessenger.kt │ ├── PolylineAnnotationMessenger.kt │ ├── Settings.kt │ ├── SnapshotterMessenger.kt │ └── ViewportInternal.kt │ └── snapshotter │ ├── SnapshotterController.kt │ └── SnapshotterInstanceManager.kt ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── androidTest │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── mapbox │ │ │ │ └── maps │ │ │ │ └── mapbox_maps_example │ │ │ │ └── MainActivityTest.java │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── mapbox │ │ │ │ │ └── maps │ │ │ │ │ └── mapbox_maps_example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ ├── ktlint.gradle │ │ ├── lint.gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ └── settings.gradle ├── assets │ ├── cluster │ │ ├── cluster_count_layer.json │ │ ├── cluster_layer.json │ │ ├── cluster_source.json │ │ └── unclustered_point_layer.json │ ├── featuresetsStyle.json │ ├── fragment_realestate_NY.json │ ├── from_crema_to_council_crest.geojson │ ├── geojson_source_large_points.json │ ├── layer.json │ ├── miami_beach.png │ ├── point_layer.json │ ├── raster_array_layers.json │ ├── sf_airport_route.geojson │ ├── source.json │ ├── sportcar.glb │ ├── style.json │ └── symbols │ │ ├── 2.0x │ │ └── custom-icon.png │ │ ├── 3.0x │ │ └── custom-icon.png │ │ └── custom-icon.png ├── integration_test │ ├── all_test.dart │ ├── animation_test.dart │ ├── annotations │ │ ├── circle_annotation_manager_test.dart │ │ ├── circle_annotation_test.dart │ │ ├── point_annotation_manager_test.dart │ │ ├── point_annotation_test.dart │ │ ├── polygon_annotation_manager_test.dart │ │ ├── polygon_annotation_test.dart │ │ ├── polyline_annotation_manager_test.dart │ │ └── polyline_annotation_test.dart │ ├── attribution_test.dart │ ├── camera_test.dart │ ├── compass_test.dart │ ├── empty_map_widget.dart │ ├── gestures_test.dart │ ├── interactive_features_test.dart │ ├── location_test.dart │ ├── logo_test.dart │ ├── map_interface_test.dart │ ├── offline_test.dart │ ├── projection_test.dart │ ├── scale_bar_test.dart │ ├── snapshotter │ │ └── snapshotter_test.dart │ ├── style │ │ ├── layer │ │ │ ├── background_layer_test.dart │ │ │ ├── circle_layer_test.dart │ │ │ ├── clip_layer_test.dart │ │ │ ├── fill_extrusion_layer_test.dart │ │ │ ├── fill_layer_test.dart │ │ │ ├── heatmap_layer_test.dart │ │ │ ├── hillshade_layer_test.dart │ │ │ ├── line_layer_test.dart │ │ │ ├── location_indicator_layer_test.dart │ │ │ ├── model_layer_test.dart │ │ │ ├── raster_layer_test.dart │ │ │ ├── raster_particle_layer_test.dart │ │ │ ├── sky_layer_test.dart │ │ │ ├── slot_layer_test.dart │ │ │ └── symbol_layer_test.dart │ │ ├── source │ │ │ ├── geojson_source_test.dart │ │ │ ├── image_source_test.dart │ │ │ ├── raster_source_test.dart │ │ │ ├── rasterarray_source_test.dart │ │ │ ├── rasterdem_source_test.dart │ │ │ └── vector_source_test.dart │ │ └── style_test.dart │ ├── utils │ │ └── list_close_to_matcher.dart │ └── viewport_test.dart ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── swiftpm │ │ │ │ └── Package.resolved │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── swiftpm │ │ │ └── Package.resolved │ ├── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ │ └── LaunchImage.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ └── README.md │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h │ └── RunnerTests │ │ └── RunnerTests.m ├── lib │ ├── animated_route_example.dart │ ├── animation_example.dart │ ├── camera_example.dart │ ├── circle_annotations_example.dart │ ├── cluster_example.dart │ ├── custom_header_example.dart │ ├── debug_options_example.dart │ ├── draggable-annotations-example.dart │ ├── edit_polygon_example.dart │ ├── example.dart │ ├── full_map_example.dart │ ├── geojson_line_example.dart │ ├── gestures_example.dart │ ├── image_source_example.dart │ ├── location_example.dart │ ├── main.dart │ ├── map_interface_example.dart │ ├── model_layer_example.dart │ ├── model_layer_interactions_example.dart │ ├── offline_map_example.dart │ ├── ornaments_example.dart │ ├── point_annotations_example.dart │ ├── polygon_annotations_example.dart │ ├── polyline_annotations_example.dart │ ├── projection_example.dart │ ├── simple_map_example.dart │ ├── snapshotter_example.dart │ ├── spinning_globe_example.dart │ ├── standard_style_import_example.dart │ ├── standard_style_interactions_example.dart │ ├── style_example.dart │ ├── tile_json_example.dart │ ├── traffic_layer_example.dart │ ├── traffic_route_line_example.dart │ ├── utils.dart │ ├── vector_tile_source_example.dart │ └── viewport_example.dart ├── pubspec.lock ├── pubspec.yaml └── test_driver │ └── integration_test.dart ├── ios ├── .gitignore ├── mapbox_maps_flutter.podspec └── mapbox_maps_flutter │ ├── .swiftlint.yml │ ├── Package.resolved │ ├── Package.swift │ └── Sources │ └── mapbox_maps_flutter │ └── Classes │ ├── AnimationController.swift │ ├── Annotations │ ├── AnnotationController.swift │ ├── BaseAnnotationMessenger.swift │ ├── CircleAnnotationController.swift │ ├── PointAnnotationController.swift │ ├── PolygonAnnotationController.swift │ └── PolylineAnnotationController.swift │ ├── AnyFlutterStreamHandler.swift │ ├── AttributionController.swift │ ├── CameraController.swift │ ├── CompassController.swift │ ├── CustomHttpServiceInterceptor.swift │ ├── EnumsMapping.swift │ ├── EventHandler.swift │ ├── Extensions.swift │ ├── Generated │ ├── CircleAnnotationMessenger.swift │ ├── GestureListeners.swift │ ├── LogBackend.swift │ ├── MapInterfaces.swift │ ├── OfflineMessenger.swift │ ├── PerformaceStatistics.swift │ ├── PointAnnotationMessenger.swift │ ├── PolygonAnnotationMessenger.swift │ ├── PolylineAnnotationMessenger.swift │ ├── Settings.swift │ ├── SnapshotterMessenger.swift │ └── ViewportInternal.swift │ ├── GesturesController.swift │ ├── InteractionsController.swift │ ├── LocationController.swift │ ├── LoggingController.swift │ ├── LogoController.swift │ ├── MapEvents+JSON.swift │ ├── MapInterfaceController.swift │ ├── MapProjectionController.swift │ ├── MapboxMapController.swift │ ├── MapboxMapFactory.swift │ ├── MapboxMapsPlugin.swift │ ├── MapboxOptionsController.swift │ ├── Offline │ ├── OfflineController.swift │ ├── OfflineMapInstanceManager.swift │ └── TileStoreController.swift │ ├── PerformanceStatisticsController.swift │ ├── ScalebarController.swift │ ├── Snapshotter │ ├── SnapshotterController.swift │ └── SnapshotterInstanceManager.swift │ ├── StyleController.swift │ ├── StyleLights.swift │ ├── TurfAdapters.swift │ ├── Viewport │ ├── States.swift │ ├── Transitions.swift │ └── ViewportController.swift │ └── mapbox_maps_flutter.h ├── lib ├── mapbox_maps_flutter.dart └── src │ ├── annotation │ ├── annotation_manager.dart │ ├── circle_annotation_manager.dart │ ├── point_annotation_manager.dart │ ├── polygon_annotation_manager.dart │ └── polyline_annotation_manager.dart │ ├── callbacks.dart │ ├── cancelable.dart │ ├── deprecated.dart │ ├── events.dart │ ├── extensions.dart │ ├── http │ └── http_service.dart │ ├── location_settings.dart │ ├── log_configuration.dart │ ├── map_events.dart │ ├── map_widget.dart │ ├── mapbox_map.dart │ ├── mapbox_maps_options.dart │ ├── mapbox_maps_platform.dart │ ├── offline │ ├── offline_manager.dart │ ├── offline_messenger.dart │ ├── offline_switch.dart │ └── tile_store.dart │ ├── package_info.dart │ ├── pigeons │ ├── circle_annotation_messenger.dart │ ├── gesture_listeners.dart │ ├── log_backend.dart │ ├── map_interfaces.dart │ ├── performace_statistics.dart │ ├── point_annotation_messenger.dart │ ├── polygon_annotation_messenger.dart │ ├── polyline_annotation_messenger.dart │ └── settings.dart │ ├── snapshotter │ ├── snapshotter.dart │ └── snapshotter_messenger.dart │ ├── style │ ├── interactive_features │ │ ├── interactive_features.dart │ │ ├── standard_buildings.dart │ │ ├── standard_place_labels.dart │ │ └── standard_poi.dart │ ├── layer │ │ ├── background_layer.dart │ │ ├── circle_layer.dart │ │ ├── clip_layer.dart │ │ ├── fill_extrusion_layer.dart │ │ ├── fill_layer.dart │ │ ├── heatmap_layer.dart │ │ ├── hillshade_layer.dart │ │ ├── line_layer.dart │ │ ├── location_indicator_layer.dart │ │ ├── model_layer.dart │ │ ├── raster_layer.dart │ │ ├── raster_particle_layer.dart │ │ ├── sky_layer.dart │ │ ├── slot_layer.dart │ │ └── symbol_layer.dart │ ├── mapbox_styles.dart │ ├── source │ │ ├── geojson_source.dart │ │ ├── image_source.dart │ │ ├── raster_source.dart │ │ ├── rasterarray_source.dart │ │ ├── rasterdem_source.dart │ │ └── vector_source.dart │ └── style.dart │ ├── turf_adapters.dart │ ├── utils.dart │ └── viewport │ ├── state_viewport_extension.dart │ ├── states │ ├── camera_viewport_state.dart │ ├── follow_puck_viewport_state.dart │ ├── idle_viewport_state.dart │ ├── overview_viewport_state.dart │ ├── style_default_viewport_state.dart │ └── viewport_state.dart │ ├── transitions │ ├── default_viewport_transition.dart │ ├── easing_viewport_transition.dart │ ├── fly_viewport_transition.dart │ └── viewport_transition.dart │ └── viewport_internal.dart ├── package-lock.json ├── pubspec.yaml ├── scripts ├── check-format.sh ├── check_api_breakage.sh ├── check_test_suite.dart ├── license.sh └── update-version.sh └── test └── events_test.dart /.fastlane/Appfile: -------------------------------------------------------------------------------- 1 | app_identifier "com.mapbox.maps.FlutterMapsExample" # The bundle identifier of your app 2 | itc_team_name "Mapbox, Inc." 3 | -------------------------------------------------------------------------------- /.fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | default_platform(:ios) 2 | 3 | ENV["FASTLANE_SKIP_UPDATE_CHECK"] = "1" 4 | ENV["SPACESHIP_SKIP_2FA_UPGRADE"] = "1" 5 | 6 | platform :ios do 7 | 8 | lane :build_examples_tests do 9 | setup_circle_ci 10 | sync_code_signing(type: "development") 11 | update_code_signing_settings( 12 | use_automatic_signing: false, 13 | path: "example/ios/Runner.xcodeproj", 14 | team_id: "GJZR2MEM28", # Developer Portal Team ID, 15 | profile_name: lane_context[SharedValues::MATCH_PROVISIONING_PROFILE_MAPPING]["com.mapbox.maps.FlutterMapsExample"], 16 | targets: ["Runner"], 17 | code_sign_identity: "Apple Development: Created via API", 18 | ) 19 | update_code_signing_settings( 20 | use_automatic_signing: false, 21 | path: "example/ios/Runner.xcodeproj", 22 | team_id: "GJZR2MEM28", # Developer Portal Team ID, 23 | profile_name: lane_context[SharedValues::MATCH_PROVISIONING_PROFILE_MAPPING]["com.mapbox.maps.FlutterRunnerTests"], 24 | targets: ["RunnerTests"], 25 | code_sign_identity: "Apple Development: Created via API", 26 | ) 27 | # build tests archive in the `output_directory` to launch on firebase 28 | run_tests( 29 | workspace: 'example/ios/Runner.xcworkspace', 30 | scheme: 'Runner', # XCTest scheme 31 | xcconfig: "example/ios/Flutter/Release.xcconfig", 32 | derived_data_path: "example/build/output", 33 | configuration: "Release", 34 | xcargs: "SWIFT_TREAT_WARNINGS_AS_ERRORS=NO COMPILER_INDEX_STORE_ENABLE=NO", 35 | skip_detect_devices: true, # Required 36 | build_for_testing: true, # Required 37 | sdk: 'iphoneos', # Required 38 | should_zip_build_products: true, # Must be true to set the correct format for Firebase Test Lab, 39 | result_bundle: true, 40 | output_directory: "example/build/output/", 41 | code_coverage: true 42 | ) 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /.fastlane/Matchfile: -------------------------------------------------------------------------------- 1 | git_url("git@github.com:mapbox/apple-certificates.git") 2 | type("development") # The default type, can be: appstore, adhoc, enterprise or development 3 | app_identifier(["com.mapbox.maps.FlutterMapsExample", "com.mapbox.maps.FlutterRunnerTests"]) 4 | username("applemachine@mapbox.com") 5 | force_legacy_encryption(true) -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Mark files as generated in Github PRs 2 | ## pigeon 3 | lib/src/pigeons/* linguist-generated=true 4 | android/src/main/java/com/mapbox/maps/pigeons/* linguist-generated=true 5 | ios/Classes/*h linguist-generated=true 6 | ios/Classes/*m linguist-generated=true 7 | 8 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @mapbox/maps-flutter 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### What does this pull request do? 2 | 3 | 4 | 5 | ### What is the motivation and context behind this change? 6 | 7 | 8 | 9 | ### Pull request checklist: 10 | - [ ] Add a changelog entry. 11 | - [ ] Write tests for all new functionality. If tests were not written, please explain why. 12 | - [ ] Add documentation comments for any added or updated public APIs. 13 | 14 | PRs must be submitted under the terms of our Contributor License Agreement [CLA](../CONTRIBUTING.md#contributor-license-agreement). 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # Visual Studio Code related 20 | .classpath 21 | .project 22 | .settings/ 23 | .vscode/ 24 | 25 | # Flutter repo-specific 26 | /bin/cache/ 27 | /bin/mingit/ 28 | /dev/benchmarks/mega_gallery/ 29 | /dev/bots/.recipe_deps 30 | /dev/bots/android_tools/ 31 | /dev/docs/doc/ 32 | /dev/docs/flutter.docs.zip 33 | /dev/docs/lib/ 34 | /dev/docs/pubspec.yaml 35 | /dev/integration_tests/**/xcuserdata 36 | /dev/integration_tests/**/Pods 37 | /packages/flutter/coverage/ 38 | version 39 | 40 | # packages file containing multi-root paths 41 | .packages.generated 42 | 43 | # Flutter/Dart/Pub related 44 | **/doc/api/ 45 | .dart_tool/ 46 | .flutter-plugins 47 | .flutter-plugins-dependencies 48 | .packages 49 | .pub-cache/ 50 | .pub/ 51 | build/ 52 | flutter_*.png 53 | linked_*.ds 54 | unlinked.ds 55 | unlinked_spec.ds 56 | 57 | # Android related 58 | **/android/.gradle 59 | **/android/captures/ 60 | **/android/gradlew.bat 61 | **/android/local.properties 62 | **/android/**/GeneratedPluginRegistrant.java 63 | **/android/key.properties 64 | *.jks 65 | 66 | # iOS/XCode related 67 | **/ios/.build/ 68 | **/ios/.swiftpm/ 69 | **/ios/**/*.mode1v3 70 | **/ios/**/*.mode2v3 71 | **/ios/**/*.moved-aside 72 | **/ios/**/*.pbxuser 73 | **/ios/**/*.perspectivev3 74 | **/ios/**/*sync/ 75 | **/ios/**/.sconsign.dblite 76 | **/ios/**/.tags* 77 | **/ios/**/.vagrant/ 78 | **/ios/**/DerivedData/ 79 | **/ios/**/Icon? 80 | **/ios/**/Pods/ 81 | **/ios/**/.symlinks/ 82 | **/ios/**/profile 83 | **/ios/**/xcuserdata 84 | **/ios/.generated/ 85 | **/ios/Flutter/App.framework 86 | **/ios/Flutter/Flutter.framework 87 | **/ios/Flutter/Flutter.podspec 88 | **/ios/Flutter/Generated.xcconfig 89 | **/ios/Flutter/app.flx 90 | **/ios/Flutter/app.zip 91 | **/ios/Flutter/flutter_assets/ 92 | **/ios/Flutter/flutter_export_environment.sh 93 | **/ios/ServiceDefinitions.json 94 | **/ios/Runner/GeneratedPluginRegistrant.* 95 | .fastlane/README.md 96 | .fastlane/report.xml 97 | 98 | # macOS 99 | **/macos/Flutter/GeneratedPluginRegistrant.swift 100 | **/macos/Flutter/Flutter-Debug.xcconfig 101 | **/macos/Flutter/Flutter-Release.xcconfig 102 | **/macos/Flutter/Flutter-Profile.xcconfig 103 | 104 | # Coverage 105 | coverage/ 106 | 107 | # Symbols 108 | app.*.symbols 109 | 110 | # Exceptions to above rules. 111 | !**/ios/**/default.mode1v3 112 | !**/ios/**/default.mode2v3 113 | !**/ios/**/default.pbxuser 114 | !**/ios/**/default.perspectivev3 115 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 116 | !/dev/ci/**/Gemfile.lock 117 | !**/Podfile.lock 118 | !**/example/pubspec.lock 119 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/.gitmodules -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f4abaa0735eba4dfd8f33f73363911d63931fe03 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /.pubignore: -------------------------------------------------------------------------------- 1 | *.lock 2 | **/android/gradlew 3 | **/android/gradlew.bat 4 | **/android/gradle/wrapper/gradle-wrapper.jar 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane", "~> 2.227.2" 4 | 5 | plugins_path = File.join(File.dirname(__FILE__), '.fastlane', 'Pluginfile') 6 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 7 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures Dart code analyzer to check for errors, warnings, and lints. 2 | # 3 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 4 | # IDEs. The analyzer can also be invoked from the command line by running `flutter analyze`. 5 | 6 | # The following line activates a set of recommended lints for Flutter apps and packages. 7 | include: package:flutter_lints/flutter.yaml 8 | 9 | analyzer: 10 | errors: 11 | library_private_types_in_public_api: error 12 | 13 | # Additional information can be found at https://dart.dev/guides/language/analysis-options 14 | -------------------------------------------------------------------------------- /android/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{kt,kts}] 2 | indent_size=2 3 | insert_final_newline=false 4 | disabled_rules=no-wildcard-imports -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.mapbox.maps.mapbox_maps' 2 | version '1.0.0' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.8.22' 6 | repositories { 7 | google() 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:7.3.0' 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | 17 | rootProject.allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | maven { 22 | url 'https://api.mapbox.com/downloads/v2/releases/maven' 23 | } 24 | maven { 25 | url 'https://api.mapbox.com/downloads/v2/snapshots/maven' 26 | } 27 | } 28 | } 29 | 30 | apply plugin: 'com.android.library' 31 | apply plugin: 'kotlin-android' 32 | 33 | android { 34 | compileSdk 33 35 | 36 | namespace 'com.mapbox.maps.mapbox_maps' 37 | sourceSets { 38 | main.java.srcDirs += 'src/main/kotlin' 39 | } 40 | defaultConfig { 41 | minSdkVersion 21 42 | } 43 | 44 | compileOptions { 45 | sourceCompatibility JavaVersion.VERSION_1_8 46 | targetCompatibility JavaVersion.VERSION_1_8 47 | } 48 | 49 | kotlinOptions { 50 | jvmTarget = "1.8" 51 | } 52 | } 53 | 54 | if (file("$rootDir/gradle/ktlint.gradle").exists() && file("$rootDir/gradle/lint.gradle").exists()) { 55 | project.apply { 56 | from("$rootDir/gradle/ktlint.gradle") 57 | from("$rootDir/gradle/lint.gradle") 58 | } 59 | } 60 | 61 | dependencies { 62 | implementation "com.mapbox.maps:android:11.13.0" 63 | 64 | implementation "androidx.annotation:annotation:1.5.0" 65 | implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2" 66 | } 67 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4096M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'mapbox_maps' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/Accessors.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import com.mapbox.maps.Snapshotter 4 | 5 | // ⚠️ Danger zone ⚠️ 6 | 7 | fun Snapshotter.styleManager(): com.mapbox.maps.StyleManager { 8 | return javaClass.getDeclaredField("coreSnapshotter").let { 9 | it.isAccessible = true 10 | return@let it.get(this) as com.mapbox.maps.StyleManager 11 | } 12 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/AnimationController.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import android.content.Context 4 | import com.mapbox.common.Cancelable 5 | import com.mapbox.maps.MapboxMap 6 | import com.mapbox.maps.mapbox_maps.pigeons.* 7 | import com.mapbox.maps.plugin.animation.easeTo 8 | import com.mapbox.maps.plugin.animation.flyTo 9 | import com.mapbox.maps.plugin.animation.moveBy 10 | import com.mapbox.maps.plugin.animation.pitchBy 11 | import com.mapbox.maps.plugin.animation.rotateBy 12 | import com.mapbox.maps.plugin.animation.scaleBy 13 | 14 | class AnimationController(private val mapboxMap: MapboxMap, private val context: Context) : _AnimationManager { 15 | var cancelable: Cancelable? = null 16 | override fun easeTo( 17 | cameraOptions: CameraOptions, 18 | mapAnimationOptions: MapAnimationOptions? 19 | ) { 20 | cancelable = mapboxMap.easeTo( 21 | cameraOptions.toCameraOptions(context), 22 | mapAnimationOptions?.toMapAnimationOptions() 23 | ) 24 | } 25 | 26 | override fun flyTo( 27 | cameraOptions: CameraOptions, 28 | mapAnimationOptions: MapAnimationOptions? 29 | ) { 30 | cancelable = mapboxMap.flyTo( 31 | cameraOptions.toCameraOptions(context), 32 | mapAnimationOptions?.toMapAnimationOptions() 33 | ) 34 | } 35 | 36 | override fun moveBy( 37 | screenCoordinate: ScreenCoordinate, 38 | mapAnimationOptions: MapAnimationOptions? 39 | ) { 40 | cancelable = mapboxMap.moveBy( 41 | screenCoordinate.toScreenCoordinate(context), 42 | mapAnimationOptions?.toMapAnimationOptions() 43 | ) 44 | } 45 | 46 | override fun rotateBy( 47 | first: ScreenCoordinate, 48 | second: ScreenCoordinate, 49 | mapAnimationOptions: MapAnimationOptions? 50 | ) { 51 | cancelable = mapboxMap.rotateBy( 52 | first.toScreenCoordinate(context), 53 | second.toScreenCoordinate(context), 54 | mapAnimationOptions?.toMapAnimationOptions() 55 | ) 56 | } 57 | 58 | override fun scaleBy( 59 | amount: Double, 60 | screenCoordinate: ScreenCoordinate?, 61 | mapAnimationOptions: MapAnimationOptions? 62 | ) { 63 | cancelable = mapboxMap.scaleBy( 64 | amount, 65 | screenCoordinate?.toScreenCoordinate(context), 66 | mapAnimationOptions?.toMapAnimationOptions() 67 | ) 68 | } 69 | 70 | override fun pitchBy(pitch: Double, mapAnimationOptions: MapAnimationOptions?) { 71 | cancelable = mapboxMap.pitchBy(pitch, mapAnimationOptions?.toMapAnimationOptions()) 72 | } 73 | 74 | override fun cancelCameraAnimation() { 75 | cancelable?.cancel() 76 | } 77 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/AttributionController.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import com.mapbox.maps.MapView 4 | import com.mapbox.maps.mapbox_maps.mapping.applyFromFLT 5 | import com.mapbox.maps.mapbox_maps.mapping.toFLT 6 | import com.mapbox.maps.mapbox_maps.pigeons.* 7 | import com.mapbox.maps.plugin.attribution.attribution 8 | 9 | class AttributionController(private val mapView: MapView) : 10 | AttributionSettingsInterface { 11 | override fun getSettings(): AttributionSettings = mapView.attribution.toFLT(mapView.context) 12 | override fun updateSettings(settings: AttributionSettings) { 13 | mapView.attribution.applyFromFLT(settings, mapView.context) 14 | } 15 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/CompassController.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import com.mapbox.maps.MapView 4 | import com.mapbox.maps.mapbox_maps.mapping.applyFromFLT 5 | import com.mapbox.maps.mapbox_maps.mapping.toFLT 6 | import com.mapbox.maps.mapbox_maps.pigeons.* 7 | import com.mapbox.maps.plugin.compass.compass 8 | 9 | class CompassController(private val mapView: MapView) : 10 | CompassSettingsInterface { 11 | override fun getSettings(): CompassSettings = mapView.compass.toFLT(mapView.context) 12 | override fun updateSettings(settings: CompassSettings) { 13 | mapView.compass.applyFromFLT(settings, mapView.context) 14 | } 15 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/LocationComponentController.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import android.content.Context 4 | import com.mapbox.maps.MapView 5 | import com.mapbox.maps.mapbox_maps.mapping.applyFromFLT 6 | import com.mapbox.maps.mapbox_maps.mapping.toFLT 7 | import com.mapbox.maps.mapbox_maps.pigeons.* 8 | import com.mapbox.maps.plugin.locationcomponent.createDefault2DPuck 9 | import com.mapbox.maps.plugin.locationcomponent.location 10 | 11 | class LocationComponentController( 12 | private val mapView: MapView, 13 | private val context: Context 14 | ) : _LocationComponentSettingsInterface { 15 | override fun getSettings(): LocationComponentSettings = mapView.location.toFLT(context) 16 | 17 | override fun updateSettings(settings: LocationComponentSettings, useDefaultPuck2DIfNeeded: Boolean) { 18 | if (useDefaultPuck2DIfNeeded) { 19 | mapView.location.locationPuck = createDefault2DPuck(withBearing = settings.puckBearingEnabled == true) 20 | } 21 | mapView.location.applyFromFLT(settings, useDefaultPuck2DIfNeeded, context) 22 | } 23 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/LoggingController.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import android.os.Handler 4 | import android.os.Looper 5 | import com.mapbox.common.LogConfiguration 6 | import com.mapbox.common.LoggingLevel 7 | import com.mapbox.maps.mapbox_maps.pigeons.* 8 | import io.flutter.plugin.common.BinaryMessenger 9 | 10 | class LoggingController : com.mapbox.common.LogWriterBackend { 11 | private val handler = Handler(Looper.getMainLooper()) 12 | 13 | companion object { 14 | private var backend: LogWriterBackend? = null 15 | private val instance = LoggingController() 16 | 17 | fun setup(binaryMessenger: BinaryMessenger) { 18 | backend = LogWriterBackend(binaryMessenger) 19 | LogConfiguration.registerLogWriterBackend(instance) 20 | } 21 | } 22 | 23 | override fun writeLog(level: LoggingLevel, message: String) { 24 | handler.post { 25 | backend?.writeLog(level.toFLTLoggingLevel(), message) { } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/LogoController.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import com.mapbox.maps.MapView 4 | import com.mapbox.maps.mapbox_maps.mapping.applyFromFLT 5 | import com.mapbox.maps.mapbox_maps.mapping.toFLT 6 | import com.mapbox.maps.mapbox_maps.pigeons.* 7 | import com.mapbox.maps.plugin.logo.logo 8 | 9 | class LogoController(private val mapView: MapView) : 10 | LogoSettingsInterface { 11 | override fun getSettings(): LogoSettings = mapView.logo.toFLT(mapView.context) 12 | override fun updateSettings(settings: LogoSettings) { 13 | mapView.logo.applyFromFLT(settings, mapView.context) 14 | } 15 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/MapProjectionController.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import com.mapbox.geojson.Point 4 | import com.mapbox.maps.MapboxMap 5 | import com.mapbox.maps.mapbox_maps.pigeons.* 6 | 7 | class MapProjectionController(private val mapboxMap: MapboxMap) : Projection { 8 | override fun getMetersPerPixelAtLatitude(latitude: Double, zoom: Double): Double { 9 | return mapboxMap.getMetersPerPixelAtLatitude(latitude, zoom) 10 | } 11 | 12 | override fun projectedMetersForCoordinate(coordinate: Point): ProjectedMeters { 13 | return mapboxMap.projectedMetersForCoordinate(coordinate).toFLTProjectedMeters() 14 | } 15 | 16 | override fun coordinateForProjectedMeters(projectedMeters: ProjectedMeters): Point { 17 | return mapboxMap.coordinateForProjectedMeters(projectedMeters.toProjectedMeters()) 18 | } 19 | 20 | override fun unproject( 21 | coordinate: MercatorCoordinate, 22 | zoomScale: Double 23 | ): Point { 24 | return mapboxMap.unproject(coordinate.toMercatorCoordinate(), zoomScale) 25 | } 26 | 27 | override fun project( 28 | coordinate: Point, 29 | zoomScale: Double 30 | ): MercatorCoordinate { 31 | return mapboxMap.project(coordinate, zoomScale).toFLTMercatorCoordinate() 32 | } 33 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/MapboxMapFactory.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import com.mapbox.common.FeatureTelemetryCounter 6 | import com.mapbox.maps.MapInitOptions 7 | import com.mapbox.maps.MapOptions 8 | import com.mapbox.maps.Style 9 | import com.mapbox.maps.applyDefaultParams 10 | import com.mapbox.maps.mapbox_maps.pigeons._MapInterface 11 | import io.flutter.embedding.engine.plugins.FlutterPlugin 12 | import io.flutter.plugin.common.BinaryMessenger 13 | import io.flutter.plugin.platform.PlatformView 14 | import io.flutter.plugin.platform.PlatformViewFactory 15 | 16 | class MapboxMapFactory( 17 | private val messenger: BinaryMessenger, 18 | private val flutterAssets: FlutterPlugin.FlutterAssets, 19 | private val lifecycleProvider: MapboxMapsPlugin.LifecycleProvider 20 | ) : PlatformViewFactory(_MapInterface.codec) { 21 | 22 | @SuppressLint("RestrictedApi") 23 | override fun create(context: Context?, viewId: Int, args: Any?): PlatformView { 24 | if (context == null) { 25 | throw RuntimeException("Context is null, can't create MapView!") 26 | } 27 | val params = args as Map 28 | val mapOptions = params["mapOptions"] as com.mapbox.maps.mapbox_maps.pigeons.MapOptions? 29 | val cameraOptions = params["cameraOptions"] as com.mapbox.maps.mapbox_maps.pigeons.CameraOptions? 30 | val channelSuffix = params["channelSuffix"] as Long 31 | val textureView = params["textureView"] as? Boolean ?: false 32 | val styleUri = params["styleUri"] as? String ?: Style.STANDARD 33 | val pluginVersion = params["mapboxPluginVersion"] as String 34 | val eventTypes = params["eventTypes"] as List 35 | 36 | val mapInitOptions = MapInitOptions( 37 | context = context, 38 | mapOptions = mapOptions?.toMapOptions(context) ?: MapOptions.Builder() 39 | .applyDefaultParams(context).build(), 40 | cameraOptions = cameraOptions?.toCameraOptions(context), 41 | textureView = textureView, 42 | styleUri = styleUri 43 | ) 44 | mapCounter.increment() 45 | return MapboxMapController( 46 | context, 47 | mapInitOptions, 48 | lifecycleProvider, 49 | messenger, 50 | channelSuffix, 51 | pluginVersion, 52 | eventTypes 53 | ) 54 | } 55 | 56 | companion object { 57 | @SuppressLint("RestrictedApi") 58 | private val mapCounter = FeatureTelemetryCounter.create("maps-mobile/flutter/map") 59 | } 60 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/PerformanceStatisticsController.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import com.mapbox.maps.MapboxMap 4 | import com.mapbox.maps.mapbox_maps.pigeons.PerformanceStatisticsListener 5 | import com.mapbox.maps.mapbox_maps.pigeons.PerformanceStatisticsOptions 6 | import com.mapbox.maps.mapbox_maps.pigeons._PerformanceStatisticsApi 7 | import io.flutter.plugin.common.BinaryMessenger 8 | 9 | class PerformanceStatisticsController( 10 | private val mapboxMap: MapboxMap, 11 | messenger: BinaryMessenger, 12 | channelSuffix: String 13 | ) : _PerformanceStatisticsApi { 14 | private val performanceStatisticsListener: PerformanceStatisticsListener = 15 | PerformanceStatisticsListener(messenger, channelSuffix) 16 | 17 | override fun startPerformanceStatisticsCollection(options: PerformanceStatisticsOptions) { 18 | // stop previous collection to match the behavior with iOS 19 | mapboxMap.stopPerformanceStatisticsCollection() 20 | 21 | mapboxMap.startPerformanceStatisticsCollection(options.toPerformanceStatisticsOptions()) { statistics -> 22 | performanceStatisticsListener.onPerformanceStatisticsCollected(statistics.toPerformanceStatistics()) { } 23 | } 24 | } 25 | 26 | override fun stopPerformanceStatisticsCollection() { 27 | mapboxMap.stopPerformanceStatisticsCollection() 28 | } 29 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/ScaleBarController.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps 2 | 3 | import com.mapbox.maps.MapView 4 | import com.mapbox.maps.mapbox_maps.mapping.applyFromFLT 5 | import com.mapbox.maps.mapbox_maps.mapping.toFLT 6 | import com.mapbox.maps.mapbox_maps.pigeons.* 7 | import com.mapbox.maps.plugin.scalebar.scalebar 8 | 9 | class ScaleBarController(private val mapView: MapView) : 10 | ScaleBarSettingsInterface { 11 | override fun getSettings(): ScaleBarSettings = mapView.scalebar.toFLT(mapView.context) 12 | override fun updateSettings(settings: ScaleBarSettings) { 13 | mapView.scalebar.applyFromFLT(settings, mapView.context) 14 | } 15 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/ControllerDelegate.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps.annotation 2 | 3 | import com.mapbox.maps.plugin.annotation.AnnotationManager 4 | 5 | interface ControllerDelegate { 6 | fun getManager(managerId: String): AnnotationManager<*, *, *, *, *, *, *> 7 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/annotation/PolygonAnnotationEnumsExtensions.kt: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | 3 | import com.mapbox.maps.mapbox_maps.pigeons.* 4 | 5 | // FLT to Android 6 | 7 | fun FillElevationReference.toFillElevationReference(): com.mapbox.maps.extension.style.layers.properties.generated.FillElevationReference { 8 | return when (this) { 9 | FillElevationReference.NONE -> com.mapbox.maps.extension.style.layers.properties.generated.FillElevationReference.NONE 10 | FillElevationReference.HD_ROAD_BASE -> com.mapbox.maps.extension.style.layers.properties.generated.FillElevationReference.HD_ROAD_BASE 11 | FillElevationReference.HD_ROAD_MARKUP -> com.mapbox.maps.extension.style.layers.properties.generated.FillElevationReference.HD_ROAD_MARKUP 12 | else -> throw(RuntimeException("Unsupported FillElevationReference: $this")) 13 | } 14 | } 15 | fun FillTranslateAnchor.toFillTranslateAnchor(): com.mapbox.maps.extension.style.layers.properties.generated.FillTranslateAnchor { 16 | return when (this) { 17 | FillTranslateAnchor.MAP -> com.mapbox.maps.extension.style.layers.properties.generated.FillTranslateAnchor.MAP 18 | FillTranslateAnchor.VIEWPORT -> com.mapbox.maps.extension.style.layers.properties.generated.FillTranslateAnchor.VIEWPORT 19 | else -> throw(RuntimeException("Unsupported FillTranslateAnchor: $this")) 20 | } 21 | } 22 | 23 | // Android to FLT 24 | 25 | fun com.mapbox.maps.extension.style.layers.properties.generated.FillElevationReference.toFLTFillElevationReference(): FillElevationReference { 26 | return when (this) { 27 | com.mapbox.maps.extension.style.layers.properties.generated.FillElevationReference.NONE -> FillElevationReference.NONE 28 | com.mapbox.maps.extension.style.layers.properties.generated.FillElevationReference.HD_ROAD_BASE -> FillElevationReference.HD_ROAD_BASE 29 | com.mapbox.maps.extension.style.layers.properties.generated.FillElevationReference.HD_ROAD_MARKUP -> FillElevationReference.HD_ROAD_MARKUP 30 | else -> throw(RuntimeException("Unsupported FillElevationReference: $this")) 31 | } 32 | } 33 | fun com.mapbox.maps.extension.style.layers.properties.generated.FillTranslateAnchor.toFLTFillTranslateAnchor(): FillTranslateAnchor { 34 | return when (this) { 35 | com.mapbox.maps.extension.style.layers.properties.generated.FillTranslateAnchor.MAP -> FillTranslateAnchor.MAP 36 | com.mapbox.maps.extension.style.layers.properties.generated.FillTranslateAnchor.VIEWPORT -> FillTranslateAnchor.VIEWPORT 37 | else -> throw(RuntimeException("Unsupported FillTranslateAnchor: $this")) 38 | } 39 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/http/CustomHttpServiceInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps.http 2 | 3 | import com.mapbox.common.HttpRequest 4 | import com.mapbox.common.HttpRequestOrResponse 5 | import com.mapbox.common.HttpResponse 6 | import com.mapbox.common.HttpServiceFactory 7 | import com.mapbox.common.HttpServiceInterceptorInterface 8 | import com.mapbox.common.HttpServiceInterceptorRequestContinuation 9 | import com.mapbox.common.HttpServiceInterceptorResponseContinuation 10 | 11 | class CustomHttpServiceInterceptor : HttpServiceInterceptorInterface { 12 | private var customHeaders: MutableMap = mutableMapOf() 13 | 14 | override fun onRequest(request: HttpRequest, continuation: HttpServiceInterceptorRequestContinuation) { 15 | val currentHeaders = HashMap(request.headers) 16 | 17 | currentHeaders.putAll(customHeaders) 18 | val modifiedRequest = request.toBuilder() 19 | .headers(currentHeaders) 20 | .build() 21 | val requestOrResponse = HttpRequestOrResponse(modifiedRequest) 22 | continuation.run(requestOrResponse) 23 | } 24 | 25 | override fun onResponse(response: HttpResponse, continuation: HttpServiceInterceptorResponseContinuation) { 26 | continuation.run(response) 27 | } 28 | 29 | fun setCustomHeaders(headers: Map) { 30 | customHeaders.clear() 31 | customHeaders.putAll(headers) 32 | HttpServiceFactory.setHttpServiceInterceptor(this) 33 | } 34 | 35 | companion object { 36 | private var instance: CustomHttpServiceInterceptor? = null 37 | 38 | fun getInstance(): CustomHttpServiceInterceptor { 39 | if (instance == null) { 40 | instance = CustomHttpServiceInterceptor() 41 | } 42 | return instance!! 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/mapping/AttributionMappings.kt: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | package com.mapbox.maps.mapbox_maps.mapping 3 | 4 | import android.content.Context 5 | import com.mapbox.maps.mapbox_maps.pigeons.* 6 | import com.mapbox.maps.mapbox_maps.toDevicePixels 7 | import com.mapbox.maps.mapbox_maps.toLogicalPixels 8 | import com.mapbox.maps.plugin.attribution.generated.AttributionSettingsInterface 9 | 10 | fun AttributionSettingsInterface.applyFromFLT(settings: AttributionSettings, context: Context) { 11 | updateSettings { 12 | settings.enabled?.let { this.enabled = it } 13 | settings.iconColor?.let { this.iconColor = it.toInt() } 14 | settings.position?.let { this.position = it.toPosition() } 15 | settings.marginLeft?.let { this.marginLeft = it.toDevicePixels(context) } 16 | settings.marginTop?.let { this.marginTop = it.toDevicePixels(context) } 17 | settings.marginRight?.let { this.marginRight = it.toDevicePixels(context) } 18 | settings.marginBottom?.let { this.marginBottom = it.toDevicePixels(context) } 19 | settings.clickable?.let { this.clickable = it } 20 | } 21 | } 22 | 23 | fun AttributionSettingsInterface.toFLT(context: Context) = AttributionSettings( 24 | enabled = enabled, 25 | iconColor = iconColor.toUInt().toLong(), 26 | position = position.toOrnamentPosition(), 27 | marginLeft = marginLeft.toLogicalPixels(context), 28 | marginTop = marginTop.toLogicalPixels(context), 29 | marginRight = marginRight.toLogicalPixels(context), 30 | marginBottom = marginBottom.toLogicalPixels(context), 31 | clickable = clickable, 32 | ) 33 | 34 | // End of generated file. -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/mapping/CompassMappings.kt: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | package com.mapbox.maps.mapbox_maps.mapping 3 | 4 | import android.content.Context 5 | import android.graphics.Bitmap 6 | import android.graphics.BitmapFactory 7 | import com.mapbox.maps.ImageHolder 8 | import com.mapbox.maps.mapbox_maps.pigeons.* 9 | import com.mapbox.maps.mapbox_maps.toDevicePixels 10 | import com.mapbox.maps.mapbox_maps.toLogicalPixels 11 | import com.mapbox.maps.plugin.compass.generated.CompassSettingsInterface 12 | import java.io.ByteArrayOutputStream 13 | 14 | fun CompassSettingsInterface.applyFromFLT(settings: CompassSettings, context: Context) { 15 | updateSettings { 16 | settings.enabled?.let { this.enabled = it } 17 | settings.position?.let { this.position = it.toPosition() } 18 | settings.marginLeft?.let { this.marginLeft = it.toDevicePixels(context) } 19 | settings.marginTop?.let { this.marginTop = it.toDevicePixels(context) } 20 | settings.marginRight?.let { this.marginRight = it.toDevicePixels(context) } 21 | settings.marginBottom?.let { this.marginBottom = it.toDevicePixels(context) } 22 | settings.opacity?.let { this.opacity = it.toFloat() } 23 | settings.rotation?.let { this.rotation = it.toFloat() } 24 | settings.visibility?.let { this.visibility = it } 25 | settings.fadeWhenFacingNorth?.let { this.fadeWhenFacingNorth = it } 26 | settings.clickable?.let { this.clickable = it } 27 | settings.image?.let { this.image = if (it.isNotEmpty()) ImageHolder.from(BitmapFactory.decodeByteArray(it, 0, it.size)) else null } 28 | } 29 | } 30 | 31 | fun CompassSettingsInterface.toFLT(context: Context) = CompassSettings( 32 | enabled = enabled, 33 | position = position.toOrnamentPosition(), 34 | marginLeft = marginLeft.toLogicalPixels(context), 35 | marginTop = marginTop.toLogicalPixels(context), 36 | marginRight = marginRight.toLogicalPixels(context), 37 | marginBottom = marginBottom.toLogicalPixels(context), 38 | opacity = opacity.toDouble(), 39 | rotation = rotation.toDouble(), 40 | visibility = visibility, 41 | fadeWhenFacingNorth = fadeWhenFacingNorth, 42 | clickable = clickable, 43 | image = image?.bitmap?.let { bitmap -> 44 | ByteArrayOutputStream().also { stream -> 45 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream) 46 | }.toByteArray() 47 | }, 48 | ) 49 | 50 | // End of generated file. -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/mapping/LogoMappings.kt: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | package com.mapbox.maps.mapbox_maps.mapping 3 | 4 | import android.content.Context 5 | import com.mapbox.maps.mapbox_maps.pigeons.* 6 | import com.mapbox.maps.mapbox_maps.toDevicePixels 7 | import com.mapbox.maps.mapbox_maps.toLogicalPixels 8 | import com.mapbox.maps.plugin.logo.generated.LogoSettingsInterface 9 | 10 | fun LogoSettingsInterface.applyFromFLT(settings: LogoSettings, context: Context) { 11 | updateSettings { 12 | settings.enabled?.let { this.enabled = it } 13 | settings.position?.let { this.position = it.toPosition() } 14 | settings.marginLeft?.let { this.marginLeft = it.toDevicePixels(context) } 15 | settings.marginTop?.let { this.marginTop = it.toDevicePixels(context) } 16 | settings.marginRight?.let { this.marginRight = it.toDevicePixels(context) } 17 | settings.marginBottom?.let { this.marginBottom = it.toDevicePixels(context) } 18 | } 19 | } 20 | 21 | fun LogoSettingsInterface.toFLT(context: Context) = LogoSettings( 22 | enabled = enabled, 23 | position = position.toOrnamentPosition(), 24 | marginLeft = marginLeft.toLogicalPixels(context), 25 | marginTop = marginTop.toLogicalPixels(context), 26 | marginRight = marginRight.toLogicalPixels(context), 27 | marginBottom = marginBottom.toLogicalPixels(context), 28 | ) 29 | 30 | // End of generated file. -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/mapping/OrnamentPositionMapping.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps.mapping 2 | 3 | import android.view.Gravity 4 | import com.mapbox.maps.mapbox_maps.pigeons.OrnamentPosition 5 | 6 | fun OrnamentPosition.toPosition(): Int { 7 | return when (this) { 8 | OrnamentPosition.BOTTOM_LEFT -> Gravity.BOTTOM or Gravity.START 9 | OrnamentPosition.BOTTOM_RIGHT -> Gravity.BOTTOM or Gravity.END 10 | OrnamentPosition.TOP_LEFT -> Gravity.TOP or Gravity.START 11 | OrnamentPosition.TOP_RIGHT -> Gravity.TOP or Gravity.END 12 | } 13 | } 14 | 15 | fun Int.toOrnamentPosition(): OrnamentPosition { 16 | return when (this) { 17 | Gravity.BOTTOM or Gravity.START -> OrnamentPosition.BOTTOM_LEFT 18 | Gravity.BOTTOM or Gravity.END -> OrnamentPosition.BOTTOM_RIGHT 19 | Gravity.TOP or Gravity.START -> OrnamentPosition.TOP_LEFT 20 | else -> { 21 | OrnamentPosition.TOP_RIGHT 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/mapping/ScaleBarMappings.kt: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | package com.mapbox.maps.mapbox_maps.mapping 3 | 4 | import android.content.Context 5 | import com.mapbox.maps.mapbox_maps.pigeons.* 6 | import com.mapbox.maps.mapbox_maps.toDevicePixels 7 | import com.mapbox.maps.mapbox_maps.toLogicalPixels 8 | import com.mapbox.maps.plugin.scalebar.generated.ScaleBarSettingsInterface 9 | 10 | fun ScaleBarSettingsInterface.applyFromFLT(settings: ScaleBarSettings, context: Context) { 11 | updateSettings { 12 | settings.enabled?.let { this.enabled = it } 13 | settings.position?.let { this.position = it.toPosition() } 14 | settings.marginLeft?.let { this.marginLeft = it.toDevicePixels(context) } 15 | settings.marginTop?.let { this.marginTop = it.toDevicePixels(context) } 16 | settings.marginRight?.let { this.marginRight = it.toDevicePixels(context) } 17 | settings.marginBottom?.let { this.marginBottom = it.toDevicePixels(context) } 18 | settings.textColor?.let { this.textColor = it.toInt() } 19 | settings.primaryColor?.let { this.primaryColor = it.toInt() } 20 | settings.secondaryColor?.let { this.secondaryColor = it.toInt() } 21 | settings.borderWidth?.let { this.borderWidth = it.toDevicePixels(context) } 22 | settings.height?.let { this.height = it.toDevicePixels(context) } 23 | settings.textBarMargin?.let { this.textBarMargin = it.toDevicePixels(context) } 24 | settings.textBorderWidth?.let { this.textBorderWidth = it.toDevicePixels(context) } 25 | settings.textSize?.let { this.textSize = it.toFloat() } 26 | settings.isMetricUnits?.let { this.isMetricUnits = it } 27 | settings.refreshInterval?.let { this.refreshInterval = it } 28 | settings.showTextBorder?.let { this.showTextBorder = it } 29 | settings.ratio?.let { this.ratio = it.toFloat() } 30 | settings.useContinuousRendering?.let { this.useContinuousRendering = it } 31 | } 32 | } 33 | 34 | fun ScaleBarSettingsInterface.toFLT(context: Context) = ScaleBarSettings( 35 | enabled = enabled, 36 | position = position.toOrnamentPosition(), 37 | marginLeft = marginLeft.toLogicalPixels(context), 38 | marginTop = marginTop.toLogicalPixels(context), 39 | marginRight = marginRight.toLogicalPixels(context), 40 | marginBottom = marginBottom.toLogicalPixels(context), 41 | textColor = textColor.toUInt().toLong(), 42 | primaryColor = primaryColor.toUInt().toLong(), 43 | secondaryColor = secondaryColor.toUInt().toLong(), 44 | borderWidth = borderWidth.toLogicalPixels(context), 45 | height = height.toLogicalPixels(context), 46 | textBarMargin = textBarMargin.toLogicalPixels(context), 47 | textBorderWidth = textBorderWidth.toLogicalPixels(context), 48 | textSize = textSize.toDouble(), 49 | isMetricUnits = isMetricUnits, 50 | refreshInterval = refreshInterval, 51 | showTextBorder = showTextBorder, 52 | ratio = ratio.toDouble(), 53 | useContinuousRendering = useContinuousRendering, 54 | ) 55 | 56 | // End of generated file. -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/mapping/turf/TurfAdapters.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps.mapping.turf 2 | 3 | import com.google.gson.Gson 4 | import com.mapbox.geojson.* 5 | 6 | fun Point.toList(): List { 7 | return listOf(mapOf("coordinates" to coordinates())) 8 | } 9 | 10 | object PointDecoder { 11 | @Suppress("UNCHECKED_CAST") 12 | fun fromList(list: List): Point { 13 | val rawPoint = list.first() as Map 14 | val coordinates = rawPoint["coordinates"] as List 15 | 16 | return Point.fromLngLat(coordinates[0], coordinates[1]) 17 | } 18 | } 19 | 20 | fun LineString.toList(): List { 21 | return listOf(mapOf("coordinates" to coordinates().map { it.coordinates() })) 22 | } 23 | 24 | object LineStringDecoder { 25 | @Suppress("UNCHECKED_CAST") 26 | fun fromList(list: List): LineString { 27 | val rawData = list.first() as Map 28 | 29 | return LineString.fromLngLats( 30 | (rawData["coordinates"] as List>).map { 31 | Point.fromLngLat(it.first(), it.last()) 32 | } 33 | ) 34 | } 35 | } 36 | 37 | fun Polygon.toList(): List { 38 | return listOf(mapOf("coordinates" to coordinates().map { it.map { it.coordinates() } })) 39 | } 40 | 41 | object PolygonDecoder { 42 | @Suppress("UNCHECKED_CAST") 43 | fun fromList(list: List): Polygon { 44 | val rawData = list.first() as Map 45 | 46 | return Polygon.fromLngLats( 47 | (rawData["coordinates"] as List>>).map { 48 | it.map { Point.fromLngLat(it.first(), it.last()) } 49 | } 50 | ) 51 | } 52 | } 53 | 54 | fun Feature.toList(): List { 55 | return listOf(this.toJson()) 56 | } 57 | 58 | object FeatureDecoder { 59 | @Suppress("UNCHECKED_CAST") 60 | fun fromList(list: List): Feature { 61 | val rawData = list.first() as Map 62 | 63 | val gson = Gson() 64 | val json = gson.toJson(rawData) 65 | 66 | return Feature.fromJson(json) 67 | } 68 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/offline/OfflineMapInstanceManager.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps.offline 2 | 3 | import android.content.Context 4 | import com.mapbox.common.TileStore 5 | import com.mapbox.maps.MapboxMapsOptions 6 | import com.mapbox.maps.mapbox_maps.pigeons.* 7 | import io.flutter.plugin.common.BinaryMessenger 8 | 9 | class OfflineMapInstanceManager( 10 | private val context: Context, 11 | private val messenger: BinaryMessenger, 12 | ) : _OfflineMapInstanceManager, _TileStoreInstanceManager { 13 | 14 | override fun setupOfflineManager(channelSuffix: String) { 15 | val offlineControler = OfflineController(context, messenger, channelSuffix) 16 | _OfflineManager.setUp(messenger, offlineControler, channelSuffix) 17 | } 18 | 19 | override fun tearDownOfflineManager(channelSuffix: String) { 20 | _OfflineManager.setUp(messenger, null, channelSuffix) 21 | } 22 | 23 | override fun setupTileStore(channelSuffix: String, filePath: String?) { 24 | val tileStore = filePath?.let { TileStore.create(it) } ?: TileStore.create() 25 | MapboxMapsOptions.tileStore = tileStore 26 | val tileStoreController = TileStoreController(context, messenger, channelSuffix, tileStore) 27 | _TileStore.setUp(messenger, tileStoreController, channelSuffix) 28 | } 29 | 30 | override fun tearDownTileStore(channelSuffix: String) { 31 | _TileStore.setUp(messenger, null, channelSuffix) 32 | MapboxMapsOptions.tileStore = null 33 | } 34 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/offline/OfflineSwitch.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps.offline 2 | 3 | import com.mapbox.maps.mapbox_maps.pigeons._OfflineSwitch 4 | 5 | class OfflineSwitch : _OfflineSwitch { 6 | 7 | private val switcher = com.mapbox.common.OfflineSwitch.getInstance() 8 | 9 | override fun setMapboxStackConnected(connected: Boolean) { 10 | switcher.isMapboxStackConnected = connected 11 | } 12 | 13 | override fun isMapboxStackConnected(): Boolean { 14 | return switcher.isMapboxStackConnected 15 | } 16 | } -------------------------------------------------------------------------------- /android/src/main/kotlin/com/mapbox/maps/mapbox_maps/snapshotter/SnapshotterInstanceManager.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps.snapshot 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import com.mapbox.maps.MapboxStyleManager 6 | import com.mapbox.maps.Snapshotter 7 | import com.mapbox.maps.mapbox_maps.MapboxEventHandler 8 | import com.mapbox.maps.mapbox_maps.StyleController 9 | import com.mapbox.maps.mapbox_maps.pigeons.MapSnapshotOptions 10 | import com.mapbox.maps.mapbox_maps.pigeons.StyleManager 11 | import com.mapbox.maps.mapbox_maps.pigeons._SnapshotterInstanceManager 12 | import com.mapbox.maps.mapbox_maps.pigeons._SnapshotterMessenger 13 | import com.mapbox.maps.mapbox_maps.styleManager 14 | import com.mapbox.maps.mapbox_maps.toSnapshotOptions 15 | import com.mapbox.maps.mapbox_maps.toSnapshotOverlayOptions 16 | import io.flutter.plugin.common.BinaryMessenger 17 | 18 | class SnapshotterInstanceManager( 19 | private val context: Context, 20 | private val messenger: BinaryMessenger, 21 | ) : _SnapshotterInstanceManager { 22 | 23 | @SuppressLint("RestrictedApi") 24 | override fun setupSnapshotterForSuffix( 25 | suffix: String, 26 | eventTypes: List, 27 | options: MapSnapshotOptions 28 | ) { 29 | val snapshotter = Snapshotter( 30 | context, 31 | options = options.toSnapshotOptions(context), 32 | overlayOptions = options.toSnapshotOverlayOptions() 33 | ) 34 | val styleManager: com.mapbox.maps.StyleManager = snapshotter.styleManager() // TODO: expose this on Android 35 | val eventHandler = MapboxEventHandler(styleManager, messenger, eventTypes.map { it }, suffix) 36 | val snapshotterController = SnapshotterController(context, snapshotter, eventHandler) 37 | val mapboxStyleManager = MapboxStyleManager( 38 | styleManager, 39 | options.pixelRatio.toFloat(), 40 | mapLoadingErrorDelegate = {} 41 | ) 42 | val snapshotterStyleController = StyleController(context, mapboxStyleManager) 43 | 44 | _SnapshotterMessenger.setUp(messenger, snapshotterController, suffix) 45 | StyleManager.setUp(messenger, snapshotterStyleController, suffix) 46 | } 47 | 48 | override fun tearDownSnapshotterForSuffix(suffix: String) { 49 | _SnapshotterMessenger.setUp(messenger, null, suffix) 50 | StyleManager.setUp(messenger, null, suffix) 51 | } 52 | } -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f4abaa0735eba4dfd8f33f73363911d63931fe03 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # mapbox_maps_example 2 | 3 | Demonstrates how to use the Mapbox Maps Flutter SDK. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle 2 | /captures/ 3 | /gradlew.bat 4 | /local.properties 5 | GeneratedPluginRegistrant.java 6 | 7 | # Remember to never publicly share your keystore. 8 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 9 | key.properties 10 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | id "dev.flutter.flutter-gradle-plugin" 5 | } 6 | 7 | def localProperties = new Properties() 8 | def localPropertiesFile = rootProject.file('local.properties') 9 | if (localPropertiesFile.exists()) { 10 | localPropertiesFile.withReader('UTF-8') { reader -> 11 | localProperties.load(reader) 12 | } 13 | } 14 | 15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 16 | if (flutterVersionCode == null) { 17 | flutterVersionCode = '1' 18 | } 19 | 20 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 21 | if (flutterVersionName == null) { 22 | flutterVersionName = '1.0' 23 | } 24 | 25 | android { 26 | namespace "com.mapbox.maps.mapbox_maps_example" 27 | compileSdk 34 28 | 29 | sourceSets { 30 | main.java.srcDirs += 'src/main/kotlin' 31 | } 32 | 33 | compileOptions { 34 | sourceCompatibility JavaVersion.VERSION_1_8 35 | targetCompatibility JavaVersion.VERSION_1_8 36 | } 37 | 38 | kotlinOptions { 39 | jvmTarget = "1.8" 40 | } 41 | 42 | defaultConfig { 43 | applicationId "com.mapbox.maps.flutter.example" 44 | minSdkVersion 21 45 | targetSdkVersion 33 46 | versionCode flutterVersionCode.toInteger() 47 | versionName flutterVersionName 48 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 49 | } 50 | 51 | buildTypes { 52 | release { 53 | // TODO: Add your own signing config for the release build. 54 | // Signing with the debug keys for now, so `flutter run --release` works. 55 | signingConfig signingConfigs.debug 56 | minifyEnabled true 57 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt') 58 | } 59 | } 60 | } 61 | 62 | flutter { 63 | source '../..' 64 | } 65 | 66 | dependencies { 67 | androidTestImplementation 'androidx.test:runner:1.2.0' 68 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 69 | } 70 | -------------------------------------------------------------------------------- /example/android/app/src/androidTest/java/com/mapbox/maps/mapbox_maps_example/MainActivityTest.java: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps_example; 2 | 3 | import android.Manifest.permission; 4 | import androidx.test.rule.ActivityTestRule; 5 | import androidx.test.rule.GrantPermissionRule; 6 | import dev.flutter.plugins.integration_test.FlutterTestRunner; 7 | import org.junit.Rule; 8 | import org.junit.runner.RunWith; 9 | 10 | @RunWith(FlutterTestRunner.class) 11 | public class MainActivityTest { 12 | 13 | @Rule 14 | public GrantPermissionRule permissionRule = 15 | GrantPermissionRule.grant(permission.ACCESS_COARSE_LOCATION); 16 | 17 | @Rule 18 | public ActivityTestRule rule = 19 | new ActivityTestRule<>(MainActivity.class, true, false); 20 | } -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 18 | 22 | 25 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 40 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/mapbox/maps/mapbox_maps_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.maps.mapbox_maps_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = '../build' 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | project.evaluationDependsOn(':app') 12 | } 13 | 14 | tasks.register("clean", Delete) { 15 | delete rootProject.buildDir 16 | } 17 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4096M 2 | android.useAndroidX=true 3 | android.enableJetifier=false 4 | useLocalDependencies=false 5 | -------------------------------------------------------------------------------- /example/android/gradle/ktlint.gradle: -------------------------------------------------------------------------------- 1 | configurations { 2 | ktlint 3 | } 4 | 5 | dependencies { 6 | ktlint "com.pinterest:ktlint:0.39.0" 7 | } 8 | 9 | task ktlint(type: JavaExec, group: "verification") { 10 | description = "Check Kotlin code style." 11 | classpath = configurations.ktlint 12 | main = "com.pinterest.ktlint.Main" 13 | args "src/**/*.kt" 14 | } 15 | 16 | task ktlintFormat(type: JavaExec, group: "formatting") { 17 | description = "Fix Kotlin code style deviations." 18 | classpath = configurations.ktlint 19 | main = "com.pinterest.ktlint.Main" 20 | args "-F", "src/**/*.kt" 21 | } -------------------------------------------------------------------------------- /example/android/gradle/lint.gradle: -------------------------------------------------------------------------------- 1 | android { 2 | lintOptions { 3 | checkReleaseBuilds false 4 | warningsAsErrors true 5 | xmlReport false 6 | disable 'AllowBackup', 'UnusedResources' 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Apr 30 20:27:36 EEST 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "7.3.1" apply false 22 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false 23 | } 24 | 25 | include ":app" 26 | 27 | if (file("../../../scripts/utils.gradle").exists()) { 28 | apply from: "../../../scripts/utils.gradle" 29 | setupExtendedDebugEnvironment() 30 | } 31 | -------------------------------------------------------------------------------- /example/assets/cluster/cluster_count_layer.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cluster-count", 3 | "type": "symbol", 4 | "source": "earthquakes", 5 | "filter": [ 6 | "has", 7 | "point_count" 8 | ], 9 | "layout": { 10 | "text-field": "{point_count_abbreviated}", 11 | "text-font": [ 12 | "DIN Offc Pro Medium", 13 | "Arial Unicode MS Bold" 14 | ], 15 | "text-size": 12 16 | } 17 | } -------------------------------------------------------------------------------- /example/assets/cluster/cluster_layer.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "clusters", 3 | "type": "circle", 4 | "source": "earthquakes", 5 | "filter": [ 6 | "has", 7 | "point_count" 8 | ], 9 | "paint": { 10 | "circle-color": [ 11 | "step", 12 | [ 13 | "get", 14 | "point_count" 15 | ], 16 | "#51bbd6", 17 | 100, 18 | "#f1f075", 19 | 750, 20 | "#f28cb1" 21 | ], 22 | "circle-radius": [ 23 | "step", 24 | [ 25 | "get", 26 | "point_count" 27 | ], 28 | 20, 29 | 100, 30 | 30, 31 | 750, 32 | 40 33 | ] 34 | } 35 | } -------------------------------------------------------------------------------- /example/assets/cluster/cluster_source.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "geojson", 3 | "data": "https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson", 4 | "cluster": true, 5 | "clusterMaxZoom": 14, 6 | "clusterRadius": 50 7 | } -------------------------------------------------------------------------------- /example/assets/cluster/unclustered_point_layer.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "unclustered-point", 3 | "type": "circle", 4 | "source": "earthquakes", 5 | "filter": [ 6 | "!", 7 | [ 8 | "has", 9 | "point_count" 10 | ] 11 | ], 12 | "paint": { 13 | "circle-color": "#11b4da", 14 | "circle-radius": 4, 15 | "circle-stroke-width": 1, 16 | "circle-stroke-color": "#fff" 17 | } 18 | } -------------------------------------------------------------------------------- /example/assets/from_crema_to_council_crest.geojson: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "features": [ 4 | { 5 | "type": "Feature", 6 | "id": "featureID", 7 | "properties": { 8 | "name": "Crema to Council Crest" 9 | }, 10 | "geometry": { 11 | "type": "LineString", 12 | "coordinates": [ 13 | [-122.483696, 37.833818], 14 | [-122.483482, 37.833174], 15 | [-122.483396, 37.8327], 16 | [-122.483568, 37.832056], 17 | [-122.48404, 37.831141], 18 | [-122.48404, 37.830497], 19 | [-122.483482, 37.82992], 20 | [-122.483568, 37.829548], 21 | [-122.48507, 37.829446], 22 | [-122.4861, 37.828802], 23 | [-122.486958, 37.82931], 24 | [-122.487001, 37.830802], 25 | [-122.487516, 37.831683], 26 | [-122.488031, 37.832158], 27 | [-122.488889, 37.832971], 28 | [-122.489876, 37.832632], 29 | [-122.490434, 37.832937], 30 | [-122.49125, 37.832429], 31 | [-122.491636, 37.832564], 32 | [-122.492237, 37.833378], 33 | [-122.493782, 37.833683] 34 | ] 35 | } 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /example/assets/layer.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom", 3 | "type": "circle", 4 | "source": "source", 5 | "paint": { 6 | "circle-radius": 20, 7 | "circle-color": "#FF3300", 8 | "circle-pitch-alignment": "map" 9 | } 10 | } -------------------------------------------------------------------------------- /example/assets/miami_beach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/assets/miami_beach.png -------------------------------------------------------------------------------- /example/assets/point_layer.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "points", 3 | "type": "symbol", 4 | "source": "source", 5 | "layout": { 6 | "icon-image": "icon", 7 | "icon-size": 1 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/assets/raster_array_layers.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 8, 3 | "name": "Temperature", 4 | "sources": { 5 | "mapbox": { 6 | "type": "raster-array", 7 | "tiles": ["mapbox://tiles/example/{z}/{x}/{y}.mrt"], 8 | "scheme": "xyz", 9 | "minzoom": 1, 10 | "maxzoom": 4, 11 | "attribution": "mapbox", 12 | "volatile": true, 13 | "raster_layers": [ 14 | { 15 | "fields": { 16 | "bands": [ 17 | "1659898800", "1659902400", "1659906000", "1659909600", "1659913200", "1659916800" 18 | ], 19 | "buffer": 1, 20 | "units": "degrees" 21 | }, 22 | "id": "temperature", 23 | "maxzoom": 3, 24 | "minzoom": 0 25 | }, 26 | { 27 | "fields": { 28 | "bands": [ 29 | "1659898800", "1659902400", "1659906000", "1659909600", "1659913200", "1659916800" 30 | ], 31 | "buffer": 1, 32 | "units": "percent" 33 | }, 34 | "id": "humidity", 35 | "maxzoom": 3, 36 | "minzoom": 0 37 | } 38 | ] 39 | } 40 | }, 41 | "layers": [ 42 | { 43 | "id": "temperature", 44 | "type": "raster", 45 | "source": "mapbox", 46 | "source-layer": "temperature", 47 | "paint": { 48 | "raster-color": [ 49 | "interpolate", 50 | [ 51 | "linear" 52 | ], 53 | [ 54 | "raster-value" 55 | ], 56 | -5, 57 | "rgba(94, 79, 162, 0.8)", 58 | 0, 59 | "rgba(75, 160, 177, 0.8)", 60 | 5, 61 | "rgba(160, 217, 163, 0.8)", 62 | 10, 63 | "rgba(235, 247, 166, 0.8)", 64 | 15, 65 | "rgba(254, 232, 154, 0.8)", 66 | 20, 67 | "rgba(251, 163, 94, 0.8)", 68 | 25, 69 | "rgba(225, 82, 74, 0.8)", 70 | 30, 71 | "rgba(158, 1, 66, 0.8)" 72 | ], 73 | "raster-color-range": [-5, 30] 74 | } 75 | }] 76 | } -------------------------------------------------------------------------------- /example/assets/source.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "geojson", 3 | "title": "Mapbox Garage", 4 | "attribution":"© Mapbox", 5 | "marker-symbol": "monument", 6 | "data": { 7 | "type": "Feature", 8 | "id": "point", 9 | "geometry": { 10 | "type": "Point", 11 | "coordinates": [ 12 | -77.032667, 13 | 38.913175 14 | ] 15 | }, 16 | "properties": { 17 | "title": "Mapbox Garage", 18 | "marker-symbol": "monument" 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /example/assets/sportcar.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/assets/sportcar.glb -------------------------------------------------------------------------------- /example/assets/style.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 8, 3 | "name": "Land", 4 | "metadata": { 5 | "mapbox:autocomposite": true 6 | }, 7 | "sources": { 8 | "composite": { 9 | "url": "mapbox://mapbox.mapbox-terrain-v2", 10 | "type": "vector" 11 | } 12 | }, 13 | "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", 14 | "layers": [ 15 | { 16 | "layout": { 17 | "visibility": "visible" 18 | }, 19 | "type": "fill", 20 | "source": "composite", 21 | "id": "admin", 22 | "paint": { 23 | "fill-color": "hsl(359, 100%, 50%)", 24 | "fill-opacity": 1 25 | }, 26 | "source-layer": "landcover" 27 | }, 28 | { 29 | "layout": { 30 | "visibility": "visible" 31 | }, 32 | "type": "fill", 33 | "source": "composite", 34 | "id": "layer-0", 35 | "paint": { 36 | "fill-opacity": 1, 37 | "fill-color": "hsl(359, 100%, 50%)" 38 | }, 39 | "source-layer": "Layer_0" 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /example/assets/symbols/2.0x/custom-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/assets/symbols/2.0x/custom-icon.png -------------------------------------------------------------------------------- /example/assets/symbols/3.0x/custom-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/assets/symbols/3.0x/custom-icon.png -------------------------------------------------------------------------------- /example/assets/symbols/custom-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/assets/symbols/custom-icon.png -------------------------------------------------------------------------------- /example/integration_test/annotations/circle_annotation_test.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | import 'package:integration_test/integration_test.dart'; 5 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 6 | import '../empty_map_widget.dart' as app; 7 | 8 | void main() { 9 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 10 | 11 | testWidgets('create CircleAnnotation', (WidgetTester tester) async { 12 | final mapFuture = app.main(); 13 | await tester.pumpAndSettle(); 14 | final mapboxMap = await mapFuture; 15 | final manager = await mapboxMap.annotations.createCircleAnnotationManager(); 16 | var geometry = Point(coordinates: Position(1.0, 2.0)); 17 | 18 | var circleAnnotationOptions = CircleAnnotationOptions( 19 | geometry: geometry, 20 | circleSortKey: 1.0, 21 | circleBlur: 1.0, 22 | circleColor: Colors.red.value, 23 | circleOpacity: 1.0, 24 | circleRadius: 1.0, 25 | circleStrokeColor: Colors.red.value, 26 | circleStrokeOpacity: 1.0, 27 | circleStrokeWidth: 1.0, 28 | ); 29 | final annotation = await manager.create(circleAnnotationOptions); 30 | var point = annotation.geometry; 31 | expect(1.0, point.coordinates.lng); 32 | expect(2.0, point.coordinates.lat); 33 | expect(1.0, annotation.circleSortKey); 34 | expect(1.0, annotation.circleBlur); 35 | expect(Colors.red.value, annotation.circleColor); 36 | expect(1.0, annotation.circleOpacity); 37 | expect(1.0, annotation.circleRadius); 38 | expect(Colors.red.value, annotation.circleStrokeColor); 39 | expect(1.0, annotation.circleStrokeOpacity); 40 | expect(1.0, annotation.circleStrokeWidth); 41 | }); 42 | 43 | testWidgets('update and delete CircleAnnotation', 44 | (WidgetTester tester) async { 45 | final mapFuture = app.main(); 46 | await tester.pumpAndSettle(); 47 | final mapboxMap = await mapFuture; 48 | final manager = await mapboxMap.annotations.createCircleAnnotationManager(); 49 | var geometry = Point(coordinates: Position(1.0, 2.0)); 50 | 51 | var circleAnnotationOptions = CircleAnnotationOptions( 52 | geometry: geometry, 53 | ); 54 | final annotation = await manager.create(circleAnnotationOptions); 55 | var point = annotation.geometry; 56 | var newPoint = Point( 57 | coordinates: 58 | Position(point.coordinates.lng + 1.0, point.coordinates.lat + 1.0)); 59 | annotation.geometry = newPoint; 60 | await manager.update(annotation); 61 | await manager.delete(annotation); 62 | 63 | for (var i = 0; i < 10; i++) { 64 | await manager.create(circleAnnotationOptions); 65 | } 66 | 67 | await manager.deleteAll(); 68 | }); 69 | } 70 | // End of generated file. 71 | -------------------------------------------------------------------------------- /example/integration_test/attribution_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_test/flutter_test.dart'; 5 | import 'package:integration_test/integration_test.dart'; 6 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 7 | import 'empty_map_widget.dart' as app; 8 | 9 | void main() { 10 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 11 | 12 | testWidgets('Attribution settings', (WidgetTester tester) async { 13 | final mapFuture = app.main(); 14 | await tester.pumpAndSettle(); 15 | final mapboxMap = await mapFuture; 16 | final attribution = mapboxMap.attribution; 17 | var settings = AttributionSettings( 18 | enabled: false, 19 | iconColor: Colors.blue.value, 20 | position: OrnamentPosition.TOP_RIGHT, 21 | marginLeft: 1, 22 | marginTop: 2, 23 | marginRight: 3, 24 | marginBottom: 4, 25 | clickable: true, 26 | ); 27 | await attribution.updateSettings(settings); 28 | var updatedSettings = await attribution.getSettings(); 29 | expect(updatedSettings.enabled, isFalse); 30 | expect(updatedSettings.position, OrnamentPosition.TOP_RIGHT); 31 | expect(updatedSettings.iconColor, Colors.blue.value); 32 | if (Platform.isIOS) { 33 | // on iOS margins for the current position are preserved 34 | expect(updatedSettings.marginTop, 2); 35 | expect(updatedSettings.marginRight, 3); 36 | } else { 37 | expect(updatedSettings.marginLeft, 1); 38 | expect(updatedSettings.marginTop, 2); 39 | expect(updatedSettings.marginRight, 3); 40 | expect(updatedSettings.marginBottom, 4); 41 | expect(updatedSettings.clickable, true); 42 | } 43 | }); 44 | } 45 | -------------------------------------------------------------------------------- /example/integration_test/compass_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/services.dart'; 4 | import 'package:flutter_test/flutter_test.dart'; 5 | import 'package:integration_test/integration_test.dart'; 6 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 7 | import 'empty_map_widget.dart' as app; 8 | 9 | void main() { 10 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 11 | 12 | testWidgets('Compass settings', (WidgetTester tester) async { 13 | final mapFuture = app.main(); 14 | await tester.pumpAndSettle(); 15 | final mapboxMap = await mapFuture; 16 | final compass = mapboxMap.compass; 17 | final ByteData bytes = 18 | await rootBundle.load('assets/symbols/custom-icon.png'); 19 | final Uint8List iconData = bytes.buffer.asUint8List(); 20 | var settings = CompassSettings( 21 | enabled: true, 22 | position: OrnamentPosition.TOP_LEFT, 23 | marginLeft: 1, 24 | marginTop: 2, 25 | marginRight: 3, 26 | marginBottom: 4, 27 | opacity: 0.5, 28 | rotation: 10, 29 | visibility: true, 30 | fadeWhenFacingNorth: true, 31 | clickable: true, 32 | image: iconData, 33 | ); 34 | await compass.updateSettings(settings); 35 | var updatedSettings = await compass.getSettings(); 36 | expect(updatedSettings.position, OrnamentPosition.TOP_LEFT); 37 | expect(updatedSettings.fadeWhenFacingNorth, true); 38 | expect(updatedSettings.visibility, true); 39 | if (Platform.isIOS) { 40 | expect(updatedSettings.marginLeft, 1); 41 | expect(updatedSettings.marginTop, 2); 42 | } else { 43 | expect(updatedSettings.enabled, true); 44 | expect(updatedSettings.marginLeft, 1); 45 | expect(updatedSettings.marginTop, 2); 46 | expect(updatedSettings.marginRight, 3); 47 | expect(updatedSettings.marginBottom, 4); 48 | expect(updatedSettings.clickable, true); 49 | expect(updatedSettings.opacity, 0.5); 50 | expect(updatedSettings.rotation, 10); 51 | expect(updatedSettings.clickable, true); 52 | // FIXME failing test 53 | // expect(updatedSettings.image, iconData); 54 | } 55 | }); 56 | } 57 | -------------------------------------------------------------------------------- /example/integration_test/logo_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | import 'package:integration_test/integration_test.dart'; 5 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 6 | import 'empty_map_widget.dart' as app; 7 | 8 | void main() { 9 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 10 | 11 | testWidgets('Logo settings', (WidgetTester tester) async { 12 | final mapFuture = app.main(); 13 | await tester.pumpAndSettle(); 14 | final mapboxMap = await mapFuture; 15 | final logo = mapboxMap.logo; 16 | var settings = LogoSettings( 17 | enabled: false, 18 | position: OrnamentPosition.BOTTOM_LEFT, 19 | marginLeft: 1, 20 | marginTop: 2, 21 | marginRight: 3, 22 | marginBottom: 4); 23 | await logo.updateSettings(settings); 24 | var getSettings = await logo.getSettings(); 25 | expect(getSettings.position, OrnamentPosition.BOTTOM_LEFT); 26 | expect(getSettings.enabled, isFalse); 27 | if (Platform.isIOS) { 28 | expect(getSettings.marginLeft, 1); 29 | expect(getSettings.marginBottom, 4); 30 | } else { 31 | expect(getSettings.marginLeft, 1); 32 | expect(getSettings.marginTop, 2); 33 | expect(getSettings.marginRight, 3); 34 | expect(getSettings.marginBottom, 4); 35 | } 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /example/integration_test/projection_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:integration_test/integration_test.dart'; 3 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 4 | import 'empty_map_widget.dart' as app; 5 | 6 | void main() { 7 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 8 | 9 | testWidgets('getMetersPerPixelAtLatitude', (WidgetTester tester) async { 10 | final mapFuture = app.main(); 11 | await tester.pumpAndSettle(); 12 | 13 | final mapboxMap = await mapFuture; 14 | var meters = 15 | await mapboxMap.projection.getMetersPerPixelAtLatitude(1.0, 16.0); 16 | expect(meters.round(), 1); 17 | }); 18 | 19 | testWidgets('projectedMetersForCoordinate', (WidgetTester tester) async { 20 | final mapFuture = app.main(); 21 | await tester.pumpAndSettle(); 22 | 23 | final mapboxMap = await mapFuture; 24 | var projectedMeters = 25 | await mapboxMap.projection.projectedMetersForCoordinate(Point( 26 | coordinates: Position( 27 | 1.0, 28 | 60, 29 | ))); 30 | expect(projectedMeters.easting.floor(), 111195); 31 | expect(projectedMeters.northing.floor(), 8390350); 32 | }); 33 | 34 | testWidgets('coordinateForProjectedMeters', (WidgetTester tester) async { 35 | final mapFuture = app.main(); 36 | await tester.pumpAndSettle(); 37 | 38 | final mapboxMap = await mapFuture; 39 | final point = await mapboxMap.projection.coordinateForProjectedMeters( 40 | ProjectedMeters(northing: 100000.0, easting: 100000.0)); 41 | expect((point.coordinates.lng as double).floor(), 0); 42 | expect((point.coordinates.lat as double).floor(), 0); 43 | }); 44 | 45 | testWidgets('unproject', (WidgetTester tester) async { 46 | final mapFuture = app.main(); 47 | await tester.pumpAndSettle(); 48 | 49 | final mapboxMap = await mapFuture; 50 | final point = await mapboxMap.projection 51 | .unproject(MercatorCoordinate(x: 1.0, y: 1.0), 16); 52 | expect((point.coordinates.lng as double).floor(), -180); 53 | expect((point.coordinates.lat as double).floor(), 85); 54 | }); 55 | 56 | testWidgets('project', (WidgetTester tester) async { 57 | final mapFuture = app.main(); 58 | await tester.pumpAndSettle(); 59 | 60 | final mapboxMap = await mapFuture; 61 | var mercatorCoordinate = await mapboxMap.projection.project( 62 | Point( 63 | coordinates: Position( 64 | 1.0, 65 | 60, 66 | )), 67 | 16); 68 | expect(mercatorCoordinate.x.floor(), 4118); 69 | expect(mercatorCoordinate.y.floor(), 2378); 70 | }); 71 | } 72 | -------------------------------------------------------------------------------- /example/integration_test/scale_bar_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_test/flutter_test.dart'; 5 | import 'package:integration_test/integration_test.dart'; 6 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 7 | import 'empty_map_widget.dart' as app; 8 | 9 | void main() { 10 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 11 | 12 | testWidgets('ScaleBar settings', (WidgetTester tester) async { 13 | final mapFuture = app.main(); 14 | await tester.pumpAndSettle(); 15 | final mapboxMap = await mapFuture; 16 | final scaleBar = mapboxMap.scaleBar; 17 | var settings = ScaleBarSettings( 18 | enabled: true, 19 | position: OrnamentPosition.BOTTOM_RIGHT, 20 | marginLeft: 1, 21 | marginTop: 2, 22 | marginRight: 3, 23 | marginBottom: 4, 24 | textColor: Colors.black.value, 25 | primaryColor: Colors.red.value, 26 | secondaryColor: Colors.blue.value, 27 | borderWidth: 2, 28 | height: 10, 29 | textBarMargin: 1, 30 | textBorderWidth: 2, 31 | textSize: 10, 32 | isMetricUnits: true, 33 | refreshInterval: 10, 34 | showTextBorder: true, 35 | ratio: 1.5, 36 | useContinuousRendering: true, 37 | ); 38 | await scaleBar.updateSettings(settings); 39 | var updatedSettings = await scaleBar.getSettings(); 40 | expect(updatedSettings.position, OrnamentPosition.BOTTOM_RIGHT); 41 | expect(updatedSettings.isMetricUnits, true); 42 | if (Platform.isIOS) { 43 | expect(updatedSettings.marginRight, 3); 44 | expect(updatedSettings.marginBottom, 4); 45 | } else { 46 | expect(updatedSettings.marginLeft, 1); 47 | expect(updatedSettings.marginTop, 2); 48 | expect(updatedSettings.marginRight, 3); 49 | expect(updatedSettings.marginBottom, 4); 50 | // iOS doesn't support these settings 51 | expect(updatedSettings.textColor, Colors.black.value); 52 | expect(updatedSettings.primaryColor, Colors.red.value); 53 | expect(updatedSettings.secondaryColor, Colors.blue.value); 54 | expect(updatedSettings.borderWidth, 2); 55 | expect(updatedSettings.height, 10); 56 | expect(updatedSettings.textBarMargin, 1); 57 | expect(updatedSettings.textBorderWidth, 2); 58 | expect(updatedSettings.textSize, 10); 59 | expect(updatedSettings.refreshInterval, 10); 60 | expect(updatedSettings.showTextBorder, true); 61 | expect(updatedSettings.ratio, 1.5); 62 | expect(updatedSettings.useContinuousRendering, true); 63 | } 64 | }); 65 | } 66 | -------------------------------------------------------------------------------- /example/integration_test/style/layer/clip_layer_test.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:integration_test/integration_test.dart'; 4 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 5 | import '../../empty_map_widget.dart' as app; 6 | 7 | void main() { 8 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | testWidgets('Add ClipLayer', (WidgetTester tester) async { 11 | final mapFuture = app.main(); 12 | await tester.pumpAndSettle(); 13 | final mapboxMap = await mapFuture; 14 | 15 | await mapboxMap.style.addLayer(ClipLayer( 16 | id: 'layer', 17 | sourceId: 'source', 18 | visibility: Visibility.NONE, 19 | minZoom: 1.0, 20 | maxZoom: 20.0, 21 | slot: LayerSlot.BOTTOM, 22 | clipLayerScope: ["a", "b", "c"], 23 | clipLayerTypes: ["model", "symbol"], 24 | )); 25 | var layer = await mapboxMap.style.getLayer('layer') as ClipLayer; 26 | expect('source', layer.sourceId); 27 | expect(layer.minZoom, 1); 28 | expect(layer.maxZoom, 20); 29 | expect(layer.slot, LayerSlot.BOTTOM); 30 | expect(layer.visibility, Visibility.NONE); 31 | expect(layer.clipLayerScope, ["a", "b", "c"]); 32 | expect(layer.clipLayerTypes, ["model", "symbol"]); 33 | }); 34 | 35 | testWidgets('Add ClipLayer with expressions', (WidgetTester tester) async { 36 | final mapFuture = app.main(); 37 | await tester.pumpAndSettle(); 38 | final mapboxMap = await mapFuture; 39 | 40 | await mapboxMap.style.addLayer(ClipLayer( 41 | id: 'layer', 42 | sourceId: 'source', 43 | visibilityExpression: ['string', 'none'], 44 | filter: [ 45 | "==", 46 | ["get", "type"], 47 | "Feature" 48 | ], 49 | minZoom: 1.0, 50 | maxZoom: 20.0, 51 | slot: LayerSlot.BOTTOM, 52 | clipLayerScopeExpression: [ 53 | 'literal', 54 | ["a", "b", "c"] 55 | ], 56 | clipLayerTypesExpression: [ 57 | 'literal', 58 | ["model", "symbol"] 59 | ], 60 | )); 61 | var layer = await mapboxMap.style.getLayer('layer') as ClipLayer; 62 | expect('source', layer.sourceId); 63 | expect(layer.minZoom, 1); 64 | expect(layer.maxZoom, 20); 65 | expect(layer.slot, LayerSlot.BOTTOM); 66 | expect(layer.visibility, Visibility.NONE); 67 | expect(layer.filter, [ 68 | "==", 69 | ["get", "type"], 70 | "Feature" 71 | ]); 72 | expect(layer.clipLayerScope, ["a", "b", "c"]); 73 | expect(layer.clipLayerTypes, ["model", "symbol"]); 74 | }); 75 | } 76 | // End of generated file. 77 | -------------------------------------------------------------------------------- /example/integration_test/style/layer/slot_layer_test.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:integration_test/integration_test.dart'; 4 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 5 | import '../../empty_map_widget.dart' as app; 6 | 7 | void main() { 8 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | testWidgets('Add SlotLayer', (WidgetTester tester) async { 11 | final mapFuture = app.main(); 12 | await tester.pumpAndSettle(); 13 | final mapboxMap = await mapFuture; 14 | 15 | await mapboxMap.style.addLayer(SlotLayer( 16 | id: 'layer', 17 | visibility: Visibility.NONE, 18 | minZoom: 1.0, 19 | maxZoom: 20.0, 20 | slot: LayerSlot.BOTTOM, 21 | )); 22 | var layer = await mapboxMap.style.getLayer('layer') as SlotLayer; 23 | expect(layer.minZoom, 1); 24 | expect(layer.maxZoom, 20); 25 | expect(layer.slot, LayerSlot.BOTTOM); 26 | expect(layer.visibility, Visibility.NONE); 27 | }); 28 | 29 | testWidgets('Add SlotLayer with expressions', (WidgetTester tester) async { 30 | final mapFuture = app.main(); 31 | await tester.pumpAndSettle(); 32 | final mapboxMap = await mapFuture; 33 | 34 | await mapboxMap.style.addLayer(SlotLayer( 35 | id: 'layer', 36 | visibilityExpression: ['string', 'none'], 37 | filter: [ 38 | "==", 39 | ["get", "type"], 40 | "Feature" 41 | ], 42 | minZoom: 1.0, 43 | maxZoom: 20.0, 44 | slot: LayerSlot.BOTTOM, 45 | )); 46 | var layer = await mapboxMap.style.getLayer('layer') as SlotLayer; 47 | expect(layer.minZoom, 1); 48 | expect(layer.maxZoom, 20); 49 | expect(layer.slot, LayerSlot.BOTTOM); 50 | expect(layer.visibility, Visibility.NONE); 51 | expect(layer.filter, [ 52 | "==", 53 | ["get", "type"], 54 | "Feature" 55 | ]); 56 | }); 57 | } 58 | // End of generated file. 59 | -------------------------------------------------------------------------------- /example/integration_test/style/source/image_source_test.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:integration_test/integration_test.dart'; 4 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 5 | import '../../empty_map_widget.dart' as app; 6 | 7 | void main() { 8 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | testWidgets('Add ImageSource', (WidgetTester tester) async { 11 | final mapFuture = app.main(); 12 | await tester.pumpAndSettle(); 13 | final mapboxMap = await mapFuture; 14 | await app.events.onMapLoaded.future; 15 | 16 | await mapboxMap.style.addSource(ImageSource( 17 | id: "source", 18 | coordinates: [ 19 | [0.0, 1.0], 20 | [0.0, 1.0], 21 | [0.0, 1.0], 22 | [0.0, 1.0] 23 | ], 24 | prefetchZoomDelta: 1.0, 25 | )); 26 | 27 | var source = await mapboxMap.style.getSource('source') as ImageSource; 28 | expect(source.id, 'source'); 29 | var coordinates = await source.coordinates; 30 | expect(coordinates, [ 31 | [0.0, 1.0], 32 | [0.0, 1.0], 33 | [0.0, 1.0], 34 | [0.0, 1.0] 35 | ]); 36 | 37 | var prefetchZoomDelta = await source.prefetchZoomDelta; 38 | expect(prefetchZoomDelta, 1.0); 39 | }); 40 | } 41 | // End of generated file. 42 | -------------------------------------------------------------------------------- /example/integration_test/style/source/raster_source_test.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:integration_test/integration_test.dart'; 4 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 5 | import '../../empty_map_widget.dart' as app; 6 | 7 | void main() { 8 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | testWidgets('Add RasterSource', (WidgetTester tester) async { 11 | final mapFuture = app.main(); 12 | await tester.pumpAndSettle(); 13 | final mapboxMap = await mapFuture; 14 | await app.events.onMapLoaded.future; 15 | 16 | await mapboxMap.style.addSource(RasterSource( 17 | id: "source", 18 | tiles: ["a", "b", "c"], 19 | bounds: [0.0, 1.0, 2.0, 3.0], 20 | minzoom: 1.0, 21 | maxzoom: 1.0, 22 | tileSize: 1.0, 23 | scheme: Scheme.XYZ, 24 | attribution: "abc", 25 | volatile: true, 26 | prefetchZoomDelta: 1.0, 27 | tileCacheBudget: 28 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)), 29 | minimumTileUpdateInterval: 1.0, 30 | maxOverscaleFactorForParentTiles: 1.0, 31 | tileRequestsDelay: 1.0, 32 | tileNetworkRequestsDelay: 1.0, 33 | )); 34 | 35 | var source = await mapboxMap.style.getSource('source') as RasterSource; 36 | expect(source.id, 'source'); 37 | var tiles = await source.tiles; 38 | expect(tiles, ["a", "b", "c"]); 39 | 40 | var bounds = await source.bounds; 41 | expect(bounds, [0.0, 1.0, 2.0, 3.0]); 42 | 43 | var minzoom = await source.minzoom; 44 | expect(minzoom, 1.0); 45 | 46 | var maxzoom = await source.maxzoom; 47 | expect(maxzoom, 1.0); 48 | 49 | var tileSize = await source.tileSize; 50 | expect(tileSize, 1.0); 51 | 52 | var scheme = await source.scheme; 53 | expect(scheme, Scheme.XYZ); 54 | 55 | var attribution = await source.attribution; 56 | expect(attribution, "abc"); 57 | 58 | var volatile = await source.volatile; 59 | expect(volatile, true); 60 | 61 | var prefetchZoomDelta = await source.prefetchZoomDelta; 62 | expect(prefetchZoomDelta, 1.0); 63 | 64 | var tileCacheBudget = await source.tileCacheBudget; 65 | expect(tileCacheBudget?.size, 66 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)).size); 67 | expect(tileCacheBudget?.type, 68 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)).type); 69 | 70 | var minimumTileUpdateInterval = await source.minimumTileUpdateInterval; 71 | expect(minimumTileUpdateInterval, 1.0); 72 | 73 | var maxOverscaleFactorForParentTiles = 74 | await source.maxOverscaleFactorForParentTiles; 75 | expect(maxOverscaleFactorForParentTiles, 1.0); 76 | 77 | var tileRequestsDelay = await source.tileRequestsDelay; 78 | expect(tileRequestsDelay, 1.0); 79 | 80 | var tileNetworkRequestsDelay = await source.tileNetworkRequestsDelay; 81 | expect(tileNetworkRequestsDelay, 1.0); 82 | }); 83 | } 84 | // End of generated file. 85 | -------------------------------------------------------------------------------- /example/integration_test/style/source/rasterarray_source_test.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:integration_test/integration_test.dart'; 4 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 5 | import '../../empty_map_widget.dart' as app; 6 | 7 | void main() { 8 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | testWidgets('Add RasterArraySource', (WidgetTester tester) async { 11 | final mapFuture = app.main(); 12 | await tester.pumpAndSettle(); 13 | final mapboxMap = await mapFuture; 14 | await app.events.onMapLoaded.future; 15 | 16 | await mapboxMap.style.addSource(RasterArraySource( 17 | id: "source", 18 | tiles: ["a", "b", "c"], 19 | bounds: [0.0, 1.0, 2.0, 3.0], 20 | minzoom: 1.0, 21 | maxzoom: 1.0, 22 | tileSize: 1.0, 23 | attribution: "abc", 24 | tileCacheBudget: 25 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)), 26 | )); 27 | 28 | var source = await mapboxMap.style.getSource('source') as RasterArraySource; 29 | expect(source.id, 'source'); 30 | var tiles = await source.tiles; 31 | expect(tiles, ["a", "b", "c"]); 32 | 33 | var bounds = await source.bounds; 34 | expect(bounds, [0.0, 1.0, 2.0, 3.0]); 35 | 36 | var minzoom = await source.minzoom; 37 | expect(minzoom, 1.0); 38 | 39 | var maxzoom = await source.maxzoom; 40 | expect(maxzoom, 1.0); 41 | 42 | var tileSize = await source.tileSize; 43 | expect(tileSize, 1.0); 44 | 45 | var attribution = await source.attribution; 46 | expect(attribution, "abc"); 47 | 48 | var tileCacheBudget = await source.tileCacheBudget; 49 | expect(tileCacheBudget?.size, 50 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)).size); 51 | expect(tileCacheBudget?.type, 52 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)).type); 53 | }); 54 | } 55 | // End of generated file. 56 | -------------------------------------------------------------------------------- /example/integration_test/style/source/rasterdem_source_test.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:integration_test/integration_test.dart'; 4 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 5 | import '../../empty_map_widget.dart' as app; 6 | 7 | void main() { 8 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | testWidgets('Add RasterDemSource', (WidgetTester tester) async { 11 | final mapFuture = app.main(); 12 | await tester.pumpAndSettle(); 13 | final mapboxMap = await mapFuture; 14 | await app.events.onMapLoaded.future; 15 | 16 | await mapboxMap.style.addSource(RasterDemSource( 17 | id: "source", 18 | tiles: ["a", "b", "c"], 19 | bounds: [0.0, 1.0, 2.0, 3.0], 20 | minzoom: 1.0, 21 | maxzoom: 1.0, 22 | tileSize: 1.0, 23 | attribution: "abc", 24 | encoding: Encoding.TERRARIUM, 25 | volatile: true, 26 | prefetchZoomDelta: 1.0, 27 | tileCacheBudget: 28 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)), 29 | minimumTileUpdateInterval: 1.0, 30 | maxOverscaleFactorForParentTiles: 1.0, 31 | tileRequestsDelay: 1.0, 32 | tileNetworkRequestsDelay: 1.0, 33 | )); 34 | 35 | var source = await mapboxMap.style.getSource('source') as RasterDemSource; 36 | expect(source.id, 'source'); 37 | var tiles = await source.tiles; 38 | expect(tiles, ["a", "b", "c"]); 39 | 40 | var bounds = await source.bounds; 41 | expect(bounds, [0.0, 1.0, 2.0, 3.0]); 42 | 43 | var minzoom = await source.minzoom; 44 | expect(minzoom, 1.0); 45 | 46 | var maxzoom = await source.maxzoom; 47 | expect(maxzoom, 1.0); 48 | 49 | var tileSize = await source.tileSize; 50 | expect(tileSize, 1.0); 51 | 52 | var attribution = await source.attribution; 53 | expect(attribution, "abc"); 54 | 55 | var encoding = await source.encoding; 56 | expect(encoding, Encoding.TERRARIUM); 57 | 58 | var volatile = await source.volatile; 59 | expect(volatile, true); 60 | 61 | var prefetchZoomDelta = await source.prefetchZoomDelta; 62 | expect(prefetchZoomDelta, 1.0); 63 | 64 | var tileCacheBudget = await source.tileCacheBudget; 65 | expect(tileCacheBudget?.size, 66 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)).size); 67 | expect(tileCacheBudget?.type, 68 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)).type); 69 | 70 | var minimumTileUpdateInterval = await source.minimumTileUpdateInterval; 71 | expect(minimumTileUpdateInterval, 1.0); 72 | 73 | var maxOverscaleFactorForParentTiles = 74 | await source.maxOverscaleFactorForParentTiles; 75 | expect(maxOverscaleFactorForParentTiles, 1.0); 76 | 77 | var tileRequestsDelay = await source.tileRequestsDelay; 78 | expect(tileRequestsDelay, 1.0); 79 | 80 | var tileNetworkRequestsDelay = await source.tileNetworkRequestsDelay; 81 | expect(tileNetworkRequestsDelay, 1.0); 82 | }); 83 | } 84 | // End of generated file. 85 | -------------------------------------------------------------------------------- /example/integration_test/style/source/vector_source_test.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:integration_test/integration_test.dart'; 4 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 5 | import '../../empty_map_widget.dart' as app; 6 | 7 | void main() { 8 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | testWidgets('Add VectorSource', (WidgetTester tester) async { 11 | final mapFuture = app.main(); 12 | await tester.pumpAndSettle(); 13 | final mapboxMap = await mapFuture; 14 | await app.events.onMapLoaded.future; 15 | 16 | await mapboxMap.style.addSource(VectorSource( 17 | id: "source", 18 | tiles: ["a", "b", "c"], 19 | bounds: [0.0, 1.0, 2.0, 3.0], 20 | scheme: Scheme.XYZ, 21 | minzoom: 1.0, 22 | maxzoom: 1.0, 23 | attribution: "abc", 24 | volatile: true, 25 | prefetchZoomDelta: 1.0, 26 | tileCacheBudget: 27 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)), 28 | minimumTileUpdateInterval: 1.0, 29 | maxOverscaleFactorForParentTiles: 1.0, 30 | tileRequestsDelay: 1.0, 31 | tileNetworkRequestsDelay: 1.0, 32 | )); 33 | 34 | var source = await mapboxMap.style.getSource('source') as VectorSource; 35 | expect(source.id, 'source'); 36 | var tiles = await source.tiles; 37 | expect(tiles, ["a", "b", "c"]); 38 | 39 | var bounds = await source.bounds; 40 | expect(bounds, [0.0, 1.0, 2.0, 3.0]); 41 | 42 | var scheme = await source.scheme; 43 | expect(scheme, Scheme.XYZ); 44 | 45 | var minzoom = await source.minzoom; 46 | expect(minzoom, 1.0); 47 | 48 | var maxzoom = await source.maxzoom; 49 | expect(maxzoom, 1.0); 50 | 51 | var attribution = await source.attribution; 52 | expect(attribution, "abc"); 53 | 54 | var volatile = await source.volatile; 55 | expect(volatile, true); 56 | 57 | var prefetchZoomDelta = await source.prefetchZoomDelta; 58 | expect(prefetchZoomDelta, 1.0); 59 | 60 | var tileCacheBudget = await source.tileCacheBudget; 61 | expect(tileCacheBudget?.size, 62 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)).size); 63 | expect(tileCacheBudget?.type, 64 | TileCacheBudget.inMegabytes(TileCacheBudgetInMegabytes(size: 3)).type); 65 | 66 | var minimumTileUpdateInterval = await source.minimumTileUpdateInterval; 67 | expect(minimumTileUpdateInterval, 1.0); 68 | 69 | var maxOverscaleFactorForParentTiles = 70 | await source.maxOverscaleFactorForParentTiles; 71 | expect(maxOverscaleFactorForParentTiles, 1.0); 72 | 73 | var tileRequestsDelay = await source.tileRequestsDelay; 74 | expect(tileRequestsDelay, 1.0); 75 | 76 | var tileNetworkRequestsDelay = await source.tileNetworkRequestsDelay; 77 | expect(tileNetworkRequestsDelay, 1.0); 78 | }); 79 | } 80 | // End of generated file. 81 | -------------------------------------------------------------------------------- /example/integration_test/utils/list_close_to_matcher.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | 3 | Matcher listCloseTo(List? value, num delta) => 4 | _IsListCloseTo(value, delta); 5 | 6 | class _IsListCloseTo extends Matcher { 7 | final List? _value; 8 | final num _delta; 9 | 10 | const _IsListCloseTo(this._value, this._delta); 11 | 12 | @override 13 | bool matches(dynamic list, Map matchState) { 14 | if (_value == null || list == null) { 15 | return false; 16 | } 17 | if (_value!.length != list.length) { 18 | return false; 19 | } 20 | for (var i = 0; i < _value!.length; i++) { 21 | final expected = _value![i]; 22 | final actual = list[i]; 23 | if (expected is num && actual is num) { 24 | final pairIsCloseTo = closeTo(expected, _delta).matches(actual, {}); 25 | if (!pairIsCloseTo) { 26 | return false; 27 | } 28 | } 29 | } 30 | return true; 31 | } 32 | 33 | @override 34 | Description describe(Description description) => description 35 | .add('a numeric value within ') 36 | .addDescriptionOf(_delta) 37 | .add(' of ') 38 | .addDescriptionOf(_value); 39 | } 40 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/ephemeral/ 22 | Flutter/app.flx 23 | Flutter/app.zip 24 | Flutter/flutter_assets/ 25 | Flutter/flutter_export_environment.sh 26 | ServiceDefinitions.json 27 | Runner/GeneratedPluginRegistrant.* 28 | 29 | # Exceptions to above rules. 30 | !default.mode1v3 31 | !default.mode2v3 32 | !default.pbxuser 33 | !default.perspectivev3 34 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 14.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "originHash" : "4318c2484ab9dc428393050abd1a2cf472742ce37f110e161575df4110dd38ab", 3 | "pins" : [ 4 | { 5 | "identity" : "mapbox-common-ios", 6 | "kind" : "remoteSourceControl", 7 | "location" : "https://github.com/mapbox/mapbox-common-ios.git", 8 | "state" : { 9 | "revision" : "69473089df0de073b89ece86977b17c75f519b5c", 10 | "version" : "24.13.0" 11 | } 12 | }, 13 | { 14 | "identity" : "mapbox-core-maps-ios", 15 | "kind" : "remoteSourceControl", 16 | "location" : "https://github.com/mapbox/mapbox-core-maps-ios.git", 17 | "state" : { 18 | "revision" : "8e62d3de5cc8d66b32c710a34df176e29e5c6777", 19 | "version" : "11.13.0" 20 | } 21 | }, 22 | { 23 | "identity" : "mapbox-maps-ios", 24 | "kind" : "remoteSourceControl", 25 | "location" : "https://github.com/mapbox/mapbox-maps-ios.git", 26 | "state" : { 27 | "revision" : "fe447519610f1a523e1b0f20645cc51c2438d545", 28 | "version" : "11.13.0" 29 | } 30 | }, 31 | { 32 | "identity" : "turf-swift", 33 | "kind" : "remoteSourceControl", 34 | "location" : "https://github.com/mapbox/turf-swift.git", 35 | "state" : { 36 | "revision" : "bf840e6b9529d105687840fe2c9dcd74197d46d1", 37 | "version" : "4.0.0" 38 | } 39 | } 40 | ], 41 | "version" : 3 42 | } 43 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "originHash" : "4318c2484ab9dc428393050abd1a2cf472742ce37f110e161575df4110dd38ab", 3 | "pins" : [ 4 | { 5 | "identity" : "mapbox-common-ios", 6 | "kind" : "remoteSourceControl", 7 | "location" : "https://github.com/mapbox/mapbox-common-ios.git", 8 | "state" : { 9 | "revision" : "69473089df0de073b89ece86977b17c75f519b5c", 10 | "version" : "24.13.0" 11 | } 12 | }, 13 | { 14 | "identity" : "mapbox-core-maps-ios", 15 | "kind" : "remoteSourceControl", 16 | "location" : "https://github.com/mapbox/mapbox-core-maps-ios.git", 17 | "state" : { 18 | "revision" : "8e62d3de5cc8d66b32c710a34df176e29e5c6777", 19 | "version" : "11.13.0" 20 | } 21 | }, 22 | { 23 | "identity" : "mapbox-maps-ios", 24 | "kind" : "remoteSourceControl", 25 | "location" : "https://github.com/mapbox/mapbox-maps-ios.git", 26 | "state" : { 27 | "revision" : "fe447519610f1a523e1b0f20645cc51c2438d545", 28 | "version" : "11.13.0" 29 | } 30 | }, 31 | { 32 | "identity" : "turf-swift", 33 | "kind" : "remoteSourceControl", 34 | "location" : "https://github.com/mapbox/turf-swift.git", 35 | "state" : { 36 | "revision" : "bf840e6b9529d105687840fe2c9dcd74197d46d1", 37 | "version" : "4.0.0" 38 | } 39 | } 40 | ], 41 | "version" : 3 42 | } 43 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import mapbox_maps_flutter 3 | import Flutter 4 | 5 | @main 6 | @objc class AppDelegate: FlutterAppDelegate { 7 | override func application( 8 | _ application: UIApplication, 9 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 10 | ) -> Bool { 11 | GeneratedPluginRegistrant.register(with: self) 12 | 13 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-maps-flutter/fe736f43d4623b4a7782a19236bb1b0305f35de3/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | mapbox_maps_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | 47 | NSLocationWhenInUseUsageDescription 48 | Need location when in use 49 | NSLocationAlwaysAndWhenInUseUsageDescription 50 | Always and when in use! 51 | NSLocationUsageDescription 52 | Older devices need location. 53 | NSLocationAlwaysUsageDescription 54 | Can I haz location always? 55 | UIApplicationSupportsIndirectInputEvents 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/ios/RunnerTests/RunnerTests.m: -------------------------------------------------------------------------------- 1 | @import XCTest; 2 | @import integration_test; 3 | 4 | INTEGRATION_TEST_IOS_RUNNER(RunnerTests) 5 | -------------------------------------------------------------------------------- /example/lib/custom_header_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 3 | 4 | import 'example.dart'; 5 | 6 | class CustomHeaderExample extends StatefulWidget implements Example { 7 | @override 8 | final Widget leading = const Icon(Icons.network_check); 9 | @override 10 | final String title = 'Custom Header Example'; 11 | @override 12 | final String? subtitle = null; 13 | 14 | @override 15 | State createState() => CustomHeaderExampleState(); 16 | } 17 | 18 | class CustomHeaderExampleState extends State { 19 | CustomHeaderExampleState(); 20 | 21 | MapboxMap? mapboxMap; 22 | var mapProject = StyleProjectionName.globe; 23 | var locale = 'en'; 24 | 25 | _onMapCreated(MapboxMap mapboxMap) { 26 | this.mapboxMap = mapboxMap; 27 | mapboxMap.setCustomHeaders({'Authorization': 'Bearer your_access_token'}); 28 | } 29 | 30 | @override 31 | void initState() { 32 | super.initState(); 33 | } 34 | 35 | @override 36 | void dispose() { 37 | super.dispose(); 38 | mapboxMap?.setCustomHeaders({}); 39 | } 40 | 41 | @override 42 | Widget build(BuildContext context) { 43 | final MapWidget mapWidget = MapWidget( 44 | key: ValueKey("mapWidget"), 45 | onMapCreated: _onMapCreated, 46 | onResourceRequestListener: (request) { 47 | return null; 48 | }, 49 | ); 50 | 51 | final List listViewChildren = []; 52 | 53 | listViewChildren.addAll( 54 | [], 55 | ); 56 | 57 | return Column( 58 | mainAxisSize: MainAxisSize.min, 59 | children: [ 60 | Center( 61 | child: SizedBox( 62 | width: MediaQuery.of(context).size.width, 63 | height: MediaQuery.of(context).size.height - 400, 64 | child: mapWidget), 65 | ), 66 | ], 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /example/lib/example.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | abstract interface class Example extends Widget { 4 | Widget get leading; 5 | String get title; 6 | String? get subtitle; 7 | } 8 | -------------------------------------------------------------------------------- /example/lib/geojson_line_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart' show rootBundle; 3 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 4 | 5 | import 'example.dart'; 6 | 7 | class DrawGeoJsonLineExample extends StatefulWidget implements Example { 8 | @override 9 | final Widget leading = const Icon(Icons.map); 10 | @override 11 | final String title = 'Draw GeoJson Line'; 12 | @override 13 | final String? subtitle = null; 14 | 15 | @override 16 | State createState() => DrawGeoJsonLineExampleState(); 17 | } 18 | 19 | class DrawGeoJsonLineExampleState extends State { 20 | MapboxMap? mapboxMap; 21 | var isLight = true; 22 | 23 | _onMapCreated(MapboxMap mapboxMap) async { 24 | this.mapboxMap = mapboxMap; 25 | } 26 | 27 | _onStyleLoadedCallback(StyleLoadedEventData data) async { 28 | var data = await rootBundle 29 | .loadString('assets/from_crema_to_council_crest.geojson'); 30 | 31 | await mapboxMap?.style.addSource(GeoJsonSource(id: "line", data: data)); 32 | await mapboxMap?.style.addLayer(LineLayer( 33 | id: "line_layer", 34 | sourceId: "line", 35 | lineJoin: LineJoin.ROUND, 36 | lineCap: LineCap.ROUND, 37 | lineColor: Colors.red.value, 38 | lineWidth: 6.0)); 39 | 40 | // Wait 5 seconds, then update the GeoJSONSource with the new line 41 | await Future.delayed(Duration(seconds: 5)); 42 | 43 | var newFeature = Feature( 44 | id: "featureID", 45 | geometry: LineString(coordinates: [ 46 | Position(-122.483696, 37.833818), 47 | Position(-122.4861, 37.828802), 48 | Position(-122.493782, 37.833683), 49 | Position(-122.48959, 37.8366109), 50 | Position(-122.483696, 37.833818) 51 | ])); 52 | await mapboxMap?.style 53 | .updateGeoJSONSourceFeatures("line", "new_line", [newFeature]); 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context) { 58 | return new Scaffold( 59 | body: MapWidget( 60 | key: ValueKey("mapWidget"), 61 | styleUri: MapboxStyles.MAPBOX_STREETS, 62 | cameraOptions: CameraOptions( 63 | center: Point(coordinates: Position(-122.486052, 37.830348)), 64 | zoom: 14.0), 65 | onMapCreated: _onMapCreated, 66 | onStyleLoadedListener: _onStyleLoadedCallback)); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /example/lib/image_source_example.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart' show rootBundle; 5 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 6 | 7 | import 'example.dart'; 8 | 9 | class ImageSourceExample extends StatefulWidget implements Example { 10 | @override 11 | final Widget leading = const Icon(Icons.map); 12 | @override 13 | final String title = 'Image source'; 14 | @override 15 | final String? subtitle = null; 16 | 17 | @override 18 | State createState() => ImageSourceExampleState(); 19 | } 20 | 21 | class ImageSourceExampleState extends State { 22 | MapboxMap? mapboxMap; 23 | var isLight = true; 24 | 25 | _onMapCreated(MapboxMap mapboxMap) async { 26 | this.mapboxMap = mapboxMap; 27 | } 28 | 29 | _onStyleLoaded(StyleLoadedEventData data) async { 30 | await mapboxMap?.style 31 | .addSource(ImageSource(id: "image_source-id", coordinates: [ 32 | [-80.11725, 25.7836], 33 | [-80.1397431334, 25.783548], 34 | [-80.13964, 25.7680], 35 | [-80.11725, 25.76795] 36 | ])); 37 | await mapboxMap?.style.addLayer(RasterLayer( 38 | id: "image_layer-id", 39 | sourceId: "image_source-id", 40 | )); 41 | var imageSource = 42 | await mapboxMap?.style.getSource("image_source-id") as ImageSource; 43 | final ByteData bytes = await rootBundle.load('assets/miami_beach.png'); 44 | final Uint8List list = bytes.buffer.asUint8List(); 45 | imageSource.updateImage(MbxImage(width: 280, height: 203, data: list)); 46 | } 47 | 48 | @override 49 | Widget build(BuildContext context) { 50 | return new Scaffold( 51 | body: MapWidget( 52 | key: ValueKey("mapWidget"), 53 | styleUri: MapboxStyles.DARK, 54 | cameraOptions: CameraOptions( 55 | center: Point(coordinates: Position(-80.1263, 25.7845)), zoom: 12.0), 56 | onMapCreated: _onMapCreated, 57 | onStyleLoadedListener: _onStyleLoaded, 58 | )); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /example/lib/simple_map_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 3 | import 'example.dart'; 4 | 5 | class SimpleMapExample extends StatefulWidget implements Example { 6 | const SimpleMapExample({super.key}); 7 | 8 | @override 9 | final Widget leading = const Icon(Icons.map_outlined); 10 | @override 11 | final String title = 'Display a simple map'; 12 | @override 13 | final String subtitle = 14 | 'Create and display a map that uses the default Mapbox Standard style.'; 15 | 16 | @override 17 | State createState() => _SimpleMapState(); 18 | } 19 | 20 | class _SimpleMapState extends State { 21 | _SimpleMapState(); 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | return MapWidget( 26 | styleUri: MapboxStyles.STANDARD, 27 | viewport: CameraViewportState( 28 | center: Point(coordinates: Position(-117.918976, 33.812092)), 29 | zoom: 15.0, 30 | ), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /example/lib/snapshotter_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 3 | 4 | import 'example.dart'; 5 | 6 | class SnapshotterExample extends StatefulWidget implements Example { 7 | @override 8 | final Widget leading = const Icon(Icons.camera_alt_outlined); 9 | @override 10 | final String title = 'Create a static map snapshot'; 11 | @override 12 | final String subtitle = 13 | "Create a static, non-interactive image of a map style with specified camera position."; 14 | 15 | @override 16 | State createState() => SnapshotterExampleState(); 17 | } 18 | 19 | class SnapshotterExampleState extends State { 20 | SnapshotterExampleState(); 21 | 22 | GlobalKey _snapshotKey = GlobalKey(); 23 | MapboxMap? mapboxMap; 24 | Image? snapshotImage; 25 | Snapshotter? _snapshotter; 26 | bool snapshotting = false; 27 | 28 | @override 29 | void dispose() { 30 | _snapshotter?.dispose(); 31 | super.dispose(); 32 | } 33 | 34 | _onMapCreated(MapboxMap mapboxMap) async { 35 | this.mapboxMap = mapboxMap; 36 | 37 | _snapshotter = await Snapshotter.create( 38 | options: MapSnapshotOptions( 39 | size: Size(width: 400, height: 400), 40 | pixelRatio: MediaQuery.of(context).devicePixelRatio), 41 | ); 42 | await _snapshotter?.style.setStyleURI(MapboxStyles.OUTDOORS); 43 | } 44 | 45 | _onMapIdle(MapIdleEventData data) async { 46 | if (snapshotting) { 47 | return; 48 | } 49 | snapshotting = true; 50 | 51 | RenderBox snapshotBox = 52 | _snapshotKey.currentContext!.findRenderObject() as RenderBox; 53 | if (snapshotBox.hasSize) { 54 | _snapshotter?.setSize( 55 | Size(width: snapshotBox.size.width, height: snapshotBox.size.height)); 56 | } 57 | 58 | final cameraState = await mapboxMap!.getCameraState(); 59 | _snapshotter?.setCamera(cameraState.toCameraOptions()); 60 | 61 | final snapshot = await _snapshotter?.start(); 62 | 63 | if (snapshot != null) { 64 | setState(() { 65 | snapshotImage = Image.memory(snapshot); 66 | }); 67 | } 68 | snapshotting = false; 69 | } 70 | 71 | @override 72 | Widget build(BuildContext context) { 73 | final MapWidget mapWidget = MapWidget( 74 | key: ValueKey("mapWidget"), 75 | onMapCreated: _onMapCreated, 76 | onMapIdleListener: _onMapIdle, 77 | ); 78 | return Scaffold( 79 | body: Column( 80 | crossAxisAlignment: CrossAxisAlignment.stretch, 81 | children: [ 82 | Expanded(child: mapWidget), 83 | SizedBox( 84 | height: 12, 85 | child: ColoredBox( 86 | color: Colors.amber, 87 | ), 88 | ), 89 | Expanded( 90 | key: _snapshotKey, 91 | child: snapshotImage ?? ColoredBox(color: Colors.grey)), 92 | ], 93 | ), 94 | ); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /example/lib/tile_json_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 3 | 4 | import 'example.dart'; 5 | 6 | class TileJsonExample extends StatefulWidget implements Example { 7 | @override 8 | final Widget leading = const Icon(Icons.map); 9 | @override 10 | final String title = 'Tile Json'; 11 | @override 12 | final String? subtitle = null; 13 | 14 | @override 15 | State createState() => TileJsonExampleState(); 16 | } 17 | 18 | class TileJsonExampleState extends State { 19 | MapboxMap? mapboxMap; 20 | var isLight = true; 21 | 22 | _onMapCreated(MapboxMap mapboxMap) { 23 | this.mapboxMap = mapboxMap; 24 | mapboxMap.style.setStyleJSON("{}"); 25 | } 26 | 27 | _onStyleLoaded(StyleLoadedEventData data) async { 28 | await mapboxMap?.style.addSource(RasterSource( 29 | id: "source", 30 | tiles: ["https://tile.openstreetmap.org/{z}/{x}/{y}.png"], 31 | tileSize: 256, 32 | scheme: Scheme.XYZ, 33 | minzoom: 0, 34 | maxzoom: 18, 35 | bounds: [-180.0, -85.0, 180.0, 85.0], 36 | attribution: "© OpenStreetMap contributors, CC-BY-SA")); 37 | await mapboxMap?.style 38 | .addLayer(RasterLayer(id: "layer", sourceId: "source")); 39 | } 40 | 41 | @override 42 | Widget build(BuildContext context) { 43 | return new Scaffold( 44 | body: MapWidget( 45 | key: ValueKey("mapWidget"), 46 | cameraOptions: CameraOptions( 47 | center: Point(coordinates: Position(-80.1263, 25.7845)), zoom: 12.0), 48 | onMapCreated: _onMapCreated, 49 | onStyleLoadedListener: _onStyleLoaded, 50 | )); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /example/lib/vector_tile_source_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart'; 3 | 4 | import 'example.dart'; 5 | 6 | class VectorTileSourceExample extends StatefulWidget implements Example { 7 | @override 8 | final Widget leading = const Icon(Icons.map); 9 | @override 10 | final String title = 'Vector Tile Source'; 11 | @override 12 | final String? subtitle = null; 13 | 14 | @override 15 | State createState() => VectorTileSourceExampleState(); 16 | } 17 | 18 | class VectorTileSourceExampleState extends State { 19 | MapboxMap? mapboxMap; 20 | 21 | _onMapCreated(MapboxMap mapboxMap) async { 22 | this.mapboxMap = mapboxMap; 23 | } 24 | 25 | _onStyleLoadedCallback(StyleLoadedEventData data) async { 26 | await mapboxMap?.style.addSource(VectorSource( 27 | id: "terrain-data", url: "mapbox://mapbox.mapbox-terrain-v2")); 28 | await mapboxMap?.style.addLayerAt( 29 | LineLayer( 30 | id: "terrain-data", 31 | sourceId: "terrain-data", 32 | sourceLayer: "contour", 33 | lineJoin: LineJoin.ROUND, 34 | lineCap: LineCap.ROUND, 35 | lineColor: Colors.red.value, 36 | lineWidth: 1.9), 37 | LayerPosition(above: "country-label")); 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | return new Scaffold( 43 | body: MapWidget( 44 | key: ValueKey("mapWidget"), 45 | styleUri: MapboxStyles.LIGHT, 46 | cameraOptions: CameraOptions( 47 | center: Point(coordinates: Position(-122.447303, 37.753574)), 48 | zoom: 13.0), 49 | onMapCreated: _onMapCreated, 50 | onStyleLoadedListener: _onStyleLoadedCallback)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mapbox_maps_example 2 | description: Demonstrates how to use the Mapbox Maps Flutter SDK. 3 | version: "1.0.0-beta.1" 4 | 5 | # The following line prevents the package from being accidentally published to 6 | # pub.dev using `pub publish`. This is preferred for private packages. 7 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 8 | 9 | 10 | environment: 11 | sdk: ">=3.0.0 <4.0.0" 12 | flutter: ">=3.10.0" 13 | 14 | dependencies: 15 | flutter: 16 | sdk: flutter 17 | 18 | mapbox_maps_flutter: 19 | # When depending on this package from a real application you should use: 20 | # mapbox_maps_flutter: ^x.y.z 21 | path: ../ 22 | 23 | cupertino_icons: ^1.0.2 24 | geolocator: ^13.0.4 25 | geolocator_android: 4.6.1 # pinned as 4.6.2 doesn't work with our old gradle, safe to unpin after gradle update 26 | font_awesome_flutter: ^10.1.0 27 | http: ^1.3.0 28 | path_provider: ^2.1.3 29 | 30 | dev_dependencies: 31 | flutter_test: 32 | sdk: flutter 33 | integration_test: 34 | sdk: flutter 35 | turf: ^0.0.7 36 | 37 | # For information on the generic Dart part of this file, see the 38 | # following page: https://dart.dev/tools/pub/pubspec 39 | 40 | # The following section is specific to Flutter. 41 | flutter: 42 | 43 | # The following line ensures that the Material Icons font is 44 | # included with your application, so that you can use the icons in 45 | # the material Icons class. 46 | uses-material-design: true 47 | 48 | # To add assets to your application, add an assets section, like this: 49 | # assets: 50 | # - images/a_dot_burr.jpeg 51 | # - images/a_dot_ham.jpeg 52 | assets: 53 | - assets/ 54 | - assets/symbols/ 55 | - assets/cluster/ 56 | # An image asset can refer to one or more resolution-specific "variants", see 57 | # https://flutter.dev/assets-and-images/#resolution-aware. 58 | 59 | # For details regarding adding assets from package dependencies, see 60 | # https://flutter.dev/assets-and-images/#from-packages 61 | 62 | # To add custom fonts to your application, add a fonts section here, 63 | # in this "flutter" section. Each entry in this list should have a 64 | # "family" key with the font family name, and a "fonts" key with a 65 | # list giving the asset and other descriptors for the font. For 66 | # example: 67 | # fonts: 68 | # - family: Schyler 69 | # fonts: 70 | # - asset: fonts/Schyler-Regular.ttf 71 | # - asset: fonts/Schyler-Italic.ttf 72 | # style: italic 73 | # - family: Trajan Pro 74 | # fonts: 75 | # - asset: fonts/TrajanPro.ttf 76 | # - asset: fonts/TrajanPro_Bold.ttf 77 | # weight: 700 78 | # 79 | # For details regarding fonts from package dependencies, 80 | # see https://flutter.dev/custom-fonts/#from-packages 81 | -------------------------------------------------------------------------------- /example/test_driver/integration_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:integration_test/integration_test_driver.dart'; 2 | 3 | Future main() => integrationDriver(); 4 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/ephemeral/ 38 | /Flutter/flutter_export_environment.sh 39 | 40 | **/.build/ 41 | **/.swiftpm/ 42 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint mapbox_maps_flutter.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'mapbox_maps_flutter' 7 | s.version = '2.9.0' 8 | 9 | s.summary = 'Mapbox Maps SDK Flutter Plugin.' 10 | s.description = 'An officially developed solution from Mapbox that enables use of our latest Maps SDK product.' 11 | s.homepage = 'https://pub.dev/packages/mapbox_maps_flutter' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'Mapbox' => 'mobile@mapbox.com' } 14 | s.source = { :path => '.' } 15 | 16 | s.source_files = 'mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '14.0' 19 | 20 | s.dependency 'MapboxMaps', '11.13.0' 21 | s.dependency 'Turf', '4.0.0' 22 | 23 | # Flutter.framework does not contain a i386 slice. 24 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 25 | s.swift_version = '5.8' 26 | end 27 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/.swiftlint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | allow_zero_lintable_files: true 3 | excluded: 4 | - Sources/mapbox_maps_flutter/Classes/Generated 5 | - Sources/mapbox_maps_flutter/Classes/*AnnotationController.swift 6 | - .build/ 7 | disabled_rules: 8 | - comment_spacing 9 | - computed_accessors_order 10 | - force_try 11 | - function_body_length 12 | - identifier_name 13 | - line_length 14 | - shorthand_operator 15 | - todo 16 | - trailing_comma 17 | - type_name 18 | - function_parameter_count 19 | - type_body_length 20 | - cyclomatic_complexity 21 | - superfluous_disable_command 22 | file_length: 23 | warning: 1500 24 | error: 1500 25 | custom_rules: 26 | trojan_source: 27 | regex: "[\u202A\u202B\u202D\u202E\u2066\u2067\u2068\u202C\u2069]" 28 | severity: error 29 | message: "Source should not contain characters that may be used in reordering attacks. See https://trojansource.codes/trojan-source.pdf" 30 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "mapbox-common-ios", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/mapbox/mapbox-common-ios.git", 7 | "state" : { 8 | "revision" : "69473089df0de073b89ece86977b17c75f519b5c", 9 | "version" : "24.13.0" 10 | } 11 | }, 12 | { 13 | "identity" : "mapbox-core-maps-ios", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/mapbox/mapbox-core-maps-ios.git", 16 | "state" : { 17 | "revision" : "8e62d3de5cc8d66b32c710a34df176e29e5c6777", 18 | "version" : "11.13.0" 19 | } 20 | }, 21 | { 22 | "identity" : "mapbox-maps-ios", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/mapbox/mapbox-maps-ios.git", 25 | "state" : { 26 | "revision" : "fe447519610f1a523e1b0f20645cc51c2438d545", 27 | "version" : "11.13.0" 28 | } 29 | }, 30 | { 31 | "identity" : "turf-swift", 32 | "kind" : "remoteSourceControl", 33 | "location" : "https://github.com/mapbox/turf-swift.git", 34 | "state" : { 35 | "revision" : "bf840e6b9529d105687840fe2c9dcd74197d46d1", 36 | "version" : "4.0.0" 37 | } 38 | } 39 | ], 40 | "version" : 2 41 | } 42 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.9 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "mapbox_maps_flutter", 8 | platforms: [ 9 | .iOS("14.0"), 10 | ], 11 | products: [ 12 | .library(name: "mapbox-maps-flutter", targets: ["mapbox_maps_flutter"]) 13 | ], 14 | dependencies: [ 15 | .package(url: "https://github.com/mapbox/mapbox-maps-ios.git", exact: "11.13.0"), 16 | ], 17 | targets: [ 18 | .target( 19 | name: "mapbox_maps_flutter", 20 | dependencies: [ 21 | .product(name: "MapboxMaps", package: "mapbox-maps-ios"), 22 | ], 23 | resources: [] 24 | ) 25 | ] 26 | ) 27 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/AnimationController.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | @_spi(Experimental) import MapboxMaps 3 | import Flutter 4 | 5 | final class AnimationController: _AnimationManager { 6 | private static let errorCode = "0" 7 | 8 | func easeTo(cameraOptions: CameraOptions, mapAnimationOptions: MapAnimationOptions?) throws { 9 | var cameraDuration = 1.0 10 | if mapAnimationOptions != nil && mapAnimationOptions!.duration != nil { 11 | cameraDuration = Double(mapAnimationOptions!.duration!) / 1000.0 12 | } 13 | cancelable = camera.ease(to: cameraOptions.toCameraOptions(), duration: cameraDuration) 14 | } 15 | 16 | func flyTo(cameraOptions: CameraOptions, mapAnimationOptions: MapAnimationOptions?) throws { 17 | var cameraDuration = 1.0 18 | if mapAnimationOptions != nil && mapAnimationOptions!.duration != nil { 19 | cameraDuration = Double(mapAnimationOptions!.duration!) / 1000.0 20 | } 21 | cancelable = camera.fly(to: cameraOptions.toCameraOptions(), duration: cameraDuration) 22 | } 23 | 24 | func pitchBy(pitch: Double, mapAnimationOptions: MapAnimationOptions?) throws { 25 | throw FlutterError(code: AnimationController.errorCode, message: "Not available.", details: nil) 26 | } 27 | 28 | func scaleBy(amount: Double, screenCoordinate: ScreenCoordinate?, mapAnimationOptions: MapAnimationOptions?) throws { 29 | throw FlutterError(code: AnimationController.errorCode, message: "Not available.", details: nil) 30 | } 31 | 32 | func moveBy(screenCoordinate: ScreenCoordinate, mapAnimationOptions: MapAnimationOptions?) throws { 33 | throw FlutterError(code: AnimationController.errorCode, message: "Not available.", details: nil) 34 | } 35 | 36 | func rotateBy(first: ScreenCoordinate, second: ScreenCoordinate, mapAnimationOptions: MapAnimationOptions?) throws { 37 | throw FlutterError(code: AnimationController.errorCode, message: "Not available.", details: nil) 38 | } 39 | 40 | func cancelCameraAnimation() throws { 41 | if cancelable != nil { 42 | cancelable?.cancel() 43 | } 44 | } 45 | 46 | private var camera: CameraAnimationsManager 47 | private var cancelable: MapboxMaps.Cancelable? 48 | init(withMapView mapView: MapView) { 49 | self.camera = mapView.camera 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/AnyFlutterStreamHandler.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | 3 | final class AnyFlutterStreamHandler: NSObject, FlutterStreamHandler { 4 | private(set) var eventSink: FlutterEventSink? 5 | 6 | func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { 7 | eventSink = { value in 8 | DispatchQueue.main.async { 9 | events(value) 10 | } 11 | } 12 | return nil 13 | } 14 | 15 | func onCancel(withArguments arguments: Any?) -> FlutterError? { 16 | eventSink = nil 17 | return nil 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/AttributionController.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | @_spi(Experimental) @_spi(Restricted) import MapboxMaps 3 | 4 | final class AttributionController: AttributionSettingsInterface { 5 | 6 | func updateSettings(settings: AttributionSettings) throws { 7 | var attributionButton = ornaments.options.attributionButton 8 | switch settings.position { 9 | case .bOTTOMLEFT: 10 | attributionButton.position = .bottomLeading 11 | attributionButton.margins = CGPoint(x: settings.marginLeft ?? 0, y: settings.marginBottom ?? 0) 12 | case .bOTTOMRIGHT, .none: 13 | attributionButton.position = .bottomTrailing 14 | attributionButton.margins = CGPoint(x: settings.marginRight ?? 0, y: settings.marginBottom ?? 0) 15 | case .tOPLEFT: 16 | attributionButton.position = .topLeading 17 | attributionButton.margins = CGPoint(x: settings.marginLeft ?? 0, y: settings.marginTop ?? 0) 18 | case .tOPRIGHT: 19 | attributionButton.position = .topTrailing 20 | attributionButton.margins = CGPoint(x: settings.marginRight ?? 0, y: settings.marginTop ?? 0) 21 | } 22 | attributionButton.visibility = (settings.enabled ?? true) ? .visible : .hidden 23 | ornaments.options.attributionButton = attributionButton 24 | 25 | if let iconColor = settings.iconColor { 26 | ornaments.attributionButton.tintColor = uiColorFromHex(rgbValue: iconColor) 27 | } 28 | } 29 | 30 | func getSettings() throws -> AttributionSettings { 31 | let options = ornaments.options.attributionButton 32 | let position = getFLT_SETTINGSOrnamentPosition(position: options.position) 33 | let iconColor = ornaments.attributionButton.tintColor.rgb() 34 | 35 | return AttributionSettings( 36 | enabled: options.visibility != .hidden, 37 | iconColor: Int64(iconColor), 38 | position: position, 39 | marginLeft: options.margins.x, 40 | marginTop: options.margins.y, 41 | marginRight: options.margins.x, 42 | marginBottom: options.margins.y, 43 | clickable: nil 44 | ) 45 | } 46 | 47 | func getFLT_SETTINGSOrnamentPosition(position: MapboxMaps.OrnamentPosition) -> OrnamentPosition { 48 | switch position { 49 | case .bottomLeading: 50 | return .bOTTOMLEFT 51 | case .bottomTrailing: 52 | return .bOTTOMRIGHT 53 | case .topLeading: 54 | return .tOPLEFT 55 | default: 56 | return.tOPRIGHT 57 | } 58 | } 59 | 60 | private var ornaments: OrnamentsManager 61 | private var cancelable: Cancelable? 62 | 63 | init(withMapView mapView: MapView) { 64 | self.ornaments = mapView.ornaments 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/CustomHttpServiceInterceptor.swift: -------------------------------------------------------------------------------- 1 | import MapboxMaps 2 | 3 | final class CustomHttpServiceInterceptor: HttpServiceInterceptorInterface { 4 | 5 | var customHeaders: [String: String] = [:] 6 | 7 | func onRequest(for request: HttpRequest, continuation: @escaping HttpServiceInterceptorRequestContinuation) { 8 | var modifiedHeaders = request.headers 9 | 10 | for (key, value) in customHeaders { 11 | modifiedHeaders[key] = value 12 | } 13 | 14 | let modifiedRequest = HttpRequest( 15 | method: request.method, 16 | url: request.url, 17 | headers: modifiedHeaders, 18 | timeout: request.timeout, 19 | networkRestriction: request.networkRestriction, 20 | sdkInformation: request.sdkInformation, 21 | body: request.body, 22 | flags: request.flags 23 | ) 24 | continuation(HttpRequestOrResponse.fromHttpRequest(modifiedRequest)) 25 | } 26 | 27 | func onResponse(for response: HttpResponse, continuation: @escaping HttpServiceInterceptorResponseContinuation) { 28 | continuation(response) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/LoggingController.swift: -------------------------------------------------------------------------------- 1 | import MapboxMaps 2 | import Foundation 3 | import Flutter 4 | 5 | final class LoggingController { 6 | static private var backend: LogWriterBackend? 7 | static private let instance = LoggingController() 8 | 9 | static func setup(_ binaryMessanger: FlutterBinaryMessenger) { 10 | backend = .init(binaryMessenger: binaryMessanger) 11 | LogConfiguration.registerLogWriterBackend(forLogWriter: instance) 12 | } 13 | } 14 | 15 | extension LoggingController: MapboxCommon.LogWriterBackend { 16 | func writeLog(for level: MapboxCommon.LoggingLevel, message: String) { 17 | DispatchQueue.main.async { 18 | LoggingController.backend?.writeLog( 19 | level: level.toFLTLoggingLevel(), 20 | message: message, 21 | completion: { _ in } 22 | ) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/LogoController.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | @_spi(Experimental) @_spi(Restricted) import MapboxMaps 3 | 4 | final class LogoController: LogoSettingsInterface { 5 | func updateSettings(settings: LogoSettings) throws { 6 | var logo = ornaments.options.logo 7 | switch settings.position { 8 | case .bOTTOMLEFT, .none: 9 | logo.position = .bottomLeading 10 | logo.margins = CGPoint(x: settings.marginLeft ?? 0, y: settings.marginBottom ?? 0) 11 | case .bOTTOMRIGHT: 12 | logo.position = .bottomTrailing 13 | logo.margins = CGPoint(x: settings.marginRight ?? 0, y: settings.marginBottom ?? 0) 14 | case .tOPLEFT: 15 | logo.position = .topLeading 16 | logo.margins = CGPoint(x: settings.marginLeft ?? 0, y: settings.marginTop ?? 0) 17 | case .tOPRIGHT: 18 | logo.position = .topTrailing 19 | logo.margins = CGPoint(x: settings.marginRight ?? 0, y: settings.marginTop ?? 0) 20 | } 21 | logo.visibility = (settings.enabled ?? true) ? .visible : .hidden 22 | ornaments.options.logo = logo 23 | } 24 | 25 | func getSettings() throws -> LogoSettings { 26 | let options = ornaments.options.logo 27 | let position = getFLT_SETTINGSOrnamentPosition(position: options.position) 28 | return LogoSettings( 29 | enabled: options.visibility != .hidden, 30 | position: position, 31 | marginLeft: options.margins.x, 32 | marginTop: options.margins.y, 33 | marginRight: options.margins.x, 34 | marginBottom: options.margins.y 35 | ) 36 | } 37 | 38 | func getFLT_SETTINGSOrnamentPosition(position: MapboxMaps.OrnamentPosition) -> OrnamentPosition { 39 | switch position { 40 | case .bottomLeading: 41 | return .bOTTOMLEFT 42 | case .bottomTrailing: 43 | return .bOTTOMRIGHT 44 | case .topLeading: 45 | return .tOPLEFT 46 | default: 47 | return.tOPRIGHT 48 | } 49 | } 50 | 51 | private var ornaments: OrnamentsManager 52 | private var cancelable: Cancelable? 53 | 54 | init(withMapView mapView: MapView) { 55 | self.ornaments = mapView.ornaments 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/MapProjectionController.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import MapboxMaps 3 | import UIKit 4 | import Turf 5 | 6 | class MapProjectionController: Projection { 7 | func getMetersPerPixelAtLatitude(latitude: Double, zoom: Double) throws -> Double { 8 | return MapboxMaps.Projection.metersPerPoint(for: latitude, zoom: zoom) 9 | } 10 | 11 | func projectedMetersForCoordinate(coordinate: Point) throws -> ProjectedMeters { 12 | let projectedMeters = MapboxMaps.Projection.projectedMeters(for: coordinate.coordinates) 13 | return ProjectedMeters(northing: projectedMeters.northing, easting: projectedMeters.easting) 14 | } 15 | 16 | func coordinateForProjectedMeters(projectedMeters: ProjectedMeters) throws -> Point { 17 | return Point(MapboxMaps.Projection.coordinate(for: projectedMeters.toProjectedMeters())) 18 | } 19 | 20 | func project(coordinate: Point, zoomScale: Double) throws -> MercatorCoordinate { 21 | let coordinate = MapboxMaps.Projection.project(coordinate.coordinates, zoomScale: zoomScale) 22 | return coordinate.toFLTMercatorCoordinate() 23 | } 24 | 25 | func unproject(coordinate: MercatorCoordinate, zoomScale: Double) throws -> Point { 26 | return Point(MapboxMaps.Projection.unproject(coordinate.toMercatorCoordinate(), zoomScale: zoomScale)) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/MapboxMapFactory.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import MapboxMaps 3 | import MapboxCommon 4 | import MapboxCommon_Private 5 | 6 | final class MapboxMapFactory: NSObject, FlutterPlatformViewFactory { 7 | private static let mapCounter = FeatureTelemetryCounter.create(forName: "maps-mobile/flutter/map") 8 | 9 | var registrar: FlutterPluginRegistrar 10 | 11 | deinit { 12 | _MapboxOptionsSetup.setUp(binaryMessenger: registrar.messenger(), api: nil) 13 | _MapboxMapsOptionsSetup.setUp(binaryMessenger: registrar.messenger(), api: nil) 14 | } 15 | 16 | init(withRegistrar registrar: FlutterPluginRegistrar) { 17 | self.registrar = registrar 18 | } 19 | 20 | func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol { 21 | return MapInterfacesPigeonCodec.shared 22 | } 23 | 24 | func create( 25 | withFrame frame: CGRect, 26 | viewIdentifier viewId: Int64, 27 | arguments args: Any? 28 | ) -> FlutterPlatformView { 29 | 30 | guard let args = args as? [String: Any] else { 31 | return MapboxMapController( 32 | withFrame: frame, 33 | mapInitOptions: MapInitOptions(), 34 | channelSuffix: 0, 35 | registrar: registrar, 36 | pluginVersion: "", 37 | eventTypes: [] 38 | ) 39 | } 40 | 41 | let styleURI = (args["styleUri"] as? String).map(StyleURI.init(rawValue:)) 42 | let mapOptions = args["mapOptions"] as? MapOptions 43 | let cameraOptions = args["cameraOptions"] as? CameraOptions 44 | 45 | let mapInitOptions = MapInitOptions( 46 | mapOptions: mapOptions?.toMapOptions() ?? MapboxMaps.MapOptions(), 47 | cameraOptions: cameraOptions?.toCameraOptions(), 48 | styleURI: styleURI ?? .standard 49 | ) 50 | 51 | Self.mapCounter.increment() 52 | return MapboxMapController( 53 | withFrame: frame, 54 | mapInitOptions: mapInitOptions, 55 | channelSuffix: args["channelSuffix"] as? Int ?? 0, 56 | registrar: registrar, 57 | pluginVersion: args["mapboxPluginVersion"] as? String ?? "", 58 | eventTypes: args["eventTypes"] as? [Int] ?? [] 59 | ) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/MapboxMapsPlugin.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import MapboxMaps 4 | 5 | public class MapboxMapsPlugin: NSObject, FlutterPlugin { 6 | public static func register(with registrar: FlutterPluginRegistrar) { 7 | let instance = MapboxMapFactory(withRegistrar: registrar) 8 | registrar.register(instance, withId: "plugins.flutter.io/mapbox_maps") 9 | 10 | setupStaticChannels(with: registrar) 11 | } 12 | 13 | private static func setupStaticChannels(with registrar: FlutterPluginRegistrar) { 14 | let binaryMessenger = registrar.messenger() 15 | 16 | let mapboxOptionsController = MapboxOptionsController(assetKeyLookup: registrar.lookupKey(forAsset:)) 17 | let snapshotterInstanceManager = SnapshotterInstanceManager(binaryMessenger: binaryMessenger) 18 | let offlineMapInstanceManager = OfflineMapInstanceManager(binaryMessenger: binaryMessenger) 19 | 20 | _MapboxOptionsSetup.setUp(binaryMessenger: binaryMessenger, api: mapboxOptionsController) 21 | _MapboxMapsOptionsSetup.setUp(binaryMessenger: binaryMessenger, api: mapboxOptionsController) 22 | _SnapshotterInstanceManagerSetup.setUp(binaryMessenger: binaryMessenger, api: snapshotterInstanceManager) 23 | _OfflineMapInstanceManagerSetup.setUp(binaryMessenger: binaryMessenger, api: offlineMapInstanceManager) 24 | _TileStoreInstanceManagerSetup.setUp(binaryMessenger: binaryMessenger, api: offlineMapInstanceManager) 25 | _OfflineSwitchSetup.setUp(binaryMessenger: binaryMessenger, api: OfflineSwitch.shared) 26 | 27 | LoggingController.setup(binaryMessenger) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Offline/OfflineMapInstanceManager.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import MapboxMaps 3 | 4 | final class OfflineMapInstanceManager: _OfflineMapInstanceManager, _TileStoreInstanceManager { 5 | enum `Error`: Swift.Error { 6 | case invalidTileStorePath 7 | } 8 | 9 | private let binaryMessenger: FlutterBinaryMessenger 10 | 11 | init(binaryMessenger: FlutterBinaryMessenger) { 12 | self.binaryMessenger = binaryMessenger 13 | } 14 | 15 | func setupOfflineManager(channelSuffix: String) throws { 16 | let offlineController = OfflineController(messenger: SuffixBinaryMessenger(messenger: binaryMessenger, suffix: channelSuffix)) 17 | _OfflineManagerSetup.setUp(binaryMessenger: binaryMessenger, api: offlineController, messageChannelSuffix: channelSuffix) 18 | } 19 | 20 | func tearDownOfflineManager(channelSuffix: String) throws { 21 | _OfflineManagerSetup.setUp(binaryMessenger: binaryMessenger, api: nil, messageChannelSuffix: channelSuffix) 22 | } 23 | 24 | func setupTileStore(channelSuffix: String, filePath: String?) throws { 25 | let tileStore: TileStore 26 | if let filePath { 27 | tileStore = .shared(for: URL(fileURLWithPath: filePath)) 28 | } else { 29 | tileStore = .default 30 | } 31 | 32 | MapboxMapsOptions.tileStore = tileStore 33 | let tileStoreController = TileStoreController(messenger: SuffixBinaryMessenger(messenger: binaryMessenger, suffix: channelSuffix), tileStore: tileStore) 34 | 35 | _TileStoreSetup.setUp(binaryMessenger: binaryMessenger, api: tileStoreController, messageChannelSuffix: channelSuffix) 36 | } 37 | 38 | func tearDownTileStore(channelSuffix: String) throws { 39 | _TileStoreSetup.setUp(binaryMessenger: binaryMessenger, api: nil, messageChannelSuffix: channelSuffix) 40 | MapboxMapsOptions.tileStore = nil 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/PerformanceStatisticsController.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | @_spi(Experimental) import MapboxMaps 3 | 4 | final class PerformanceStatisticsController: _PerformanceStatisticsApi { 5 | private let mapboxMap: MapboxMap 6 | private var collectionCancelable: AnyCancelable? 7 | private var performanceStatisticsListener: PerformanceStatisticsListener? 8 | 9 | init(mapboxMap: MapboxMap, messenger: SuffixBinaryMessenger) { 10 | self.mapboxMap = mapboxMap 11 | performanceStatisticsListener = PerformanceStatisticsListener( 12 | binaryMessenger: messenger.messenger, 13 | messageChannelSuffix: messenger.suffix 14 | ) 15 | } 16 | 17 | func startPerformanceStatisticsCollection(options: PerformanceStatisticsOptions) throws { 18 | let options = options.toPerformanceStatisticsOptions() 19 | collectionCancelable = mapboxMap.collectPerformanceStatistics(options) { [weak self] statistics in 20 | self?.performanceStatisticsListener?.onPerformanceStatisticsCollected( 21 | statistics: statistics.toFLTPerformanceStatistics(), 22 | completion: { _ in } 23 | ) 24 | } 25 | } 26 | 27 | func stopPerformanceStatisticsCollection() throws { 28 | collectionCancelable = nil 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Snapshotter/SnapshotterInstanceManager.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import MapboxMaps 3 | import Flutter 4 | 5 | final class SnapshotterInstanceManager: _SnapshotterInstanceManager { 6 | private let binaryMessenger: FlutterBinaryMessenger 7 | 8 | init(binaryMessenger: FlutterBinaryMessenger) { 9 | self.binaryMessenger = binaryMessenger 10 | } 11 | 12 | func setupSnapshotterForSuffix(suffix: String, eventTypes: [Int64], options: MapSnapshotOptions) throws { 13 | let snapshotter = Snapshotter(options: options.toMapSnapshotOptions()) 14 | 15 | let snapshotterController = SnapshotterController( 16 | snapshotter: snapshotter, 17 | eventTypes: eventTypes.map(Int.init), 18 | binaryMessenger: binaryMessenger, 19 | channelSuffix: suffix 20 | ) 21 | let snapshotStyleController = StyleController(styleManager: snapshotter) 22 | 23 | _SnapshotterMessengerSetup.setUp(binaryMessenger: binaryMessenger, api: snapshotterController, messageChannelSuffix: suffix) 24 | StyleManagerSetup.setUp(binaryMessenger: binaryMessenger, api: snapshotStyleController, messageChannelSuffix: suffix) 25 | 26 | } 27 | 28 | func tearDownSnapshotterForSuffix(suffix: String) throws { 29 | StyleManagerSetup.setUp(binaryMessenger: binaryMessenger, api: nil, messageChannelSuffix: suffix) 30 | _SnapshotterMessengerSetup.setUp(binaryMessenger: binaryMessenger, api: nil, messageChannelSuffix: suffix) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/StyleLights.swift: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | import MapboxMaps 3 | 4 | extension MapboxMaps.DirectionalLight { 5 | init(_ fltValue: DirectionalLight) { 6 | self.init(id: fltValue.id) 7 | 8 | if let castShadows = fltValue.castShadows { 9 | self.castShadows = .constant(castShadows) 10 | } 11 | if let color = fltValue.color { 12 | self.color = .constant(StyleColor(rgb: color)) 13 | } 14 | self.colorTransition = fltValue.colorTransition?.toStyleTransition() 15 | if let direction = fltValue.direction { 16 | self.direction = .constant(direction.compactMap { $0 }) 17 | } 18 | self.directionTransition = fltValue.directionTransition?.toStyleTransition() 19 | if let intensity = fltValue.intensity { 20 | self.intensity = .constant(intensity) 21 | } 22 | self.intensityTransition = fltValue.intensityTransition?.toStyleTransition() 23 | if let shadowIntensity = fltValue.shadowIntensity { 24 | self.shadowIntensity = .constant(shadowIntensity) 25 | } 26 | self.shadowIntensityTransition = fltValue.shadowIntensityTransition?.toStyleTransition() 27 | } 28 | } 29 | extension MapboxMaps.AmbientLight { 30 | init(_ fltValue: AmbientLight) { 31 | self.init(id: fltValue.id) 32 | 33 | if let color = fltValue.color { 34 | self.color = .constant(StyleColor(rgb: color)) 35 | } 36 | self.colorTransition = fltValue.colorTransition?.toStyleTransition() 37 | if let intensity = fltValue.intensity { 38 | self.intensity = .constant(intensity) 39 | } 40 | self.intensityTransition = fltValue.intensityTransition?.toStyleTransition() 41 | } 42 | } 43 | extension MapboxMaps.FlatLight { 44 | init(_ fltValue: FlatLight) { 45 | self.init(id: fltValue.id) 46 | 47 | if let anchor = fltValue.anchor { 48 | self.anchor = MapboxMaps.Anchor(anchor).map { Value.constant($0) } 49 | } 50 | if let color = fltValue.color { 51 | self.color = .constant(StyleColor(rgb: color)) 52 | } 53 | self.colorTransition = fltValue.colorTransition?.toStyleTransition() 54 | if let intensity = fltValue.intensity { 55 | self.intensity = .constant(intensity) 56 | } 57 | self.intensityTransition = fltValue.intensityTransition?.toStyleTransition() 58 | if let position = fltValue.position { 59 | self.position = .constant(position.compactMap { $0 }) 60 | } 61 | self.positionTransition = fltValue.positionTransition?.toStyleTransition() 62 | } 63 | } 64 | // End of generated file. 65 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Viewport/States.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import MapboxMaps 3 | import Flutter 4 | import UIKit 5 | @_implementationOnly import MapboxCommon_Private.MBXLog_Internal 6 | 7 | extension _OverviewViewportStateOptions { 8 | func toOptions() -> OverviewViewportStateOptions { 9 | let geometry = try! JSONDecoder().decode(Geometry.self, from: geometry.data(using: .utf8)!) 10 | return .init( 11 | geometry: geometry, 12 | geometryPadding: geometryPadding.toUIEdgeInsets(), 13 | bearing: bearing, 14 | pitch: pitch?.CGFloat, 15 | padding: padding?.toUIEdgeInsets(), 16 | maxZoom: maxZoom, 17 | offset: offset?.toCGPoint(), 18 | animationDuration: Double(animationDurationMs) / 1000.0 19 | ) 20 | } 21 | } 22 | 23 | extension _FollowPuckViewportStateOptions { 24 | func toOptions() -> FollowPuckViewportStateOptions { 25 | let bearing: FollowPuckViewportStateBearing? 26 | switch self.bearing { 27 | case .heading: 28 | bearing = .heading 29 | case .constant: 30 | if bearingValue == nil { 31 | Log.error(forMessage: "Invalid FollowPuckViewportStateOptions, bearing mode is constant but no bearing value was provided", category: "Viewport") 32 | } 33 | bearing = bearingValue.map(FollowPuckViewportStateBearing.constant) 34 | case .course: 35 | bearing = .course 36 | case .none: 37 | bearing = nil 38 | } 39 | return .init( 40 | zoom: zoom?.CGFloat, 41 | bearing: bearing, 42 | pitch: pitch?.CGFloat) 43 | } 44 | } 45 | 46 | final class StyleDefaultViewportState: ViewportState { 47 | private var token: AnyCancelable? 48 | 49 | private let result: Signal 50 | private let mapboxMap: MapboxMap 51 | 52 | init(mapboxMap: MapboxMap) { 53 | if mapboxMap.isStyleLoaded { 54 | result = Signal(just: StyleLoaded(timeInterval: EventTimeInterval(begin: Date(), end: Date()))) 55 | } else { 56 | result = mapboxMap.onStyleLoaded 57 | } 58 | 59 | self.mapboxMap = mapboxMap 60 | } 61 | 62 | func observeDataSource(with handler: @escaping (MapboxMaps.CameraOptions) -> Bool) -> MapboxMaps.Cancelable { 63 | return result.observe { [mapboxMap] _ in 64 | _ = handler(mapboxMap.styleDefaultCamera) 65 | } 66 | } 67 | 68 | func startUpdatingCamera() { 69 | token = result.observe { [mapboxMap] _ in 70 | mapboxMap.setCamera(to: mapboxMap.styleDefaultCamera) 71 | } 72 | } 73 | 74 | func stopUpdatingCamera() { 75 | token = nil 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/Viewport/Transitions.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import MapboxMaps 3 | 4 | extension _DefaultViewportTransitionOptions { 5 | public func toOptions() -> DefaultViewportTransitionOptions { 6 | return DefaultViewportTransitionOptions(maxDuration: Double(maxDurationMs) / 1000.0) 7 | } 8 | } 9 | 10 | extension _FlyViewportTransitionOptions { 11 | public var duration: TimeInterval? { durationMs.map { Double($0) / 1000.0 } } 12 | } 13 | 14 | extension _EasingViewportTransitionOptions { 15 | var duration: TimeInterval { Double(durationMs) / 1000.0 } 16 | var controlPoint1: CGPoint { CGPoint(x: a, y: b) } 17 | var controlPoint2: CGPoint { CGPoint(x: c, y: d) } 18 | } 19 | 20 | final class GenericViewportTransition: ViewportTransition { 21 | typealias AnimationRunner = (MapboxMaps.CameraOptions, @escaping AnimationCompletion) -> MapboxMaps.Cancelable 22 | private let runAnimation: AnimationRunner 23 | 24 | internal init(runAnimation: @escaping AnimationRunner) { 25 | self.runAnimation = runAnimation 26 | } 27 | 28 | public func run(to toState: MapboxMaps.ViewportState, 29 | completion: @escaping (Bool) -> Void) -> MapboxMaps.Cancelable { 30 | var transitionAnimationCancellable: MapboxMaps.Cancelable? 31 | let toStateCancellable = toState.observeDataSource { [runAnimation] cameraOptions in 32 | transitionAnimationCancellable = runAnimation(cameraOptions) { animationPosition in 33 | completion(animationPosition == .end) 34 | } 35 | return false 36 | } 37 | 38 | return MapboxMaps.AnyCancelable { 39 | toStateCancellable.cancel() 40 | transitionAnimationCancellable?.cancel() 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/mapbox_maps_flutter.h: -------------------------------------------------------------------------------- 1 | // 2 | // mapbox_maps_flutter.h 3 | // Pods 4 | // 5 | // Created by Kevin Li on 2022/4/18. 6 | // 7 | 8 | #ifndef mapbox_maps_flutter_h 9 | #define mapbox_maps_flutter_h 10 | 11 | 12 | #endif /* mapbox_maps_flutter_h */ 13 | -------------------------------------------------------------------------------- /lib/src/cancelable.dart: -------------------------------------------------------------------------------- 1 | part of '../mapbox_maps_flutter.dart'; 2 | 3 | /// A class representing a cancelable operation or task. 4 | /// 5 | /// This can be used to manage operations that may need to be 6 | /// canceled before completion, such as asynchronous tasks or 7 | /// long-running processes. 8 | class Cancelable { 9 | final void Function() _cancel; 10 | 11 | Cancelable._(this._cancel); 12 | 13 | void cancel() { 14 | _cancel(); 15 | } 16 | } 17 | 18 | extension on StreamSubscription { 19 | /// Cancels the subscription and returns a [Cancelable] object. 20 | Cancelable asCancelable() { 21 | return Cancelable._(cancel); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/src/extensions.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | extension Conversion on CameraState { 4 | CameraOptions toCameraOptions() { 5 | return CameraOptions( 6 | center: center, 7 | padding: padding, 8 | zoom: zoom, 9 | bearing: bearing, 10 | pitch: pitch, 11 | ); 12 | } 13 | 14 | static CameraState fromJson(Map json) { 15 | return CameraState( 16 | center: Point.fromJson(json['center']), 17 | padding: _MbxEdgeInsetsCodable.fromJson(json['padding']), 18 | zoom: json['zoom'].toDouble(), 19 | bearing: json['bearing'].toDouble(), 20 | pitch: json['pitch'].toDouble()); 21 | } 22 | } 23 | 24 | extension _MbxEdgeInsetsCodable on MbxEdgeInsets { 25 | static MbxEdgeInsets fromJson(Map json) { 26 | return MbxEdgeInsets( 27 | top: json["top"].toDouble(), 28 | left: json["left"].toDouble(), 29 | bottom: json["bottom"].toDouble(), 30 | right: json["right"].toDouble(), 31 | ); 32 | } 33 | 34 | static MbxEdgeInsets fromEdgeInsets(EdgeInsets edgeInsets) { 35 | return MbxEdgeInsets( 36 | top: edgeInsets.top, 37 | left: edgeInsets.left, 38 | bottom: edgeInsets.bottom, 39 | right: edgeInsets.right, 40 | ); 41 | } 42 | } 43 | 44 | extension ScreenBoxToJson on ScreenBox { 45 | dynamic toJson() { 46 | return { 47 | 'min': min.toJson(), 48 | 'max': max.toJson(), 49 | }; 50 | } 51 | } 52 | 53 | extension ScreenCoordinateToJson on ScreenCoordinate { 54 | dynamic toJson() { 55 | return { 56 | 'x': x, 57 | 'y': y, 58 | }; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/src/http/http_service.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// A service that handles HTTP-related functionality for Mapbox 4 | class MapboxHttpService { 5 | late final MethodChannel _channel; 6 | final BinaryMessenger binaryMessenger; 7 | final int channelSuffix; 8 | 9 | /// Creates a new MapboxHttpService instance 10 | /// 11 | /// [binaryMessenger] is used for platform channel communication 12 | /// [channelSuffix] is used to create a unique channel identifier when multiple instances 13 | /// of the service are needed. This should match the suffix used on the platform side. 14 | MapboxHttpService( 15 | {required this.binaryMessenger, required this.channelSuffix}) { 16 | _channel = MethodChannel('plugins.flutter.io.${channelSuffix.toString()}', 17 | const StandardMethodCodec(), binaryMessenger); 18 | } 19 | 20 | /// Sets custom headers for all Mapbox HTTP requests 21 | /// 22 | /// [headers] is a map of header names to header values 23 | /// 24 | /// Throws a [PlatformException] if the native implementation is not available 25 | /// or if the operation fails 26 | Future setCustomHeaders(Map headers) async { 27 | try { 28 | await _channel.invokeMethod('map#setCustomHeaders', {'headers': headers}); 29 | } on MissingPluginException catch (e) { 30 | throw PlatformException( 31 | code: 'MISSING_IMPLEMENTATION', 32 | message: 'Native implementation for setCustomHeaders is not available', 33 | details: e.toString(), 34 | ); 35 | } catch (e) { 36 | throw PlatformException( 37 | code: 'SET_HEADERS_FAILED', 38 | message: 'Failed to set custom headers', 39 | details: e.toString(), 40 | ); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/src/location_settings.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// Shows a location puck on the map. 4 | class LocationSettings { 5 | final _LocationComponentSettingsInterface _api; 6 | 7 | LocationSettings._(this._api); 8 | 9 | /// Returns [LocationComponentSettings] allowing to show location indicator on the map, 10 | /// customize indicator's appearance and position. 11 | Future getSettings() async { 12 | return _api.getSettings(); 13 | } 14 | 15 | /// Accepts an instance of [LocationComponentSettings] allowing to apply location. 16 | /// indicator configuration changes. 17 | /// 18 | /// Note: By default [DefaultLocationPuck2D] is used if no [LocationComponentSettings.locationPuck] specified. 19 | Future updateSettings(LocationComponentSettings settings) async { 20 | if (settings.locationPuck == null) { 21 | // If locationPuck is not set, fallback to use DefaultLocationPuck2D. 22 | settings.locationPuck = 23 | LocationPuck(locationPuck2D: DefaultLocationPuck2D()); 24 | } else { 25 | settings.locationPuck?.locationPuck3D?.modelUri = 26 | await MapboxMapsOptions._getFlutterAssetPath( 27 | settings.locationPuck?.locationPuck3D?.modelUri); 28 | } 29 | _api.updateSettings(settings, 30 | settings.locationPuck?.locationPuck2D is DefaultLocationPuck2D); 31 | } 32 | } 33 | 34 | /// Default 2D location indicator appearance. 35 | class DefaultLocationPuck2D extends LocationPuck2D { 36 | /// Creates an instance of the default 2D location indicator, 37 | /// allowing to customize apects of it([topImage], [bearingImage], [opacity] etc.). 38 | DefaultLocationPuck2D( 39 | {super.topImage, 40 | super.bearingImage, 41 | super.shadowImage, 42 | super.scaleExpression, 43 | super.opacity}); 44 | } 45 | -------------------------------------------------------------------------------- /lib/src/log_configuration.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// A class that allows to configure Mapbox SDKs logging per application. 4 | final class LogConfiguration { 5 | static bool _initialized = false; 6 | 7 | LogConfiguration._() {} 8 | 9 | /// Sets the backend which writes the log. 10 | /// 11 | /// Pass backend which writes logs as [backend], if you provide null for this parameter then previously 12 | /// used logger backend will be replaced with Mapbox default implementation. 13 | static void registerLogWriterBackend(LogWriterBackend? backend) { 14 | LogWriterBackend.setUp(backend); 15 | } 16 | 17 | static void _setupDebugLoggingIfNeeded() { 18 | if (!kDebugMode) { 19 | return; 20 | } 21 | 22 | if (_initialized) { 23 | return; 24 | } 25 | _initialized = true; 26 | 27 | if (bool.fromEnvironment('MAPBOX_LOG_DEBUG', defaultValue: true)) { 28 | LogConfiguration.registerLogWriterBackend(_DebugLoggingBackend()); 29 | } 30 | } 31 | } 32 | 33 | enum _FlutterLoggingLevel { 34 | debug(500), 35 | info(800), 36 | warning(900), 37 | error(1000); 38 | 39 | final int value; 40 | 41 | const _FlutterLoggingLevel(this.value); 42 | } 43 | 44 | extension on LoggingLevel { 45 | _FlutterLoggingLevel get asFlutterLoggingLevel { 46 | switch (this) { 47 | case LoggingLevel.debug: 48 | return _FlutterLoggingLevel.debug; 49 | case LoggingLevel.info: 50 | return _FlutterLoggingLevel.info; 51 | case LoggingLevel.warning: 52 | return _FlutterLoggingLevel.warning; 53 | case LoggingLevel.error: 54 | return _FlutterLoggingLevel.error; 55 | } 56 | } 57 | } 58 | 59 | final class _DebugLoggingBackend extends LogWriterBackend { 60 | @override 61 | void writeLog(LoggingLevel level, String message) { 62 | developer.log(message, 63 | level: level.asFlutterLoggingLevel.value, name: 'mapbox-maps-flutter'); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/src/offline/offline_switch.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// Instance that allows connecting or disconnecting the Mapbox stack to the network. 4 | final class OfflineSwitch { 5 | final _OfflineSwitch _api = _OfflineSwitch(); 6 | OfflineSwitch._() {} 7 | 8 | static final OfflineSwitch shared = OfflineSwitch._(); 9 | 10 | Future get isMapboxStackConnected { 11 | return _api.isMapboxStackConnected(); 12 | } 13 | 14 | Future setMapboxStackConnected(bool isConnected) { 15 | return _api.setMapboxStackConnected(isConnected); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/src/package_info.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | const String mapboxPluginVersion = '2.9.0'; 4 | -------------------------------------------------------------------------------- /lib/src/style/interactive_features/standard_buildings.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | part of '../../../mapbox_maps_flutter.dart'; 3 | 4 | /// Featureset describing the buildings. 5 | /// 6 | /// Use the ``StandardBuildings()`` descriptor to handle interactions on Buildings features: 7 | /// 8 | /// ```dart 9 | /// mapboxMap.addInteraction(TapInteraction(StandardBuildings(), (feature, context) { 10 | /// // Handle the tapped feature here 11 | /// })); 12 | /// ``` 13 | extension StandardBuildingsFeature 14 | on TypedFeaturesetFeature { 15 | /// A feature state. 16 | /// 17 | /// This is a **snapshot** of the state that the feature had when it was interacted with. 18 | /// To update and read the original state, use ``MapboxMap/setFeatureState()`` and ``MapboxMap/getFeatureState()``. 19 | StandardBuildingsState get stateSnapshot { 20 | return StandardBuildingsState() 21 | ..highlight = state["highlight"] as bool? 22 | ..select = state["select"] as bool?; 23 | } 24 | 25 | /// A high-level building group like building-2d, building-3d, etc. 26 | String? get group { 27 | return properties["group"] as String?; 28 | } 29 | } 30 | 31 | /// A featureset of StandardBuildings features. 32 | class StandardBuildings extends FeaturesetDescriptor { 33 | StandardBuildings({String importId = "basemap"}) 34 | : super(featuresetId: "buildings", importId: importId); 35 | } 36 | 37 | /// Represents available states for StandardBuildings features in the Standard style. 38 | class StandardBuildingsState extends FeatureState { 39 | /// When `true`, the building is highlighted. Use this state to create a temporary effect (e.g. hover). 40 | bool? highlight; 41 | 42 | /// When `true`, the building is selected. Use this state to create a permanent effect. Note: the `select` state has a higher priority than `highlight`. 43 | bool? select; 44 | 45 | @override 46 | Map get map { 47 | return { 48 | "highlight": highlight, 49 | "select": select, 50 | }; 51 | } 52 | 53 | StandardBuildingsState({this.highlight, this.select}) 54 | : super(map: { 55 | "highlight": highlight, 56 | "select": select, 57 | }); 58 | } 59 | -------------------------------------------------------------------------------- /lib/src/style/interactive_features/standard_place_labels.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | part of '../../../mapbox_maps_flutter.dart'; 3 | 4 | /// Points for labeling places including countries, states, cities, towns, and neighborhoods. 5 | /// 6 | /// Use the ``StandardPlaceLabels()`` descriptor to handle interactions on Place Labels features: 7 | /// 8 | /// ```dart 9 | /// mapboxMap.addInteraction(TapInteraction(StandardPlaceLabels(), (feature, context) { 10 | /// // Handle the tapped feature here 11 | /// })); 12 | /// ``` 13 | extension StandardPlaceLabelsFeature 14 | on TypedFeaturesetFeature { 15 | /// A feature state. 16 | /// 17 | /// This is a **snapshot** of the state that the feature had when it was interacted with. 18 | /// To update and read the original state, use ``MapboxMap/setFeatureState()`` and ``MapboxMap/getFeatureState()``. 19 | StandardPlaceLabelsState get stateSnapshot { 20 | return StandardPlaceLabelsState() 21 | ..hide = state["hide"] as bool? 22 | ..highlight = state["highlight"] as bool? 23 | ..select = state["select"] as bool?; 24 | } 25 | 26 | /// Name of the place label. 27 | String? get name { 28 | return properties["name"] as String?; 29 | } 30 | 31 | /// Provides a broad distinction between place types. 32 | String? get category { 33 | return properties["class"] as String?; 34 | } 35 | } 36 | 37 | /// A featureset of StandardPlaceLabels features. 38 | class StandardPlaceLabels extends FeaturesetDescriptor { 39 | StandardPlaceLabels({String importId = "basemap"}) 40 | : super(featuresetId: "place-labels", importId: importId); 41 | } 42 | 43 | /// Represents available states for StandardPlaceLabels features in the Standard style. 44 | class StandardPlaceLabelsState extends FeatureState { 45 | /// When `true`, hides the label. Use this state when displaying a custom annotation on top. 46 | bool? hide; 47 | 48 | /// When `true`, the feature is highlighted. Use this state to create a temporary effect (e.g. hover). 49 | bool? highlight; 50 | 51 | /// When `true`, the feature is selected. Use this state to create a permanent effect. Note: the `select` state has a higher priority than `highlight`. 52 | bool? select; 53 | 54 | @override 55 | Map get map { 56 | return { 57 | "hide": hide, 58 | "highlight": highlight, 59 | "select": select, 60 | }; 61 | } 62 | 63 | StandardPlaceLabelsState({this.hide, this.highlight, this.select}) 64 | : super(map: { 65 | "hide": hide, 66 | "highlight": highlight, 67 | "select": select, 68 | }); 69 | } 70 | -------------------------------------------------------------------------------- /lib/src/style/layer/slot_layer.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | part of mapbox_maps_flutter; 3 | 4 | /// Marks the position of a slot. 5 | class SlotLayer extends Layer { 6 | SlotLayer({ 7 | required String id, 8 | Visibility? visibility, 9 | List? visibilityExpression, 10 | List? filter, 11 | double? minZoom, 12 | double? maxZoom, 13 | String? slot, 14 | @Deprecated("This property has no effect on SlotLayer") String? sourceId, 15 | @Deprecated("This property has no effect on SlotLayer") String? sourceLayer, 16 | }) : super( 17 | id: id, 18 | visibility: visibility, 19 | visibilityExpression: visibilityExpression, 20 | filter: filter, 21 | maxZoom: maxZoom, 22 | minZoom: minZoom, 23 | slot: slot); 24 | 25 | @override 26 | String getType() => "slot"; 27 | 28 | /// The id of the source. 29 | @Deprecated("This property has no effect on SlotLayer") 30 | String get sourceId => ""; 31 | 32 | /// A source layer is an individual layer of data within a vector source. A vector source can have multiple source layers. 33 | @Deprecated("This property has no effect on SlotLayer") 34 | String? sourceLayer; 35 | 36 | @override 37 | Future _encode() async { 38 | var layout = {}; 39 | if (visibilityExpression != null) { 40 | layout["visibility"] = visibilityExpression!; 41 | } 42 | if (visibility != null) { 43 | layout["visibility"] = 44 | visibility!.name.toLowerCase().replaceAll("_", "-"); 45 | } 46 | 47 | var paint = {}; 48 | var properties = { 49 | "id": id, 50 | "type": getType(), 51 | "layout": layout, 52 | "paint": paint, 53 | }; 54 | if (minZoom != null) { 55 | properties["minzoom"] = minZoom!; 56 | } 57 | if (maxZoom != null) { 58 | properties["maxzoom"] = maxZoom!; 59 | } 60 | if (slot != null) { 61 | properties["slot"] = slot!; 62 | } 63 | if (filter != null) { 64 | properties["filter"] = filter!; 65 | } 66 | 67 | return json.encode(properties); 68 | } 69 | 70 | static SlotLayer decode(String properties) { 71 | var map = json.decode(properties); 72 | if (map["layout"] == null) { 73 | map["layout"] = {}; 74 | } 75 | if (map["paint"] == null) { 76 | map["paint"] = {}; 77 | } 78 | return SlotLayer( 79 | id: map["id"], 80 | minZoom: map["minzoom"]?.toDouble(), 81 | maxZoom: map["maxzoom"]?.toDouble(), 82 | slot: map["slot"], 83 | visibility: map["layout"]["visibility"] == null 84 | ? Visibility.VISIBLE 85 | : Visibility.values.firstWhere((e) => e.name 86 | .toLowerCase() 87 | .replaceAll("_", "-") 88 | .contains(map["layout"]["visibility"])), 89 | visibilityExpression: _optionalCastList(map["layout"]["visibility"]), 90 | filter: _optionalCastList(map["filter"]), 91 | ); 92 | } 93 | } 94 | 95 | // End of generated file. 96 | -------------------------------------------------------------------------------- /lib/src/style/mapbox_styles.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// A convenience object to access [the style ID](https://docs.mapbox.com/help/glossary/style-id/) strings of the professionally-designed 4 | /// map styles made by Mapbox. 5 | class MapboxStyles { 6 | /// Mapbox Standard is a general-purpose style with 3D visualization. 7 | static const String STANDARD = "mapbox://styles/mapbox/standard"; 8 | 9 | /// Mapbox Standard Satellite 10 | static const String STANDARD_SATELLITE = 11 | "mapbox://styles/mapbox/standard-satellite"; 12 | 13 | /// Mapbox Streets: A complete base map, perfect for incorporating your own data. Using this 14 | /// constant means your map style will always use the latest version and may change as we 15 | /// improve the style. 16 | static const String MAPBOX_STREETS = "mapbox://styles/mapbox/streets-v12"; 17 | 18 | /// Outdoors: A general-purpose style tailored to outdoor activities. Using this constant means 19 | /// your map style will always use the latest version and may change as we improve the style. 20 | static const String OUTDOORS = "mapbox://styles/mapbox/outdoors-v12"; 21 | 22 | /// Light: Subtle light backdrop for data visualizations. Using this constant means your map 23 | /// style will always use the latest version and may change as we improve the style. 24 | static const String LIGHT = "mapbox://styles/mapbox/light-v11"; 25 | 26 | /// Dark: Subtle dark backdrop for data visualizations. Using this constant means your map style 27 | /// will always use the latest version and may change as we improve the style. 28 | static const String DARK = "mapbox://styles/mapbox/dark-v11"; 29 | 30 | /// Satellite: A beautiful global satellite and aerial imagery layer. Using this constant means 31 | /// your map style will always use the latest version and may change as we improve the style. 32 | static const String SATELLITE = "mapbox://styles/mapbox/satellite-v9"; 33 | 34 | /// Satellite Streets: Global satellite and aerial imagery with unobtrusive labels. Using this 35 | /// constant means your map style will always use the latest version and may change as we 36 | /// improve the style. 37 | static const String SATELLITE_STREETS = 38 | "mapbox://styles/mapbox/satellite-streets-v12"; 39 | } 40 | 41 | /// A pre-specified location in the style where layer will be added to. 42 | /// (such as on top of existing land layers, but below all labels). 43 | class LayerSlot { 44 | /// Place layer above POI labels and behind Place and Transit labels. 45 | static const String TOP = "top"; 46 | 47 | /// Place layer above lines (roads, etc.) and behind 3D buildings. 48 | static const String MIDDLE = "middle"; 49 | 50 | /// Place layer above polygons (land, landuse, water, etc.) 51 | static const String BOTTOM = "bottom"; 52 | } 53 | -------------------------------------------------------------------------------- /lib/src/utils.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// Returns back the passed value casted to the desired type 4 | /// or null if typecasting fails 5 | T? _optionalCast(dynamic value) { 6 | if (value is T) { 7 | return value; 8 | } 9 | // Cast int(num) to double, 10 | // as GL Native converts e.g. 1.0 to 1 (int), 11 | // which trips dart up 12 | if (value is num && T == double) { 13 | return value.toDouble() as T; 14 | } 15 | return null; 16 | } 17 | 18 | List? _optionalCastList(dynamic value) { 19 | if (value is List) { 20 | return value.where((value) => value is T).cast().toList(); 21 | } 22 | return null; 23 | } 24 | -------------------------------------------------------------------------------- /lib/src/viewport/state_viewport_extension.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | ViewportTransition? _viewportTransition; 4 | Function(bool)? _viewportTransitionCompletion; 5 | 6 | extension WidgetViewportAnimation on State { 7 | /// Applies the animation to the map viewport. 8 | /// 9 | /// Use this function to apply animation to viewport state change. 10 | /// 11 | /// ```dart 12 | /// final _viewport = ... 13 | /// 14 | /// @override 15 | /// Widget build(BuildContext context) { 16 | /// TextButton(onPressed: () { 17 | /// setStateWithViewportAnimation(() { 18 | /// _viewport = CameraViewportState(...); 19 | // }); 20 | /// } 21 | /// ``` 22 | /// 23 | /// See [ViewportState] and [ViewportTransition] documentation for more details. 24 | @experimental 25 | void setStateWithViewportAnimation(VoidCallback fn, 26 | {ViewportTransition? transition = const DefaultViewportTransition(), 27 | void Function(bool)? completion}) { 28 | _viewportTransition = transition; 29 | _viewportTransitionCompletion?.call(false); 30 | _viewportTransitionCompletion = completion; 31 | // ignore: invalid_use_of_protected_member 32 | setState(fn); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/src/viewport/states/camera_viewport_state.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// Manually sets camera to specified properties. 4 | final class CameraViewportState extends ViewportState { 5 | /// The geographic coordinate that will be rendered at the midpoint of the map. 6 | final Point? center; 7 | 8 | /// Add insets to the map, adjusting the visible region by shifting the camera's viewport. 9 | final EdgeInsets? padding; 10 | 11 | /// Point in the map's coordinate system about which `zoom` and `bearing` should be applied. Mutually exclusive with `center`. 12 | final Offset? anchor; 13 | 14 | /// The zoom level of the map. 15 | final double? zoom; 16 | 17 | /// The bearing of the map, measured in degrees clockwise from true north. 18 | final double? bearing; 19 | 20 | /// Pitch toward the horizon measured in degrees, with 0 degrees resulting in a top-down view for a two-dimensional map. 21 | final double? pitch; 22 | 23 | /// Creates a [CameraViewportState] with the specified camera properties. 24 | /// 25 | /// This constructor allows you to manually set the camera's position and orientation on the map. You can specify the [center] coordinate to render at the midpoint of the map, or use an [anchor] point in the map's coordinate system about which [zoom] and [bearing] transformations are applied. Note that [center] and [anchor] are mutually exclusive; you should provide only one of them. 26 | /// 27 | /// The [zoom] parameter sets the zoom level of the map, controlling how close or far the camera is from the Earth's surface. The [bearing] parameter defines the rotation of the map, measured in degrees clockwise from true north, allowing you to orient the map to a specific direction. 28 | /// 29 | /// With the [pitch] parameter, you can adjust the angle of the camera toward the horizon, measured in degrees. A [pitch] of 0 degrees results in a top-down view, while higher values tilt the map to provide a three-dimensional perspective. 30 | /// 31 | /// You can also specify [padding] to add insets to the map, adjusting the visible region by shifting the camera's viewport. 32 | const CameraViewportState({ 33 | this.center, 34 | this.padding, 35 | this.anchor, 36 | this.zoom, 37 | this.bearing, 38 | this.pitch, 39 | }) : super(); 40 | } 41 | -------------------------------------------------------------------------------- /lib/src/viewport/states/idle_viewport_state.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// Idle viewport represents the state when user freely drags the map. 4 | /// 5 | /// Setting the [IdleViewportState] viewport results in cancelling any ongoing camera animation. 6 | final class IdleViewportState extends ViewportState { 7 | /// Idle viewport represents the state when user freely drags the map. 8 | const IdleViewportState() : super(); 9 | } 10 | -------------------------------------------------------------------------------- /lib/src/viewport/states/style_default_viewport_state.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// Sets camera to the default camera options defined in the current style. 4 | /// 5 | /// See more in the [Mapbox Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/root/#center). 6 | final class StyleDefaultViewportState extends ViewportState { 7 | /// Sets camera to the default camera options defined in the current style. 8 | const StyleDefaultViewportState() : super(); 9 | } 10 | -------------------------------------------------------------------------------- /lib/src/viewport/transitions/default_viewport_transition.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// A [ViewportTransition] that provides a default animation for viewport changes. 4 | /// 5 | /// The [DefaultViewportTransition] offers smooth and visually appealing animations for all viewport transitions. 6 | /// It automatically determines the best animation settings to ensure a consistent and polished user experience. 7 | /// 8 | /// **Note:** It is recommended to use the default animation with the [FollowPuckViewportState] viewport, 9 | /// as it supports moving animation targets like the user location puck. Other animation options may not 10 | /// handle moving targets as smoothly. 11 | /// 12 | /// ### Example 13 | /// 14 | /// ```dart 15 | /// final viewportTransition = DefaultViewportTransition( 16 | /// maxDuration: Duration(milliseconds: 3500), 17 | /// ); 18 | /// ``` 19 | /// 20 | /// This creates a default viewport transition with a maximum animation duration of 3.5 seconds. 21 | final class DefaultViewportTransition extends ViewportTransition { 22 | /// The maximum duration of the animation. 23 | /// 24 | /// The animation will not exceed this duration, regardless of the changes in the viewport. 25 | /// Defaults to `Duration(milliseconds: 3500)`. 26 | final Duration maxDuration; 27 | 28 | /// Creates a [DefaultViewportTransition] with an optional [maxDuration]. 29 | /// 30 | /// The [maxDuration] parameter allows you to specify the maximum duration for the animation. 31 | /// By default, it is set to 3.5 seconds. 32 | const DefaultViewportTransition({ 33 | this.maxDuration = const Duration(milliseconds: 3500), 34 | }) : super(); 35 | } 36 | -------------------------------------------------------------------------------- /lib/src/viewport/transitions/easing_viewport_transition.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// A [ViewportTransition] that animates viewport changes using an easing curve. 4 | /// 5 | /// The [EasingViewportTransition] allows you to define smooth animations between different viewport states 6 | /// by specifying a [curve] and a [duration]. This provides a customizable way to control how camera 7 | /// transitions occur in your application. 8 | /// 9 | /// ### Example 10 | /// 11 | /// ```dart 12 | /// // Using the default easing curve (easeInOut) 13 | /// final transition = EasingViewportTransition( 14 | /// duration: Duration(seconds: 2), 15 | /// ); 16 | /// 17 | /// // Using a custom easing curve 18 | /// final transition = EasingViewportTransition( 19 | /// curve: Curves.fastOutSlowIn, 20 | /// duration: Duration(milliseconds: 1500), 21 | /// ); 22 | /// 23 | /// // Using a linear easing curve 24 | /// final transition = EasingViewportTransition.linear( 25 | /// duration: Duration(seconds: 1), 26 | /// ); 27 | /// ``` 28 | /// 29 | /// In these examples, different easing curves and durations are used to animate the viewport transitions. 30 | final class EasingViewportTransition extends ViewportTransition { 31 | /// The easing curve to use for the animation. 32 | /// 33 | /// This defines the rate of change of the animation over time. You can use any [Cubic] curve, 34 | /// including predefined curves from [Curves] like [Curves.easeInOut], [Curves.linear], etc. 35 | /// 36 | /// Defaults to [Curves.easeInOut]. 37 | final Cubic curve; 38 | 39 | /// The duration of the animation. 40 | /// 41 | /// Specifies how long the animation should take to complete. 42 | final Duration duration; 43 | 44 | /// Creates an [EasingViewportTransition] with the specified [curve] and [duration]. 45 | /// 46 | /// The [curve] parameter defines the easing function to use for the animation, and the [duration] 47 | /// specifies the length of time the animation should run. 48 | /// 49 | /// - [curve]: The easing curve to use for the animation. Defaults to [Curves.easeInOut]. 50 | /// - [duration]: The duration of the animation. 51 | const EasingViewportTransition({ 52 | this.curve = Curves.easeInOut, 53 | required this.duration, 54 | }) : super(); 55 | 56 | /// Creates an [EasingViewportTransition] with a linear easing curve. 57 | /// 58 | /// This constructor sets the [curve] to a linear curve (`Cubic(0, 0, 1, 1)`), resulting in a constant animation speed. 59 | /// 60 | /// - [duration]: The duration of the animation. 61 | const EasingViewportTransition.linear({ 62 | required Duration duration, 63 | }) : this(curve: const Cubic(0, 0, 1, 1), duration: duration); 64 | } 65 | -------------------------------------------------------------------------------- /lib/src/viewport/transitions/fly_viewport_transition.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// A [ViewportTransition] that performs a fly animation over a specified duration. 4 | /// 5 | /// The [FlyViewportTransition] animates the camera using a flight path that typically follows a zoom-out, 6 | /// flight, and zoom-in pattern. This creates a dynamic and engaging transition between different viewport 7 | /// states, giving users a sense of movement across the map. 8 | /// 9 | /// ### Example 10 | /// 11 | /// ```dart 12 | /// final flyTransition = FlyViewportTransition( 13 | /// duration: Duration(seconds: 5), 14 | /// ); 15 | /// ``` 16 | /// 17 | /// In this example, the fly animation will occur over 5 seconds. If [duration] is not specified, 18 | /// the transition will use a default duration determined by the system. 19 | final class FlyViewportTransition extends ViewportTransition { 20 | /// The duration of the fly animation. 21 | /// 22 | /// Specifies how long the fly animation should take to complete. If not provided, a default duration 23 | /// will be used by the system. 24 | final Duration? duration; 25 | 26 | /// Creates a [FlyViewportTransition] with an optional [duration]. 27 | /// 28 | /// - [duration]: The duration of the animation. If null, a default duration is used. 29 | const FlyViewportTransition({this.duration}) : super(); 30 | } 31 | -------------------------------------------------------------------------------- /lib/src/viewport/transitions/viewport_transition.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_maps_flutter; 2 | 3 | /// A base class for defining custom viewport transitions. 4 | /// 5 | /// The [ViewportTransition] class serves as an abstract foundation for various types of animations 6 | /// that can be applied when transitioning between different viewport states in a map. Subclasses of 7 | /// [ViewportTransition] implement specific animation behaviors, such as easing animations, fly animations, 8 | /// or default system animations. 9 | /// 10 | /// See also: 11 | /// - [DefaultViewportTransition], which provides the default animation for viewport transitions. 12 | /// - [EasingViewportTransition], which animates transitions using an easing curve. 13 | /// - [FlyViewportTransition], which performs a fly-over animation. 14 | sealed class ViewportTransition { 15 | /// Creates a [ViewportTransition]. 16 | /// 17 | /// This constructor is typically called by subclasses to initialize the base class. 18 | const ViewportTransition(); 19 | } 20 | 21 | extension on ViewportTransition { 22 | _ViewportTransitionStorage _toStorage() { 23 | return switch (this) { 24 | DefaultViewportTransition transition => transition._toStorage(), 25 | FlyViewportTransition transition => transition._toStorage(), 26 | EasingViewportTransition transition => transition._toStorage(), 27 | }; 28 | } 29 | } 30 | 31 | extension on DefaultViewportTransition { 32 | _ViewportTransitionStorage _toStorage() => _ViewportTransitionStorage( 33 | type: _ViewportTransitionType.defaultTransition, 34 | options: _DefaultViewportTransitionOptions( 35 | maxDurationMs: maxDuration.inMilliseconds, 36 | ), 37 | ); 38 | } 39 | 40 | extension on FlyViewportTransition { 41 | _ViewportTransitionStorage _toStorage() { 42 | return _ViewportTransitionStorage( 43 | type: _ViewportTransitionType.fly, 44 | options: _FlyViewportTransitionOptions( 45 | durationMs: duration?.inMilliseconds, 46 | ), 47 | ); 48 | } 49 | } 50 | 51 | extension on EasingViewportTransition { 52 | _ViewportTransitionStorage _toStorage() { 53 | return _ViewportTransitionStorage( 54 | type: _ViewportTransitionType.easing, 55 | options: _EasingViewportTransitionOptions( 56 | durationMs: duration.inMilliseconds, 57 | a: curve.a, 58 | b: curve.b, 59 | c: curve.c, 60 | d: curve.d, 61 | ), 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mapbox-maps-flutter", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mapbox_maps_flutter 2 | description: Interactive, thoroughly customizable maps powered by Mapbox Maps mobile SDKs. 3 | version: 2.9.0 4 | homepage: https://github.com/mapbox/mapbox-maps-flutter 5 | 6 | environment: 7 | sdk: ">=3.4.4 <4.0.0" 8 | flutter: ">=3.22.3" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | flutter_plugin_android_lifecycle: ^2.0.5 14 | turf: ^0.0.8 15 | typed_data: ^1.3.0 16 | meta: ^1.9.1 17 | 18 | dev_dependencies: 19 | integration_test: 20 | sdk: flutter 21 | flutter_test: 22 | sdk: flutter 23 | test: ^1.19.0 24 | flutter_lints: ^5.0.0 25 | 26 | # For information on the generic Dart part of this file, see the 27 | # following page: https://dart.dev/tools/pub/pubspec 28 | 29 | # The following section is specific to Flutter. 30 | flutter: 31 | plugin: 32 | platforms: 33 | android: 34 | package: com.mapbox.maps.mapbox_maps 35 | pluginClass: MapboxMapsPlugin 36 | ios: 37 | pluginClass: MapboxMapsPlugin 38 | -------------------------------------------------------------------------------- /scripts/check-format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "-> Running 'flutter format' to check project dart style." 4 | 5 | RESULT=$(flutter format -n lib example/lib example/integration_test) 6 | 7 | if [[ $? != 0 ]]; then 8 | echo "----> Command failed." 9 | elif [[ $RESULT == *"0 changed"* ]]; then 10 | echo "----> All format is good ✅" 11 | else 12 | echo "----> Some files are not well formated:" 13 | echo "$RESULT" 14 | exit 1 15 | fi -------------------------------------------------------------------------------- /scripts/check_api_breakage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Check if dart_apitool is activated globally 5 | if ! dart pub global list | grep -q 'dart_apitool'; then 6 | echo "dart_apitool is not activated globally. Please run: dart pub global activate dart_apitool" 7 | exit 1 8 | fi 9 | 10 | # Get the current stable version of mapbox_maps_flutter on pub.dev 11 | PACKAGE_NAME="mapbox_maps_flutter" 12 | PACKAGE_VERSION=$(curl -s "https://pub.dev/api/packages/$PACKAGE_NAME" | grep -o '"latest":{"version":"[^"]*' | grep -o '[0-9]\+\(\.[0-9]\+\)*') 13 | echo "Current stable version of mapbox_maps_flutter: $PACKAGE_VERSION" 14 | 15 | # Get the path of local mapbox-maps-flutter 16 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 17 | LOCAL_PACKAGE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" 18 | 19 | # Run dart_apitool to check for API breakage 20 | dart-apitool diff \ 21 | --old pub://$PACKAGE_NAME/$PACKAGE_VERSION \ 22 | --new $LOCAL_PACKAGE_ROOT \ 23 | --version-check-mode=onlyBreakingChanges -------------------------------------------------------------------------------- /scripts/check_test_suite.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: avoid_print 2 | 3 | import 'dart:io'; 4 | 5 | // Checks that all test files in the integration_test directory 6 | // are included in the aggregated test suite file(integration_test/all_test.dart). 7 | // 8 | // Should be run from the root of the examples project. 9 | void main() { 10 | // Directory containing your integration tests 11 | final integrationTestDir = Directory('integration_test'); 12 | 13 | // Aggregated test suite file (e.g., app_test.dart) 14 | final aggregatedTestSuiteFile = File('integration_test/all_test.dart'); 15 | 16 | // Get all test files in the integration_test directory (ending with _test.dart) 17 | final allTestFiles = integrationTestDir 18 | .listSync(recursive: true) 19 | .where((entity) => entity is File && entity.path.endsWith('_test.dart')) 20 | .map((file) => file.path.replaceFirst('integration_test/', '')) 21 | .toList(); 22 | 23 | // Get imported test files from the aggregated test suite 24 | final aggregatedTestContent = aggregatedTestSuiteFile.readAsStringSync(); 25 | final includedTestFiles = RegExp(r"^import '([^']+)'", multiLine: true) 26 | .allMatches(aggregatedTestContent) 27 | .map((match) => match.group(1)) 28 | .toList(); 29 | 30 | // Normalize paths (to be safe for different platforms like Windows vs Unix) 31 | final missingTests = allTestFiles 32 | .where((testFile) => !includedTestFiles.contains(testFile)) 33 | .toList(); 34 | 35 | missingTests.remove('all_test.dart'); // Exclude the aggregated test suite file itself 36 | 37 | if (missingTests.isNotEmpty) { 38 | print('The following test files are missing from the aggregated test suite:'); 39 | for (var missingTest in missingTests) { 40 | print(missingTest); 41 | } 42 | print(''); 43 | print('Import the missing test files in the integration_test/all_test.dart.'); 44 | print("Don't forget to invoke the main function of the test file as well."); 45 | exit(1); // Exit with error code 1 if there are missing tests 46 | } else { 47 | print('All test files are included in the aggregated test suite.'); 48 | exit(0); // Success 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /scripts/update-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if argument is provided 4 | if [ $# -eq 0 ]; then 5 | echo "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | VERSION="$1" 10 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 11 | 12 | # Validate the version format (e.g., 1.0.0 or 1.0.0-rc.1) 13 | if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+(\.[0-9]+)*)?$ ]]; then 14 | echo "Error: Invalid version format. Use 'X.Y.Z' or 'X.Y.Z-rc.1'." 15 | exit 1 16 | fi 17 | 18 | echo "Updating MapboxMaps Flutter SDK version: $VERSION" 19 | 20 | PUBSPEC_FILE="$SCRIPT_DIR/../pubspec.yaml" 21 | sed -i '' "s/^version: .*/version: $VERSION/" "$PUBSPEC_FILE" 22 | 23 | PODSPEC_FILE="$SCRIPT_DIR/../ios/mapbox_maps_flutter.podspec" 24 | sed -i '' "s/\(s\.version *= *\)\'[^\']*\'/\1\'$VERSION\'/" "$PODSPEC_FILE" 25 | 26 | PACKAGE_INFO_FILE="$SCRIPT_DIR/../lib/src/package_info.dart" 27 | sed -i '' "s/^const String mapboxPluginVersion = .*/const String mapboxPluginVersion = '$VERSION';/" "$PACKAGE_INFO_FILE" 28 | --------------------------------------------------------------------------------