From a1e186c83c9f8e54e40598b68515b2b774405ccd Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Sun, 22 Sep 2024 18:51:44 +0200 Subject: [PATCH 1/8] fix: 1338 - longitude +-180 with correct polylines and polygons Impacted files * `crs.dart`: new methods `getHalfWorldWidth` and `projectList` * `painter.dart`: refactored using pre-computed `List` * `polygon.dart`: added an example around longitude 180 * `polyline.dart`: added an example around longitude 180 * `polyline_layer.dart`: we don't cull polylines that go beyond longitude 180 * `projected_polygon.dart`: using new method `Projection.projectList` * `projected_polyline.dart`: using new method `Projection.projectList` --- example/lib/pages/polygon.dart | 29 +++++++++ example/lib/pages/polyline.dart | 17 ++++++ lib/src/geo/crs.dart | 40 ++++++++++++ lib/src/layer/polygon_layer/painter.dart | 61 +++++++------------ .../polygon_layer/projected_polygon.dart | 25 ++------ .../layer/polyline_layer/polyline_layer.dart | 8 +++ .../polyline_layer/projected_polyline.dart | 19 +++--- 7 files changed, 134 insertions(+), 65 deletions(-) diff --git a/example/lib/pages/polygon.dart b/example/lib/pages/polygon.dart index 1489e49a1..98d50b3e4 100644 --- a/example/lib/pages/polygon.dart +++ b/example/lib/pages/polygon.dart @@ -328,6 +328,35 @@ class _PolygonPageState extends State { simplificationTolerance: 0, useAltRendering: true, polygons: [ + Polygon( + points: const [ + LatLng(40, 150), + LatLng(45, 160), + LatLng(50, 170), + LatLng(55, 180), + LatLng(50, -170), + LatLng(45, -160), + LatLng(40, -150), + LatLng(35, -160), + LatLng(30, -170), + LatLng(25, -180), + LatLng(30, 170), + LatLng(35, 160), + ], + holePointsList: const [ + [ + LatLng(45, 175), + LatLng(45, -175), + LatLng(35, -175), + LatLng(35, 175), + ], + ], + color: const Color(0xFFFF0000), + hitValue: ( + title: 'Red Line', + subtitle: 'Across the universe...', + ), + ), Polygon( points: const [ LatLng(50, -18), diff --git a/example/lib/pages/polyline.dart b/example/lib/pages/polyline.dart index 60ef904a8..499481017 100644 --- a/example/lib/pages/polyline.dart +++ b/example/lib/pages/polyline.dart @@ -22,6 +22,23 @@ class _PolylinePageState extends State { List>? _hoverLines; final _polylinesRaw = >[ + Polyline( + points: const [ + LatLng(40, 150), + LatLng(45, 160), + LatLng(50, 170), + LatLng(55, 180), + LatLng(50, -170), + LatLng(45, -160), + LatLng(40, -150), + ], + strokeWidth: 8, + color: const Color(0xFFFF0000), + hitValue: ( + title: 'Red Line', + subtitle: 'Across the universe...', + ), + ), Polyline( points: [ const LatLng(51.5, -0.09), diff --git a/lib/src/geo/crs.dart b/lib/src/geo/crs.dart index 63b5e1936..c8ea74bf1 100644 --- a/lib/src/geo/crs.dart +++ b/lib/src/geo/crs.dart @@ -2,6 +2,7 @@ import 'dart:math' as math hide Point; import 'dart:math' show Point; import 'package:flutter_map/src/misc/bounds.dart'; +import 'package:flutter_map/src/misc/simplify.dart'; import 'package:latlong2/latlong.dart'; import 'package:meta/meta.dart'; import 'package:proj4dart/proj4dart.dart' as proj4; @@ -388,6 +389,45 @@ abstract class Projection { /// unproject cartesian x,y coordinates to [LatLng]. LatLng unprojectXY(double x, double y); + + /// Returns half the width of the world in geometry coordinates. + double getHalfWorldWidth() { + final (x0, _) = projectXY(const LatLng(0, 0)); + final (x180, _) = projectXY(const LatLng(0, 180)); + return x0 > x180 ? x0 - x180 : x180 - x0; + } + + /// Projects a list of [LatLng]s into geometry coordinates. + /// + /// All resulting points gather somehow around the first point, or the + /// optional [referencePoint] if provided. + /// The typical use-case is when you display the whole world: you don't want + /// longitudes -179 and 179 to be projected each on one side. + /// [referencePoint] is used for polygon holes: we want the holes to be + /// displayed close to the polygon, not on the other side of the world. + List projectList(List points, {LatLng? referencePoint}) { + late double previousX; + final halfWorldWith = getHalfWorldWidth(); + return List.generate( + points.length, + (j) { + if (j == 0 && referencePoint != null) { + (previousX, _) = projectXY(referencePoint); + } + var (x, y) = projectXY(points[j]); + if (j > 0 || referencePoint != null) { + if (x - previousX > halfWorldWith) { + x -= 2 * halfWorldWith; + } else if (x - previousX < -halfWorldWith) { + x += 2 * halfWorldWith; + } + } + previousX = x; + return DoublePoint(x, y); + }, + growable: false, + ); + } } class _LonLat extends Projection { diff --git a/lib/src/layer/polygon_layer/painter.dart b/lib/src/layer/polygon_layer/painter.dart index 44aff4b8b..91ed21a74 100644 --- a/lib/src/layer/polygon_layer/painter.dart +++ b/lib/src/layer/polygon_layer/painter.dart @@ -286,13 +286,12 @@ base class _PolygonPainter // and the normal points are the same filledPath.fillType = PathFillType.evenOdd; - final holeOffsetsList = List>.generate( - holePointsList.length, - (i) => getOffsets(camera, origin, holePointsList[i]), - growable: false, - ); - - for (final holeOffsets in holeOffsetsList) { + for (final singleHolePoints in projectedPolygon.holePoints) { + final holeOffsets = getOffsetsXY( + camera: camera, + origin: origin, + points: singleHolePoints, + ); filledPath.addPolygon(holeOffsets, true); // TODO: Potentially more efficient and may change the need to do @@ -307,15 +306,23 @@ base class _PolygonPainter } if (!polygon.disableHolesBorder && polygon.borderStrokeWidth > 0.0) { - _addHoleBordersToPath( - borderPath, - polygon, - holeOffsetsList, - size, - canvas, - _getBorderPaint(polygon), - polygon.borderStrokeWidth, - ); + final borderPaint = _getBorderPaint(polygon); + for (final singleHolePoints in projectedPolygon.holePoints) { + final holeOffsets = getOffsetsXY( + camera: camera, + origin: origin, + points: singleHolePoints, + ); + _addBorderToPath( + borderPath, + polygon, + holeOffsets, + size, + canvas, + borderPaint, + polygon.borderStrokeWidth, + ); + } } } @@ -434,28 +441,6 @@ base class _PolygonPainter } } - void _addHoleBordersToPath( - Path path, - Polygon polygon, - List> holeOffsetsList, - Size canvasSize, - Canvas canvas, - Paint paint, - double strokeWidth, - ) { - for (final offsets in holeOffsetsList) { - _addBorderToPath( - path, - polygon, - offsets, - canvasSize, - canvas, - paint, - strokeWidth, - ); - } - } - ({Offset min, Offset max}) _getBounds(Offset origin, Polygon polygon) { final bBox = polygon.boundingBox; return ( diff --git a/lib/src/layer/polygon_layer/projected_polygon.dart b/lib/src/layer/polygon_layer/projected_polygon.dart index 1c25ef0f5..af18c74be 100644 --- a/lib/src/layer/polygon_layer/projected_polygon.dart +++ b/lib/src/layer/polygon_layer/projected_polygon.dart @@ -18,35 +18,22 @@ class _ProjectedPolygon with HitDetectableElement { _ProjectedPolygon._fromPolygon(Projection projection, Polygon polygon) : this._( polygon: polygon, - points: List.generate( - polygon.points.length, - (j) { - final (x, y) = projection.projectXY(polygon.points[j]); - return DoublePoint(x, y); - }, - growable: false, - ), + points: projection.projectList(polygon.points), holePoints: () { final holes = polygon.holePointsList; if (holes == null || holes.isEmpty || + polygon.points.isEmpty || holes.every((e) => e.isEmpty)) { return >[]; } return List>.generate( holes.length, - (j) { - final points = holes[j]; - return List.generate( - points.length, - (k) { - final (x, y) = projection.projectXY(points[k]); - return DoublePoint(x, y); - }, - growable: false, - ); - }, + (j) => projection.projectList( + holes[j], + referencePoint: polygon.points[0], + ), growable: false, ); }(), diff --git a/lib/src/layer/polyline_layer/polyline_layer.dart b/lib/src/layer/polyline_layer/polyline_layer.dart index 47da085ff..1741f6e2e 100644 --- a/lib/src/layer/polyline_layer/polyline_layer.dart +++ b/lib/src/layer/polyline_layer/polyline_layer.dart @@ -140,6 +140,8 @@ class _PolylineLayerState extends State> projection.project(boundsAdjusted.northEast), ); + final halfWorldWidth = projection.getHalfWorldWidth(); + for (final projectedPolyline in polylines) { final polyline = projectedPolyline.polyline; @@ -149,6 +151,12 @@ class _PolylineLayerState extends State> continue; } + // TODO: think about how to cull polylines that go beyond the universe. + if (projectedPolyline.goesBeyondTheUniverse(halfWorldWidth)) { + yield projectedPolyline; + continue; + } + // pointer that indicates the start of the visible polyline segment int start = -1; bool containsSegment = false; diff --git a/lib/src/layer/polyline_layer/projected_polyline.dart b/lib/src/layer/polyline_layer/projected_polyline.dart index eca98465a..feb05bbe1 100644 --- a/lib/src/layer/polyline_layer/projected_polyline.dart +++ b/lib/src/layer/polyline_layer/projected_polyline.dart @@ -16,13 +16,16 @@ class _ProjectedPolyline with HitDetectableElement { _ProjectedPolyline._fromPolyline(Projection projection, Polyline polyline) : this._( polyline: polyline, - points: List.generate( - polyline.points.length, - (j) { - final (x, y) = projection.projectXY(polyline.points[j]); - return DoublePoint(x, y); - }, - growable: false, - ), + points: projection.projectList(polyline.points), ); + + /// Returns true if the points stretch on different versions of the world. + bool goesBeyondTheUniverse(double halfWorldWidth) { + for (final point in points) { + if (point.x > halfWorldWidth || point.x < -halfWorldWidth) { + return true; + } + } + return false; + } } From ae9a22d1fdbc25f341d7d1bfdcdb501a5863a8be Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Sun, 22 Sep 2024 19:07:56 +0200 Subject: [PATCH 2/8] Typo fix. --- lib/src/geo/crs.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/geo/crs.dart b/lib/src/geo/crs.dart index c8ea74bf1..d72596444 100644 --- a/lib/src/geo/crs.dart +++ b/lib/src/geo/crs.dart @@ -407,7 +407,7 @@ abstract class Projection { /// displayed close to the polygon, not on the other side of the world. List projectList(List points, {LatLng? referencePoint}) { late double previousX; - final halfWorldWith = getHalfWorldWidth(); + final halfWorldWidth = getHalfWorldWidth(); return List.generate( points.length, (j) { @@ -416,10 +416,10 @@ abstract class Projection { } var (x, y) = projectXY(points[j]); if (j > 0 || referencePoint != null) { - if (x - previousX > halfWorldWith) { - x -= 2 * halfWorldWith; - } else if (x - previousX < -halfWorldWith) { - x += 2 * halfWorldWith; + if (x - previousX > halfWorldWidth) { + x -= 2 * halfWorldWidth; + } else if (x - previousX < -halfWorldWidth) { + x += 2 * halfWorldWidth; } } previousX = x; From f1c1e31ab9bb9086c8b98917e324ca5b5834be26 Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Fri, 27 Sep 2024 14:59:21 +0200 Subject: [PATCH 3/8] fix: always display at least one instance of the polyline/polygon Impacted files: * `offsets.dart`: new method `getAddedWorldWidth`, used to add/subtract a world width in order to display visible polylines * `painter.dart`: minor fix, as now we may unproject coordinates from the wrong world --- lib/src/layer/polyline_layer/painter.dart | 5 +++- lib/src/misc/offsets.dart | 32 +++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/src/layer/polyline_layer/painter.dart b/lib/src/layer/polyline_layer/painter.dart index 1f60aee39..0a7f21def 100644 --- a/lib/src/layer/polyline_layer/painter.dart +++ b/lib/src/layer/polyline_layer/painter.dart @@ -274,7 +274,10 @@ base class _PolylinePainter double strokeWidthInMeters, ) { final r = _distance.offset(p0, strokeWidthInMeters, 180); - final delta = o0 - getOffset(camera, origin, r); + var delta = o0 - getOffset(camera, origin, r); + if (delta.dx < 0) { + delta = delta.translate(camera.crs.scale(camera.zoom), 0); + } return delta.distance; } diff --git a/lib/src/misc/offsets.dart b/lib/src/misc/offsets.dart index c22c216de..e6c08c8b7 100644 --- a/lib/src/misc/offsets.dart +++ b/lib/src/misc/offsets.dart @@ -60,13 +60,41 @@ List getOffsetsXY({ final oy = -origin.dy; final len = realPoints.length; + /// Returns additional world width in order to have visible points. + double getAddedWorldWidth() { + final List addedWidths = [ + 0, + 2 * crs.projection.getHalfWorldWidth(), + -2 * crs.projection.getHalfWorldWidth(), + ]; + final p = realPoints.elementAt(0); + late double result; + late double bestX; + for (int i = 0; i < addedWidths.length; i++) { + final addedWidth = addedWidths[i]; + final (x, _) = crs.transform(p.x + addedWidth, p.y, zoomScale); + if (i == 0) { + result = addedWidth; + bestX = x; + continue; + } + if ((bestX + ox).abs() > (x + ox).abs()) { + result = addedWidth; + bestX = x; + } + } + return result; + } + + final double addedWorldWidth = getAddedWorldWidth(); + // Optimization: monomorphize the CrsWithStaticTransformation-case to avoid // the virtual function overhead. if (crs case final CrsWithStaticTransformation crs) { final v = List.filled(len, Offset.zero, growable: true); for (int i = 0; i < len; ++i) { final p = realPoints.elementAt(i); - final (x, y) = crs.transform(p.x, p.y, zoomScale); + final (x, y) = crs.transform(p.x + addedWorldWidth, p.y, zoomScale); v[i] = Offset(x + ox, y + oy); } return v; @@ -75,7 +103,7 @@ List getOffsetsXY({ final v = List.filled(len, Offset.zero, growable: true); for (int i = 0; i < len; ++i) { final p = realPoints.elementAt(i); - final (x, y) = crs.transform(p.x, p.y, zoomScale); + final (x, y) = crs.transform(p.x + addedWorldWidth, p.y, zoomScale); v[i] = Offset(x + ox, y + oy); } return v; From 1beb1990af3a570ed4367235375402ca930db0ef Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Tue, 1 Oct 2024 17:50:42 +0200 Subject: [PATCH 4/8] refactoring Impacted files: * `crs.dart`: replaced "half world width" with "world width", in order to avoid answering to the question "why HALF?" * `offsets.dart`: now we display the occurrence closer to the screen center; minor refactoring * `painter.dart`: minor fix regarding side-effects on `_metersToStrokeWidth` * `polyline_layer.dart`: now computes the limits projected from -180 and 180 instead of "half world width" * `projected_polyline.dart`: moved code to `polyline_layer.dart` --- lib/src/geo/crs.dart | 23 ++++++++++++------- lib/src/layer/polyline_layer/painter.dart | 5 +++- .../layer/polyline_layer/polyline_layer.dart | 18 +++++++++++---- .../polyline_layer/projected_polyline.dart | 10 -------- lib/src/misc/offsets.dart | 9 +++++--- 5 files changed, 39 insertions(+), 26 deletions(-) diff --git a/lib/src/geo/crs.dart b/lib/src/geo/crs.dart index d72596444..ca3b3eaf9 100644 --- a/lib/src/geo/crs.dart +++ b/lib/src/geo/crs.dart @@ -390,11 +390,18 @@ abstract class Projection { /// unproject cartesian x,y coordinates to [LatLng]. LatLng unprojectXY(double x, double y); - /// Returns half the width of the world in geometry coordinates. - double getHalfWorldWidth() { + /// Returns the width of the world in geometry coordinates. + /// + /// Is used at least in 2 cases: + /// * my polyline crosses longitude 180, and I somehow need to "add a world" + /// to the coordinates in order to display a continuous polyline + /// * when my map scrolls around longitude 180 and I have a marker in this + /// area, the marker may be projected a world away, depending on the map being + /// centered either in the 179 or the -179 part - again, we can "add a world" + double getWorldWidth() { final (x0, _) = projectXY(const LatLng(0, 0)); final (x180, _) = projectXY(const LatLng(0, 180)); - return x0 > x180 ? x0 - x180 : x180 - x0; + return 2 * (x0 > x180 ? x0 - x180 : x180 - x0); } /// Projects a list of [LatLng]s into geometry coordinates. @@ -407,7 +414,7 @@ abstract class Projection { /// displayed close to the polygon, not on the other side of the world. List projectList(List points, {LatLng? referencePoint}) { late double previousX; - final halfWorldWidth = getHalfWorldWidth(); + final worldWidth = getWorldWidth(); return List.generate( points.length, (j) { @@ -416,10 +423,10 @@ abstract class Projection { } var (x, y) = projectXY(points[j]); if (j > 0 || referencePoint != null) { - if (x - previousX > halfWorldWidth) { - x -= 2 * halfWorldWidth; - } else if (x - previousX < -halfWorldWidth) { - x += 2 * halfWorldWidth; + if (x - previousX > worldWidth / 2) { + x -= worldWidth; + } else if (x - previousX < -worldWidth / 2) { + x += worldWidth; } } previousX = x; diff --git a/lib/src/layer/polyline_layer/painter.dart b/lib/src/layer/polyline_layer/painter.dart index 0a7f21def..1d85b57df 100644 --- a/lib/src/layer/polyline_layer/painter.dart +++ b/lib/src/layer/polyline_layer/painter.dart @@ -275,8 +275,11 @@ base class _PolylinePainter ) { final r = _distance.offset(p0, strokeWidthInMeters, 180); var delta = o0 - getOffset(camera, origin, r); + final worldSize = camera.crs.scale(camera.zoom); if (delta.dx < 0) { - delta = delta.translate(camera.crs.scale(camera.zoom), 0); + delta = delta.translate(worldSize, 0); + } else if (delta.dx >= worldSize) { + delta = delta.translate(-worldSize, 0); } return delta.distance; } diff --git a/lib/src/layer/polyline_layer/polyline_layer.dart b/lib/src/layer/polyline_layer/polyline_layer.dart index 1741f6e2e..0aae00f7f 100644 --- a/lib/src/layer/polyline_layer/polyline_layer.dart +++ b/lib/src/layer/polyline_layer/polyline_layer.dart @@ -140,8 +140,8 @@ class _PolylineLayerState extends State> projection.project(boundsAdjusted.northEast), ); - final halfWorldWidth = projection.getHalfWorldWidth(); - + final (xWest, _) = projection.projectXY(const LatLng(0, -180)); + final (xEast, _) = projection.projectXY(const LatLng(0, 180)); for (final projectedPolyline in polylines) { final polyline = projectedPolyline.polyline; @@ -151,8 +151,18 @@ class _PolylineLayerState extends State> continue; } - // TODO: think about how to cull polylines that go beyond the universe. - if (projectedPolyline.goesBeyondTheUniverse(halfWorldWidth)) { + /// Returns true if the points stretch on different versions of the world. + bool stretchesBeyondTheLimits() { + for (final point in projectedPolyline.points) { + if (point.x > xEast || point.x < xWest) { + return true; + } + } + return false; + } + + // TODO: think about how to cull polylines that go beyond -180/180. + if (stretchesBeyondTheLimits()) { yield projectedPolyline; continue; } diff --git a/lib/src/layer/polyline_layer/projected_polyline.dart b/lib/src/layer/polyline_layer/projected_polyline.dart index feb05bbe1..9ba15e4f5 100644 --- a/lib/src/layer/polyline_layer/projected_polyline.dart +++ b/lib/src/layer/polyline_layer/projected_polyline.dart @@ -18,14 +18,4 @@ class _ProjectedPolyline with HitDetectableElement { polyline: polyline, points: projection.projectList(polyline.points), ); - - /// Returns true if the points stretch on different versions of the world. - bool goesBeyondTheUniverse(double halfWorldWidth) { - for (final point in points) { - if (point.x > halfWorldWidth || point.x < -halfWorldWidth) { - return true; - } - } - return false; - } } diff --git a/lib/src/misc/offsets.dart b/lib/src/misc/offsets.dart index e6c08c8b7..0e6aa1771 100644 --- a/lib/src/misc/offsets.dart +++ b/lib/src/misc/offsets.dart @@ -62,11 +62,13 @@ List getOffsetsXY({ /// Returns additional world width in order to have visible points. double getAddedWorldWidth() { + final worldWidth = crs.projection.getWorldWidth(); final List addedWidths = [ 0, - 2 * crs.projection.getHalfWorldWidth(), - -2 * crs.projection.getHalfWorldWidth(), + worldWidth, + -worldWidth, ]; + final halfScreenWidth = camera.size.x / 2; final p = realPoints.elementAt(0); late double result; late double bestX; @@ -78,7 +80,8 @@ List getOffsetsXY({ bestX = x; continue; } - if ((bestX + ox).abs() > (x + ox).abs()) { + if ((bestX + ox - halfScreenWidth).abs() > + (x + ox - halfScreenWidth).abs()) { result = addedWidth; bestX = x; } From d79dc89fd76542158c62b25265d6e5e4a14f6acf Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Thu, 10 Oct 2024 09:35:51 +0200 Subject: [PATCH 5/8] "example" build fix --- example/android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 25c5926e3..c07dc1f84 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -25,7 +25,7 @@ if (flutterVersionName == null) { android { namespace "dev.fleaflet.flutter_map.example" compileSdk flutter.compileSdkVersion - ndkVersion flutter.ndkVersion + ndkVersion "25.1.8937393" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 From 8c272b3be935a9c7df6919eb12bf582e96fe1343 Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Thu, 10 Oct 2024 10:19:23 +0200 Subject: [PATCH 6/8] "example" build fix, just trying --- example/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 37c2fb06f..89cca9a20 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: proj4dart: ^2.1.0 shared_preferences: ^2.3.2 url_launcher: ^6.3.0 + url_launcher_android: ^6.3.12 url_strategy: ^0.3.0 vector_math: ^2.1.4 From 1f9628068311d1623c2c85aed42e71a47c3b56f5 Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Thu, 10 Oct 2024 14:46:26 +0200 Subject: [PATCH 7/8] "example" build fix, just trying --- example/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 89cca9a20..65e733f62 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: proj4dart: ^2.1.0 shared_preferences: ^2.3.2 url_launcher: ^6.3.0 - url_launcher_android: ^6.3.12 + url_launcher_android: 6.3.2 url_strategy: ^0.3.0 vector_math: ^2.1.4 From cc6f1ddc46f708bd5219c9a927de80c2b6ac4eef Mon Sep 17 00:00:00 2001 From: monsieurtanuki Date: Tue, 3 Dec 2024 08:53:51 +0100 Subject: [PATCH 8/8] minor fix --- example/pubspec.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 6bbec60d5..6fc340d43 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,7 +18,6 @@ dependencies: proj4dart: ^2.1.0 shared_preferences: ^2.3.2 url_launcher: ^6.3.0 - url_launcher_android: 6.3.2 url_strategy: ^0.3.0 vector_math: ^2.1.4