diff --git a/.github/ISSUE_TEMPLATE/bug-report.yaml b/.github/ISSUE_TEMPLATE/bug-report.yaml index 87454f1d1..21a40f273 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yaml +++ b/.github/ISSUE_TEMPLATE/bug-report.yaml @@ -8,63 +8,55 @@ body: value: " # Bug Report - Thanks for taking the time to fill out this bug report! It helps us to improve the experience for you and other developers that may be facing a similar problem. We aim to respond to bug reports as soon as possible, but it may take longer to resolve this issue depending on its complexity and severity. To help us verify the issue quicker, please include as much information as you can. + Thanks for taking the time to fill out this bug report! To help us verify the issue quicker, please include as much information as you can. + + + --- + + + Before reporting a bug, please: + + * Check if there is already an open or closed issue that is similar to yours + + * Ensure that you have fully read the documentation (both the website and API docs) that pertains to the function you're having problems with + + * Ensure that your Flutter environment is correctly installed & set-up + + * Remember that we're volunteers trying our best to help, so please be polite + + + --- " - - type: markdown - attributes: - value: --- - type: textarea - id: description + id: details attributes: label: What is the bug? - description: What were you implementing when you found this issue? What happens when the bug triggers? - validations: - required: true - - type: textarea - id: expected-behaviour - attributes: - label: What is the expected behaviour? - description: What do you think should have happened? + description: What were you implementing when you found this issue? What happens when the bug triggers? What do you think should have happened instead? Please include as much detail as possible, including screenshots and screen-recordings if you can. validations: required: true - type: textarea id: reproduce attributes: - label: How can we reproduce this issue? + label: How can we reproduce it? description: | - Please include a [minimal reproducible example](https://en.wikipedia.org/wiki/Minimal_reproducible_example) (preferable), otherwise detail the exact steps to reproduce this issue. - If you do not include any information here, it will take longer for us to verify your issue. - placeholder: Text automatically formatted as Dart code, on submission - render: dart + Please include a fully formatted [minimal reproducible example](https://en.wikipedia.org/wiki/Minimal_reproducible_example) wrapped in a [Dart code block](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting), otherwise, detail the exact steps to reproduce this issue. + If you do not include any information here, it will take longer for us to verify your issue. + validations: + required: true - type: textarea id: solution attributes: label: Do you have a potential solution? - description: "If so, please detail it: it will make it quicker for us to fix the issue" - - type: textarea - id: additional-info - attributes: - label: Can you provide any other information? - description: | - Please attach any other logs, screenshots, or screen recordings. - Is there anything else you'd like to say? + description: "If so, please detail it: it will make it quicker for us to fix the issue." - type: markdown attributes: value: --- - - type: dropdown + - type: input id: platform attributes: - label: Platforms Affected - description: What platforms does this issue affect? - multiple: true - options: - - Android - - iOS - - Web - - Windows - - MacOS - - Linux - - Other + label: Platforms + description: Please detail the devices and operating systems you can reproduce this bug on, separated by commas. + placeholder: eg. Android 13 (Samsung Galaxy S99), Windows 11 (x64) validations: required: true - type: dropdown @@ -78,35 +70,4 @@ body: - "Erroneous: Prevents normal functioning and causes errors in the console" - "Fatal: Causes the application to crash" validations: - required: true - - type: dropdown - id: frequency - attributes: - label: Frequency - description: How often does this issue occur? - options: - - "Once: Occurred on a single occasion" - - "Rarely: Occurs every so often" - - "Often: Occurs more often than when it doesn't" - - "Consistently: Always occurs at the same time and location" - validations: - required: true - - type: markdown - attributes: - value: --- - - type: checkboxes - id: terms - attributes: - label: Requirements - description: These are in place to prevent spam and unnecessary reports. - options: - - label: I agree to follow this project's [Code of Conduct](https://github.com/fleaflet/flutter_map/blob/master/CODE_OF_CONDUCT.md) - required: true - - label: My Flutter/Dart installation is unaltered, and `flutter doctor` finds no relevant issues - required: true - - label: I am using the [latest stable version](https://pub.dev/packages/flutter_map) of this package - required: true - - label: I have checked the FAQs section on the documentation website - required: true - - label: I have checked for similar issues which may be duplicates - required: true + required: true \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 35e62dc6f..ecc1b73da 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,8 @@ blank_issues_enabled: false contact_links: - - name: Discord Server + - name: Get Help url: https://discord.gg/egEGeByf4q - about: Need more generalised help, or just want to talk? Join the Discord server! - - name: Common Issues - url: https://docs.fleaflet.dev/usage/common-issues - about: Check whether your issue is listed as a common issue in the documentation - - name: Plugins - url: https://docs.fleaflet.dev/plugins/list - about: If you need help with a plugin, please ask on their issue tracker first + about: Don't quite understand how to implement something, or just want to talk? Join the Discord server! + - name: Documentation + url: https://docs.fleaflet.dev/ + about: Before posting an issue, please ensure you read the documentation thoroughly diff --git a/.github/ISSUE_TEMPLATE/feature-request.yaml b/.github/ISSUE_TEMPLATE/feature-request.yaml index 7e042184f..a28faa540 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yaml +++ b/.github/ISSUE_TEMPLATE/feature-request.yaml @@ -8,11 +8,24 @@ body: value: " # Feature Request - Thanks for taking the time to let us know what you want to see! It helps us to improve the experience for you and other developers that may be facing a similar problem. Unfortunately, response times for feature requests are longer than bug reports, as they are lower priority. If you want this functionality implemented quickly, please make a Pull Request to go alongside this feature request. + Thanks for taking the time to let us know what you want to see! + Unfortunately, response times for feature requests are longer than bug reports, as they are lower priority. If you want this functionality implemented quickly, please make a Pull Request to go alongside this feature request. + + + --- + + + Before requesting a feature, please: + + * Check if there is already an open or closed issue that is similar to yours + + * Ensure that you're using the latest version of flutter_map + + * Ensure that you've read the documentation (both the website and API docs) thoroughly + + + --- " - - type: markdown - attributes: - value: --- - type: textarea id: description attributes: @@ -25,32 +38,14 @@ body: attributes: label: What other alternatives are available? description: Have you used any workarounds, for example? - - type: textarea - id: additional-info - attributes: - label: Can you provide any other information? - description: | - Please attach any other logs, screenshots, or screen recordings. - Is there anything else you'd like to say? - type: markdown attributes: value: --- - - type: dropdown - id: platform + - type: textarea + id: additional-info attributes: - label: Platforms Affected - description: What platforms does this issue affect? - multiple: true - options: - - Android - - iOS - - Web - - Windows - - MacOS - - Linux - - Other - validations: - required: true + label: Can you provide any other information? + description: Is there anything else you'd like to say? - type: dropdown id: severity attributes: @@ -62,18 +57,3 @@ body: - "Obtrusive: No workarounds are available, and this is essential to me" validations: required: true - - type: markdown - attributes: - value: --- - - type: checkboxes - id: terms - attributes: - label: Requirements - description: These are in place to prevent spam and unnecessary reports. - options: - - label: I agree to follow this project's [Code of Conduct](https://github.com/fleaflet/flutter_map/blob/master/CODE_OF_CONDUCT.md) - required: true - - label: I am using the [latest stable version](https://pub.dev/packages/flutter_map) of this package - required: true - - label: I have checked for similar feature requests which may be duplicates - required: true diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml deleted file mode 100644 index 5a66de71e..000000000 --- a/.github/workflows/flutter.yml +++ /dev/null @@ -1,119 +0,0 @@ -name: Analyse & Build -on: [push, workflow_dispatch] - -jobs: - package-analysis: - name: "Analyse Package" - runs-on: ubuntu-latest - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - name: Run Dart Package Analyser - uses: axel-op/dart-package-analyzer@v3 - id: analysis - with: - githubToken: ${{ secrets.GITHUB_TOKEN }} - - name: Check Package Scores - env: - TOTAL: ${{ steps.analysis.outputs.total }} - TOTAL_MAX: ${{ steps.analysis.outputs.total_max }} - run: | - if (( $TOTAL < $TOTAL_MAX )) - then - echo Package score less than available score. Improve the score! - exit 1 - fi - - content-analysis: - name: "Analyse Contents" - runs-on: ubuntu-latest - steps: - - name: Checkout Repository - uses: actions/checkout@v3 - - name: Setup Java 17 Environment - uses: actions/setup-java@v3 - with: - distribution: "temurin" - java-version: "17" - - name: Setup Flutter Environment - uses: subosito/flutter-action@v2 - with: - channel: "stable" - - name: Ensure Correct Flutter Installation - run: flutter --version - - name: Get All Dependencies - run: flutter pub get - - name: Check Formatting - run: dart format --output=none --set-exit-if-changed . - - name: Check Lints - run: dart analyze --fatal-infos --fatal-warnings - - name: Run Tests - run: flutter test -r expanded - - #check-example-changes: - # name: "Check Example Application For Changes" - # runs-on: "ubuntu-20.04" - # outputs: - # example_changed: ${{ steps.check_file_changed.outputs.example_changed }} - # steps: - # - name: Checkout Repository - # uses: actions/checkout@v3 - # with: - # fetch-depth: 2 - # - name: Compare Commit Diffs - # shell: pwsh - # id: check_file_changed - # run: | - # $diff = git diff --name-only HEAD^ HEAD - # $SourceDiff = $diff | Where-Object { $_ -match '^example/'} - # $HasDiff = $SourceDiff.Length -gt 0 - # Write-Host "::set-output name=example_changed::$HasDiff" - # - #build-example: - # name: "Build Example Applications" - # runs-on: windows-latest - # needs: [check-example-changes, content-analysis, package-analysis] - # if: needs.check-example-changes.outputs.example_changed == 'True' - # defaults: - # run: - # working-directory: ./example - # steps: - # - name: Checkout Repository - # uses: actions/checkout@v3 - # - name: Setup Java 17 Environment - # uses: actions/setup-java@v3 - # with: - # distribution: "temurin" - # java-version: "17" - # - name: Setup Flutter Environment - # uses: subosito/flutter-action@v2 - # with: - # channel: "stable" - # - name: Ensure Correct Flutter Installation - # run: flutter --version - # - name: Ensure Clean Flutter Environment - # run: flutter clean - # - name: Remove Existing Prebuilt Applications - # run: Remove-Item "prebuiltExampleApplications" -Recurse -ErrorAction Ignore - # working-directory: . - # - name: Create Prebuilt Applications (Output) Directory - # run: md prebuiltExampleApplications - # working-directory: . - # - name: Build Android Application - # run: flutter build apk --split-per-abi --obfuscate --split-debug-info=/symbols - # - name: Move Android Application To Output Directory - # run: move "example\build\app\outputs\flutter-apk\app-armeabi-v7a-release.apk" "prebuiltExampleApplications\AndroidApplication.apk" - # working-directory: . - # - name: Build Windows Application - # run: flutter build windows --obfuscate --split-debug-info=/symbols - # - name: Archive (ZIP) Windows Application To Output Directory - # uses: vimtor/action-zip@v1 - # with: - # files: ./example/build/windows/runner/Release - # dest: prebuiltExampleApplications/WindowsApplication.zip - # - name: Commit Output Directory - # uses: EndBug/add-and-commit@v9.0.1 - # with: - # message: "Built Example Applications" - # add: "prebuiltExampleApplications/" - # default_author: github_actions diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..362eaa629 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,138 @@ +name: Analyse, Test & Build +on: [push, pull_request, workflow_dispatch] + +jobs: + score-package: + name: "Score Package" + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Run Dart Package Analyser + uses: axel-op/dart-package-analyzer@v3 + id: analysis + with: + githubToken: ${{ secrets.GITHUB_TOKEN }} + - name: Check Package Scores + env: + TOTAL: ${{ steps.analysis.outputs.total }} + TOTAL_MAX: ${{ steps.analysis.outputs.total_max }} + run: | + if (( $TOTAL < $TOTAL_MAX )) + then + echo Package score less than available score. Improve the score! + exit 1 + fi + + analyse-code: + name: "Analyse Code" + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Setup Flutter Environment + uses: subosito/flutter-action@v2 + with: + channel: "stable" + - name: Get All Dependencies + run: flutter pub get + - name: Check Formatting + run: dart format --output=none --set-exit-if-changed . + - name: Check Lints + run: dart analyze --fatal-infos --fatal-warnings + + run-tests: + name: "Run Tests" + runs-on: ubuntu-latest + needs: analyse-code + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Setup Flutter Environment + uses: subosito/flutter-action@v2 + with: + channel: "stable" + - name: Run Tests + run: flutter test -r expanded + + build-web: + name: "Build Web Example App" + runs-on: ubuntu-latest + needs: run-tests + defaults: + run: + working-directory: ./example + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Setup Flutter Environment + uses: subosito/flutter-action@v2 + with: + channel: "stable" + - name: Build Web Application + run: flutter build web + - name: Archive Artifact + uses: actions/upload-artifact@v3.1.2 + with: + name: web-build + path: example/build/web + if-no-files-found: error + + build-android: + name: "Build Android Example App" + runs-on: ubuntu-latest + needs: run-tests + defaults: + run: + working-directory: ./example + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Setup Java 17 Environment + uses: actions/setup-java@v3 + with: + distribution: "temurin" + java-version: "17" + - name: Setup Flutter Environment + uses: subosito/flutter-action@v2 + with: + channel: "stable" + - name: Build Android Application + run: flutter build apk + - name: Archive Artifact + uses: actions/upload-artifact@v3.1.2 + with: + name: apk-build + path: example/build/app/outputs/apk/release + if-no-files-found: error + + build-windows: + name: "Build Windows Example App" + runs-on: windows-latest + needs: run-tests + defaults: + run: + working-directory: ./example + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + - name: Setup Java 17 Environment + uses: actions/setup-java@v3 + with: + distribution: "temurin" + java-version: "17" + - name: Setup Flutter Environment + uses: subosito/flutter-action@v2 + with: + channel: "stable" + - name: Build Windows Application + run: flutter build windows + - name: Create Windows Application Installer + run: iscc "windowsApplicationInstallerSetup.iss" + working-directory: . + - name: Archive Artifact + uses: actions/upload-artifact@v3.1.2 + with: + name: exe-build + path: windowsTemp/WindowsApplication.exe + if-no-files-found: error \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 49d9082be..b23ee280e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,24 +1,44 @@ # Changelog -## [3.2.0] - 2022/02/XX +## [4.0.0] - 2022/04/XX -Contains the following additions/removals: +**"Out With The Old, In With The New"** + +Contains the following improvements: +- Reimplemented `TileLayer` and underlying systems - [#1475](https://github.com/fleaflet/flutter_map/pull/1475) +- Reimplemented attribution layers - [#1487](https://github.com/fleaflet/flutter_map/pull/1487) & [#1390](https://github.com/fleaflet/flutter_map/pull/1390) +- Added secondary tap handling to `MapOptions` - [#1448](https://github.com/fleaflet/flutter_map/pull/1448) for [#1444](https://github.com/fleaflet/flutter_map/issues/1444) +- Refactored `FlutterMapState`'s `maybeOf` method into `maybeOf` & `of` - [#1495](https://github.com/fleaflet/flutter_map/pull/1495) - Removed `LatLngBounds.pad` (unused and broken) method - [#1427](https://github.com/fleaflet/flutter_map/pull/1427) -- Migrated `LatLngBounds` to proper null safety - [#1431](https://github.com/fleaflet/flutter_map/pull/1431) -- Minor example application improvements - [#1440](https://github.com/fleaflet/flutter_map/pull/1440) +- Removed `absorbPanEventsOnScrollables` option - [#1455](https://github.com/fleaflet/flutter_map/pull/1455) for [#1454](https://github.com/fleaflet/flutter_map/issues/1454) +- Removed leftover deprecations - [#1475](https://github.com/fleaflet/flutter_map/pull/1475) +- Improved rotation gestures (cause rotation about the gesture center) - [#1437](https://github.com/fleaflet/flutter_map/pull/1437) +- Improved number (`num`/`int`/`double`) consistency internally - [#1482](https://github.com/fleaflet/flutter_map/pull/1482) +- Minor example application improvements - [#1440](https://github.com/fleaflet/flutter_map/pull/1440) & [#1487](https://github.com/fleaflet/flutter_map/pull/1487) Contains the following bug fixes: -- Fixed deprecations - [#1438](https://github.com/fleaflet/flutter_map/pull/1438) +- Prevented scrolling of list and simultaneous panning of map on some platforms - [#1453](https://github.com/fleaflet/flutter_map/pull/1453) +- Improved `LatLngBounds`'s null safety situation to improve stability - [#1431](https://github.com/fleaflet/flutter_map/pull/1431) +- Migrated from multiple deprecated APIs - [#1438](https://github.com/fleaflet/flutter_map/pull/1438) + +Contains the following performance and stability improvements: + +- Batched polygon and polyline rendering to minimize redraws and maximize their efficiency - [#1442](https://github.com/fleaflet/flutter_map/pull/1442) & [#1462](https://github.com/fleaflet/flutter_map/pull/1462) +- Added a threshold for rasterization to avoid excessive fixed overhead cost for cheap redraws - [#1462](https://github.com/fleaflet/flutter_map/pull/1462) Many thanks to these contributors (in no particular order): - @pablojimpas - @augustweinbren - @ignatz +- @rorystephenson +- @ianthetechie - ... and all the maintainers +And an additional special thanks to @rorystephenson & @ignatz for investing so much of their time into this project recently - we appreciate it! + ## [3.1.0] - 2022/12/21 Contains the following additions/removals: @@ -51,6 +71,8 @@ Many thanks to these contributors (in no particular order): ## [3.0.0] - 2022/09/04 +**"Boiler(plate) Repairs"** + Contains the following additions/removals: - Multiple changes - [#1333](https://github.com/fleaflet/flutter_map/pull/1333) @@ -146,6 +168,8 @@ Many thanks to these contributors (in no particular order): ## [2.0.0] - 2022/07/11 +**"~~Blocked By OSM~~"** + Contains the following additions/removals: - Added adjustable mouse wheel zoom speed - [#1289](https://github.com/fleaflet/flutter_map/pull/1289) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index b79bef70c..000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,7 +0,0 @@ -# Contributing - -*Please note: A code of conduct is present in this project, please follow it in all your interactions with this project, including contributions.* - -Read the contributing instructions on the documentation website: . - -We always appreciate your ideas and changes! diff --git a/LICENSE b/LICENSE index 7acb4398a..760dc4f77 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -Copyright (c) 2020, the flutter_map authors -Copyright (c) 2010-2019, Vladimir Agafonkin -Copyright (c) 2010-2011, CloudMade +Copyright (c) 2018-2023, the 'flutter_map' authors and maintainers +Loosely based on the original works of 'leaflet.js' (c) by Vladimir Agafonkin & CloudMade + All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/example/.gitignore b/example/.gitignore index 5141725b7..ca799e1b1 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -30,11 +30,14 @@ .pub-cache/ .pub/ /build/ + +# Gets generated when running the app and we don't need anything special in the +# Podfile so we can ignore it and let flutter generate it. +ios/Podfile # TODO: document why we don't want this file pubspec.lock # Web related -lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 43e428b5d..145f610b0 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -13,12 +13,12 @@ if (flutterRoot == null) { def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { - flutterVersionCode = '1' + flutterVersionCode = '4' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { - flutterVersionName = '1.0' + flutterVersionName = '4.0.0' } apply plugin: 'com.android.application' @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 31 + compileSdkVersion 33 sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/example/assets/ProjectIcon.ico b/example/assets/ProjectIcon.ico new file mode 100644 index 000000000..07baf3221 Binary files /dev/null and b/example/assets/ProjectIcon.ico differ diff --git a/example/assets/ProjectIcon.png b/example/assets/ProjectIcon.png new file mode 100644 index 000000000..8603d0a3d Binary files /dev/null and b/example/assets/ProjectIcon.png differ diff --git a/example/lib/main.dart b/example/lib/main.dart index 59cc99095..6c7ed31d8 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -46,7 +46,7 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - title: 'Flutter Map Example', + title: 'flutter_map Demo', theme: ThemeData.light(useMaterial3: true), home: const HomePage(), routes: { diff --git a/example/lib/pages/animated_map_controller.dart b/example/lib/pages/animated_map_controller.dart index 4dbdce2c5..b33592f17 100644 --- a/example/lib/pages/animated_map_controller.dart +++ b/example/lib/pages/animated_map_controller.dart @@ -16,15 +16,9 @@ class AnimatedMapControllerPage extends StatefulWidget { class AnimatedMapControllerPageState extends State with TickerProviderStateMixin { - // Note the addition of the TickerProviderStateMixin here. If you are getting an error like - // 'The class 'TickerProviderStateMixin' can't be used as a mixin because it extends a class other than Object.' - // in your IDE, you can probably fix it by adding an analysis_options.yaml file to your project - // with the following content: - // analyzer: - // language: - // enableSuperMixins: true - // See https://github.com/flutter/flutter/issues/14317#issuecomment-361085869 - // This project didn't require that change, so YMMV. + static const _startedId = 'AnimatedMapController#MoveStarted'; + static const _inProgressId = 'AnimatedMapController#MoveInProgress'; + static const _finishedId = 'AnimatedMapController#MoveFinished'; static final london = LatLng(51.5, -0.09); static final paris = LatLng(48.8566, 2.3522); @@ -55,10 +49,29 @@ class AnimatedMapControllerPageState extends State final Animation animation = CurvedAnimation(parent: controller, curve: Curves.fastOutSlowIn); + // Note this method of encoding the target destination is a workaround. + // When proper animated movement is supported (see #1263) we should be able + // to detect an appropriate animated movement event which contains the + // target zoom/center. + final startIdWithTarget = + '$_startedId#${destLocation.latitude},${destLocation.longitude},$destZoom'; + bool hasTriggeredMove = false; + controller.addListener(() { - mapController.move( - LatLng(latTween.evaluate(animation), lngTween.evaluate(animation)), - zoomTween.evaluate(animation)); + final String id; + if (animation.value == 1.0) { + id = _finishedId; + } else if (!hasTriggeredMove) { + id = startIdWithTarget; + } else { + id = _inProgressId; + } + + hasTriggeredMove |= mapController.move( + LatLng(latTween.evaluate(animation), lngTween.evaluate(animation)), + zoomTween.evaluate(animation), + id: id, + ); }); animation.addStatusListener((status) { @@ -187,6 +200,7 @@ class AnimatedMapControllerPageState extends State urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', userAgentPackageName: 'dev.fleaflet.flutter_map.example', + tileUpdateTransformer: _animatedMoveTileUpdateTransformer, ), MarkerLayer(markers: markers), ], @@ -198,3 +212,39 @@ class AnimatedMapControllerPageState extends State ); } } + +/// Causes tiles to be prefetched at the target location and disables pruning +/// whilst animating movement. When proper animated movement is added (see +/// #1263) we should just detect the appropriate AnimatedMove events and +/// use their target zoom/center. +final _animatedMoveTileUpdateTransformer = + TileUpdateTransformer.fromHandlers(handleData: (updateEvent, sink) { + final mapEvent = updateEvent.mapEvent; + + final id = mapEvent is MapEventMove ? mapEvent.id : null; + if (id?.startsWith(AnimatedMapControllerPageState._startedId) == true) { + final parts = id!.split('#')[2].split(','); + final lat = double.parse(parts[0]); + final lon = double.parse(parts[1]); + final zoom = double.parse(parts[2]); + + // When animated movement starts load tiles at the target location and do + // not prune. Disabling pruning means existing tiles will remain visible + // whilst animating. + sink.add( + updateEvent.loadOnly( + loadCenterOverride: LatLng(lat, lon), + loadZoomOverride: zoom, + ), + ); + } else if (id == AnimatedMapControllerPageState._inProgressId) { + // Do not prune or load whilst animating so that any existing tiles remain + // visible. A smarter implementation may start pruning once we are close to + // the target zoom/location. + } else if (id == AnimatedMapControllerPageState._finishedId) { + // We already prefetched the tiles when animation started so just prune. + sink.add(updateEvent.pruneOnly()); + } else { + sink.add(updateEvent); + } +}); diff --git a/example/lib/pages/custom_crs/custom_crs.dart b/example/lib/pages/custom_crs/custom_crs.dart index 6d50c37d7..14596d7e9 100644 --- a/example/lib/pages/custom_crs/custom_crs.dart +++ b/example/lib/pages/custom_crs/custom_crs.dart @@ -154,17 +154,19 @@ class _CustomCrsPageState extends State { ), ], children: [ - TileLayer( + Opacity( opacity: 1, - backgroundColor: Colors.transparent, - wmsOptions: WMSTileLayerOptions( - // Set the WMS layer's CRS - crs: epsg3413CRS, - transparent: true, - format: 'image/jpeg', - baseUrl: - 'https://www.gebco.net/data_and_products/gebco_web_services/north_polar_view_wms/mapserv?', - layers: ['gebco_north_polar_view'], + child: TileLayer( + backgroundColor: Colors.transparent, + wmsOptions: WMSTileLayerOptions( + // Set the WMS layer's CRS + crs: epsg3413CRS, + transparent: true, + format: 'image/jpeg', + baseUrl: + 'https://www.gebco.net/data_and_products/gebco_web_services/north_polar_view_wms/mapserv?', + layers: ['gebco_north_polar_view'], + ), ), ), ], diff --git a/example/lib/pages/epsg3413_crs.dart b/example/lib/pages/epsg3413_crs.dart index 64b49f686..75b591601 100644 --- a/example/lib/pages/epsg3413_crs.dart +++ b/example/lib/pages/epsg3413_crs.dart @@ -150,16 +150,18 @@ class _EPSG3413PageState extends State { ), ], children: [ - TileLayer( + Opacity( opacity: 1, - backgroundColor: Colors.transparent, - wmsOptions: WMSTileLayerOptions( - crs: epsg3413CRS, - transparent: true, - format: 'image/jpeg', - baseUrl: - 'https://www.gebco.net/data_and_products/gebco_web_services/north_polar_view_wms/mapserv?', - layers: ['gebco_north_polar_view'], + child: TileLayer( + backgroundColor: Colors.transparent, + wmsOptions: WMSTileLayerOptions( + crs: epsg3413CRS, + transparent: true, + format: 'image/jpeg', + baseUrl: + 'https://www.gebco.net/data_and_products/gebco_web_services/north_polar_view_wms/mapserv?', + layers: ['gebco_north_polar_view'], + ), ), ), OverlayImageLayer( diff --git a/example/lib/pages/map_inside_listview.dart b/example/lib/pages/map_inside_listview.dart index 5eccb3c28..dd8c32624 100644 --- a/example/lib/pages/map_inside_listview.dart +++ b/example/lib/pages/map_inside_listview.dart @@ -26,13 +26,8 @@ class MapInsideListViewPage extends StatelessWidget { center: LatLng(51.5, -0.09), zoom: 5, ), - children: [ - TileLayer( - urlTemplate: - 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', - userAgentPackageName: 'dev.fleaflet.flutter_map.example', - ), - const FlutterMapZoomButtons( + nonRotatedChildren: const [ + FlutterMapZoomButtons( minZoom: 4, maxZoom: 19, mini: true, @@ -40,6 +35,13 @@ class MapInsideListViewPage extends StatelessWidget { alignment: Alignment.bottomLeft, ), ], + children: [ + TileLayer( + urlTemplate: + 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', + userAgentPackageName: 'dev.fleaflet.flutter_map.example', + ), + ], ), ), const Card( diff --git a/example/lib/pages/tile_builder_example.dart b/example/lib/pages/tile_builder_example.dart index 16a52e04d..d32081149 100644 --- a/example/lib/pages/tile_builder_example.dart +++ b/example/lib/pages/tile_builder_example.dart @@ -15,13 +15,13 @@ class TileBuilderPage extends StatefulWidget { class _TileBuilderPageState extends State { bool darkMode = false; bool loadingTime = false; - bool showCoords = false; + bool showCoordinates = false; bool grid = false; int panBuffer = 0; // mix of [coordinateDebugTileBuilder] and [loadingTimeDebugTileBuilder] from tile_builder.dart - Widget tileBuilder(BuildContext context, Widget tileWidget, Tile tile) { - final coords = tile.coords; + Widget tileBuilder(BuildContext context, Widget tileWidget, TileImage tile) { + final coords = tile.coordinates; return Container( decoration: BoxDecoration( @@ -31,21 +31,21 @@ class _TileBuilderPageState extends State { fit: StackFit.passthrough, children: [ tileWidget, - if (loadingTime || showCoords) + if (loadingTime || showCoordinates) Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - if (showCoords) + if (showCoordinates) Text( '${coords.x.floor()} : ${coords.y.floor()} : ${coords.z.floor()}', style: Theme.of(context).textTheme.headlineSmall, ), if (loadingTime) Text( - tile.loaded == null + tile.loadFinishedAt == null ? 'Loading' // sometimes result is negative which shouldn't happen, abs() corrects it - : '${(tile.loaded!.millisecond - tile.loadStarted.millisecond).abs()} ms', + : '${(tile.loadFinishedAt!.millisecond - tile.loadStarted!.millisecond).abs()} ms', style: Theme.of(context).textTheme.headlineSmall, ), ], @@ -77,11 +77,11 @@ class _TileBuilderPageState extends State { FloatingActionButton.extended( heroTag: 'coords', label: Text( - showCoords ? 'Hide coords' : 'Show coords', + showCoordinates ? 'Hide coords' : 'Show coords', textAlign: TextAlign.center, ), - icon: Icon(showCoords ? Icons.unarchive : Icons.bug_report), - onPressed: () => setState(() => showCoords = !showCoords), + icon: Icon(showCoordinates ? Icons.unarchive : Icons.bug_report), + onPressed: () => setState(() => showCoordinates = !showCoordinates), ), const SizedBox(height: 8), FloatingActionButton.extended( @@ -125,13 +125,13 @@ class _TileBuilderPageState extends State { zoom: 5, ), children: [ - TileLayer( - urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', - userAgentPackageName: 'dev.fleaflet.flutter_map.example', - tileBuilder: tileBuilder, - tilesContainerBuilder: - darkMode ? darkModeTilesContainerBuilder : null, - panBuffer: panBuffer, + _darkModeContainerIfEnabled( + TileLayer( + urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', + userAgentPackageName: 'dev.fleaflet.flutter_map.example', + tileBuilder: tileBuilder, + panBuffer: panBuffer, + ), ), MarkerLayer( markers: [ @@ -150,4 +150,10 @@ class _TileBuilderPageState extends State { ), ); } + + Widget _darkModeContainerIfEnabled(Widget child) { + if (!darkMode) return child; + + return darkModeTilesContainerBuilder(context, child); + } } diff --git a/example/lib/pages/tile_loading_error_handle.dart b/example/lib/pages/tile_loading_error_handle.dart index 5aa3da8d0..502d12ff8 100644 --- a/example/lib/pages/tile_loading_error_handle.dart +++ b/example/lib/pages/tile_loading_error_handle.dart @@ -47,7 +47,7 @@ class _TileLoadingErrorHandleState extends State { // TileProvider with a caching and retry strategy, like // NetworkTileProvider or CachedNetworkTileProvider userAgentPackageName: 'dev.fleaflet.flutter_map.example', - errorTileCallback: (Tile tile, error) { + errorTileCallback: (tile, error, stackTrace) { if (needLoadingError) { WidgetsBinding.instance.addPostFrameCallback((_) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( diff --git a/example/lib/widgets/drawer.dart b/example/lib/widgets/drawer.dart index 4769aa3e2..35eb43efa 100644 --- a/example/lib/widgets/drawer.dart +++ b/example/lib/widgets/drawer.dart @@ -58,9 +58,25 @@ Drawer buildDrawer(BuildContext context, String currentRoute) { return Drawer( child: ListView( children: [ - const DrawerHeader( - child: Center( - child: Text('Flutter Map Examples'), + DrawerHeader( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/ProjectIcon.png', + height: 48, + ), + const SizedBox(height: 16), + const Text( + 'flutter_map Demo', + style: TextStyle(fontWeight: FontWeight.bold), + ), + const Text( + '© flutter_map Authors & Contributors', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 14), + ), + ], ), ), _buildMenuItem( diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index 6b401e500..d151654e4 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,9 @@ import FlutterMacOS import Foundation import location +import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index e389f291b..9234876f7 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_map_example description: Example application for 'flutter_map' package publish_to: "none" -version: 1.0.0 +version: 4.0.0 environment: sdk: ">=2.18.0 <3.0.0" @@ -61,3 +61,4 @@ flutter: - assets/map/anholt_osmbright/14/8726/ - assets/map/anholt_osmbright/14/8727/ - assets/map/epsg3413/amsr2.png + - assets/ diff --git a/example/web/favicon.png b/example/web/favicon.png index 8aaa46ac1..8603d0a3d 100644 Binary files a/example/web/favicon.png and b/example/web/favicon.png differ diff --git a/example/web/icons/Icon-192.png b/example/web/icons/Icon-192.png index b749bfef0..f9f76fc57 100644 Binary files a/example/web/icons/Icon-192.png and b/example/web/icons/Icon-192.png differ diff --git a/example/web/icons/Icon-512.png b/example/web/icons/Icon-512.png index 88cfd48df..9d38f6e4a 100644 Binary files a/example/web/icons/Icon-512.png and b/example/web/icons/Icon-512.png differ diff --git a/example/web/icons/Icon-maskable-192.png b/example/web/icons/Icon-maskable-192.png index eb9b4d76e..f9f76fc57 100644 Binary files a/example/web/icons/Icon-maskable-192.png and b/example/web/icons/Icon-maskable-192.png differ diff --git a/example/web/icons/Icon-maskable-512.png b/example/web/icons/Icon-maskable-512.png index d69c56691..9d38f6e4a 100644 Binary files a/example/web/icons/Icon-maskable-512.png and b/example/web/icons/Icon-maskable-512.png differ diff --git a/example/web/index.html b/example/web/index.html index 6cbe5dff0..74938b05c 100644 --- a/example/web/index.html +++ b/example/web/index.html @@ -19,18 +19,19 @@ - + - + - flutter_map Example + flutter_map Demo