diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d57519cd..cb50845bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,17 @@ Please consider [donating](https://docs.fleaflet.dev/supporters#support-us) or [ This CHANGELOG does not include every commit and/or PR - it is a hand picked selection of the ones that have an effect on you. For a full list of changes, please check the GitHub repository releases/tags. -## [8.1.0] - 2025/02/XX +## [8.1.1] - 2025/03/08 + +Contains the following user-affecting bug fixes: + +- Prevent infinite looping when polygon labels displayed on rotated map - [#2054](https://github.com/fleaflet/flutter_map/pull/2054) for [#2052](https://github.com/fleaflet/flutter_map/issues/2052) + +Many thanks to these contributors (in no particular order): + +- @monsieurtanuki + +## [8.1.0] - 2025/02/25 Contains the following user-affecting changes: @@ -12,8 +22,8 @@ Contains the following user-affecting changes: Contains the following user-affecting bug fixes: -- Ensure movement gestures emit events when starting - [#2035](https://github.com/fleaflet/flutter_map/pull/2035) -- Ensure `MapController.rotateAroundPoint` does not move map when already rotated - [#2029](https://github.com/fleaflet/flutter_map/pull/2029) +- Ensure movement gestures emit events when starting - [#2035](https://github.com/fleaflet/flutter_map/pull/2035) for [#1939](https://github.com/fleaflet/flutter_map/issues/1939) +- Ensure `MapController.rotateAroundPoint` does not move map when already rotated - [#2029](https://github.com/fleaflet/flutter_map/pull/2029) for [#2028](https://github.com/fleaflet/flutter_map/issues/2028) Many thanks to these contributors (in no particular order): diff --git a/example/pubspec.yaml b/example/pubspec.yaml index b8c2d1d4a..1e79a8509 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: 8.1.0 +version: 8.1.1 environment: sdk: ">=3.6.0 <4.0.0" diff --git a/lib/src/layer/polygon_layer/label.dart b/lib/src/layer/polygon_layer/label.dart index ee0ba04c7..e3de7d4fd 100644 --- a/lib/src/layer/polygon_layer/label.dart +++ b/lib/src/layer/polygon_layer/label.dart @@ -17,13 +17,26 @@ void Function(Canvas canvas)? _buildLabelTextPainter({ // Cull labels where the polygon is still on the map but the label would not be. // Currently this is only enabled when the map isn't rotated, since the placementOffset // is relative to the MobileLayerTransformer rather than in actual screen coordinates. + final double textWidth; + final double textHeight; + final double mapWidth; + final double mapHeight; if (rotationRad == 0) { - if (dx + width / 2 < 0 || dx - width / 2 > mapSize.width) { - return null; - } - if (dy + height / 2 < 0 || dy - height / 2 > mapSize.height) { - return null; - } + textWidth = width; + textHeight = height; + mapWidth = mapSize.width; + mapHeight = mapSize.height; + } else { + // lazily we imagine the worst case scenario regarding sizes, instead of + // computing the angles + textWidth = textHeight = max(width, height); + mapWidth = mapHeight = max(mapSize.width, mapSize.height); + } + if (dx + textWidth / 2 < 0 || dx - textWidth / 2 > mapWidth) { + return null; + } + if (dy + textHeight / 2 < 0 || dy - textHeight / 2 > mapHeight) { + return null; } // Note: I'm pretty sure this doesn't work for concave shapes. It would be more diff --git a/lib/src/layer/shared/feature_layer_utils.dart b/lib/src/layer/shared/feature_layer_utils.dart index 789e9969f..42c882c72 100644 --- a/lib/src/layer/shared/feature_layer_utils.dart +++ b/lib/src/layer/shared/feature_layer_utils.dart @@ -54,13 +54,26 @@ mixin FeatureLayerUtils on CustomPainter { /// Internally, the worker is invoked in the 'negative' worlds (worlds to the /// left of the 'primary' world) until repetition is stopped, then in the /// 'positive' worlds: <--||-->. - bool workAcrossWorlds(WorldWorkControl Function(double shift) work) { + bool workAcrossWorlds( + WorldWorkControl Function(double shift) work, + ) { + // Protection in case of unexpected infinite loop if `work` never returns + // `invisible`. e.g. https://github.com/fleaflet/flutter_map/issues/2052. + const maxShiftsCount = 10; + int shiftsCount = 0; + + void protectInfiniteLoop() { + if (++shiftsCount > maxShiftsCount) throw const StackOverflowError(); + } + + protectInfiniteLoop(); if (work(0) == WorldWorkControl.hit) return true; if (worldWidth == 0) return false; negativeWorldsLoop: for (double shift = -worldWidth;; shift -= worldWidth) { + protectInfiniteLoop(); switch (work(shift)) { case WorldWorkControl.hit: return true; @@ -71,6 +84,7 @@ mixin FeatureLayerUtils on CustomPainter { } for (double shift = worldWidth;; shift += worldWidth) { + protectInfiniteLoop(); switch (work(shift)) { case WorldWorkControl.hit: return true; diff --git a/pubspec.yaml b/pubspec.yaml index b9a200c0d..65019902f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_map description: A versatile mapping package for Flutter, that's simple and easy to learn, yet completely customizable and configurable -version: 8.1.0 +version: 8.1.1 repository: https://github.com/fleaflet/flutter_map issue_tracker: https://github.com/fleaflet/flutter_map/issues diff --git a/windowsApplicationInstallerSetup.iss b/windowsApplicationInstallerSetup.iss index bcd43743d..2ddb822ed 100644 --- a/windowsApplicationInstallerSetup.iss +++ b/windowsApplicationInstallerSetup.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "flutter_map Demo" -#define MyAppVersion "for 8.1.0" +#define MyAppVersion "for 8.1.1" #define MyAppPublisher "fleaflet" #define MyAppURL "https://github.com/fleaflet/flutter_map" #define MyAppSupportURL "https://github.com/fleaflet/flutter_map/issues"