├── .github ├── stale.yml └── workflows │ └── flutter_ci.yml ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── RELEASE.md ├── android ├── .gitignore ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── mapbox │ └── mapboxgl │ ├── BitmapUtils.java │ ├── Convert.java │ ├── GeoJSONUtils.java │ ├── GlobalMethodHandler.java │ ├── LayerPropertyConverter.java │ ├── MapBoxUtils.java │ ├── MapboxHttpRequestUtil.java │ ├── MapboxMapBuilder.java │ ├── MapboxMapController.java │ ├── MapboxMapFactory.java │ ├── MapboxMapOptionsSink.java │ ├── MapboxMapsPlugin.java │ ├── OfflineChannelHandlerImpl.java │ ├── OfflineManagerUtils.java │ ├── OnCameraMoveListener.java │ ├── OnInfoWindowTappedListener.java │ └── SourcePropertyConverter.java ├── doc ├── RUNNING_EXAMPLE_CODE.md └── img │ ├── example-iphone.jpeg │ └── xcode-bundle-identifier.png ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── .project │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── app │ │ ├── .classpath │ │ ├── .project │ │ ├── .settings │ │ │ └── org.eclipse.buildship.core.prefs │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── mapbox │ │ │ │ │ └── mapboxglexample │ │ │ │ │ └── MainActivity.java │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── mapbox │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── 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 │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ └── settings_aar.gradle ├── assets │ ├── fill-extrusion │ │ └── indoor_3d_map.json │ ├── fill │ │ └── cat_silhouette_pattern.png │ ├── style.json │ ├── sydney.png │ └── symbols │ │ ├── 2.0x │ │ └── custom-icon.png │ │ ├── 3.0x │ │ └── custom-icon.png │ │ └── custom-icon.png ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── .last_build_id │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── 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 │ │ └── main.m ├── lib │ ├── animate_camera.dart │ ├── annotation_order_maps.dart │ ├── click_annotations.dart │ ├── custom_marker.dart │ ├── full_map.dart │ ├── generated_plugin_registrant.dart │ ├── layer.dart │ ├── line.dart │ ├── local_style.dart │ ├── main.dart │ ├── map_ui.dart │ ├── move_camera.dart │ ├── offline_region_map.dart │ ├── offline_regions.dart │ ├── page.dart │ ├── place_batch.dart │ ├── place_circle.dart │ ├── place_fill.dart │ ├── place_source.dart │ ├── place_symbol.dart │ ├── scrolling_map.dart │ ├── sources.dart │ └── take_snapshot.dart ├── macos │ ├── .gitignore │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── app_icon_1024.png │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ └── app_icon_64.png │ │ ├── Base.lproj │ │ └── MainMenu.xib │ │ ├── Configs │ │ ├── AppInfo.xcconfig │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── Warnings.xcconfig │ │ ├── DebugProfile.entitlements │ │ ├── Info.plist │ │ ├── MainFlutterWindow.swift │ │ └── Release.entitlements ├── pubspec.yaml └── web │ ├── favicon.png │ ├── icons │ ├── Icon-192.png │ └── Icon-512.png │ ├── index.html │ └── manifest.json ├── flutter_mapbox_gl.iml ├── install_formatting_tools.sh ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── Constants.swift │ ├── Convert.swift │ ├── Enums.swift │ ├── Extensions.swift │ ├── LayerPropertyConverter.swift │ ├── MapboxMapController.swift │ ├── MapboxMapFactory.swift │ ├── MapboxMapOptionsSink.swift │ ├── MapboxMapsPlugin.h │ ├── MapboxMapsPlugin.m │ ├── MethodCallError.swift │ ├── OfflineChannelHandler.swift │ ├── OfflineManagerUtils.swift │ ├── OfflinePackDownloadManager.swift │ ├── OfflineRegion.swift │ ├── OfflineRegionDefinition.swift │ ├── RNMBImageUtils.swift │ ├── SourcePropertyConverter.swift │ └── SwiftMapboxGlFlutterPlugin.swift └── mapbox_gl.podspec ├── lib ├── mapbox_gl.dart └── src │ ├── annotation_manager.dart │ ├── color_tools.dart │ ├── controller.dart │ ├── download_region_status.dart │ ├── global.dart │ ├── layer_expressions.dart │ ├── layer_properties.dart │ ├── mapbox_map.dart │ ├── offline_region.dart │ └── util.dart ├── mapbox_gl_platform_interface ├── CHANGELOG.md ├── LICENSE ├── README.md ├── lib │ ├── mapbox_gl_platform_interface.dart │ └── src │ │ ├── annotation.dart │ │ ├── callbacks.dart │ │ ├── camera.dart │ │ ├── circle.dart │ │ ├── fill.dart │ │ ├── line.dart │ │ ├── location.dart │ │ ├── mapbox_gl_platform_interface.dart │ │ ├── method_channel_mapbox_gl.dart │ │ ├── snapshot.dart │ │ ├── source_properties.dart │ │ ├── symbol.dart │ │ └── ui.dart └── pubspec.yaml ├── mapbox_gl_web ├── CHANGELOG.md ├── LICENSE ├── README.md ├── ios │ └── mapbox_gl_web.podspec ├── lib │ ├── mapbox_gl_web.dart │ └── src │ │ ├── convert.dart │ │ ├── layer_tools.dart │ │ ├── mapbox_map_plugin.dart │ │ ├── mapbox_web_gl_platform.dart │ │ └── options_sink.dart └── pubspec.yaml ├── pubspec.lock ├── pubspec.yaml ├── screenshot.png └── scripts ├── input └── style.json ├── lib ├── conversions.dart └── generate.dart ├── pubspec.lock ├── pubspec.yaml └── templates ├── LayerPropertyConverter.java.template ├── LayerPropertyConverter.swift.template ├── layer_expressions.dart.template ├── layer_properties.dart.template ├── layer_tools.dart.template └── source_properties.dart.template /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: stale 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false -------------------------------------------------------------------------------- /.github/workflows/flutter_ci.yml: -------------------------------------------------------------------------------- 1 | name: Flutter CI 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | lint: 7 | name: "Static code analysis" 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - uses: actions/setup-java@v1 13 | with: 14 | java-version: "12.x" 15 | - uses: subosito/flutter-action@v1 16 | with: 17 | flutter-version: "2.10.5" 18 | - run: flutter pub get 19 | - name: Lint analysis 20 | run: cd example && flutter analyze 21 | 22 | check-dart-formatting: 23 | name: "Check Dart formatting" 24 | runs-on: ubuntu-latest 25 | 26 | steps: 27 | - uses: actions/checkout@v1 28 | - uses: subosito/flutter-action@v1 29 | - name: Check Dart formatting 30 | run: dart format --set-exit-if-changed . 31 | 32 | check-swift-formatting: 33 | name: "Check Swift formatting" 34 | runs-on: ubuntu-latest 35 | 36 | steps: 37 | - uses: actions/checkout@v1 38 | - name: get SwiftFormat 39 | run: ./install_formatting_tools.sh 40 | - name: Check Swift formatting 41 | run: ./swiftformat --swiftversion 4.2 --maxwidth 100 --lint ios 42 | 43 | check-java-formatting: 44 | name: "Check Java formatting" 45 | runs-on: ubuntu-latest 46 | 47 | steps: 48 | - uses: actions/checkout@v1 49 | - name: get google-java-format 50 | run: ./install_formatting_tools.sh 51 | - name: Check Java formatting 52 | run: > 53 | java 54 | --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED 55 | --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED 56 | --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED 57 | --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED 58 | --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED 59 | -jar google-java-format-1.13.0-all-deps.jar --set-exit-if-changed -n $(find . -type f -name "*.java") 60 | 61 | build-android: 62 | environment: ANDROID_CI_DOWNLOADS_TOKEN 63 | name: "Build Android apk" 64 | runs-on: ubuntu-latest 65 | steps: 66 | - uses: actions/checkout@v1 67 | - uses: actions/setup-java@v1 68 | with: 69 | java-version: "12.x" 70 | - uses: subosito/flutter-action@v2 71 | with: 72 | flutter-version: "2.10.5" 73 | - run: flutter pub get 74 | - name: Build example APK 75 | run: cd example && flutter build apk 76 | env: 77 | SDK_REGISTRY_TOKEN: ${{ secrets.SDK_REGISTRY_ANDROID}} 78 | 79 | build-iOS: 80 | environment: ANDROID_CI_DOWNLOADS_TOKEN 81 | name: Build iOS package 82 | runs-on: macos-latest 83 | 84 | steps: 85 | - uses: actions/checkout@v1 86 | - uses: actions/setup-java@v1 87 | with: 88 | java-version: "12.x" 89 | - uses: subosito/flutter-action@v2 90 | with: 91 | flutter-version: "2.10.5" 92 | - run: flutter pub get 93 | - name: build iOS package 94 | run: | 95 | echo "machine api.mapbox.com 96 | login mapbox 97 | password $SDK_REGISTRY_TOKEN" >> ~/.netrc 98 | chmod 600 ~/.netrc 99 | cd ./example 100 | flutter build ios --release --no-codesign 101 | env: 102 | SDK_REGISTRY_TOKEN: ${{ secrets.SDK_REGISTRY_IOS}} 103 | 104 | build-web: 105 | name: "Build web" 106 | runs-on: ubuntu-latest 107 | 108 | steps: 109 | - uses: actions/checkout@v1 110 | - uses: actions/setup-java@v1 111 | with: 112 | java-version: "12.x" 113 | - uses: subosito/flutter-action@v1 114 | - run: flutter config --enable-web 115 | - run: flutter pub get 116 | - name: Build web 117 | run: cd example && flutter build web 118 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | *.cxx 8 | .DS_Store 9 | .atom/ 10 | .buildlog/ 11 | .history 12 | .svn/ 13 | .fvm/ 14 | 15 | # IntelliJ related 16 | *.iml 17 | *.ipr 18 | *.iws 19 | .idea/ 20 | 21 | # Visual Studio Code related 22 | .classpath 23 | .project 24 | .settings/ 25 | .vscode/ 26 | 27 | # Flutter repo-specific 28 | /bin/cache/ 29 | /bin/mingit/ 30 | /dev/benchmarks/mega_gallery/ 31 | /dev/bots/.recipe_deps 32 | /dev/bots/android_tools/ 33 | /dev/docs/doc/ 34 | /dev/docs/flutter.docs.zip 35 | /dev/docs/lib/ 36 | /dev/docs/pubspec.yaml 37 | /dev/integration_tests/**/xcuserdata 38 | /dev/integration_tests/**/Pods 39 | /packages/flutter/coverage/ 40 | version 41 | 42 | # packages file containing multi-root paths 43 | .packages.generated 44 | 45 | # Flutter/Dart/Pub related 46 | **/doc/api/ 47 | .dart_tool/ 48 | .flutter-plugins 49 | .flutter-plugins-dependencies 50 | .packages 51 | .pub-cache/ 52 | .pub/ 53 | build/ 54 | flutter_*.png 55 | linked_*.ds 56 | unlinked.ds 57 | unlinked_spec.ds 58 | 59 | # Android related 60 | **/android/**/gradle-wrapper.jar 61 | **/android/.gradle 62 | **/android/captures/ 63 | **/android/gradlew 64 | **/android/gradlew.bat 65 | **/android/local.properties 66 | **/android/**/GeneratedPluginRegistrant.java 67 | **/android/key.properties 68 | *.jks 69 | 70 | # iOS/XCode related 71 | **/ios/**/*.mode1v3 72 | **/ios/**/*.mode2v3 73 | **/ios/**/*.moved-aside 74 | **/ios/**/*.pbxuser 75 | **/ios/**/*.perspectivev3 76 | **/ios/**/*sync/ 77 | **/ios/**/.sconsign.dblite 78 | **/ios/**/.tags* 79 | **/ios/**/.vagrant/ 80 | **/ios/**/DerivedData/ 81 | **/ios/**/Icon? 82 | **/ios/**/Pods/ 83 | **/ios/**/.symlinks/ 84 | **/ios/**/profile 85 | **/ios/**/xcuserdata 86 | **/ios/.generated/ 87 | **/ios/Flutter/App.framework 88 | **/ios/Flutter/Flutter.framework 89 | **/ios/Flutter/Flutter.podspec 90 | **/ios/Flutter/Generated.xcconfig 91 | **/ios/Flutter/app.flx 92 | **/ios/Flutter/app.zip 93 | **/ios/Flutter/flutter_assets/ 94 | **/ios/Flutter/flutter_export_environment.sh 95 | **/ios/ServiceDefinitions.json 96 | **/ios/Runner/GeneratedPluginRegistrant.* 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 | __MACOSX/ 104 | 105 | # Coverage 106 | coverage/ 107 | 108 | # Binaries 109 | google-java-format-1.13.0-all-deps.jar 110 | swiftformat 111 | 112 | # Symbols 113 | app.*.symbols 114 | 115 | # Exceptions to above rules. 116 | !**/ios/**/default.mode1v3 117 | !**/ios/**/default.mode2v3 118 | !**/ios/**/default.pbxuser 119 | !**/ios/**/default.perspectivev3 120 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 121 | !/dev/ci/**/Gemfile.lock 122 | 123 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We welcome contributions to this repository. Please follow these steps if you're interested in making contributions: 4 | 5 | - Please familiarize yourself with the process of running the example app and adding Mapbox access tokens as described in the Readme. 6 | 7 | - Ensure that existing [pull requests](https://github.com/tobrun/flutter-mapbox-gl/pulls) and [issues](https://github.com/tobrun/flutter-mapbox-gl/issues) don’t already cover your contributions or questions. 8 | 9 | - Create a new branch that will contain your contributed code. Along with your contribution you should also adapt the example app to showcase any new features or APIs you have developed. This also makes testing your contribution much easier. In an ideal case, you also make your contribution cross platform but this isn't a true requirement. Eventually create a pull request once you're done making changes. 10 | 11 | # Code of conduct 12 | Everyone is invited to participate in open source projects and public discussions: we want to create a welcoming and friendly environment. Harassment of participants or other unethical and unprofessional behavior will not be tolerated in this repository spaces. The [Contributor Covenant](http://contributor-covenant.org) applies to this project and we ask that you please read [the full text](http://contributor-covenant.org/version/1/2/0/). 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | flutter-mapbox-gl copyright (c) 2021, 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 7 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | format: 2 | java \ 3 | --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ 4 | --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ 5 | --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ 6 | --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ 7 | --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ 8 | -jar google-java-format-1.13.0-all-deps.jar -r $(shell find . -type f -name "*.java") 9 | flutter format . 10 | ./swiftformat --swiftversion 4.2 --maxwidth 100 ios 11 | 12 | install_formatting: 13 | ./install_formatting_tools.sh 14 | 15 | codegen: 16 | dart scripts/lib/generate.dart -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | ## Release 2 | 3 | This document describes the steps needed to make a release: 4 | 5 | ### Update Changelog 6 | 7 | For each supported library: 8 | - `mapbox_gl_platform_interface` 9 | - `mapbox_gl_web` 10 | - `flutter-mapbox-gl` 11 | 12 | Update the changelog by listing the commits that occurred for that given library. 13 | Starting with `flutter-mapbox-gl` allows you to capture them all and be more granular 14 | when updating the other libraries. Once the CHANGELOG.md's are updated, make a PR 15 | and merge to master. 16 | 17 | ### Release libraries 18 | 19 | #### Release `mapbox_gl_platform_interface` 20 | 21 | Update library version in `mapbox_gl_platform_interface/pubspec.yaml` and run `flutter pub publish`. 22 | 23 | #### Release `mapbox_gl_web` 24 | 25 | Update library version in `mapbox_gl_web/pubspec.yaml` in `mapbox_gl_platform_interface`, 26 | 27 | 28 | ``` 29 | Replace: 30 | mapbox_gl_platform_interface: 31 | git: 32 | url: https://github.com/tobrun/flutter-mapbox-gl.git 33 | path: mapbox_gl_platform_interface 34 | 35 | With: 36 | mapbox_gl_platform_interface: ^0.10.0 37 | 38 | Remove: 39 | dependency_overrides: 40 | mapbox_gl_platform_interface: 41 | path: ../mapbox_gl_platform_interface 42 | ``` 43 | 44 | and run `flutter pub publish` in `mapbox_gl_web`. 45 | 46 | #### Release `flutter-mapbox-gl` 47 | 48 | Update library version in `pubspec.yaml`, replace both web as platform interface conform to above and run `flutter pub publish` from root of project. 49 | 50 | ### Tag Release 51 | 52 | Once the PR that updates version numbers is merged, create a release for that version number 53 | with the contents of the root CHANGELOG.md. -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | gradlew 10 | gradlew.bat -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.mapbox.mapboxgl' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | mavenCentral() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:4.2.0' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | def token = System.getenv('SDK_REGISTRY_TOKEN') ?: project.properties['MAPBOX_DOWNLOADS_TOKEN'] 17 | if (token == null || token.empty) { 18 | throw new Exception("SDK Registry token is null. See README.md for more information.") 19 | } 20 | repositories { 21 | google() 22 | mavenCentral() 23 | maven { 24 | url 'https://api.mapbox.com/downloads/v2/releases/maven' 25 | authentication { 26 | basic(BasicAuthentication) 27 | } 28 | credentials { 29 | username = "mapbox" 30 | password = token 31 | } 32 | } 33 | } 34 | } 35 | 36 | apply plugin: 'com.android.library' 37 | 38 | android { 39 | namespace "com.mapbox.mapboxgl" 40 | compileSdkVersion 31 41 | ndkVersion "20.1.5948944" 42 | 43 | defaultConfig { 44 | minSdkVersion 20 45 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 46 | multiDexEnabled true 47 | } 48 | lintOptions { 49 | disable 'InvalidPackage' 50 | } 51 | compileOptions { 52 | sourceCompatibility JavaVersion.VERSION_1_8 53 | targetCompatibility JavaVersion.VERSION_1_8 54 | } 55 | dependencies { 56 | implementation "com.mapbox.mapboxsdk:mapbox-android-sdk:9.6.2" 57 | implementation "com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v9:0.9.0" 58 | implementation "com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v9:0.12.0" 59 | implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-offline-v9:0.7.0' 60 | implementation 'com.squareup.okhttp3:okhttp:4.9.0' 61 | implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:5.1.0' 62 | } 63 | compileOptions { 64 | sourceCompatibility 1.8 65 | targetCompatibility 1.8 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /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-6.9.1-all.zip -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'mapbox_gl' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/java/com/mapbox/mapboxgl/BitmapUtils.java: -------------------------------------------------------------------------------- 1 | package com.mapbox.mapboxgl; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.net.Uri; 6 | import android.util.Base64; 7 | import android.util.Log; 8 | import java.io.ByteArrayOutputStream; 9 | import java.io.File; 10 | import java.io.FileOutputStream; 11 | import java.io.IOException; 12 | import java.io.OutputStream; 13 | 14 | /** Created by nickitaliano on 10/9/17. */ 15 | public class BitmapUtils { 16 | private static final String LOG_TAG = "BitmapUtils"; 17 | 18 | public static String createTempFile(Context context, Bitmap bitmap) { 19 | File tempFile = null; 20 | FileOutputStream outputStream = null; 21 | 22 | try { 23 | tempFile = File.createTempFile(LOG_TAG, ".jpeg", context.getCacheDir()); 24 | outputStream = new FileOutputStream(tempFile); 25 | } catch (IOException e) { 26 | Log.w(LOG_TAG, e.getLocalizedMessage()); 27 | } 28 | 29 | if (tempFile == null) { 30 | return null; 31 | } 32 | 33 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); 34 | closeSnapshotOutputStream(outputStream); 35 | return Uri.fromFile(tempFile).toString(); 36 | } 37 | 38 | public static String createBase64(Bitmap bitmap) { 39 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 40 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); 41 | byte[] bitmapBytes = outputStream.toByteArray(); 42 | closeSnapshotOutputStream(outputStream); 43 | String base64Prefix = "data:image/jpeg;base64,"; 44 | return base64Prefix + Base64.encodeToString(bitmapBytes, Base64.NO_WRAP); 45 | } 46 | 47 | private static void closeSnapshotOutputStream(OutputStream outputStream) { 48 | if (outputStream == null) { 49 | return; 50 | } 51 | try { 52 | outputStream.close(); 53 | } catch (IOException e) { 54 | Log.w(LOG_TAG, e.getLocalizedMessage()); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /android/src/main/java/com/mapbox/mapboxgl/GeoJSONUtils.java: -------------------------------------------------------------------------------- 1 | package com.mapbox.mapboxgl; 2 | 3 | import com.mapbox.geojson.Feature; 4 | import com.mapbox.geojson.FeatureCollection; 5 | import com.mapbox.geojson.Geometry; 6 | import com.mapbox.geojson.GeometryCollection; 7 | import com.mapbox.geojson.Point; 8 | import com.mapbox.mapboxsdk.geometry.LatLng; 9 | import com.mapbox.mapboxsdk.geometry.LatLngBounds; 10 | import com.mapbox.turf.TurfMeasurement; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class GeoJSONUtils { 15 | public static LatLng toLatLng(Point point) { 16 | if (point == null) { 17 | return null; 18 | } 19 | return new LatLng(point.latitude(), point.longitude()); 20 | } 21 | 22 | private static GeometryCollection toGeometryCollection(List features) { 23 | ArrayList geometries = new ArrayList<>(); 24 | geometries.ensureCapacity(features.size()); 25 | for (Feature feature : features) { 26 | geometries.add(feature.geometry()); 27 | } 28 | return GeometryCollection.fromGeometries(geometries); 29 | } 30 | 31 | public static LatLngBounds toLatLngBounds(FeatureCollection featureCollection) { 32 | List features = featureCollection.features(); 33 | 34 | double[] bbox = TurfMeasurement.bbox(toGeometryCollection(features)); 35 | 36 | return LatLngBounds.from(bbox[3], bbox[2], bbox[1], bbox[0]); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /android/src/main/java/com/mapbox/mapboxgl/MapBoxUtils.java: -------------------------------------------------------------------------------- 1 | package com.mapbox.mapboxgl; 2 | 3 | import android.content.Context; 4 | import android.content.pm.ApplicationInfo; 5 | import android.content.pm.PackageManager; 6 | import android.os.Bundle; 7 | import android.util.Log; 8 | import androidx.annotation.NonNull; 9 | import com.mapbox.mapboxsdk.Mapbox; 10 | 11 | abstract class MapBoxUtils { 12 | private static final String TAG = "MapboxMapController"; 13 | 14 | static Mapbox getMapbox(Context context, String accessToken) { 15 | return Mapbox.getInstance(context, accessToken == null ? getAccessToken(context) : accessToken); 16 | } 17 | 18 | private static String getAccessToken(@NonNull Context context) { 19 | try { 20 | ApplicationInfo ai = 21 | context 22 | .getPackageManager() 23 | .getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); 24 | Bundle bundle = ai.metaData; 25 | String token = bundle.getString("com.mapbox.token"); 26 | if (token == null || token.isEmpty()) { 27 | throw new NullPointerException(); 28 | } 29 | return token; 30 | } catch (Exception e) { 31 | Log.e( 32 | TAG, 33 | "Failed to find an Access Token in the Application meta-data. Maps may not load" 34 | + " correctly. Please refer to the installation guide at" 35 | + " https://github.com/tobrun/flutter-mapbox-gl#mapbox-access-token for" 36 | + " troubleshooting advice." 37 | + e.getMessage()); 38 | } 39 | return null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /android/src/main/java/com/mapbox/mapboxgl/MapboxHttpRequestUtil.java: -------------------------------------------------------------------------------- 1 | package com.mapbox.mapboxgl; 2 | 3 | import com.mapbox.mapboxsdk.module.http.HttpRequestUtil; 4 | import io.flutter.plugin.common.MethodChannel; 5 | import java.util.Map; 6 | import okhttp3.OkHttpClient; 7 | import okhttp3.Request; 8 | 9 | abstract class MapboxHttpRequestUtil { 10 | 11 | public static void setHttpHeaders(Map headers, MethodChannel.Result result) { 12 | HttpRequestUtil.setOkHttpClient(getOkHttpClient(headers, result).build()); 13 | result.success(null); 14 | } 15 | 16 | private static OkHttpClient.Builder getOkHttpClient( 17 | Map headers, MethodChannel.Result result) { 18 | try { 19 | return new OkHttpClient.Builder() 20 | .addNetworkInterceptor( 21 | chain -> { 22 | Request.Builder builder = chain.request().newBuilder(); 23 | for (Map.Entry header : headers.entrySet()) { 24 | if (header.getKey() == null || header.getKey().trim().isEmpty()) { 25 | continue; 26 | } 27 | if (header.getValue() == null || header.getValue().trim().isEmpty()) { 28 | builder.removeHeader(header.getKey()); 29 | } else { 30 | builder.header(header.getKey(), header.getValue()); 31 | } 32 | } 33 | return chain.proceed(builder.build()); 34 | }); 35 | } catch (Exception e) { 36 | result.error( 37 | "OK_HTTP_CLIENT_ERROR", 38 | "An unexcepted error happened during creating http " + "client" + e.getMessage(), 39 | null); 40 | throw new RuntimeException(e); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /android/src/main/java/com/mapbox/mapboxgl/MapboxMapFactory.java: -------------------------------------------------------------------------------- 1 | package com.mapbox.mapboxgl; 2 | 3 | import android.content.Context; 4 | import com.mapbox.mapboxsdk.camera.CameraPosition; 5 | import io.flutter.plugin.common.BinaryMessenger; 6 | import io.flutter.plugin.common.StandardMessageCodec; 7 | import io.flutter.plugin.platform.PlatformView; 8 | import io.flutter.plugin.platform.PlatformViewFactory; 9 | import java.util.Map; 10 | 11 | public class MapboxMapFactory extends PlatformViewFactory { 12 | 13 | private final BinaryMessenger messenger; 14 | private final MapboxMapsPlugin.LifecycleProvider lifecycleProvider; 15 | 16 | public MapboxMapFactory( 17 | BinaryMessenger messenger, MapboxMapsPlugin.LifecycleProvider lifecycleProvider) { 18 | super(StandardMessageCodec.INSTANCE); 19 | this.messenger = messenger; 20 | this.lifecycleProvider = lifecycleProvider; 21 | } 22 | 23 | @Override 24 | public PlatformView create(Context context, int id, Object args) { 25 | Map params = (Map) args; 26 | final MapboxMapBuilder builder = new MapboxMapBuilder(); 27 | 28 | Convert.interpretMapboxMapOptions(params.get("options"), builder, context); 29 | if (params.containsKey("initialCameraPosition")) { 30 | CameraPosition position = Convert.toCameraPosition(params.get("initialCameraPosition")); 31 | builder.setInitialCameraPosition(position); 32 | } 33 | if (params.containsKey("dragEnabled")) { 34 | boolean dragEnabled = Convert.toBoolean(params.get("dragEnabled")); 35 | builder.setDragEnabled(dragEnabled); 36 | } 37 | 38 | return builder.build( 39 | id, context, messenger, lifecycleProvider, (String) params.get("accessToken")); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /android/src/main/java/com/mapbox/mapboxgl/MapboxMapOptionsSink.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | package com.mapbox.mapboxgl; 6 | 7 | import com.mapbox.mapboxsdk.geometry.LatLngBounds; 8 | 9 | /** Receiver of MapboxMap configuration options. */ 10 | interface MapboxMapOptionsSink { 11 | void setCameraTargetBounds( 12 | LatLngBounds bounds); // todo: dddd replace with CameraPosition.Builder target 13 | 14 | void setCompassEnabled(boolean compassEnabled); 15 | 16 | // TODO: styleString is not actually a part of options. consider moving 17 | void setStyleString(String styleString); 18 | 19 | void setMinMaxZoomPreference(Float min, Float max); 20 | 21 | void setRotateGesturesEnabled(boolean rotateGesturesEnabled); 22 | 23 | void setScrollGesturesEnabled(boolean scrollGesturesEnabled); 24 | 25 | void setTiltGesturesEnabled(boolean tiltGesturesEnabled); 26 | 27 | void setTrackCameraPosition(boolean trackCameraPosition); 28 | 29 | void setZoomGesturesEnabled(boolean zoomGesturesEnabled); 30 | 31 | void setMyLocationEnabled(boolean myLocationEnabled); 32 | 33 | void setMyLocationTrackingMode(int myLocationTrackingMode); 34 | 35 | void setMyLocationRenderMode(int myLocationRenderMode); 36 | 37 | void setLogoViewMargins(int x, int y); 38 | 39 | void setCompassGravity(int gravity); 40 | 41 | void setCompassViewMargins(int x, int y); 42 | 43 | void setAttributionButtonGravity(int gravity); 44 | 45 | void setAttributionButtonMargins(int x, int y); 46 | } 47 | -------------------------------------------------------------------------------- /android/src/main/java/com/mapbox/mapboxgl/OfflineChannelHandlerImpl.java: -------------------------------------------------------------------------------- 1 | package com.mapbox.mapboxgl; 2 | 3 | import androidx.annotation.Nullable; 4 | import com.google.gson.Gson; 5 | import io.flutter.plugin.common.BinaryMessenger; 6 | import io.flutter.plugin.common.EventChannel; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | public class OfflineChannelHandlerImpl implements EventChannel.StreamHandler { 11 | private EventChannel.EventSink sink; 12 | private Gson gson = new Gson(); 13 | 14 | OfflineChannelHandlerImpl(BinaryMessenger messenger, String channelName) { 15 | EventChannel eventChannel = new EventChannel(messenger, channelName); 16 | eventChannel.setStreamHandler(this); 17 | } 18 | 19 | @Override 20 | public void onListen(Object arguments, EventChannel.EventSink events) { 21 | sink = events; 22 | } 23 | 24 | @Override 25 | public void onCancel(Object arguments) { 26 | sink = null; 27 | } 28 | 29 | void onError(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { 30 | if (sink == null) return; 31 | sink.error(errorCode, errorMessage, errorDetails); 32 | } 33 | 34 | void onSuccess() { 35 | if (sink == null) return; 36 | Map body = new HashMap<>(); 37 | body.put("status", "success"); 38 | sink.success(gson.toJson(body)); 39 | } 40 | 41 | void onStart() { 42 | if (sink == null) return; 43 | Map body = new HashMap<>(); 44 | body.put("status", "start"); 45 | sink.success(gson.toJson(body)); 46 | } 47 | 48 | void onProgress(double progress) { 49 | if (sink == null) return; 50 | Map body = new HashMap<>(); 51 | body.put("status", "progress"); 52 | body.put("progress", progress); 53 | sink.success(gson.toJson(body)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /android/src/main/java/com/mapbox/mapboxgl/OnCameraMoveListener.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | package com.mapbox.mapboxgl; 6 | 7 | import com.mapbox.mapboxsdk.camera.CameraPosition; 8 | 9 | interface OnCameraMoveListener { 10 | void onCameraMoveStarted(boolean isGesture); 11 | 12 | void onCameraMove(CameraPosition newPosition); 13 | 14 | void onCameraIdle(); 15 | } 16 | -------------------------------------------------------------------------------- /android/src/main/java/com/mapbox/mapboxgl/OnInfoWindowTappedListener.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | package com.mapbox.mapboxgl; 6 | 7 | import com.mapbox.mapboxsdk.annotations.Marker; 8 | 9 | public interface OnInfoWindowTappedListener { 10 | void onInfoWindowTapped(Marker marker); 11 | } 12 | -------------------------------------------------------------------------------- /doc/RUNNING_EXAMPLE_CODE.md: -------------------------------------------------------------------------------- 1 | # Running the example code 2 | 3 | - You'll find the example code in the `example` folder of this repository 4 | 5 | ## Secret Mapbox access token 6 | 7 | A secret access token with the `Downloads: Read` scope is required for the underlying Mapbox SDKs to be downloaded. 8 | Information on setting it up is available in the Mapbox documentation: 9 | [Android](https://docs.mapbox.com/android/maps/guides/install/), 10 | [iOS](https://docs.mapbox.com/ios/maps/guides/install/). 11 | 12 | If the properly configured token is not present, 13 | the build process fails with one the following errors *(for Android/iOS respectively)*: 14 | 15 | ``` 16 | * What went wrong: 17 | A problem occurred evaluating project ':mapbox_gl'. 18 | > SDK Registry token is null. See README.md for more information. 19 | ``` 20 | 21 | ``` 22 | [!] Error installing Mapbox-iOS-SDK 23 | curl: (22) The requested URL returned error: 401 Unauthorized 24 | ``` 25 | 26 | ## iOS 27 | - Clone this repo 28 | - Open `example/ios/Runner.xcworkspace` in XCode 29 | - On the left, select Runner and change the Bundle identifier on the `general` tab to something of your own. 30 | 31 | ![XCode bundle identier](img/xcode-bundle-identifier.png) 32 | 33 | - On the `signing & capabilities` tab change the team to your own. 34 | - Close Xcode 35 | - run `flutter build ios --dart-define ACCESS_TOKEN=sk.xxxxxxxxxxxxxxxxxxxxx` to make sure the project builds from the command line. The `ACCESS_TOKEN` is the Mapbox token you've obtained in the `Secret Mapbox access token` step described above. 36 | - The build command output should be something like: 37 | 38 | ```terminal 39 | Warning: You are using these overridden dependencies: 40 | ! mapbox_gl_platform_interface 0.15.0 from path ../mapbox_gl_platform_interface 41 | ! mapbox_gl_web 0.15.0 from path ../mapbox_gl_web 42 | Running "flutter pub get" in example... 1,918ms 43 | Building com.xxx.mapboxtest for device (ios-release)... 44 | Updating project for Xcode compatibility. 45 | Upgrading project.pbxproj 46 | Upgrading Runner.xcscheme 47 | Signing iOS app for device deployment using developer identity: "Apple Development: xxx@xxxxx.xx (XXXXXXX)" 48 | Running pod install... 2,950ms 49 | Running Xcode build... 50 | └─Compiling, linking and signing... 15.1s 51 | Xcode build done. 98.2s 52 | Built /Development/flutter/maps/example/build/ios/iphoneos/Runner.app. 53 | ``` 54 | 55 | - Open `example/ios/Runner.xcworkspace` again in XCode 56 | - Run the project connected iPhone or iOS Emulator 57 | 58 | ![XCode bundle identief](img/example-iphone.jpeg) -------------------------------------------------------------------------------- /doc/img/example-iphone.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/doc/img/example-iphone.jpeg -------------------------------------------------------------------------------- /doc/img/xcode-bundle-identifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/doc/img/xcode-bundle-identifier.png -------------------------------------------------------------------------------- /example/.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 | .fvm/ 13 | 14 | # IntelliJ related 15 | *.iml 16 | *.ipr 17 | *.iws 18 | .idea/ 19 | 20 | # Visual Studio Code related 21 | .vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /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: 2e2f19d3e9dd9bbc4e97e6b79bd573ab67c65109 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # mapbox_gl_example 2 | 3 | Demonstrates how to use the mapbox_gl plugin. 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.io/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.io/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.class 3 | .gradle 4 | /local.properties 5 | /.idea/workspace.xml 6 | /.idea/libraries 7 | .DS_Store 8 | /build 9 | /captures 10 | GeneratedPluginRegistrant.java 11 | app/src/main/res/values/developer-config.xml -------------------------------------------------------------------------------- /example/android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | android 4 | Project android created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /example/android/app/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/android/app/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | app 4 | Project app created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.buildship.core.gradleprojectnature 22 | 23 | 24 | -------------------------------------------------------------------------------- /example/android/app/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir=.. 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "dev.flutter.flutter-gradle-plugin" 4 | } 5 | 6 | def localProperties = new Properties() 7 | def localPropertiesFile = rootProject.file('local.properties') 8 | if (localPropertiesFile.exists()) { 9 | localPropertiesFile.withReader('UTF-8') { reader -> 10 | localProperties.load(reader) 11 | } 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | android { 25 | namespace "com.mapbox.mapboxglexample" 26 | compileSdkVersion 35 27 | ndkVersion "25.1.8937393" 28 | 29 | lintOptions { 30 | disable 'InvalidPackage' 31 | } 32 | 33 | defaultConfig { 34 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 35 | applicationId "com.mapbox.mapboxglexample" 36 | minSdkVersion flutter.minSdkVersion 37 | targetSdkVersion 35 38 | versionCode flutterVersionCode.toInteger() 39 | versionName flutterVersionName 40 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 41 | multiDexEnabled true 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | 50 | // To fix UnsatisfiedLinkError 51 | ndk { 52 | abiFilters 'armeabi-v7a','arm64-v8a','x86_64', 'x86' 53 | } 54 | } 55 | } 56 | compileOptions { 57 | sourceCompatibility 1.8 58 | targetCompatibility 1.8 59 | } 60 | } 61 | 62 | flutter { 63 | source '../..' 64 | } 65 | 66 | dependencies { 67 | testImplementation 'junit:junit:4.12' 68 | androidTestImplementation 'androidx.test:runner:1.1.0-alpha4' 69 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4' 70 | constraints { 71 | implementation('com.google.android.gms:play-services-location') { 72 | version { 73 | strictly "16.0.0" 74 | } 75 | because 'location: 4.2.3 does not specify version play-services-location' 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 36 | 37 | 38 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/mapbox/mapboxglexample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.mapbox.mapboxglexample; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity {} 6 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/mapbox/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mapbox.example 2 | 3 | import androidx.annotation.NonNull; 4 | import io.flutter.embedding.android.FlutterActivity 5 | import io.flutter.embedding.engine.FlutterEngine 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { 10 | GeneratedPluginRegistrant.registerWith(flutterEngine); 11 | } 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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /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 | } 12 | subprojects { 13 | project.evaluationDependsOn(':app') 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.layout.buildDirectory 18 | } 19 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | android.enableJetifier=true 2 | android.useAndroidX=true 3 | org.gradle.jvmargs=-Xmx1536M 4 | android.enableR8=true 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /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 '8.2.2' apply false 22 | } 23 | 24 | include ":app" -------------------------------------------------------------------------------- /example/android/settings_aar.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /example/assets/fill/cat_silhouette_pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/assets/fill/cat_silhouette_pattern.png -------------------------------------------------------------------------------- /example/assets/style.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 8, 3 | "name": "Example taken from https://docs.mapbox.com/ios/maps/examples/source-custom-vector/", 4 | "sources": { 5 | "mapillary": { 6 | "type": "vector", 7 | "tiles": [ 8 | "https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt" 9 | ], 10 | "attribution": "© Mapillary, CC BY", 11 | "maxzoom": 14 12 | } 13 | }, 14 | "layers": [{ 15 | "id": "background", 16 | "type": "background", 17 | "paint": { 18 | "background-color": "#485E77" 19 | } 20 | }, 21 | { 22 | "id": "mapillary-sequences", 23 | "type": "line", 24 | "source": "mapillary", 25 | "source-layer": "mapillary-sequences", 26 | "filter": [ 27 | "==", 28 | "$type", 29 | "LineString" 30 | ], 31 | "paint": { 32 | "line-color": "#F56745" 33 | } 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /example/assets/sydney.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/assets/sydney.png -------------------------------------------------------------------------------- /example/assets/symbols/2.0x/custom-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/assets/symbols/2.0x/custom-icon.png -------------------------------------------------------------------------------- /example/assets/symbols/3.0x/custom-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/assets/symbols/3.0x/custom-icon.png -------------------------------------------------------------------------------- /example/assets/symbols/custom-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/assets/symbols/custom-icon.png -------------------------------------------------------------------------------- /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/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/ios/Flutter/.last_build_id: -------------------------------------------------------------------------------- 1 | 03fcf93a7807ed5ca7e1593e013555e0 2 | -------------------------------------------------------------------------------- /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 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '9.0' 3 | use_frameworks! 4 | 5 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 6 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 7 | 8 | project 'Runner', { 9 | 'Debug' => :debug, 10 | 'Profile' => :release, 11 | 'Release' => :release, 12 | } 13 | 14 | def flutter_root 15 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 16 | unless File.exist?(generated_xcode_build_settings_path) 17 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 18 | end 19 | 20 | File.foreach(generated_xcode_build_settings_path) do |line| 21 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 22 | return matches[1].strip if matches 23 | end 24 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 25 | end 26 | 27 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 28 | 29 | flutter_ios_podfile_setup 30 | 31 | target 'Runner' do 32 | use_frameworks! 33 | use_modular_headers! 34 | 35 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 36 | end 37 | 38 | post_install do |installer| 39 | installer.pods_project.build_configurations.each do |config| 40 | config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64" 41 | end 42 | installer.pods_project.targets.each do |target| 43 | flutter_additional_ios_build_settings(target) 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /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/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/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 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | mapbox_gl_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 | io.flutter.embedded_views_preview 45 | 46 | MGLMapboxAccessToken 47 | YOUR_KEY_HERE 48 | MGLMapboxMetricsEnabledSettingShownInApp 49 | 50 | NSLocationWhenInUseUsageDescription 51 | Shows your location on the map and helps improve the map 52 | NSLocationAlwaysUsageDescription 53 | Shows your location on the map and helps improve the map 54 | CADisableMinimumFrameDurationOnPhone 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/lib/full_map.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mapbox_gl/mapbox_gl.dart'; 3 | 4 | import 'main.dart'; 5 | import 'page.dart'; 6 | 7 | class FullMapPage extends ExamplePage { 8 | FullMapPage() : super(const Icon(Icons.map), 'Full screen map'); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return const FullMap(); 13 | } 14 | } 15 | 16 | class FullMap extends StatefulWidget { 17 | const FullMap(); 18 | 19 | @override 20 | State createState() => FullMapState(); 21 | } 22 | 23 | class FullMapState extends State { 24 | MapboxMapController? mapController; 25 | var isLight = true; 26 | 27 | _onMapCreated(MapboxMapController controller) { 28 | mapController = controller; 29 | } 30 | 31 | _onStyleLoadedCallback() { 32 | ScaffoldMessenger.of(context).showSnackBar(SnackBar( 33 | content: Text("Style loaded :)"), 34 | backgroundColor: Theme.of(context).primaryColor, 35 | duration: Duration(seconds: 1), 36 | )); 37 | } 38 | 39 | @override 40 | Widget build(BuildContext context) { 41 | return new Scaffold( 42 | floatingActionButton: Padding( 43 | padding: const EdgeInsets.all(32.0), 44 | child: FloatingActionButton( 45 | child: Icon(Icons.swap_horiz), 46 | onPressed: () => setState( 47 | () => isLight = !isLight, 48 | ), 49 | ), 50 | ), 51 | body: MapboxMap( 52 | styleString: isLight ? MapboxStyles.LIGHT : MapboxStyles.DARK, 53 | accessToken: MapsDemo.ACCESS_TOKEN, 54 | onMapCreated: _onMapCreated, 55 | initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)), 56 | onStyleLoadedCallback: _onStyleLoadedCallback, 57 | )); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /example/lib/generated_plugin_registrant.dart: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // ignore_for_file: directives_ordering 6 | // ignore_for_file: lines_longer_than_80_chars 7 | // ignore_for_file: depend_on_referenced_packages 8 | 9 | import 'package:location_web/location_web.dart'; 10 | import 'package:mapbox_gl_web/mapbox_gl_web.dart'; 11 | 12 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 13 | 14 | // ignore: public_member_api_docs 15 | void registerPlugins(Registrar registrar) { 16 | LocationWebPlugin.registerWith(registrar); 17 | MapboxMapPlugin.registerWith(registrar); 18 | registrar.registerMessageHandler(); 19 | } 20 | -------------------------------------------------------------------------------- /example/lib/local_style.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:mapbox_gl/mapbox_gl.dart'; 5 | import 'package:path_provider/path_provider.dart'; 6 | 7 | import 'main.dart'; 8 | import 'page.dart'; 9 | 10 | class LocalStylePage extends ExamplePage { 11 | LocalStylePage() : super(const Icon(Icons.map), 'Local style'); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return const LocalStyle(); 16 | } 17 | } 18 | 19 | class LocalStyle extends StatefulWidget { 20 | const LocalStyle(); 21 | 22 | @override 23 | State createState() => LocalStyleState(); 24 | } 25 | 26 | class LocalStyleState extends State { 27 | MapboxMapController? mapController; 28 | String? styleAbsoluteFilePath; 29 | 30 | @override 31 | initState() { 32 | super.initState(); 33 | 34 | getApplicationDocumentsDirectory().then((dir) async { 35 | String documentDir = dir.path; 36 | String stylesDir = '$documentDir/styles'; 37 | String styleJSON = 38 | '{"version":8,"name":"Basic","constants":{},"sources":{"mapillary":{"type":"vector","tiles":["https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt"],"attribution":"© Mapillary, CC BY","maxzoom":14}},"sprite":"","glyphs":"","layers":[{"id":"background","type":"background","paint":{"background-color":"rgba(135, 149, 154, 1)"}},{"id":"water","type":"fill","source":"mapbox","source-layer":"water","paint":{"fill-color":"rgba(108, 148, 120, 1)"}}]}'; 39 | 40 | await new Directory(stylesDir).create(recursive: true); 41 | 42 | File styleFile = new File('$stylesDir/style.json'); 43 | 44 | await styleFile.writeAsString(styleJSON); 45 | 46 | setState(() { 47 | styleAbsoluteFilePath = styleFile.path; 48 | }); 49 | }); 50 | } 51 | 52 | void _onMapCreated(MapboxMapController controller) { 53 | mapController = controller; 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context) { 58 | if (styleAbsoluteFilePath == null) { 59 | return Scaffold( 60 | body: Center(child: Text('Creating local style file...')), 61 | ); 62 | } 63 | 64 | return new Scaffold( 65 | body: MapboxMap( 66 | accessToken: MapsDemo.ACCESS_TOKEN, 67 | styleString: styleAbsoluteFilePath, 68 | onMapCreated: _onMapCreated, 69 | initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)), 70 | onStyleLoadedCallback: onStyleLoadedCallback, 71 | )); 72 | } 73 | 74 | void onStyleLoadedCallback() {} 75 | } 76 | -------------------------------------------------------------------------------- /example/lib/offline_region_map.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mapbox_gl/mapbox_gl.dart'; 3 | 4 | import 'offline_regions.dart'; 5 | 6 | class OfflineRegionMap extends StatefulWidget { 7 | OfflineRegionMap(this.item); 8 | 9 | final OfflineRegionListItem item; 10 | 11 | @override 12 | _OfflineRegionMapState createState() => _OfflineRegionMapState(); 13 | } 14 | 15 | class _OfflineRegionMapState extends State { 16 | @override 17 | Widget build(BuildContext context) { 18 | return Scaffold( 19 | appBar: AppBar( 20 | title: Text('Offline Region: ${widget.item.name}'), 21 | ), 22 | body: MapboxMap( 23 | initialCameraPosition: CameraPosition( 24 | target: _center, 25 | zoom: widget.item.offlineRegionDefinition.minZoom, 26 | ), 27 | minMaxZoomPreference: MinMaxZoomPreference( 28 | widget.item.offlineRegionDefinition.minZoom, 29 | widget.item.offlineRegionDefinition.maxZoom, 30 | ), 31 | styleString: widget.item.offlineRegionDefinition.mapStyleUrl, 32 | cameraTargetBounds: CameraTargetBounds( 33 | widget.item.offlineRegionDefinition.bounds, 34 | ), 35 | ), 36 | ); 37 | } 38 | 39 | LatLng get _center { 40 | final bounds = widget.item.offlineRegionDefinition.bounds; 41 | final lat = (bounds.southwest.latitude + bounds.northeast.latitude) / 2; 42 | final lng = (bounds.southwest.longitude + bounds.northeast.longitude) / 2; 43 | return LatLng(lat, lng); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /example/lib/page.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | abstract class ExamplePage extends StatelessWidget { 8 | const ExamplePage(this.leading, this.title); 9 | 10 | final Widget leading; 11 | final String title; 12 | } 13 | -------------------------------------------------------------------------------- /example/lib/scrolling_map.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/foundation.dart'; 6 | import 'package:flutter/gestures.dart'; 7 | import 'package:flutter/material.dart'; 8 | import 'package:flutter/rendering.dart'; // ignore: unnecessary_import 9 | import 'package:mapbox_gl/mapbox_gl.dart'; 10 | 11 | import 'main.dart'; 12 | import 'page.dart'; 13 | 14 | class ScrollingMapPage extends ExamplePage { 15 | ScrollingMapPage() : super(const Icon(Icons.map), 'Scrolling map'); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return ScrollingMapBody(); 20 | } 21 | } 22 | 23 | class ScrollingMapBody extends StatefulWidget { 24 | ScrollingMapBody(); 25 | 26 | @override 27 | _ScrollingMapBodyState createState() => _ScrollingMapBodyState(); 28 | } 29 | 30 | class _ScrollingMapBodyState extends State { 31 | late MapboxMapController controllerOne; 32 | late MapboxMapController controllerTwo; 33 | 34 | final LatLng center = const LatLng(32.080664, 34.9563837); 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | return ListView( 39 | children: [ 40 | Card( 41 | child: Padding( 42 | padding: const EdgeInsets.symmetric(vertical: 30.0), 43 | child: Column( 44 | children: [ 45 | const Padding( 46 | padding: EdgeInsets.only(bottom: 12.0), 47 | child: Text('This map consumes all touch events.'), 48 | ), 49 | Center( 50 | child: SizedBox( 51 | width: 300.0, 52 | height: 300.0, 53 | child: MapboxMap( 54 | accessToken: MapsDemo.ACCESS_TOKEN, 55 | onMapCreated: onMapCreatedOne, 56 | onStyleLoadedCallback: () => onStyleLoaded(controllerOne), 57 | initialCameraPosition: CameraPosition( 58 | target: center, 59 | zoom: 11.0, 60 | ), 61 | gestureRecognizers: 62 | >[ 63 | Factory( 64 | () => EagerGestureRecognizer(), 65 | ), 66 | ].toSet(), 67 | ), 68 | ), 69 | ), 70 | ], 71 | ), 72 | ), 73 | ), 74 | Card( 75 | child: Padding( 76 | padding: const EdgeInsets.symmetric(vertical: 30.0), 77 | child: Column( 78 | children: [ 79 | const Text('This map doesn\'t consume the vertical drags.'), 80 | const Padding( 81 | padding: EdgeInsets.only(bottom: 12.0), 82 | child: 83 | Text('It still gets other gestures (e.g scale or tap).'), 84 | ), 85 | Center( 86 | child: SizedBox( 87 | width: 300.0, 88 | height: 300.0, 89 | child: MapboxMap( 90 | accessToken: MapsDemo.ACCESS_TOKEN, 91 | onMapCreated: onMapCreatedTwo, 92 | onStyleLoadedCallback: () => onStyleLoaded(controllerTwo), 93 | initialCameraPosition: CameraPosition( 94 | target: center, 95 | zoom: 11.0, 96 | ), 97 | gestureRecognizers: 98 | >[ 99 | Factory( 100 | () => ScaleGestureRecognizer(), 101 | ), 102 | ].toSet(), 103 | ), 104 | ), 105 | ), 106 | ], 107 | ), 108 | ), 109 | ), 110 | ], 111 | ); 112 | } 113 | 114 | void onMapCreatedOne(MapboxMapController controller) { 115 | this.controllerOne = controller; 116 | } 117 | 118 | void onMapCreatedTwo(MapboxMapController controller) { 119 | this.controllerTwo = controller; 120 | } 121 | 122 | void onStyleLoaded(MapboxMapController controller) { 123 | controller.addSymbol(SymbolOptions( 124 | geometry: LatLng( 125 | center.latitude, 126 | center.longitude, 127 | ), 128 | iconImage: "airport-15")); 129 | controller.addLine( 130 | LineOptions( 131 | geometry: [ 132 | LatLng(-33.86711, 151.1947171), 133 | LatLng(-33.86711, 151.1947171), 134 | LatLng(-32.86711, 151.1947171), 135 | LatLng(-33.86711, 152.1947171), 136 | ], 137 | lineColor: "#ff0000", 138 | lineWidth: 7.0, 139 | lineOpacity: 0.5, 140 | ), 141 | ); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /example/lib/take_snapshot.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | import 'dart:typed_data'; 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:mapbox_gl/mapbox_gl.dart'; 7 | 8 | import 'main.dart'; 9 | import 'page.dart'; 10 | 11 | class TakeSnapPage extends ExamplePage { 12 | TakeSnapPage() : super(const Icon(Icons.camera_alt), 'Take snapshot'); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return const TakeSnapshot(); 17 | } 18 | } 19 | 20 | class TakeSnapshot extends StatefulWidget { 21 | const TakeSnapshot(); 22 | 23 | @override 24 | State createState() => FullMapState(); 25 | } 26 | 27 | class FullMapState extends State { 28 | FullMapState(); 29 | 30 | MapboxMapController? mapController; 31 | final mapKey = GlobalKey(); 32 | String? snapshotResult; 33 | 34 | void _onMapCreated(MapboxMapController controller) { 35 | mapController = controller; 36 | } 37 | 38 | void _onTakeSnapshot([bool writeToDisk = true]) async { 39 | final renderBox = mapKey.currentContext?.findRenderObject() as RenderBox; 40 | 41 | final snapshotOptions = SnapshotOptions( 42 | width: renderBox.size.width, 43 | height: renderBox.size.height, 44 | writeToDisk: writeToDisk, 45 | withLogo: false, 46 | ); 47 | final result = await mapController?.takeSnapshot(snapshotOptions); 48 | debugPrint("result: $result"); 49 | _setResult(result); 50 | } 51 | 52 | void _onTakeSnapshotWithBounds() async { 53 | final renderBox = mapKey.currentContext?.findRenderObject() as RenderBox; 54 | final bounds = await mapController?.getVisibleRegion(); 55 | 56 | final snapshotOptions = SnapshotOptions( 57 | width: renderBox.size.width, 58 | height: renderBox.size.height, 59 | writeToDisk: true, 60 | withLogo: false, 61 | bounds: bounds, 62 | ); 63 | final uri = await mapController?.takeSnapshot(snapshotOptions); 64 | 65 | _setResult(uri); 66 | } 67 | 68 | void _onTakeSnapshotWithCameraPosition() async { 69 | final renderBox = mapKey.currentContext?.findRenderObject() as RenderBox; 70 | 71 | final snapshotOptions = SnapshotOptions( 72 | width: renderBox.size.width, 73 | height: renderBox.size.height, 74 | writeToDisk: true, 75 | withLogo: false, 76 | centerCoordinate: LatLng(40.79796, -74.126410), 77 | zoomLevel: 12, 78 | pitch: 30, 79 | heading: 20, 80 | ); 81 | final uri = await mapController?.takeSnapshot(snapshotOptions); 82 | _setResult(uri); 83 | } 84 | 85 | void _setResult(String? result) { 86 | if (result != null) { 87 | setState(() { 88 | snapshotResult = result.replaceAll("file:", ""); 89 | }); 90 | } 91 | } 92 | 93 | Uint8List convertBase64Image(String base64String) { 94 | return Base64Decoder().convert(base64String.split(',').last); 95 | } 96 | 97 | @override 98 | Widget build(BuildContext context) { 99 | final height = MediaQuery.of(context).size.height; 100 | return Column( 101 | children: [ 102 | Expanded( 103 | child: MapboxMap( 104 | key: mapKey, 105 | accessToken: MapsDemo.ACCESS_TOKEN, 106 | onMapCreated: _onMapCreated, 107 | initialCameraPosition: 108 | const CameraPosition(target: LatLng(0.0, 0.0)), 109 | myLocationEnabled: true, 110 | styleString: MapboxStyles.SATELLITE, 111 | ), 112 | ), 113 | const SizedBox( 114 | height: 5, 115 | ), 116 | Container( 117 | height: height * 0.4, 118 | child: Column( 119 | children: [ 120 | Wrap( 121 | spacing: 10, 122 | alignment: WrapAlignment.center, 123 | children: [ 124 | ElevatedButton( 125 | onPressed: _onTakeSnapshot, 126 | child: Text("Take Snap"), 127 | ), 128 | ElevatedButton( 129 | onPressed: _onTakeSnapshotWithBounds, 130 | child: Text("With Bounds"), 131 | ), 132 | ElevatedButton( 133 | onPressed: _onTakeSnapshotWithCameraPosition, 134 | child: Text("With Camera Position"), 135 | ), 136 | ElevatedButton( 137 | onPressed: () => _onTakeSnapshot(false), 138 | child: Text("With Base64"), 139 | ), 140 | ], 141 | ), 142 | const SizedBox( 143 | height: 10, 144 | ), 145 | if (snapshotResult != null) 146 | Container( 147 | decoration: BoxDecoration(border: Border.all()), 148 | child: snapshotResult!.contains("base64") 149 | ? Image.memory( 150 | convertBase64Image(snapshotResult!), 151 | gaplessPlayback: true, 152 | height: height * 0.20, 153 | ) 154 | : Image.file( 155 | File(snapshotResult!), 156 | height: height * 0.20, 157 | ), 158 | ), 159 | ], 160 | ), 161 | ) 162 | ], 163 | ); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def parse_KV_file(file, separator='=') 13 | file_abs_path = File.expand_path(file) 14 | if !File.exists? file_abs_path 15 | return []; 16 | end 17 | pods_ary = [] 18 | skip_line_start_symbols = ["#", "/"] 19 | File.foreach(file_abs_path) { |line| 20 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 21 | plugin = line.split(pattern=separator) 22 | if plugin.length == 2 23 | podname = plugin[0].strip() 24 | path = plugin[1].strip() 25 | podpath = File.expand_path("#{path}", file_abs_path) 26 | pods_ary.push({:name => podname, :path => podpath}); 27 | else 28 | puts "Invalid plugin specification: #{line}" 29 | end 30 | } 31 | return pods_ary 32 | end 33 | 34 | def pubspec_supports_macos(file) 35 | file_abs_path = File.expand_path(file) 36 | if !File.exists? file_abs_path 37 | return false; 38 | end 39 | File.foreach(file_abs_path) { |line| 40 | return true if line =~ /^\s*macos:/ 41 | } 42 | return false 43 | end 44 | 45 | target 'Runner' do 46 | use_frameworks! 47 | use_modular_headers! 48 | 49 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 50 | # referring to absolute paths on developers' machines. 51 | ephemeral_dir = File.join('Flutter', 'ephemeral') 52 | symlink_dir = File.join(ephemeral_dir, '.symlinks') 53 | symlink_plugins_dir = File.join(symlink_dir, 'plugins') 54 | system("rm -rf #{symlink_dir}") 55 | system("mkdir -p #{symlink_plugins_dir}") 56 | 57 | # Flutter Pods 58 | generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig')) 59 | if generated_xcconfig.empty? 60 | puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 61 | end 62 | generated_xcconfig.map { |p| 63 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 64 | symlink = File.join(symlink_dir, 'flutter') 65 | File.symlink(File.dirname(p[:path]), symlink) 66 | pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path])) 67 | end 68 | } 69 | 70 | # Plugin Pods 71 | plugin_pods = parse_KV_file('../.flutter-plugins') 72 | plugin_pods.map { |p| 73 | symlink = File.join(symlink_plugins_dir, p[:name]) 74 | File.symlink(p[:path], symlink) 75 | if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml')) 76 | pod p[:name], :path => File.join(symlink, 'macos') 77 | end 78 | } 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.example 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2020 com.mapbox. All rights reserved. 15 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController() 7 | let windowFrame = frame 8 | contentViewController = flutterViewController 9 | setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mapbox_gl_example 2 | description: Demonstrates how to use the mapbox_gl plugin. 3 | publish_to: 'none' 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: '>=2.12.0 <3.0.0' 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | 13 | # The following adds the Cupertino Icons font to your application. 14 | # Use with the CupertinoIcons class for iOS style icons. 15 | cupertino_icons: ^1.0.0 16 | location: ^8.0.0 17 | path_provider: ^2.0.0 18 | http: ^0.13.0 19 | collection: ^1.0.0 20 | device_info_plus: ^9.0.0 21 | 22 | dependency_overrides: 23 | mapbox_gl_platform_interface: 24 | path: ../mapbox_gl_platform_interface 25 | mapbox_gl_web: 26 | path: ../mapbox_gl_web 27 | 28 | dev_dependencies: 29 | flutter_test: 30 | sdk: flutter 31 | 32 | mapbox_gl: 33 | path: ../ 34 | 35 | # For information on the generic Dart part of this file, see the 36 | # following page: https://www.dartlang.org/tools/pub/pubspec 37 | 38 | # The following section is specific to Flutter. 39 | flutter: 40 | 41 | # The following line ensures that the Material Icons font is 42 | # included with your application, so that you can use the icons in 43 | # the material Icons class. 44 | uses-material-design: true 45 | 46 | # To add assets to your application, add an assets section, like this: 47 | # assets: 48 | # - images/a_dot_burr.jpeg 49 | # - images/a_dot_ham.jpeg 50 | 51 | # An image asset can refer to one or more resolution-specific "variants", see 52 | # https://flutter.io/assets-and-images/#resolution-aware. 53 | 54 | assets: 55 | - assets/fill/cat_silhouette_pattern.png 56 | - assets/fill-extrusion/indoor_3d_map.json 57 | - assets/symbols/custom-icon.png 58 | - assets/symbols/2.0x/custom-icon.png 59 | - assets/symbols/3.0x/custom-icon.png 60 | - assets/style.json 61 | - assets/sydney.png 62 | 63 | # For details regarding adding assets from package dependencies, see 64 | # https://flutter.io/assets-and-images/#from-packages 65 | 66 | # To add custom fonts to your application, add a fonts section here, 67 | # in this "flutter" section. Each entry in this list should have a 68 | # "family" key with the font family name, and a "fonts" key with a 69 | # list giving the asset and other descriptors for the font. For 70 | # example: 71 | # fonts: 72 | # - family: Schyler 73 | # fonts: 74 | # - asset: fonts/Schyler-Regular.ttf 75 | # - asset: fonts/Schyler-Italic.ttf 76 | # style: italic 77 | # - family: Trajan Pro 78 | # fonts: 79 | # - asset: fonts/TrajanPro.ttf 80 | # - asset: fonts/TrajanPro_Bold.ttf 81 | # weight: 700 82 | # 83 | # For details regarding fonts from package dependencies, 84 | # see https://flutter.io/custom-fonts/#from-packages 85 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | example 21 | 22 | 23 | 24 | 27 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "minimal-ui", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /flutter_mapbox_gl.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /install_formatting_tools.sh: -------------------------------------------------------------------------------- 1 | echo "Cleanup" 2 | rm swiftformat 3 | rm -r __MACOSX 4 | rm google-java-format-1.13.0-all-deps.jar 5 | 6 | if [ $(uname) = "Linux" ] 7 | then 8 | echo "Install for Linux" 9 | wget https://github.com/nicklockwood/SwiftFormat/releases/download/0.48.18/swiftformat_linux.zip 10 | unzip swiftformat_linux.zip 11 | rm swiftformat_linux.zip 12 | mv swiftformat_linux swiftformat 13 | else 14 | echo "Install for MAC" 15 | wget https://github.com/nicklockwood/SwiftFormat/releases/download/0.48.18/swiftformat.zip 16 | unzip swiftformat.zip 17 | rm swiftformat.zip 18 | fi 19 | chmod +x swiftformat 20 | 21 | wget https://github.com/google/google-java-format/releases/download/v1.13.0/google-java-format-1.13.0-all-deps.jar 22 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/Constants.swift: -------------------------------------------------------------------------------- 1 | import Mapbox 2 | import MapboxAnnotationExtension 3 | 4 | /* 5 | * The mapping is based on the values defined here: 6 | * https://docs.mapbox.com/android/api/map-sdk/8.4.0/constant-values.html 7 | */ 8 | 9 | class Constants { 10 | static let symbolIconAnchorMapping = [ 11 | "center": MGLIconAnchor.center, 12 | "left": MGLIconAnchor.left, 13 | "right": MGLIconAnchor.right, 14 | "top": MGLIconAnchor.top, 15 | "bottom": MGLIconAnchor.bottom, 16 | "top-left": MGLIconAnchor.topLeft, 17 | "top-right": MGLIconAnchor.topRight, 18 | "bottom-left": MGLIconAnchor.bottomLeft, 19 | "bottom-right": MGLIconAnchor.bottomRight, 20 | ] 21 | 22 | static let symbolTextJustificationMapping = [ 23 | "auto": MGLTextJustification.auto, 24 | "center": MGLTextJustification.center, 25 | "left": MGLTextJustification.left, 26 | "right": MGLTextJustification.right, 27 | ] 28 | 29 | static let symbolTextAnchorMapping = [ 30 | "center": MGLTextAnchor.center, 31 | "left": MGLTextAnchor.left, 32 | "right": MGLTextAnchor.right, 33 | "top": MGLTextAnchor.top, 34 | "bottom": MGLTextAnchor.bottom, 35 | "top-left": MGLTextAnchor.topLeft, 36 | "top-right": MGLTextAnchor.topRight, 37 | "bottom-left": MGLTextAnchor.bottomLeft, 38 | "bottom-right": MGLTextAnchor.bottomRight, 39 | ] 40 | 41 | static let symbolTextTransformationMapping = [ 42 | "none": MGLTextTransform.none, 43 | "lowercase": MGLTextTransform.lowercase, 44 | "uppercase": MGLTextTransform.uppercase, 45 | ] 46 | 47 | static let lineJoinMapping = [ 48 | "bevel": MGLLineJoin.bevel, 49 | "miter": MGLLineJoin.miter, 50 | "round": MGLLineJoin.round, 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /ios/Classes/Enums.swift: -------------------------------------------------------------------------------- 1 | enum MyLocationRenderMode: Int { 2 | case Normal, Compass, Gps 3 | } 4 | -------------------------------------------------------------------------------- /ios/Classes/MapboxMapFactory.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | 3 | class MapboxMapFactory: NSObject, FlutterPlatformViewFactory { 4 | var registrar: FlutterPluginRegistrar 5 | 6 | init(withRegistrar registrar: FlutterPluginRegistrar) { 7 | self.registrar = registrar 8 | super.init() 9 | } 10 | 11 | func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol { 12 | return FlutterStandardMessageCodec.sharedInstance() 13 | } 14 | 15 | func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, 16 | arguments args: Any?) -> FlutterPlatformView 17 | { 18 | return MapboxMapController( 19 | withFrame: frame, 20 | viewIdentifier: viewId, 21 | arguments: args, 22 | registrar: registrar 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ios/Classes/MapboxMapOptionsSink.swift: -------------------------------------------------------------------------------- 1 | 2 | import Mapbox 3 | 4 | protocol MapboxMapOptionsSink { 5 | func setCameraTargetBounds(bounds: MGLCoordinateBounds?) 6 | func setCompassEnabled(compassEnabled: Bool) 7 | func setStyleString(styleString: String) 8 | func setMinMaxZoomPreference(min: Double, max: Double) 9 | func setRotateGesturesEnabled(rotateGesturesEnabled: Bool) 10 | func setScrollGesturesEnabled(scrollGesturesEnabled: Bool) 11 | func setTiltGesturesEnabled(tiltGesturesEnabled: Bool) 12 | func setTrackCameraPosition(trackCameraPosition: Bool) 13 | func setZoomGesturesEnabled(zoomGesturesEnabled: Bool) 14 | func setMyLocationEnabled(myLocationEnabled: Bool) 15 | func setMyLocationTrackingMode(myLocationTrackingMode: MGLUserTrackingMode) 16 | func setMyLocationRenderMode(myLocationRenderMode: MyLocationRenderMode) 17 | func setLogoViewMargins(x: Double, y: Double) 18 | func setCompassViewPosition(position: MGLOrnamentPosition) 19 | func setCompassViewMargins(x: Double, y: Double) 20 | func setAttributionButtonMargins(x: Double, y: Double) 21 | func setAttributionButtonPosition(position: MGLOrnamentPosition) 22 | } 23 | -------------------------------------------------------------------------------- /ios/Classes/MapboxMapsPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface MapboxMapsPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/MapboxMapsPlugin.m: -------------------------------------------------------------------------------- 1 | #import "MapboxMapsPlugin.h" 2 | #import 3 | 4 | @implementation MapboxMapsPlugin 5 | + (void)registerWithRegistrar:(NSObject*)registrar { 6 | [SwiftMapboxGlFlutterPlugin registerWithRegistrar:registrar]; 7 | } 8 | @end 9 | -------------------------------------------------------------------------------- /ios/Classes/MethodCallError.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | 3 | enum MethodCallError: Error { 4 | case invalidLayerType(details: String) 5 | case invalidExpression 6 | 7 | var code: String { 8 | switch self { 9 | case .invalidLayerType: 10 | return "invalidLayerType" 11 | case .invalidExpression: 12 | return "invalidExpression" 13 | } 14 | } 15 | 16 | var message: String { 17 | switch self { 18 | case .invalidLayerType: 19 | return "Invalid layer type" 20 | case .invalidExpression: 21 | return "Invalid expression" 22 | } 23 | } 24 | 25 | var details: String { 26 | switch self { 27 | case let .invalidLayerType(details): 28 | return details 29 | case .invalidExpression: 30 | return "Could not parse expression." 31 | } 32 | } 33 | 34 | var flutterError: FlutterError { 35 | return FlutterError( 36 | code: code, 37 | message: message, 38 | details: details 39 | ) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ios/Classes/OfflineChannelHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OfflineChannelHandler.swift 3 | // location 4 | // 5 | // Created by Patryk on 03/06/2020. 6 | // 7 | 8 | import Flutter 9 | import Foundation 10 | 11 | class OfflineChannelHandler: NSObject, FlutterStreamHandler { 12 | private var sink: FlutterEventSink? 13 | 14 | init(messenger: FlutterBinaryMessenger, channelName: String) { 15 | super.init() 16 | let eventChannel = FlutterEventChannel(name: channelName, binaryMessenger: messenger) 17 | eventChannel.setStreamHandler(self) 18 | } 19 | 20 | // MARK: FlutterStreamHandler protocol compliance 21 | 22 | func onListen(withArguments _: Any?, 23 | eventSink events: @escaping FlutterEventSink) -> FlutterError? 24 | { 25 | sink = events 26 | return nil 27 | } 28 | 29 | func onCancel(withArguments _: Any?) -> FlutterError? { 30 | sink = nil 31 | return nil 32 | } 33 | 34 | // MARK: Util methods 35 | 36 | func onError(errorCode: String, errorMessage: String?, errorDetails: Any?) { 37 | sink?(FlutterError(code: errorCode, message: errorMessage, details: errorDetails)) 38 | } 39 | 40 | func onSuccess() { 41 | let body = ["status": "success"] 42 | guard let jsonData = try? JSONSerialization.data( 43 | withJSONObject: body, 44 | options: .prettyPrinted 45 | ), 46 | let jsonString = String(data: jsonData, encoding: .utf8) else { return } 47 | sink?(jsonString) 48 | } 49 | 50 | func onStart() { 51 | let body = ["status": "start"] 52 | guard let jsonData = try? JSONSerialization.data( 53 | withJSONObject: body, 54 | options: .prettyPrinted 55 | ), 56 | let jsonString = String(data: jsonData, encoding: .utf8) else { return } 57 | sink?(jsonString) 58 | } 59 | 60 | func onProgress(progress: Double) { 61 | let body: [String: Any] = ["status": "progress", "progress": progress] 62 | guard let jsonData = try? JSONSerialization.data( 63 | withJSONObject: body, 64 | options: .prettyPrinted 65 | ), 66 | let jsonString = String(data: jsonData, encoding: .utf8) else { return } 67 | sink?(jsonString) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ios/Classes/OfflineManagerUtils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OfflineManagerUtils.swift 3 | // location 4 | // 5 | // Created by Patryk on 02/06/2020. 6 | // 7 | 8 | import Flutter 9 | import Foundation 10 | import Mapbox 11 | 12 | class OfflineManagerUtils { 13 | static var activeDownloaders: [Int: OfflinePackDownloader] = [:] 14 | 15 | static func downloadRegion( 16 | definition: OfflineRegionDefinition, 17 | metadata: [String: Any], 18 | result: @escaping FlutterResult, 19 | registrar _: FlutterPluginRegistrar, 20 | channelHandler: OfflineChannelHandler 21 | ) { 22 | // Prepare downloader 23 | let downloader = OfflinePackDownloader( 24 | result: result, 25 | channelHandler: channelHandler, 26 | regionDefintion: definition, 27 | metadata: metadata 28 | ) 29 | 30 | // Download region 31 | let id = downloader.download() 32 | // retain downloader by its generated id 33 | activeDownloaders[id] = downloader 34 | } 35 | 36 | static func regionsList(result: @escaping FlutterResult) { 37 | let offlineStorage = MGLOfflineStorage.shared 38 | guard let packs = offlineStorage.packs else { 39 | result("[]") 40 | return 41 | } 42 | let regionsArgs = packs.compactMap { pack in 43 | OfflineRegion.fromOfflinePack(pack)?.toDictionary() 44 | } 45 | guard let regionsArgsJsonData = try? JSONSerialization.data(withJSONObject: regionsArgs), 46 | let regionsArgsJsonString = String(data: regionsArgsJsonData, encoding: .utf8) 47 | else { 48 | result(FlutterError(code: "RegionListError", message: nil, details: nil)) 49 | return 50 | } 51 | result(regionsArgsJsonString) 52 | } 53 | 54 | static func setOfflineTileCountLimit(result: @escaping FlutterResult, maximumCount: UInt64) { 55 | let offlineStorage = MGLOfflineStorage.shared 56 | offlineStorage.setMaximumAllowedMapboxTiles(maximumCount) 57 | result(nil) 58 | } 59 | 60 | static func deleteRegion(result: @escaping FlutterResult, id: Int) { 61 | let offlineStorage = MGLOfflineStorage.shared 62 | guard let pacs = offlineStorage.packs else { return } 63 | let packToRemove = pacs.first(where: { pack -> Bool in 64 | let contextJsonObject = try? JSONSerialization.jsonObject(with: pack.context) 65 | let contextJsonDict = contextJsonObject as? [String: Any] 66 | if let regionId = contextJsonDict?["id"] as? Int { 67 | return regionId == id 68 | } else { 69 | return false 70 | } 71 | }) 72 | if let packToRemoveUnwrapped = packToRemove { 73 | // deletion is only safe if the download is suspended 74 | packToRemoveUnwrapped.suspend() 75 | OfflineManagerUtils.releaseDownloader(id: id) 76 | 77 | offlineStorage.removePack(packToRemoveUnwrapped) { error in 78 | if let error = error { 79 | result(FlutterError( 80 | code: "DeleteRegionError", 81 | message: error.localizedDescription, 82 | details: nil 83 | )) 84 | } else { 85 | result(nil) 86 | } 87 | } 88 | } else { 89 | result(FlutterError( 90 | code: "DeleteRegionError", 91 | message: "There is no region with given id to delete", 92 | details: nil 93 | )) 94 | } 95 | } 96 | 97 | /// Removes downloader from cache so it's memory can be deallocated 98 | static func releaseDownloader(id: Int) { 99 | activeDownloaders.removeValue(forKey: id) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /ios/Classes/OfflineRegion.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OfflineRegionData.swift 3 | // location 4 | // 5 | // Created by Patryk on 02/06/2020. 6 | // 7 | 8 | import Foundation 9 | import Mapbox 10 | 11 | class OfflineRegion { 12 | let id: Int 13 | let metadata: [String: Any] 14 | let definition: OfflineRegionDefinition 15 | 16 | enum CodingKeys: CodingKey { 17 | case id, metadata, definition 18 | } 19 | 20 | init(id: Int, metadata: [String: Any], definition: OfflineRegionDefinition) { 21 | self.id = id 22 | self.metadata = metadata 23 | self.definition = definition 24 | } 25 | 26 | func prepareContext() -> Data { 27 | let context = ["metadata": metadata, "id": id] as [String: Any] 28 | let jsonData = try? JSONSerialization.data(withJSONObject: context, options: []) 29 | return jsonData ?? Data() 30 | } 31 | 32 | func toDictionary() -> [String: Any] { 33 | return [ 34 | "id": id, 35 | "metadata": metadata, 36 | "definition": definition.toDictionary(), 37 | ] 38 | } 39 | 40 | static func fromOfflinePack(_ pack: MGLOfflinePack) -> OfflineRegion? { 41 | guard let region = pack.region as? MGLTilePyramidOfflineRegion, 42 | let dataObject = try? JSONSerialization.jsonObject(with: pack.context, options: []), 43 | let dict = dataObject as? [String: Any], 44 | let id = dict["id"] as? Int, 45 | let metadata = dict["metadata"] as? [String: Any] else { return nil } 46 | return OfflineRegion( 47 | id: id, 48 | metadata: metadata, 49 | definition: OfflineRegionDefinition( 50 | bounds: [region.bounds.sw, region.bounds.ne].map { [$0.latitude, $0.longitude] }, 51 | mapStyleUrl: region.styleURL, 52 | minZoom: region.minimumZoomLevel, 53 | maxZoom: region.maximumZoomLevel 54 | ) 55 | ) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ios/Classes/OfflineRegionDefinition.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Mapbox 3 | 4 | class OfflineRegionDefinition { 5 | let bounds: [[Double]] 6 | let mapStyleUrl: URL 7 | let minZoom: Double 8 | let maxZoom: Double 9 | 10 | init(bounds: [[Double]], mapStyleUrl: URL, minZoom: Double, maxZoom: Double) { 11 | self.bounds = bounds 12 | self.mapStyleUrl = mapStyleUrl 13 | self.minZoom = minZoom 14 | self.maxZoom = maxZoom 15 | } 16 | 17 | func getBounds() -> MGLCoordinateBounds { 18 | return MGLCoordinateBounds( 19 | sw: CLLocationCoordinate2D(latitude: bounds[0][0], longitude: bounds[0][1]), 20 | ne: CLLocationCoordinate2D(latitude: bounds[1][0], longitude: bounds[1][1]) 21 | ) 22 | } 23 | 24 | static func fromDictionary(_ jsonDict: [String: Any]) -> OfflineRegionDefinition? { 25 | guard let bounds = jsonDict["bounds"] as? [[Double]], 26 | let mapStyleUrlString = jsonDict["mapStyleUrl"] as? String, 27 | let mapStyleUrl = URL(string: mapStyleUrlString), 28 | let minZoom = jsonDict["minZoom"] as? Double, 29 | let maxZoom = jsonDict["maxZoom"] as? Double 30 | else { return nil } 31 | return OfflineRegionDefinition( 32 | bounds: bounds, 33 | mapStyleUrl: mapStyleUrl, 34 | minZoom: minZoom, 35 | maxZoom: maxZoom 36 | ) 37 | } 38 | 39 | func toDictionary() -> [String: Any] { 40 | return [ 41 | "bounds": bounds, 42 | "mapStyleUrl": mapStyleUrl.absoluteString, 43 | "minZoom": minZoom, 44 | "maxZoom": maxZoom, 45 | ] 46 | } 47 | 48 | func toMGLTilePyramidOfflineRegion() -> MGLTilePyramidOfflineRegion { 49 | return MGLTilePyramidOfflineRegion( 50 | styleURL: mapStyleUrl, 51 | bounds: getBounds(), 52 | fromZoomLevel: minZoom, 53 | toZoomLevel: maxZoom 54 | ) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ios/Classes/RNMBImageUtils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RNMBImageUtils.swift 3 | // mapbox_gl 4 | // 5 | // Created by mac on 30/05/2022. 6 | // 7 | 8 | enum RNMBImageUtils { 9 | static func createTempFile(_ image: UIImage) -> URL { 10 | let fileID = UUID().uuidString 11 | let pathComponent = "Documents/rctmgl-snapshot-\(fileID).jpeg" 12 | 13 | let filePath = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent(pathComponent) 14 | 15 | let data = image.jpegData(compressionQuality: 1.0) 16 | try! data?.write(to: filePath, options: [.atomic]) 17 | return filePath 18 | } 19 | 20 | static func createBase64(_ image: UIImage) -> URL { 21 | let data = image.jpegData(compressionQuality: 1.0) 22 | let b64string: String = data!.base64EncodedString(options: [.endLineWithCarriageReturn]) 23 | let result = "data:image/jpeg;base64,\(b64string)" 24 | return URL(string: result)! 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ios/mapbox_gl.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 3 | # 4 | Pod::Spec.new do |s| 5 | s.name = 'mapbox_gl' 6 | s.version = '0.0.1' 7 | s.summary = 'A new Flutter plugin.' 8 | s.description = <<-DESC 9 | A new Flutter plugin. 10 | DESC 11 | s.homepage = 'http://example.com' 12 | s.license = { :file => '../LICENSE' } 13 | s.author = { 'Your Company' => 'email@example.com' } 14 | s.source = { :path => '.' } 15 | s.source_files = 'Classes/**/*' 16 | s.public_header_files = 'Classes/**/*.h' 17 | s.dependency 'Flutter' 18 | s.dependency 'MapboxAnnotationExtension', '~> 0.0.1-beta.1' 19 | s.dependency 'Mapbox-iOS-SDK', '~> 6.4.0' 20 | s.swift_version = '4.2' 21 | s.ios.deployment_target = '9.0' 22 | end 23 | 24 | -------------------------------------------------------------------------------- /lib/mapbox_gl.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | library mapbox_gl; 6 | 7 | import 'dart:async'; 8 | import 'dart:convert'; 9 | import 'dart:math'; 10 | import 'dart:typed_data'; 11 | 12 | import 'package:flutter/foundation.dart'; 13 | import 'package:flutter/gestures.dart'; 14 | import 'package:flutter/material.dart'; 15 | import 'package:flutter/services.dart'; 16 | import 'package:mapbox_gl_platform_interface/mapbox_gl_platform_interface.dart'; 17 | 18 | export 'package:mapbox_gl_platform_interface/mapbox_gl_platform_interface.dart' 19 | show 20 | LatLng, 21 | LatLngBounds, 22 | LatLngQuad, 23 | CameraPosition, 24 | UserLocation, 25 | UserHeading, 26 | CameraUpdate, 27 | ArgumentCallbacks, 28 | Symbol, 29 | SymbolOptions, 30 | CameraTargetBounds, 31 | MinMaxZoomPreference, 32 | MapboxStyles, 33 | MyLocationTrackingMode, 34 | MyLocationRenderMode, 35 | CompassViewPosition, 36 | AttributionButtonPosition, 37 | Annotation, 38 | Circle, 39 | CircleOptions, 40 | Line, 41 | LineOptions, 42 | Fill, 43 | FillOptions, 44 | SnapshotOptions, 45 | SourceProperties, 46 | RasterSourceProperties, 47 | VectorSourceProperties, 48 | RasterDemSourceProperties, 49 | GeojsonSourceProperties, 50 | VideoSourceProperties, 51 | ImageSourceProperties; 52 | 53 | part 'src/controller.dart'; 54 | part 'src/mapbox_map.dart'; 55 | part 'src/global.dart'; 56 | part 'src/offline_region.dart'; 57 | part 'src/download_region_status.dart'; 58 | part 'src/layer_expressions.dart'; 59 | part 'src/layer_properties.dart'; 60 | part 'src/color_tools.dart'; 61 | part 'src/annotation_manager.dart'; 62 | part 'src/util.dart'; 63 | -------------------------------------------------------------------------------- /lib/src/color_tools.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_gl; 2 | 3 | extension MapBoxColorConversion on Color { 4 | String toHexStringRGB() { 5 | final r = red.toRadixString(16).padLeft(2, '0'); 6 | final g = green.toRadixString(16).padLeft(2, '0'); 7 | final b = blue.toRadixString(16).padLeft(2, '0'); 8 | return '#$r$g$b'; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/src/download_region_status.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_gl; 2 | 3 | abstract class DownloadRegionStatus {} 4 | 5 | class Success extends DownloadRegionStatus {} 6 | 7 | class InProgress extends DownloadRegionStatus { 8 | final double progress; 9 | 10 | InProgress(this.progress); 11 | 12 | @override 13 | String toString() => 14 | "Instance of 'DownloadRegionStatus.InProgress', progress = $progress"; 15 | } 16 | 17 | class Error extends DownloadRegionStatus { 18 | final PlatformException cause; 19 | 20 | Error(this.cause); 21 | 22 | @override 23 | String toString() => 24 | "Instance of 'DownloadRegionStatus.Error', cause = ${cause.toString()}"; 25 | } 26 | -------------------------------------------------------------------------------- /lib/src/global.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | part of mapbox_gl; 6 | 7 | final MethodChannel _globalChannel = 8 | MethodChannel('plugins.flutter.io/mapbox_gl'); 9 | 10 | /// Copy tiles db file passed in to the tiles cache directory (sideloaded) to 11 | /// make tiles available offline. 12 | Future installOfflineMapTiles(String tilesDb) async { 13 | await _globalChannel.invokeMethod( 14 | 'installOfflineMapTiles', 15 | { 16 | 'tilesdb': tilesDb, 17 | }, 18 | ); 19 | } 20 | 21 | enum DragEventType { start, drag, end } 22 | 23 | Future setOffline( 24 | bool offline, { 25 | String? accessToken, 26 | }) => 27 | _globalChannel.invokeMethod( 28 | 'setOffline', 29 | { 30 | 'offline': offline, 31 | 'accessToken': accessToken, 32 | }, 33 | ); 34 | 35 | Future setHttpHeaders(Map headers) { 36 | return _globalChannel.invokeMethod( 37 | 'setHttpHeaders', 38 | { 39 | 'headers': headers, 40 | }, 41 | ); 42 | } 43 | 44 | Future> mergeOfflineRegions( 45 | String path, { 46 | String? accessToken, 47 | }) async { 48 | String regionsJson = await _globalChannel.invokeMethod( 49 | 'mergeOfflineRegions', 50 | { 51 | 'path': path, 52 | 'accessToken': accessToken, 53 | }, 54 | ); 55 | Iterable regions = json.decode(regionsJson); 56 | return regions.map((region) => OfflineRegion.fromMap(region)).toList(); 57 | } 58 | 59 | Future> getListOfRegions({String? accessToken}) async { 60 | String regionsJson = await _globalChannel.invokeMethod( 61 | 'getListOfRegions', 62 | { 63 | 'accessToken': accessToken, 64 | }, 65 | ); 66 | Iterable regions = json.decode(regionsJson); 67 | return regions.map((region) => OfflineRegion.fromMap(region)).toList(); 68 | } 69 | 70 | Future updateOfflineRegionMetadata( 71 | int id, 72 | Map metadata, { 73 | String? accessToken, 74 | }) async { 75 | final regionJson = await _globalChannel.invokeMethod( 76 | 'updateOfflineRegionMetadata', 77 | { 78 | 'id': id, 79 | 'accessToken': accessToken, 80 | 'metadata': metadata, 81 | }, 82 | ); 83 | 84 | return OfflineRegion.fromMap(json.decode(regionJson)); 85 | } 86 | 87 | Future setOfflineTileCountLimit(int limit, {String? accessToken}) => 88 | _globalChannel.invokeMethod( 89 | 'setOfflineTileCountLimit', 90 | { 91 | 'limit': limit, 92 | 'accessToken': accessToken, 93 | }, 94 | ); 95 | 96 | Future deleteOfflineRegion(int id, {String? accessToken}) => 97 | _globalChannel.invokeMethod( 98 | 'deleteOfflineRegion', 99 | { 100 | 'id': id, 101 | 'accessToken': accessToken, 102 | }, 103 | ); 104 | 105 | Future downloadOfflineRegion( 106 | OfflineRegionDefinition definition, { 107 | Map metadata = const {}, 108 | String? accessToken, 109 | Function(DownloadRegionStatus event)? onEvent, 110 | }) async { 111 | String channelName = 112 | 'downloadOfflineRegion_${DateTime.now().microsecondsSinceEpoch}'; 113 | 114 | final result = await _globalChannel 115 | .invokeMethod('downloadOfflineRegion', { 116 | 'accessToken': accessToken, 117 | 'channelName': channelName, 118 | 'definition': definition.toMap(), 119 | 'metadata': metadata, 120 | }); 121 | 122 | if (onEvent != null) { 123 | EventChannel(channelName).receiveBroadcastStream().handleError((error) { 124 | if (error is PlatformException) { 125 | onEvent(Error(error)); 126 | return Error(error); 127 | } 128 | var unknownError = Error( 129 | PlatformException( 130 | code: 'UnknowException', 131 | message: 132 | 'This error is unhandled by plugin. Please contact us if needed.', 133 | details: error, 134 | ), 135 | ); 136 | onEvent(unknownError); 137 | return unknownError; 138 | }).listen((data) { 139 | final Map jsonData = json.decode(data); 140 | DownloadRegionStatus? status; 141 | switch (jsonData['status']) { 142 | case 'start': 143 | status = InProgress(0.0); 144 | break; 145 | case 'progress': 146 | final dynamic value = jsonData['progress']; 147 | double progress = 0.0; 148 | 149 | if (value is int) { 150 | progress = value.toDouble(); 151 | } 152 | 153 | if (value is double) { 154 | progress = value; 155 | } 156 | 157 | status = InProgress(progress); 158 | break; 159 | case 'success': 160 | status = Success(); 161 | break; 162 | } 163 | onEvent(status ?? (throw 'Invalid event status ${jsonData['status']}')); 164 | }); 165 | } 166 | 167 | return OfflineRegion.fromMap(json.decode(result)); 168 | } 169 | -------------------------------------------------------------------------------- /lib/src/offline_region.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_gl; 2 | 3 | /// Description of region to be downloaded. Identifier will be generated when 4 | /// the download is initiated. 5 | class OfflineRegionDefinition { 6 | const OfflineRegionDefinition({ 7 | required this.bounds, 8 | required this.mapStyleUrl, 9 | required this.minZoom, 10 | required this.maxZoom, 11 | this.includeIdeographs = false, 12 | }); 13 | 14 | final LatLngBounds bounds; 15 | final String mapStyleUrl; 16 | final double minZoom; 17 | final double maxZoom; 18 | final bool includeIdeographs; 19 | 20 | @override 21 | String toString() => 22 | "$runtimeType, bounds = $bounds, mapStyleUrl = $mapStyleUrl, minZoom = $minZoom, maxZoom = $maxZoom"; 23 | 24 | Map toMap() { 25 | final Map data = Map(); 26 | data['bounds'] = bounds.toList(); 27 | data['mapStyleUrl'] = mapStyleUrl; 28 | data['minZoom'] = minZoom; 29 | data['maxZoom'] = maxZoom; 30 | data['includeIdeographs'] = includeIdeographs; 31 | return data; 32 | } 33 | 34 | factory OfflineRegionDefinition.fromMap(Map map) { 35 | return OfflineRegionDefinition( 36 | bounds: _latLngBoundsFromList(map['bounds']), 37 | mapStyleUrl: map['mapStyleUrl'], 38 | // small integers may deserialize to Int 39 | minZoom: map['minZoom'].toDouble(), 40 | maxZoom: map['maxZoom'].toDouble(), 41 | includeIdeographs: map['includeIdeographs'] ?? false, 42 | ); 43 | } 44 | 45 | static LatLngBounds _latLngBoundsFromList(List json) { 46 | return LatLngBounds( 47 | southwest: LatLng(json[0][0], json[0][1]), 48 | northeast: LatLng(json[1][0], json[1][1]), 49 | ); 50 | } 51 | } 52 | 53 | /// Description of a downloaded region including its identifier. 54 | class OfflineRegion { 55 | const OfflineRegion({ 56 | required this.id, 57 | required this.definition, 58 | required this.metadata, 59 | }); 60 | 61 | final int id; 62 | final OfflineRegionDefinition definition; 63 | final Map metadata; 64 | 65 | factory OfflineRegion.fromMap(Map json) { 66 | return OfflineRegion( 67 | id: json['id'], 68 | definition: OfflineRegionDefinition.fromMap(json['definition']), 69 | metadata: json['metadata'], 70 | ); 71 | } 72 | 73 | @override 74 | String toString() => 75 | "$runtimeType, id = $id, definition = $definition, metadata = $metadata"; 76 | } 77 | -------------------------------------------------------------------------------- /lib/src/util.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_gl; 2 | 3 | Map buildFeatureCollection( 4 | List> features) { 5 | return {"type": "FeatureCollection", "features": features}; 6 | } 7 | 8 | final _random = Random(); 9 | String getRandomString([int length = 10]) { 10 | const charSet = 11 | 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890'; 12 | return String.fromCharCodes(Iterable.generate( 13 | length, (_) => charSet.codeUnitAt(_random.nextInt(charSet.length)))); 14 | } 15 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.16.0, May 19, 2022 2 | * Annotation manager moved to dart [#779](https://github.com/flutter-mapbox-gl/maps/pull/779) 3 | * Fix issue with map disposal on web [#895](https://github.com/flutter-mapbox-gl/maps/pull/895) 4 | * Add support for layer zoom limits [#934](https://github.com/flutter-mapbox-gl/maps/pull/934) 5 | * Add and default to Hybrid composition on Android [#916](https://github.com/flutter-mapbox-gl/maps/pull/916) 6 | * Implement layer filtering [#997](https://github.com/flutter-mapbox-gl/maps/pull/997) 7 | * Drag event types support added [#987](https://github.com/flutter-mapbox-gl/maps/pull/987) 8 | * Support filtering on addLayer [#1024](https://github.com/flutter-mapbox-gl/maps/pull/1024) 9 | 10 | ## 0.15.0, January 13, 2022 11 | * Callbacks added to onFeatureTapped will now also get the position (`Point`) and the location (`LatLng`) of the click passed when called [#798](https://github.com/flutter-mapbox-gl/maps/pull/798) 12 | * Fix web issues with style loaded, feature tap, add promoteId, pointer change issue [#785](https://github.com/flutter-mapbox-gl/maps/pull/785) 13 | * Full style source support [#797](https://github.com/flutter-mapbox-gl/maps/pull/797) 14 | 15 | ## 0.14.0, November 13, 2021 16 | * Remove memory leaks by disposing internal components [#706](https://github.com/tobrun/flutter-mapbox-gl/pull/706) 17 | * Add support for Layers, properties and expressions backed by GeoJsonSource [#723](https://github.com/tobrun/flutter-mapbox-gl/pull/723) 18 | * Add attribution button gravity, position normally [#731](https://github.com/tobrun/flutter-mapbox-gl/pull/731) 19 | * Remove MapboxGlPlatform.getInstance [#710](https://github.com/tobrun/flutter-mapbox-gl/pull/710) 20 | 21 | ## 0.13.0, October 21, 2021 22 | * Migrate to null-safety [#607](https://github.com/tobrun/flutter-mapbox-gl/pull/607) 23 | * Support override of attribution click action (iOS) [#605](https://github.com/tobrun/flutter-mapbox-gl/pull/605) 24 | * Fix requestMyLocationLatLng in the platform interface [#697](https://github.com/tobrun/flutter-mapbox-gl/pull/697) 25 | 26 | ## 0.12.0, April 12, 2021 27 | * Batch creation/removal for circles, fills and lines [#576](https://github.com/tobrun/flutter-mapbox-gl/pull/576) 28 | 29 | ## 0.11.0, March 30, 2021 30 | * Add batch mode of screen locations [#554](https://github.com/tobrun/flutter-mapbox-gl/pull/554) 31 | 32 | ## 0.10.0, February 12, 2021 33 | * Added web support for fills [#501](https://github.com/tobrun/flutter-mapbox-gl/pull/501) 34 | * Add heading to UserLocation and expose UserLocation type [#522](https://github.com/tobrun/flutter-mapbox-gl/pull/522) 35 | * Update tracked camera position in camera#onIdle [#500](https://github.com/tobrun/flutter-mapbox-gl/pull/500) 36 | * Improved Image Source Support [#469](https://github.com/tobrun/flutter-mapbox-gl/pull/469) 37 | 38 | ## 0.9.0, October 24, 2020 39 | * Breaking change: CameraUpdate.newLatLngBounds() now supports setting different padding values for left, top, right, bottom with default of 0 for all. Implementations using the old approach with only one padding value for all edges have to be updated. [#382](https://github.com/tobrun/flutter-mapbox-gl/pull/382) 40 | * Add methods to access projection [#380](https://github.com/tobrun/flutter-mapbox-gl/pull/380) 41 | * Add fill API support for Android and iOS [#49](https://github.com/tobrun/flutter-mapbox-gl/pull/49) 42 | * Listen to OnUserLocationUpdated to provide user location to app [#237](https://github.com/tobrun/flutter-mapbox-gl/pull/237) 43 | * Add support for custom font stackn in symbol options [#359](https://github.com/tobrun/flutter-mapbox-gl/pull/359) 44 | * Basic ImageSource Support [#409](https://github.com/tobrun/flutter-mapbox-gl/pull/409) 45 | * Get meters per pixel at latitude [#416](https://github.com/tobrun/flutter-mapbox-gl/pull/416) 46 | 47 | ## 0.8.0, August 22, 2020 48 | - implementation of feature querying [#177](https://github.com/tobrun/flutter-mapbox-gl/pull/177) 49 | - Batch create/delete of symbols [#279](https://github.com/tobrun/flutter-mapbox-gl/pull/279) 50 | - Add multi map support [#315](https://github.com/tobrun/flutter-mapbox-gl/pull/315) 51 | - Add line#getGeometry and symbol#getGeometry [#281](https://github.com/tobrun/flutter-mapbox-gl/pull/281) 52 | 53 | ## 0.7.0 54 | - Initial version 55 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/LICENSE: -------------------------------------------------------------------------------- 1 | flutter-mapbox-gl copyright (c) 2018, Mapbox. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 7 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/README.md: -------------------------------------------------------------------------------- 1 | Contains the web platform implementation for the [Flutter Mapbox GL plugin](https://github.com/tobrun/flutter-mapbox-gl). -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/lib/mapbox_gl_platform_interface.dart: -------------------------------------------------------------------------------- 1 | library mapbox_gl_platform_interface; 2 | 3 | import 'dart:async'; 4 | import 'dart:convert'; 5 | import 'dart:math'; 6 | import 'dart:io'; 7 | import 'dart:typed_data'; 8 | import 'package:flutter/foundation.dart'; 9 | import 'package:flutter/gestures.dart'; 10 | import 'package:flutter/material.dart'; 11 | import 'package:flutter/rendering.dart'; 12 | import 'package:flutter/services.dart'; 13 | 14 | part 'src/annotation.dart'; 15 | part 'src/callbacks.dart'; 16 | part 'src/camera.dart'; 17 | part 'src/circle.dart'; 18 | part 'src/line.dart'; 19 | part 'src/location.dart'; 20 | part 'src/method_channel_mapbox_gl.dart'; 21 | part 'src/symbol.dart'; 22 | part 'src/fill.dart'; 23 | part 'src/ui.dart'; 24 | part 'src/snapshot.dart'; 25 | part 'src/mapbox_gl_platform_interface.dart'; 26 | part 'src/source_properties.dart'; 27 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/lib/src/annotation.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_gl_platform_interface; 2 | 3 | abstract class Annotation { 4 | String get id; 5 | Map toGeoJson(); 6 | 7 | void translate(LatLng delta); 8 | } 9 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/lib/src/callbacks.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | part of mapbox_gl_platform_interface; 6 | 7 | /// Callback function taking a single argument. 8 | typedef void ArgumentCallback(T argument); 9 | 10 | /// Mutable collection of [ArgumentCallback] instances, itself an [ArgumentCallback]. 11 | /// 12 | /// Additions and removals happening during a single [call] invocation do not 13 | /// change who gets a callback until the next such invocation. 14 | /// 15 | /// Optimized for the singleton case. 16 | class ArgumentCallbacks { 17 | final List> _callbacks = >[]; 18 | 19 | /// Callback method. Invokes the corresponding method on each callback 20 | /// in this collection. 21 | /// 22 | /// The list of callbacks being invoked is computed at the start of the 23 | /// method and is unaffected by any changes subsequently made to this 24 | /// collection. 25 | void call(T argument) { 26 | final int length = _callbacks.length; 27 | if (length == 1) { 28 | _callbacks[0].call(argument); 29 | } else if (0 < length) { 30 | for (ArgumentCallback callback 31 | in List>.from(_callbacks)) { 32 | callback(argument); 33 | } 34 | } 35 | } 36 | 37 | /// Adds a callback to this collection. 38 | void add(ArgumentCallback callback) { 39 | _callbacks.add(callback); 40 | } 41 | 42 | /// Removes a callback from this collection. 43 | /// 44 | /// Does nothing, if the callback was not present. 45 | void remove(ArgumentCallback callback) { 46 | _callbacks.remove(callback); 47 | } 48 | 49 | /// Removes all callbacks 50 | void clear() { 51 | _callbacks.clear(); 52 | } 53 | 54 | /// Whether this collection is empty. 55 | bool get isEmpty => _callbacks.isEmpty; 56 | 57 | /// Whether this collection is non-empty. 58 | bool get isNotEmpty => _callbacks.isNotEmpty; 59 | } 60 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/lib/src/circle.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | 3 | // Copyright 2018 The Chromium Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style license that can be 5 | // found in the LICENSE file. 6 | 7 | part of mapbox_gl_platform_interface; 8 | 9 | class Circle implements Annotation { 10 | Circle(this._id, this.options, [this._data]); 11 | 12 | /// A unique identifier for this circle. 13 | /// 14 | /// The identifier is an arbitrary unique string. 15 | final String _id; 16 | String get id => _id; 17 | 18 | final Map? _data; 19 | Map? get data => _data; 20 | 21 | /// The circle configuration options most recently applied programmatically 22 | /// via the map controller. 23 | /// 24 | /// The returned value does not reflect any changes made to the circle through 25 | /// touch events. Add listeners to the owning map controller to track those. 26 | CircleOptions options; 27 | 28 | @override 29 | Map toGeoJson() { 30 | final geojson = options.toGeoJson(); 31 | geojson["id"] = id; 32 | geojson["properties"]["id"] = id; 33 | 34 | return geojson; 35 | } 36 | 37 | @override 38 | void translate(LatLng delta) { 39 | options = options 40 | .copyWith(CircleOptions(geometry: this.options.geometry! + delta)); 41 | } 42 | } 43 | 44 | /// Configuration options for [Circle] instances. 45 | /// 46 | /// When used to change configuration, null values will be interpreted as 47 | /// "do not change this configuration option". 48 | class CircleOptions { 49 | /// Creates a set of circle configuration options. 50 | /// 51 | /// By default, every non-specified field is null, meaning no desire to change 52 | /// circle defaults or current configuration. 53 | const CircleOptions({ 54 | this.circleRadius, 55 | this.circleColor, 56 | this.circleBlur, 57 | this.circleOpacity, 58 | this.circleStrokeWidth, 59 | this.circleStrokeColor, 60 | this.circleStrokeOpacity, 61 | this.geometry, 62 | this.draggable, 63 | }); 64 | 65 | final double? circleRadius; 66 | final String? circleColor; 67 | final double? circleBlur; 68 | final double? circleOpacity; 69 | final double? circleStrokeWidth; 70 | final String? circleStrokeColor; 71 | final double? circleStrokeOpacity; 72 | final LatLng? geometry; 73 | final bool? draggable; 74 | 75 | static const CircleOptions defaultOptions = CircleOptions(); 76 | 77 | CircleOptions copyWith(CircleOptions changes) { 78 | return CircleOptions( 79 | circleRadius: changes.circleRadius ?? circleRadius, 80 | circleColor: changes.circleColor ?? circleColor, 81 | circleBlur: changes.circleBlur ?? circleBlur, 82 | circleOpacity: changes.circleOpacity ?? circleOpacity, 83 | circleStrokeWidth: changes.circleStrokeWidth ?? circleStrokeWidth, 84 | circleStrokeColor: changes.circleStrokeColor ?? circleStrokeColor, 85 | circleStrokeOpacity: changes.circleStrokeOpacity ?? circleStrokeOpacity, 86 | geometry: changes.geometry ?? geometry, 87 | draggable: changes.draggable ?? draggable, 88 | ); 89 | } 90 | 91 | dynamic toJson([bool addGeometry = true]) { 92 | final Map json = {}; 93 | 94 | void addIfPresent(String fieldName, dynamic value) { 95 | if (value != null) { 96 | json[fieldName] = value; 97 | } 98 | } 99 | 100 | addIfPresent('circleRadius', circleRadius); 101 | addIfPresent('circleColor', circleColor); 102 | addIfPresent('circleBlur', circleBlur); 103 | addIfPresent('circleOpacity', circleOpacity); 104 | addIfPresent('circleStrokeWidth', circleStrokeWidth); 105 | addIfPresent('circleStrokeColor', circleStrokeColor); 106 | addIfPresent('circleStrokeOpacity', circleStrokeOpacity); 107 | if (addGeometry) { 108 | addIfPresent('geometry', geometry?.toJson()); 109 | } 110 | addIfPresent('draggable', draggable); 111 | return json; 112 | } 113 | 114 | Map toGeoJson() { 115 | return { 116 | "type": "Feature", 117 | "properties": toJson(false), 118 | "geometry": { 119 | "type": "Point", 120 | "coordinates": geometry!.toGeoJsonCoordinates() 121 | } 122 | }; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/lib/src/fill.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | 3 | // Copyright 2018 The Chromium Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style license that can be 5 | // found in the LICENSE file. 6 | 7 | part of mapbox_gl_platform_interface; 8 | 9 | FillOptions translateFillOptions(FillOptions options, LatLng delta) { 10 | if (options.geometry != null) { 11 | List> newGeometry = []; 12 | for (var ring in options.geometry!) { 13 | List newRing = []; 14 | for (var coords in ring) { 15 | newRing.add(coords + delta); 16 | } 17 | newGeometry.add(newRing); 18 | } 19 | return options.copyWith(FillOptions(geometry: newGeometry)); 20 | } 21 | return options; 22 | } 23 | 24 | class Fill implements Annotation { 25 | Fill(this._id, this.options, [this._data]); 26 | 27 | /// A unique identifier for this fill. 28 | /// 29 | /// The identifier is an arbitrary unique string. 30 | final String _id; 31 | String get id => _id; 32 | 33 | final Map? _data; 34 | Map? get data => _data; 35 | 36 | /// The fill configuration options most recently applied programmatically 37 | /// via the map controller. 38 | /// 39 | /// The returned value does not reflect any changes made to the fill through 40 | /// touch events. Add listeners to the owning map controller to track those. 41 | FillOptions options; 42 | 43 | @override 44 | Map toGeoJson() { 45 | final geojson = options.toGeoJson(); 46 | geojson["id"] = id; 47 | geojson["properties"]["id"] = id; 48 | 49 | return geojson; 50 | } 51 | 52 | @override 53 | void translate(LatLng delta) { 54 | options = translateFillOptions(options, delta); 55 | } 56 | } 57 | 58 | /// Configuration options for [Fill] instances. 59 | /// 60 | /// When used to change configuration, null values will be interpreted as 61 | /// "do not change this configuration option". 62 | class FillOptions { 63 | /// Creates a set of fill configuration options. 64 | /// 65 | /// By default, every non-specified field is null, meaning no desire to change 66 | /// fill defaults or current configuration. 67 | const FillOptions( 68 | {this.fillOpacity, 69 | this.fillColor, 70 | this.fillOutlineColor, 71 | this.fillPattern, 72 | this.geometry, 73 | this.draggable}); 74 | 75 | final double? fillOpacity; 76 | final String? fillColor; 77 | final String? fillOutlineColor; 78 | final String? fillPattern; 79 | final List>? geometry; 80 | final bool? draggable; 81 | 82 | static const FillOptions defaultOptions = FillOptions(); 83 | 84 | FillOptions copyWith(FillOptions changes) { 85 | return FillOptions( 86 | fillOpacity: changes.fillOpacity ?? fillOpacity, 87 | fillColor: changes.fillColor ?? fillColor, 88 | fillOutlineColor: changes.fillOutlineColor ?? fillOutlineColor, 89 | fillPattern: changes.fillPattern ?? fillPattern, 90 | geometry: changes.geometry ?? geometry, 91 | draggable: changes.draggable ?? draggable, 92 | ); 93 | } 94 | 95 | dynamic toJson([bool addGeometry = true]) { 96 | final Map json = {}; 97 | 98 | void addIfPresent(String fieldName, dynamic value) { 99 | if (value != null) { 100 | json[fieldName] = value; 101 | } 102 | } 103 | 104 | addIfPresent('fillOpacity', fillOpacity); 105 | addIfPresent('fillColor', fillColor); 106 | addIfPresent('fillOutlineColor', fillOutlineColor); 107 | addIfPresent('fillPattern', fillPattern); 108 | if (addGeometry) { 109 | addIfPresent( 110 | 'geometry', 111 | geometry 112 | ?.map((List latLngList) => 113 | latLngList.map((LatLng latLng) => latLng.toJson()).toList()) 114 | .toList()); 115 | } 116 | addIfPresent('draggable', draggable); 117 | return json; 118 | } 119 | 120 | Map toGeoJson() { 121 | return { 122 | "type": "Feature", 123 | "properties": toJson(false), 124 | "geometry": { 125 | "type": "Polygon", 126 | "coordinates": geometry! 127 | .map((List latLngList) => latLngList 128 | .map((LatLng latLng) => latLng.toGeoJsonCoordinates()) 129 | .toList()) 130 | .toList() 131 | } 132 | }; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/lib/src/line.dart: -------------------------------------------------------------------------------- 1 | // This file is generated. 2 | 3 | // Copyright 2018 The Chromium Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style license that can be 5 | // found in the LICENSE file. 6 | 7 | part of mapbox_gl_platform_interface; 8 | 9 | class Line implements Annotation { 10 | Line(this._id, this.options, [this._data]); 11 | 12 | /// A unique identifier for this line. 13 | /// 14 | /// The identifier is an arbitrary unique string. 15 | final String _id; 16 | 17 | String get id => _id; 18 | 19 | final Map? _data; 20 | 21 | Map? get data => _data; 22 | 23 | /// The line configuration options most recently applied programmatically 24 | /// via the map controller. 25 | /// 26 | /// The returned value does not reflect any changes made to the line through 27 | /// touch events. Add listeners to the owning map controller to track those. 28 | LineOptions options; 29 | 30 | Map toGeoJson() { 31 | final geojson = options.toGeoJson(); 32 | geojson["id"] = id; 33 | geojson["properties"]["id"] = id; 34 | 35 | return geojson; 36 | } 37 | 38 | @override 39 | void translate(LatLng delta) { 40 | options = options.copyWith(LineOptions( 41 | geometry: this.options.geometry?.map((e) => e + delta).toList())); 42 | } 43 | } 44 | 45 | /// Configuration options for [Line] instances. 46 | /// 47 | /// When used to change configuration, null values will be interpreted as 48 | /// "do not change this configuration option". 49 | class LineOptions { 50 | /// Creates a set of line configuration options. 51 | /// 52 | /// By default, every non-specified field is null, meaning no desire to change 53 | /// line defaults or current configuration. 54 | const LineOptions({ 55 | this.lineJoin, 56 | this.lineOpacity, 57 | this.lineColor, 58 | this.lineWidth, 59 | this.lineGapWidth, 60 | this.lineOffset, 61 | this.lineBlur, 62 | this.linePattern, 63 | this.geometry, 64 | this.draggable, 65 | }); 66 | 67 | final String? lineJoin; 68 | final double? lineOpacity; 69 | final String? lineColor; 70 | final double? lineWidth; 71 | final double? lineGapWidth; 72 | final double? lineOffset; 73 | final double? lineBlur; 74 | final String? linePattern; 75 | final List? geometry; 76 | final bool? draggable; 77 | 78 | static const LineOptions defaultOptions = LineOptions(); 79 | 80 | LineOptions copyWith(LineOptions changes) { 81 | return LineOptions( 82 | lineJoin: changes.lineJoin ?? lineJoin, 83 | lineOpacity: changes.lineOpacity ?? lineOpacity, 84 | lineColor: changes.lineColor ?? lineColor, 85 | lineWidth: changes.lineWidth ?? lineWidth, 86 | lineGapWidth: changes.lineGapWidth ?? lineGapWidth, 87 | lineOffset: changes.lineOffset ?? lineOffset, 88 | lineBlur: changes.lineBlur ?? lineBlur, 89 | linePattern: changes.linePattern ?? linePattern, 90 | geometry: changes.geometry ?? geometry, 91 | draggable: changes.draggable ?? draggable, 92 | ); 93 | } 94 | 95 | dynamic toJson([bool addGeometry = true]) { 96 | final Map json = {}; 97 | 98 | void addIfPresent(String fieldName, dynamic value) { 99 | if (value != null) { 100 | json[fieldName] = value; 101 | } 102 | } 103 | 104 | addIfPresent('lineJoin', lineJoin); 105 | addIfPresent('lineOpacity', lineOpacity); 106 | addIfPresent('lineColor', lineColor); 107 | addIfPresent('lineWidth', lineWidth); 108 | addIfPresent('lineGapWidth', lineGapWidth); 109 | addIfPresent('lineOffset', lineOffset); 110 | addIfPresent('lineBlur', lineBlur); 111 | addIfPresent('linePattern', linePattern); 112 | if (addGeometry) { 113 | addIfPresent('geometry', 114 | geometry?.map((LatLng latLng) => latLng.toJson()).toList()); 115 | } 116 | addIfPresent('draggable', draggable); 117 | return json; 118 | } 119 | 120 | Map toGeoJson() { 121 | return { 122 | "type": "Feature", 123 | "properties": toJson(false), 124 | "geometry": { 125 | "type": "LineString", 126 | "coordinates": geometry!.map((c) => c.toGeoJsonCoordinates()).toList() 127 | } 128 | }; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/lib/src/snapshot.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_gl_platform_interface; 2 | 3 | /// Set of options for taking map snapshot 4 | class SnapshotOptions { 5 | /// Dimensions of the snapshot 6 | /// The width of the image 7 | final double width; 8 | 9 | /// Dimensions of the snapshot 10 | /// The height of the image 11 | final double height; 12 | 13 | /// If you want to take snapshot with camera position option 14 | /// 15 | /// Current center coordinate of camera position 16 | final LatLng? centerCoordinate; 17 | 18 | /// The coordinate rectangle that encompasses the bounds to capture. This is applied after the camera position 19 | final LatLngBounds? bounds; 20 | 21 | /// If you want to take snapshot with camera position option 22 | /// 23 | /// Zoom level of camera position 24 | final double? zoomLevel; 25 | 26 | /// If you want to take snapshot with camera position option 27 | /// 28 | /// Pitch toward the horizon measured in degrees, with 0 degrees resulting in a two-dimensional map 29 | final double? pitch; 30 | 31 | /// If you want to take snapshot with camera position option 32 | /// 33 | /// Heading measured in degrees clockwise from true north 34 | final double? heading; 35 | 36 | /// URL of the map style to snapshot. The URL may be a full HTTP or HTTPS URL, a Mapbox style URL 37 | final String? styleUri; 38 | 39 | /// StyleJson of the map style to snapshot 40 | final String? styleJson; 41 | 42 | /// Android Only: The flag indicating to show the Mapbox logo 43 | final bool withLogo; 44 | 45 | /// True: Save snapshot in cache and return path 46 | /// False: Return base64 value 47 | final bool writeToDisk; 48 | 49 | ///The [width] and [height] arguments must not be null 50 | SnapshotOptions( 51 | {required this.width, 52 | required this.height, 53 | this.centerCoordinate, 54 | this.bounds, 55 | this.zoomLevel, 56 | double? pitch, 57 | double? heading, 58 | this.styleUri, 59 | this.styleJson, 60 | bool? withLogo, 61 | bool? writeToDisk}) 62 | : this.withLogo = withLogo ?? false, 63 | this.writeToDisk = writeToDisk ?? true, 64 | this.pitch = pitch ?? 0, 65 | this.heading = heading ?? 0; 66 | 67 | Map toJson() { 68 | final Map json = {}; 69 | 70 | void addIfPresent(String fieldName, dynamic value) { 71 | if (value != null) { 72 | json[fieldName] = value; 73 | } 74 | } 75 | 76 | addIfPresent('width', Platform.isAndroid ? width.toInt() : width); 77 | addIfPresent('height', Platform.isAndroid ? height.toInt() : height); 78 | 79 | if (bounds != null) { 80 | if (Platform.isAndroid) { 81 | final featureCollection = { 82 | "type": "FeatureCollection", 83 | "features": [ 84 | { 85 | "type": "Feature", 86 | "properties": {}, 87 | "geometry": { 88 | "type": "Point", 89 | "coordinates": [ 90 | bounds!.northeast.longitude, 91 | bounds!.northeast.latitude 92 | ] 93 | } 94 | }, 95 | { 96 | "type": "Feature", 97 | "properties": {}, 98 | "geometry": { 99 | "type": "Point", 100 | "coordinates": [ 101 | bounds!.southwest.longitude, 102 | bounds!.southwest.latitude 103 | ] 104 | } 105 | } 106 | ] 107 | }; 108 | addIfPresent("bounds", featureCollection.toString()); 109 | } else { 110 | final list = [ 111 | [ 112 | bounds!.southwest.latitude, 113 | bounds!.southwest.longitude, 114 | ], 115 | [ 116 | bounds!.northeast.latitude, 117 | bounds!.northeast.longitude, 118 | ] 119 | ]; 120 | addIfPresent("bounds", list); 121 | } 122 | } 123 | if (centerCoordinate != null && zoomLevel != null) { 124 | if (Platform.isAndroid) { 125 | final feature = { 126 | "type": "Feature", 127 | "properties": {}, 128 | "geometry": { 129 | "type": "Point", 130 | "coordinates": [ 131 | centerCoordinate!.longitude, 132 | centerCoordinate!.latitude 133 | ] 134 | } 135 | }; 136 | addIfPresent('centerCoordinate', feature.toString()); 137 | } else { 138 | final list = [ 139 | centerCoordinate!.latitude, 140 | centerCoordinate!.longitude, 141 | ]; 142 | addIfPresent('centerCoordinate', list); 143 | } 144 | 145 | addIfPresent('zoomLevel', zoomLevel); 146 | } 147 | addIfPresent('pitch', pitch); 148 | addIfPresent('heading', heading); 149 | addIfPresent('styleUri', styleUri); 150 | addIfPresent('styleJson', styleJson); 151 | addIfPresent('withLogo', withLogo); 152 | addIfPresent('writeToDisk', writeToDisk); 153 | return json; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /mapbox_gl_platform_interface/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mapbox_gl_platform_interface 2 | description: A common platform interface for the mapbox_gl plugin. 3 | version: 0.16.0 4 | homepage: https://github.com/tobrun/flutter-mapbox-gl 5 | 6 | dependencies: 7 | flutter: 8 | sdk: flutter 9 | meta: ^1.0.5 10 | 11 | environment: 12 | sdk: '>=2.14.0 <3.0.0' 13 | flutter: ">=2.0.0" 14 | -------------------------------------------------------------------------------- /mapbox_gl_web/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.16.0, May 19, 2022 2 | * Fix type issues in query rendered features in rect [#862](https://github.com/flutter-mapbox-gl/maps/pull/862) 3 | * Annotation manager moved to dart [#779](https://github.com/flutter-mapbox-gl/maps/pull/779) 4 | * Fix issue with map disposal on web [#895](https://github.com/flutter-mapbox-gl/maps/pull/895) 5 | * Fix for rescale issues on web [#896](https://github.com/flutter-mapbox-gl/maps/pull/896) 6 | * Upgraded mapbox gl js to 2.7.0 [#889](https://github.com/flutter-mapbox-gl/maps/pull/889) 7 | * Add support for layer zoom limits [#934](https://github.com/flutter-mapbox-gl/maps/pull/934) 8 | * Implement layer filtering [#997](https://github.com/flutter-mapbox-gl/maps/pull/997) 9 | * Drag event types support added [#987](https://github.com/flutter-mapbox-gl/maps/pull/987) 10 | * Support filtering on addLayer [#1024](https://github.com/flutter-mapbox-gl/maps/pull/1024) 11 | 12 | ## 0.15.0, January 13, 2022 13 | * Callbacks added to onFeatureTapped will now also get the position (`Point`) and the location (`LatLng`) of the click passed when called [#798](https://github.com/flutter-mapbox-gl/maps/pull/798) 14 | * Fix web issues with style loaded, feature tap, add promoteId, pointer change issue [#785](https://github.com/flutter-mapbox-gl/maps/pull/785) 15 | * Add check for Dart formatting [#803](https://github.com/flutter-mapbox-gl/maps/pull/803) 16 | * Remove unnecessary print of style height and width [#847](https://github.com/flutter-mapbox-gl/maps/pull/847) 17 | * Full style source support [#797](https://github.com/flutter-mapbox-gl/maps/pull/797) 18 | * Gesture fixes [#851](https://github.com/flutter-mapbox-gl/maps/pull/851) 19 | * Fixed issue with return type of remove source on web [#854](https://github.com/flutter-mapbox-gl/maps/pull/854) 20 | 21 | ## 0.14.0, November 13, 2021 22 | * Add support for Layers, properties and expressions backed by GeoJsonSource [#723](https://github.com/tobrun/flutter-mapbox-gl/pull/723) 23 | * Add attribution button gravity, position normally [#731](https://github.com/tobrun/flutter-mapbox-gl/pull/731) 24 | * Add getSymbolLatLng and getLineLatLngs for web [#720](https://github.com/tobrun/flutter-mapbox-gl/pull/720) 25 | 26 | ## 0.13.0, October 21, 2021 27 | * Migrate to null-safety [#607](https://github.com/tobrun/flutter-mapbox-gl/pull/607) 28 | * Add missing removeLines removeCircles and removeFills [#622](https://github.com/tobrun/flutter-mapbox-gl/pull/622) 29 | * Fix Warning: Operand of null-aware operation '!' has type 'Locale' which excludes null [#676](https://github.com/tobrun/flutter-mapbox-gl/pull/676) 30 | 31 | ## 0.12.0, April 12, 2021 32 | * Dependencies: updated image package [#598](https://github.com/tobrun/flutter-mapbox-gl/pull/598) 33 | * Fix feature manager on release build [#593](https://github.com/tobrun/flutter-mapbox-gl/pull/593) 34 | * Emit onTap only for the feature above the others [#589](https://github.com/tobrun/flutter-mapbox-gl/pull/589) 35 | * Add annotationOrder to web [#588](https://github.com/tobrun/flutter-mapbox-gl/pull/588) 36 | 37 | ## 0.11.0, March 30, 2021 38 | * Fix Mapbox GL JS CSS embedding on web [#551](https://github.com/tobrun/flutter-mapbox-gl/pull/551) 39 | * Add batch mode of screen locations [#554](https://github.com/tobrun/flutter-mapbox-gl/pull/554) 40 | 41 | ## 0.10.0, February 12, 2020 42 | * Added web support for fills [#501](https://github.com/tobrun/flutter-mapbox-gl/pull/501) 43 | * Add heading to UserLocation and expose UserLocation type [#522](https://github.com/tobrun/flutter-mapbox-gl/pull/522) 44 | * Update tracked camera position in camera#onIdle [#500](https://github.com/tobrun/flutter-mapbox-gl/pull/500) 45 | * Improved Image Source Support [#469](https://github.com/tobrun/flutter-mapbox-gl/pull/469) 46 | 47 | ## 0.9.0, October 24. 2020 48 | * Breaking change: CameraUpdate.newLatLngBounds() now supports setting different padding values for left, top, right, bottom with default of 0 for all. Implementations using the old approach with only one padding value for all edges have to be updated. [#382](https://github.com/tobrun/flutter-mapbox-gl/pull/382) 49 | * web:ignore myLocationTrackingMode if myLocationEnabled is false [#363](https://github.com/tobrun/flutter-mapbox-gl/pull/363) 50 | * Add methods to access projection [#380](https://github.com/tobrun/flutter-mapbox-gl/pull/380) 51 | * Listen to OnUserLocationUpdated to provide user location to app [#237](https://github.com/tobrun/flutter-mapbox-gl/pull/237) 52 | * Get meters per pixel at latitude [#416](https://github.com/tobrun/flutter-mapbox-gl/pull/416) 53 | 54 | ## 0.8.0, August 22, 2020 55 | - implementation of feature querying [#177](https://github.com/tobrun/flutter-mapbox-gl/pull/177) 56 | - Allow setting accesstoken in flutter [#321](https://github.com/tobrun/flutter-mapbox-gl/pull/321) 57 | - Batch create/delete of symbols [#279](https://github.com/tobrun/flutter-mapbox-gl/pull/279) 58 | - Set dependencies from git [#319](https://github.com/tobrun/flutter-mapbox-gl/pull/319) 59 | - Add multi map support [#315](https://github.com/tobrun/flutter-mapbox-gl/pull/315) 60 | 61 | ## 0.7.0 62 | - Initial version 63 | -------------------------------------------------------------------------------- /mapbox_gl_web/LICENSE: -------------------------------------------------------------------------------- 1 | flutter-mapbox-gl copyright (c) 2018, Mapbox. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 7 | -------------------------------------------------------------------------------- /mapbox_gl_web/README.md: -------------------------------------------------------------------------------- 1 | Contains the web interfaces for the [Flutter Mapbox GL plugin](https://github.com/tobrun/flutter-mapbox-gl). -------------------------------------------------------------------------------- /mapbox_gl_web/ios/mapbox_gl_web.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = 'mapbox_gl_web' 4 | s.version = '0.1.0' 5 | s.summary = 'No-op implementation of mapbox_gl_web web plugin to avoid build issues on iOS' 6 | s.description = <<-DESC 7 | temp fake mapbox_gl_web plugin 8 | DESC 9 | s.homepage = 'http://example.com' 10 | s.license = { :file => '../LICENSE' } 11 | s.author = { 'Your Company' => 'email@example.com' } 12 | s.source = { :path => '.' } 13 | s.source_files = 'Classes/**/*' 14 | s.public_header_files = 'Classes/**/*.h' 15 | s.dependency 'Flutter' 16 | 17 | s.ios.deployment_target = '8.0' 18 | end -------------------------------------------------------------------------------- /mapbox_gl_web/lib/mapbox_gl_web.dart: -------------------------------------------------------------------------------- 1 | library mapbox_gl_web; 2 | 3 | import 'dart:async'; 4 | import 'dart:convert'; 5 | // FIXED HERE: https://github.com/dart-lang/linter/pull/1985 6 | // ignore_for_file: avoid_web_libraries_in_flutter 7 | import 'dart:html'; 8 | // ignore: unused_import 9 | import 'dart:js'; 10 | import 'dart:js_util'; 11 | import 'dart:math'; 12 | import 'dart:typed_data'; 13 | import 'dart:ui' as ui; 14 | import 'package:flutter/services.dart'; 15 | 16 | import 'package:flutter/foundation.dart'; 17 | import 'package:flutter/gestures.dart'; 18 | import 'package:flutter/material.dart' hide Element; 19 | 20 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 21 | import 'package:mapbox_gl_platform_interface/mapbox_gl_platform_interface.dart'; 22 | import 'package:mapbox_gl_dart/mapbox_gl_dart.dart' hide Point, Source; 23 | import 'package:mapbox_gl_dart/mapbox_gl_dart.dart' as mapbox show Point; 24 | import 'package:image/image.dart' hide Point; 25 | import 'package:js/js_util.dart' as jsUtil; 26 | import 'package:mapbox_gl_web/src/layer_tools.dart'; 27 | 28 | part 'src/convert.dart'; 29 | part 'src/mapbox_map_plugin.dart'; 30 | part 'src/options_sink.dart'; 31 | part 'src/mapbox_web_gl_platform.dart'; 32 | -------------------------------------------------------------------------------- /mapbox_gl_web/lib/src/layer_tools.dart: -------------------------------------------------------------------------------- 1 | // This file is generated by 2 | // ./scripts/lib/generate.dart 3 | 4 | const _layoutProperties = { 5 | "symbol-placement", 6 | "symbol-spacing", 7 | "symbol-avoid-edges", 8 | "symbol-sort-key", 9 | "symbol-z-order", 10 | "icon-allow-overlap", 11 | "icon-ignore-placement", 12 | "icon-optional", 13 | "icon-rotation-alignment", 14 | "icon-size", 15 | "icon-text-fit", 16 | "icon-text-fit-padding", 17 | "icon-image", 18 | "icon-rotate", 19 | "icon-padding", 20 | "icon-keep-upright", 21 | "icon-offset", 22 | "icon-anchor", 23 | "icon-pitch-alignment", 24 | "text-pitch-alignment", 25 | "text-rotation-alignment", 26 | "text-field", 27 | "text-font", 28 | "text-size", 29 | "text-max-width", 30 | "text-line-height", 31 | "text-letter-spacing", 32 | "text-justify", 33 | "text-radial-offset", 34 | "text-variable-anchor", 35 | "text-anchor", 36 | "text-max-angle", 37 | "text-writing-mode", 38 | "text-rotate", 39 | "text-padding", 40 | "text-keep-upright", 41 | "text-transform", 42 | "text-offset", 43 | "text-allow-overlap", 44 | "text-ignore-placement", 45 | "text-optional", 46 | "visibility", 47 | "circle-sort-key", 48 | "line-cap", 49 | "line-join", 50 | "line-miter-limit", 51 | "line-round-limit", 52 | "line-sort-key", 53 | "fill-sort-key", 54 | }; 55 | 56 | bool isLayoutProperty(String property) { 57 | return _layoutProperties.contains(property); 58 | } 59 | -------------------------------------------------------------------------------- /mapbox_gl_web/lib/src/mapbox_map_plugin.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_gl_web; 2 | 3 | class MapboxMapPlugin { 4 | /// Registers this class as the default instance of [MapboxGlPlatform]. 5 | static void registerWith(Registrar registrar) { 6 | MapboxGlPlatform.createInstance = () => MapboxWebGlPlatform(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /mapbox_gl_web/lib/src/options_sink.dart: -------------------------------------------------------------------------------- 1 | part of mapbox_gl_web; 2 | 3 | abstract class MapboxMapOptionsSink { 4 | // TODO: dddd replace with CameraPosition.Builder target 5 | void setCameraTargetBounds(LatLngBounds? bounds); 6 | 7 | void setCompassEnabled(bool compassEnabled); 8 | 9 | // TODO: styleString is not actually a part of options. consider moving 10 | void setStyleString(String? styleString); 11 | 12 | void setMinMaxZoomPreference(num? min, num? max); 13 | 14 | void setGestures({ 15 | required bool rotateGesturesEnabled, 16 | required bool scrollGesturesEnabled, 17 | required bool tiltGesturesEnabled, 18 | required bool zoomGesturesEnabled, 19 | required bool doubleClickZoomEnabled, 20 | }); 21 | 22 | void setTrackCameraPosition(bool trackCameraPosition); 23 | 24 | void setMyLocationEnabled(bool myLocationEnabled); 25 | 26 | void setMyLocationTrackingMode(int myLocationTrackingMode); 27 | 28 | void setMyLocationRenderMode(int myLocationRenderMode); 29 | 30 | void setLogoViewMargins(int x, int y); 31 | 32 | void setCompassAlignment(CompassViewPosition position); 33 | 34 | void setCompassViewMargins(int x, int y); 35 | 36 | void setAttributionButtonAlignment(AttributionButtonPosition position); 37 | 38 | void setAttributionButtonMargins(int x, int y); 39 | } 40 | -------------------------------------------------------------------------------- /mapbox_gl_web/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mapbox_gl_web 2 | description: Web platform implementation of mapbox_gl 3 | version: 0.16.0 4 | homepage: https://github.com/tobrun/flutter-mapbox-gl 5 | 6 | flutter: 7 | plugin: 8 | platforms: 9 | web: 10 | pluginClass: MapboxMapPlugin 11 | fileName: mapbox_gl_web.dart 12 | 13 | dependencies: 14 | flutter: 15 | sdk: flutter 16 | flutter_web_plugins: 17 | sdk: flutter 18 | meta: ^1.1.7 19 | mapbox_gl_platform_interface: 20 | git: 21 | url: https://github.com/tobrun/flutter-mapbox-gl.git 22 | path: mapbox_gl_platform_interface 23 | mapbox_gl_dart: ^0.2.1 24 | image: '>=3.0.0 <5.0.0' 25 | 26 | dependency_overrides: 27 | mapbox_gl_platform_interface: 28 | path: ../mapbox_gl_platform_interface 29 | 30 | dev_dependencies: 31 | flutter_test: 32 | sdk: flutter 33 | 34 | environment: 35 | sdk: ">=2.12.0 <3.0.0" 36 | flutter: ">=2.0.0" 37 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | sha256: a92e39b291073bb840a72cf43d96d2a63c74e9a485d227833e8ea0054d16ad16 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "3.1.2" 12 | characters: 13 | dependency: transitive 14 | description: 15 | name: characters 16 | sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "1.2.1" 20 | collection: 21 | dependency: "direct main" 22 | description: 23 | name: collection 24 | sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.17.0" 28 | crypto: 29 | dependency: transitive 30 | description: 31 | name: crypto 32 | sha256: cf75650c66c0316274e21d7c43d3dea246273af5955bd94e8184837cd577575c 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "3.0.1" 36 | flutter: 37 | dependency: "direct main" 38 | description: flutter 39 | source: sdk 40 | version: "0.0.0" 41 | flutter_web_plugins: 42 | dependency: transitive 43 | description: flutter 44 | source: sdk 45 | version: "0.0.0" 46 | image: 47 | dependency: transitive 48 | description: 49 | name: image 50 | sha256: "3e5c9ef82c0af7823be4cb5294a829a6e0548a6f6b4e261e6386509a9e03bcab" 51 | url: "https://pub.dev" 52 | source: hosted 53 | version: "3.0.2" 54 | js: 55 | dependency: transitive 56 | description: 57 | name: js 58 | sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" 59 | url: "https://pub.dev" 60 | source: hosted 61 | version: "0.6.5" 62 | mapbox_gl_dart: 63 | dependency: transitive 64 | description: 65 | name: mapbox_gl_dart 66 | sha256: de6d03718e5eb05c9eb1ddaae7f0383b28acb5afa16405e1deed7ff04dd34f3d 67 | url: "https://pub.dev" 68 | source: hosted 69 | version: "0.2.1" 70 | mapbox_gl_platform_interface: 71 | dependency: "direct main" 72 | description: 73 | path: mapbox_gl_platform_interface 74 | relative: true 75 | source: path 76 | version: "0.16.0" 77 | mapbox_gl_web: 78 | dependency: "direct main" 79 | description: 80 | path: mapbox_gl_web 81 | relative: true 82 | source: path 83 | version: "0.16.0" 84 | material_color_utilities: 85 | dependency: transitive 86 | description: 87 | name: material_color_utilities 88 | sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "0.2.0" 92 | meta: 93 | dependency: transitive 94 | description: 95 | name: meta 96 | sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "1.8.0" 100 | path: 101 | dependency: transitive 102 | description: 103 | name: path 104 | sha256: "2ad4cddff7f5cc0e2d13069f2a3f7a73ca18f66abd6f5ecf215219cdb3638edb" 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "1.8.0" 108 | petitparser: 109 | dependency: transitive 110 | description: 111 | name: petitparser 112 | sha256: "85e8f8b118afcccf948a9844d199e56260117400bd9b9982d87bf1d62ebc1690" 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "4.1.0" 116 | sky_engine: 117 | dependency: transitive 118 | description: flutter 119 | source: sdk 120 | version: "0.0.99" 121 | typed_data: 122 | dependency: transitive 123 | description: 124 | name: typed_data 125 | sha256: "53bdf7e979cfbf3e28987552fd72f637e63f3c8724c9e56d9246942dc2fa36ee" 126 | url: "https://pub.dev" 127 | source: hosted 128 | version: "1.3.0" 129 | vector_math: 130 | dependency: transitive 131 | description: 132 | name: vector_math 133 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 134 | url: "https://pub.dev" 135 | source: hosted 136 | version: "2.1.4" 137 | xml: 138 | dependency: transitive 139 | description: 140 | name: xml 141 | sha256: "88d26fad429944d29b7c418177d156d04bbef049f295cf48130eccc84f0b8b4b" 142 | url: "https://pub.dev" 143 | source: hosted 144 | version: "5.1.0" 145 | sdks: 146 | dart: ">=2.17.0-0 <3.0.0" 147 | flutter: ">=2.0.0" 148 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mapbox_gl 2 | description: A Flutter plugin for integrating Mapbox Maps inside a Flutter application on Android, iOS and web platfroms. 3 | version: 0.16.0 4 | homepage: https://github.com/tobrun/flutter-mapbox-gl 5 | 6 | dependencies: 7 | flutter: 8 | sdk: flutter 9 | mapbox_gl_platform_interface: 10 | git: 11 | url: https://github.com/tobrun/flutter-mapbox-gl.git 12 | path: mapbox_gl_platform_interface 13 | mapbox_gl_web: 14 | git: 15 | url: https://github.com/tobrun/flutter-mapbox-gl.git 16 | path: mapbox_gl_web 17 | collection: ^1.15.0 18 | 19 | dependency_overrides: 20 | mapbox_gl_platform_interface: 21 | path: ./mapbox_gl_platform_interface 22 | mapbox_gl_web: 23 | path: ./mapbox_gl_web 24 | 25 | flutter: 26 | plugin: 27 | platforms: 28 | android: 29 | package: com.mapbox.mapboxgl 30 | pluginClass: MapboxMapsPlugin 31 | ios: 32 | pluginClass: MapboxMapsPlugin 33 | web: 34 | default_package: mapbox_gl_web 35 | 36 | environment: 37 | sdk: '>=2.14.0 <3.0.0' 38 | # Flutter versions prior to 1.10 did not support the flutter.plugin.platforms map. 39 | flutter: ">=2.0.0" 40 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter-mapbox-gl/maps/4a09cc4401bb77e900f005cc1e2f712193b997af/screenshot.png -------------------------------------------------------------------------------- /scripts/lib/conversions.dart: -------------------------------------------------------------------------------- 1 | const renamedIosProperties = { 2 | "iconImage": "iconImageName", 3 | "iconRotate": "iconRotation", 4 | "iconSize": "iconScale", 5 | "iconKeepUpright": "keepsIconUpright", 6 | "iconTranslate": "iconTranslation", 7 | "iconTranslateAnchor": "iconTranslationAnchor", 8 | "iconAllowOverlap": "iconAllowsOverlap", 9 | "iconIgnorePlacement": "iconIgnoresPlacement", 10 | "textTranslate": "textTranslation", 11 | "textTranslateAnchor": "textTranslationAnchor", 12 | "textIgnorePlacement": "textIgnoresPlacement", 13 | "textField": "text", 14 | "textFont": "textFontNames", 15 | "textSize": "textFontSize", 16 | "textMaxWidth": "maximumTextWidth", 17 | "textJustify": "textJustification", 18 | "textMaxAngle": "maximumTextAngle", 19 | "textWritingMode": "textWritingModes", 20 | "textRotate": "textRotation", 21 | "textKeepUpright": "keepsTextUpright", 22 | "textAllowOverlap": "textAllowsOverlap", 23 | "symbolAvoidEdges": "symbolAvoidsEdges", 24 | "circleTranslate": "circleTranslation", 25 | "circleTranslateAnchor": "circleTranslationAnchor", 26 | "circlePitchScale": "circleScaleAlignment", 27 | "lineTranslate": "lineTranslation", 28 | "lineTranslateAnchor": "lineTranslationAnchor", 29 | "lineDasharray": "lineDashPattern", 30 | "fillAntialias": "fillAntialiased", 31 | "fillTranslate": "fillTranslation", 32 | "fillTranslateAnchor": "fillTranslationAnchor", 33 | "rasterHueRotate": "rasterHueRotation", 34 | "rasterResampling": "rasterResamplingMode", 35 | "visibility": "isVisible", 36 | "rasterBrightnessMin": "minimumRasterBrightness", 37 | "rasterBrightnessMax": "maximumRasterBrightness", 38 | "fillExtrusionTranslate": "fillExtrusionTranslation", 39 | "fillExtrusionTranslateAnchor": "fillExtrusionTranslationAnchor", 40 | "fillExtrusionVerticalGradient": "fillExtrusionHasVerticalGradient", 41 | }; 42 | 43 | const dartTypeMappingTable = { 44 | "string": "String", 45 | "array": "List", 46 | "number": "double", 47 | "enum": "String", 48 | "promoteId": "String", 49 | "boolean": "bool", 50 | "*": "Object" 51 | }; 52 | 53 | const swiftTypeMappingTable = { 54 | "string": "String", 55 | "array": "Array", 56 | "number": "Double", 57 | "enum": "String", 58 | "promoteId": "String", 59 | "boolean": "Bool", 60 | "*": "Object" 61 | }; 62 | -------------------------------------------------------------------------------- /scripts/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | mustache_template: 5 | dependency: "direct main" 6 | description: 7 | name: mustache_template 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.0.0" 11 | recase: 12 | dependency: "direct main" 13 | description: 14 | name: recase 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "4.0.0" 18 | sdks: 19 | dart: ">=2.12.0 <3.0.0" 20 | -------------------------------------------------------------------------------- /scripts/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mapbox_code_gen 2 | description: code generation for flutter-mapbox-gl 3 | 4 | version: 0.0.1 5 | 6 | environment: 7 | sdk: '>=2.12.0 <3.0.0' 8 | 9 | dependencies: 10 | mustache_template: ^2.0.0 11 | recase: ^4.0.0 12 | -------------------------------------------------------------------------------- /scripts/templates/LayerPropertyConverter.java.template: -------------------------------------------------------------------------------- 1 | // This file is generated by 2 | // ./scripts/lib/generate.dart 3 | 4 | package com.mapbox.mapboxgl; 5 | 6 | import com.mapbox.mapboxsdk.style.expressions.Expression; 7 | import com.mapbox.mapboxsdk.style.layers.PropertyFactory; 8 | import com.mapbox.mapboxsdk.style.layers.PropertyValue; 9 | 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | import com.google.gson.JsonElement; 15 | import com.google.gson.JsonParser; 16 | import com.google.gson.JsonPrimitive; 17 | 18 | 19 | import static com.mapbox.mapboxgl.Convert.toMap; 20 | 21 | class LayerPropertyConverter { 22 | {{#layerTypes}} 23 | static PropertyValue[] interpret{{typePascal}}LayerProperties(Object o) { 24 | final Map data = (Map) toMap(o); 25 | final List properties = new LinkedList(); 26 | final JsonParser parser = new JsonParser(); 27 | 28 | for (Map.Entry entry : data.entrySet()) { 29 | final JsonElement jsonElement = parser.parse(entry.getValue()); 30 | Expression expression = Expression.Converter.convert(jsonElement); 31 | switch (entry.getKey()) { 32 | {{#paint_properties}} 33 | case "{{value}}": 34 | properties.add(PropertyFactory.{{valueAsCamelCase}}(expression)); 35 | break; 36 | {{/paint_properties}} 37 | {{#layout_properties}} 38 | {{^isVisibilityProperty}} 39 | {{^requiresLiteral}} 40 | case "{{value}}": 41 | properties.add(PropertyFactory.{{valueAsCamelCase}}(expression)); 42 | {{/requiresLiteral}} 43 | {{/isVisibilityProperty}} 44 | {{#requiresLiteral}} 45 | case "{{value}}": 46 | if(jsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()){ 47 | properties.add(PropertyFactory.iconImage(jsonElement.getAsString())); 48 | }else{ 49 | properties.add(PropertyFactory.iconImage(expression)); 50 | } 51 | {{/requiresLiteral}} 52 | {{#isVisibilityProperty}} 53 | case "{{value}}": 54 | properties.add(PropertyFactory.{{valueAsCamelCase}}(entry.getValue())); 55 | {{/isVisibilityProperty}} 56 | break; 57 | {{/layout_properties}} 58 | default: 59 | break; 60 | } 61 | } 62 | 63 | return properties.toArray(new PropertyValue[properties.size()]); 64 | } 65 | 66 | {{/layerTypes}} 67 | } -------------------------------------------------------------------------------- /scripts/templates/LayerPropertyConverter.swift.template: -------------------------------------------------------------------------------- 1 | // This file is generated by 2 | // ./scripts/lib/generate.dart 3 | 4 | import Mapbox 5 | import MapboxAnnotationExtension 6 | 7 | class LayerPropertyConverter { 8 | {{#layerTypes}} 9 | class func add{{typePascal}}Properties({{typeCamel}}Layer: MGL{{typePascal}}StyleLayer, properties: [String: String]) { 10 | for (propertyName, propertyValue) in properties { 11 | let expression = interpretExpression(propertyName: propertyName, expression: propertyValue) 12 | switch propertyName { 13 | {{#paint_properties}} 14 | case "{{{value}}}": 15 | {{#isIosAsCamelCase}} 16 | {{typeCamel}}Layer.{{iosAsCamelCase}} = expression; 17 | {{/isIosAsCamelCase}} 18 | {{^isIosAsCamelCase}} 19 | {{typeCamel}}Layer.{{valueAsCamelCase}} = expression; 20 | {{/isIosAsCamelCase}} 21 | break; 22 | {{/paint_properties}} 23 | {{#layout_properties}} 24 | case "{{{value}}}": 25 | {{^isVisibilityProperty}} 26 | {{#isIosAsCamelCase}} 27 | {{typeCamel}}Layer.{{iosAsCamelCase}} = expression; 28 | {{/isIosAsCamelCase}} 29 | {{^isIosAsCamelCase}} 30 | {{typeCamel}}Layer.{{valueAsCamelCase}} = expression; 31 | {{/isIosAsCamelCase}} 32 | {{/isVisibilityProperty}} 33 | {{#isVisibilityProperty}} 34 | {{typeCamel}}Layer.{{iosAsCamelCase}} = propertyValue == "visible"; 35 | {{/isVisibilityProperty}} 36 | break; 37 | {{/layout_properties}} 38 | 39 | default: 40 | break 41 | } 42 | } 43 | } 44 | 45 | {{/layerTypes}} 46 | private class func interpretExpression(propertyName: String, expression: String) -> NSExpression? { 47 | let isColor = propertyName.contains("color"); 48 | 49 | do { 50 | let json = try JSONSerialization.jsonObject(with: expression.data(using: .utf8)!, options: .fragmentsAllowed) 51 | // this is required because NSExpression.init(mglJSONObject: json) fails to create 52 | // a proper Expression if the data of is a hexString 53 | if isColor { 54 | if let color = json as? String { 55 | return NSExpression(forConstantValue: UIColor(hexString: color)) 56 | } 57 | } 58 | // this is required because NSExpression.init(mglJSONObject: json) fails to create 59 | // a proper Expression if the data of a literal is an array 60 | if let offset = json as? [Any]{ 61 | if offset.count == 2 && offset.first is String && offset.first as? String == "literal" { 62 | if let vector = offset.last as? [Any]{ 63 | if(vector.count == 2) { 64 | if let x = vector.first as? Double, let y = vector.last as? Double { 65 | return NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: x, dy: y))) 66 | } 67 | 68 | } 69 | } 70 | } 71 | } 72 | return NSExpression.init(mglJSONObject: json) 73 | } catch { 74 | } 75 | return nil 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /scripts/templates/layer_expressions.dart.template: -------------------------------------------------------------------------------- 1 | // This file is generated by 2 | // ./scripts/lib/generate.dart 3 | 4 | part of mapbox_gl; 5 | 6 | class Expressions{ 7 | {{#expressions}} 8 | {{#docSplit}} 9 | /// {{{part}}} 10 | {{/docSplit}} 11 | static const {{valueAsCamelCase}} = "{{{value}}}"; 12 | 13 | {{/expressions}} 14 | } 15 | -------------------------------------------------------------------------------- /scripts/templates/layer_properties.dart.template: -------------------------------------------------------------------------------- 1 | // This file is generated by 2 | // ./scripts/lib/generate.dart 3 | 4 | part of mapbox_gl; 5 | 6 | abstract class LayerProperties { 7 | Map toJson(); 8 | } 9 | {{#layerTypes}} 10 | 11 | class {{typePascal}}LayerProperties implements LayerProperties { 12 | // Paint Properties 13 | {{#paint_properties}} 14 | {{#docSplit}} 15 | /// {{{part}}} 16 | {{/docSplit}} 17 | final dynamic {{valueAsCamelCase}}; 18 | 19 | {{/paint_properties}} 20 | // Layout Properties 21 | {{#layout_properties}} 22 | {{#docSplit}} 23 | /// {{{part}}} 24 | {{/docSplit}} 25 | final dynamic {{valueAsCamelCase}}; 26 | 27 | {{/layout_properties}} 28 | const {{typePascal}}LayerProperties({ 29 | {{#paint_properties}} 30 | this.{{valueAsCamelCase}}, 31 | {{/paint_properties}} 32 | {{#layout_properties}} 33 | this.{{valueAsCamelCase}}, 34 | {{/layout_properties}} 35 | }); 36 | 37 | {{typePascal}}LayerProperties copyWith({{typePascal}}LayerProperties changes) { 38 | return {{typePascal}}LayerProperties( 39 | {{#paint_properties}} 40 | {{valueAsCamelCase}}: changes.{{valueAsCamelCase}} ?? {{valueAsCamelCase}}, 41 | {{/paint_properties}} 42 | {{#layout_properties}} 43 | {{valueAsCamelCase}}: changes.{{valueAsCamelCase}} ?? {{valueAsCamelCase}}, 44 | {{/layout_properties}} 45 | ); 46 | } 47 | 48 | Map toJson() { 49 | final Map json = {}; 50 | 51 | void addIfPresent(String fieldName, dynamic value) { 52 | if (value != null) { 53 | json[fieldName] = value; 54 | } 55 | } 56 | 57 | {{#paint_properties}} 58 | addIfPresent('{{value}}', {{valueAsCamelCase}}); 59 | {{/paint_properties}} 60 | {{#layout_properties}} 61 | addIfPresent('{{value}}', {{valueAsCamelCase}}); 62 | {{/layout_properties}} 63 | return json; 64 | } 65 | 66 | factory {{typePascal}}LayerProperties.fromJson(Map json) { 67 | return {{typePascal}}LayerProperties( 68 | {{#paint_properties}} 69 | {{valueAsCamelCase}}: json['{{value}}'], 70 | {{/paint_properties}} 71 | {{#layout_properties}} 72 | {{valueAsCamelCase}}: json['{{value}}'], 73 | {{/layout_properties}} 74 | ); 75 | } 76 | 77 | } 78 | {{/layerTypes}} 79 | 80 | 81 | -------------------------------------------------------------------------------- /scripts/templates/layer_tools.dart.template: -------------------------------------------------------------------------------- 1 | // This file is generated by 2 | // ./scripts/lib/generate.dart 3 | 4 | const _layoutProperties = { 5 | {{#all_layout_properties}} 6 | "{{{property}}}", 7 | {{/all_layout_properties}} 8 | }; 9 | 10 | bool isLayoutProperty(String property){ 11 | return _layoutProperties.contains(property); 12 | } -------------------------------------------------------------------------------- /scripts/templates/source_properties.dart.template: -------------------------------------------------------------------------------- 1 | // This file is generated by 2 | // ./scripts/lib/generate.dart 3 | 4 | part of mapbox_gl_platform_interface; 5 | 6 | abstract class SourceProperties { 7 | Map toJson(); 8 | } 9 | {{#sourceTypes}} 10 | 11 | class {{typePascal}}SourceProperties implements SourceProperties { 12 | {{#properties}} 13 | {{#docSplit}} 14 | /// {{{part}}} 15 | {{/docSplit}} 16 | final {{{type}}}? {{valueAsCamelCase}}; 17 | 18 | {{/properties}} 19 | const {{typePascal}}SourceProperties({ 20 | {{#properties}} 21 | {{^hasDefault}} 22 | this.{{valueAsCamelCase}}, 23 | {{/hasDefault}} 24 | {{#hasDefault}} 25 | this.{{valueAsCamelCase}} = {{{default}}}, 26 | {{/hasDefault}} 27 | {{/properties}} 28 | }); 29 | 30 | {{typePascal}}SourceProperties copyWith( 31 | {{#properties}} 32 | {{{type}}}? {{valueAsCamelCase}}, 33 | {{/properties}} 34 | ) { 35 | return {{typePascal}}SourceProperties( 36 | {{#properties}} 37 | {{valueAsCamelCase}}: {{valueAsCamelCase}} ?? this.{{valueAsCamelCase}}, 38 | {{/properties}} 39 | ); 40 | } 41 | 42 | Map toJson() { 43 | final Map json = {}; 44 | 45 | void addIfPresent(String fieldName, dynamic value) { 46 | if (value != null) { 47 | json[fieldName] = value; 48 | } 49 | } 50 | json["type"] = "{{type}}"; 51 | {{#properties}} 52 | addIfPresent('{{value}}', {{valueAsCamelCase}}); 53 | {{/properties}} 54 | return json; 55 | } 56 | 57 | factory {{typePascal}}SourceProperties.fromJson(Map json) { 58 | return {{typePascal}}SourceProperties( 59 | {{#properties}} 60 | {{valueAsCamelCase}}: json['{{value}}'], 61 | {{/properties}} 62 | ); 63 | } 64 | 65 | } 66 | {{/sourceTypes}} 67 | 68 | 69 | --------------------------------------------------------------------------------