From 1a17eb14f139479b219a14219166512ba1ccac75 Mon Sep 17 00:00:00 2001 From: Rory Stephenson Date: Thu, 20 Jul 2023 08:19:58 +0200 Subject: [PATCH] Replace `CustomPoint` with extension methods on `Point` (#1585) * Replace CustomPoint with extension methods on Point The CustomPoint class predates dart extension methods. The name is confusing (custom in what sense, and why) and in looking at the implementation it became clear that it was essentially just adding extension methods. Changing to a Point will avoid conversions in plugins which deal with libraries that use Point. Code will work as-is without changes with the exception of the subtraction operator. Previously CustomPoint - CustomPoint did not trigger analyzer warnings but would cause a runtime exception. This is now replaced by subtract() extension methods which allow subtracting num from a Point and int from Point. * Avoid redundant maths imports * Add Point.toOffset extension method Co-authored-by: 6y * Use point extension's toOffset() --------- Co-authored-by: 6y --- example/lib/pages/custom_crs/Readme.md | 61 +++++--- example/lib/pages/custom_crs/custom_crs.dart | 10 +- example/lib/pages/epsg3413_crs.dart | 8 +- example/lib/pages/latlng_to_screen_point.dart | 6 +- example/lib/pages/point_to_latlng.dart | 4 +- lib/flutter_map.dart | 2 +- lib/src/geo/crs.dart | 54 +++---- .../flutter_map_interactive_viewer.dart | 11 +- lib/src/layer/label.dart | 5 +- lib/src/layer/marker_layer.dart | 12 +- lib/src/layer/overlay_image_layer.dart | 15 +- lib/src/layer/tile_layer/tile.dart | 5 +- .../tile_layer/tile_bounds/tile_bounds.dart | 1 + .../tile_bounds/tile_bounds_at_zoom.dart | 5 +- .../layer/tile_layer/tile_coordinates.dart | 4 +- .../layer/tile_layer/tile_image_manager.dart | 8 +- lib/src/layer/tile_layer/tile_layer.dart | 5 +- .../layer/tile_layer/tile_layer_options.dart | 2 +- lib/src/layer/tile_layer/tile_range.dart | 31 ++-- .../tile_layer/tile_range_calculator.dart | 1 + lib/src/map/camera/camera.dart | 69 ++++----- lib/src/map/camera/camera_constraint.dart | 7 +- lib/src/map/camera/camera_fit.dart | 31 ++-- lib/src/map/internal_controller.dart | 13 +- lib/src/map/map_controller.dart | 14 +- lib/src/map/map_controller_impl.dart | 15 +- lib/src/map/widget.dart | 5 +- lib/src/misc/point.dart | 88 ----------- lib/src/misc/point_extensions.dart | 130 ++++++++++++++++ lib/src/misc/private/bounds.dart | 39 +++-- test/core/bounds_test.dart | 146 ++++++++---------- .../tile_layer/tile_bounds/crs_fakes.dart | 5 +- .../tile_bounds/tile_bounds_at_zoom_test.dart | 7 +- .../tile_bounds/tile_bounds_test.dart | 18 ++- test/layer/tile_layer/tile_range_test.dart | 98 ++++++------ test/misc/frame_constraint_test.dart | 5 +- 36 files changed, 507 insertions(+), 433 deletions(-) delete mode 100644 lib/src/misc/point.dart create mode 100644 lib/src/misc/point_extensions.dart diff --git a/example/lib/pages/custom_crs/Readme.md b/example/lib/pages/custom_crs/Readme.md index bcec84d26..a79854052 100644 --- a/example/lib/pages/custom_crs/Readme.md +++ b/example/lib/pages/custom_crs/Readme.md @@ -2,43 +2,67 @@ ## Projection -To define a `Proj4Crs` (custom CRS) you have to register a projection of `proj4.Projection`. For that you must import `proj4dart` library as follows: +To define a `Proj4Crs` (custom CRS) you have to register a projection of `proj4.Projection`. For +that you must import `proj4dart` library as follows: ```dart import 'package:proj4dart/proj4dart.dart' as proj4; ``` -You can create and register your custom projection in multiple ways, but the recommended is to use a **Proj4 definition string** from [epsg.io](https://epsg.io). For example for `EPSG:3413` (_WGS 84 / NSIDC Sea Ice Polar Stereographic North_) you can find it [here](https://epsg.io/3413.proj4). This is how a Proj4 definition string looks like: +You can create and register your custom projection in multiple ways, but the recommended is to use +a **Proj4 definition string** from [epsg.io](https://epsg.io). For example for `EPSG:3413` (_WGS 84 +/ NSIDC Sea Ice Polar Stereographic North_) you can find it [here](https://epsg.io/3413.proj4). This +is how a Proj4 definition string looks like: ```dart -+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs ++proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 ++ +units += +m ++ +no_defs ``` -With this **Proj4 definition string** and a **string identifier** register your `proj4.Projection` like this: +With this **Proj4 definition string** and a **string identifier** register your `proj4.Projection` +like this: ```dart + var customProjection = proj4.Projection.add('EPSG:3413', - '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'); + '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'); ``` -For more possible ways to register `proj4.Projection` see [proj4dart documentation](https://github.com/maRci002/proj4dart). +For more possible ways to register `proj4.Projection` +see [proj4dart documentation](https://github.com/maRci002/proj4dart). ## Coordinate Reference System (CRS) -You can use your previously registered `proj4.Projection` to create a custom CRS of type `Proj4Crs`. You can use the following parameters: +You can use your previously registered `proj4.Projection` to create a custom CRS of type `Proj4Crs`. +You can use the following parameters: - `` `code` (required): string identifier for the selected CRS, e.g. `EPSG:3413` - `` `proj4Projection` (required): the `proj4.Projection` object you wish to use - `` `bounds`: bounds of the CRS in projected coordinates -- `>` `resolutions`: an array of zoom factors (projection units per pixel, eg. meters/pixel) -- `>` `scales`: scale factors (pixels per projection unit); specify either scales or resolutions, but not both! -- `>` `origins`: tile origin in projected coordinates (for TileLayer). Why is it needed? GeoServer by default can define different origins (top left coordinates) for each zoom levels. In case of origin mismatch the tile will be drawn on the wrong place: the map will jump at such zoom levels. If your origins vary with zoom levels the number of origins must match the number of resolutions. You can get the desired origins from a `GetCapabilities` WMTS call from geoserver e.g. `http://[ip:port]/geoserver/gwc/service/wmts?request=GetCapabilities`. This results an XML, and you have to look up for the `TopLeftCorner`s for each TileMatrix of your TileMatrixSet. -![Tile Origins](./origins.png) -- `` `transformation`: the transformation to use when transforming projected coordinates into pixel coordinates +- `>` `resolutions`: an array of zoom factors (projection units per pixel, eg. + meters/pixel) +- `>` `scales`: scale factors (pixels per projection unit); specify either scales or + resolutions, but not both! +- `>` `origins`: tile origin in projected coordinates (for TileLayer). Why is it needed? + GeoServer by default can define different origins (top left coordinates) for each zoom levels. In + case of origin mismatch the tile will be drawn on the wrong place: the map will jump at such zoom + levels. If your origins vary with zoom levels the number of origins must match the number of + resolutions. You can get the desired origins from a `GetCapabilities` WMTS call from geoserver + e.g. `http://[ip:port]/geoserver/gwc/service/wmts?request=GetCapabilities`. This results an XML, + and you have to look up for the `TopLeftCorner`s for each TileMatrix of your TileMatrixSet. + ![Tile Origins](./origins.png) +- `` `transformation`: the transformation to use when transforming projected + coordinates into pixel coordinates An example: ```dart + var epsg3413 = proj4.Projection.add('EPSG:3413', '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'); @@ -55,8 +79,8 @@ final resolutions = [ ]; final epsg3413Bounds = Bounds( - CustomPoint(-4511619.0, -4511336.0), - CustomPoint(4510883.0, 4510996.0), + Point(-4511619.0, -4511336.0), + Point(4510883.0, 4510996.0), ); var maxZoom = (resolutions.length - 1).toDouble(); @@ -66,7 +90,7 @@ var epsg3413CRS = Proj4Crs.fromFactory( proj4Projection: epsg3413, resolutions: resolutions, bounds: epsg3413Bounds, - origins: [CustomPoint(0, 0)], + origins: [Point(0, 0)], scales: null, transformation: null, ); @@ -77,7 +101,7 @@ var epsg3413CRS = Proj4Crs.fromFactory( Proj4Crs has multiple uses: - Set `FlutterMap`'s default CRS: - + ```dart FlutterMap( options: MapOptions( @@ -92,7 +116,7 @@ Proj4Crs has multiple uses: ``` - Set a WMS layer's CRS - + ```dart TileLayerOptions( opacity: 1.0, @@ -109,6 +133,7 @@ Proj4Crs has multiple uses: ); ``` -For complete code (with point transformation from one projection to another) see the page source code. This is how it looks like: +For complete code (with point transformation from one projection to another) see the page source +code. This is how it looks like: ![Custom CRS](./custom_crs.png) diff --git a/example/lib/pages/custom_crs/custom_crs.dart b/example/lib/pages/custom_crs/custom_crs.dart index 3022f32d2..7475fff76 100644 --- a/example/lib/pages/custom_crs/custom_crs.dart +++ b/example/lib/pages/custom_crs/custom_crs.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter_map/plugin_api.dart'; import 'package:flutter_map_example/widgets/drawer.dart'; @@ -56,8 +58,8 @@ class _CustomCrsPageState extends State { ]; final epsg3413Bounds = Bounds( - const CustomPoint(-4511619, -4511336), - const CustomPoint(4510883, 4510996), + const Point(-4511619, -4511336), + const Point(4510883, 4510996), ); maxZoom = (resolutions.length - 1).toDouble(); @@ -76,9 +78,9 @@ class _CustomCrsPageState extends State { bounds: epsg3413Bounds, // Tile origin, in projected coordinates, if set, this overrides the transformation option // Some goeserver changes origin based on zoom level - // and some are not at all (use explicit/implicit null or use [CustomPoint(0, 0)]) + // and some are not at all (use explicit/implicit null or use [Point(0, 0)]) // @see https://github.com/kartena/Proj4Leaflet/pull/171 - origins: [const CustomPoint(0, 0)], + origins: [const Point(0, 0)], // Scale factors (pixels per projection unit, for example pixels/meter) for zoom levels; // specify either scales or resolutions, not both scales: null, diff --git a/example/lib/pages/epsg3413_crs.dart b/example/lib/pages/epsg3413_crs.dart index 11d9f4636..73448f73f 100644 --- a/example/lib/pages/epsg3413_crs.dart +++ b/example/lib/pages/epsg3413_crs.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter_map/plugin_api.dart'; import 'package:flutter_map_example/widgets/drawer.dart'; @@ -37,8 +39,8 @@ class _EPSG3413PageState extends State { ]; final epsg3413Bounds = Bounds( - const CustomPoint(-4511619, -4511336), - const CustomPoint(4510883, 4510996), + const Point(-4511619, -4511336), + const Point(4510883, 4510996), ); maxZoom = (resolutions.length - 1).toDouble(); @@ -55,7 +57,7 @@ class _EPSG3413PageState extends State { proj4Projection: epsg3413, resolutions: resolutions, bounds: epsg3413Bounds, - origins: [const CustomPoint(0, 0)], + origins: [const Point(0, 0)], scales: null, transformation: null, ); diff --git a/example/lib/pages/latlng_to_screen_point.dart b/example/lib/pages/latlng_to_screen_point.dart index db629de91..f5e3e69bd 100644 --- a/example/lib/pages/latlng_to_screen_point.dart +++ b/example/lib/pages/latlng_to_screen_point.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/plugin_api.dart'; @@ -18,7 +20,7 @@ class LatLngScreenPointTestPage extends StatefulWidget { class _LatLngScreenPointTestPageState extends State { late final MapController _mapController; - CustomPoint _textPos = const CustomPoint(10, 10); + Point _textPos = const Point(10, 10); @override void initState() { @@ -48,7 +50,7 @@ class _LatLngScreenPointTestPageState extends State { onMapEvent: onMapEvent, onTap: (tapPos, latLng) { final pt1 = _mapController.camera.latLngToScreenPoint(latLng); - _textPos = CustomPoint(pt1.x, pt1.y); + _textPos = Point(pt1.x, pt1.y); setState(() {}); }, initialCenter: const LatLng(51.5, -0.09), diff --git a/example/lib/pages/point_to_latlng.dart b/example/lib/pages/point_to_latlng.dart index e0ab2c55f..5aff99507 100644 --- a/example/lib/pages/point_to_latlng.dart +++ b/example/lib/pages/point_to_latlng.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map_example/widgets/drawer.dart'; @@ -106,7 +108,7 @@ class PointToLatlngPage extends State { void updatePoint(MapEvent? event, BuildContext context) { final pointX = _getPointX(context); setState(() { - latLng = mapController.camera.pointToLatLng(CustomPoint(pointX, pointY)); + latLng = mapController.camera.pointToLatLng(Point(pointX, pointY)); }); } diff --git a/lib/flutter_map.dart b/lib/flutter_map.dart index 99f6eeab0..a37757612 100644 --- a/lib/flutter_map.dart +++ b/lib/flutter_map.dart @@ -35,6 +35,6 @@ export 'package:flutter_map/src/map/widget.dart'; export 'package:flutter_map/src/misc/center_zoom.dart'; export 'package:flutter_map/src/misc/fit_bounds_options.dart'; export 'package:flutter_map/src/misc/move_and_rotate_result.dart'; -export 'package:flutter_map/src/misc/point.dart'; +export 'package:flutter_map/src/misc/point_extensions.dart'; export 'package:flutter_map/src/misc/position.dart'; export 'package:flutter_map/src/misc/private/positioned_tap_detector_2.dart'; diff --git a/lib/src/geo/crs.dart b/lib/src/geo/crs.dart index c0adefafb..1c69b9b81 100644 --- a/lib/src/geo/crs.dart +++ b/lib/src/geo/crs.dart @@ -1,6 +1,6 @@ -import 'dart:math' as math; +import 'dart:math' as math hide Point; +import 'dart:math' show Point; -import 'package:flutter_map/src/misc/point.dart'; import 'package:flutter_map/src/misc/private/bounds.dart'; import 'package:latlong2/latlong.dart'; import 'package:meta/meta.dart'; @@ -22,18 +22,18 @@ abstract class Crs { /// Converts a point on the sphere surface (with a certain zoom) in a /// map point. - CustomPoint latLngToPoint(LatLng latlng, double zoom) { + Point latLngToPoint(LatLng latlng, double zoom) { try { final projectedPoint = projection.project(latlng); final scale = this.scale(zoom); return transformation.transform(projectedPoint, scale.toDouble()); } catch (e) { - return const CustomPoint(0, 0); + return const Point(0, 0); } } /// Converts a map point to the sphere coordinate (at a certain zoom). - LatLng pointToLatLng(CustomPoint point, double zoom) => projection + LatLng pointToLatLng(Point point, double zoom) => projection .unproject(transformation.untransform(point, scale(zoom).toDouble())); /// Zoom to Scale function. @@ -177,7 +177,7 @@ class Proj4Crs extends Crs { required String code, required proj4.Projection proj4Projection, Transformation? transformation, - List? origins, + List? origins, Bounds? bounds, List? scales, List? resolutions, @@ -223,7 +223,7 @@ class Proj4Crs extends Crs { /// Converts a point on the sphere surface (with a certain zoom) in a /// map point. @override - CustomPoint latLngToPoint(LatLng latlng, double zoom) { + Point latLngToPoint(LatLng latlng, double zoom) { try { final projectedPoint = projection.project(latlng); final scale = this.scale(zoom); @@ -231,13 +231,13 @@ class Proj4Crs extends Crs { return transformation.transform(projectedPoint, scale.toDouble()); } catch (e) { - return const CustomPoint(0, 0); + return const Point(0, 0); } } /// Converts a map point to the sphere coordinate (at a certain zoom). @override - LatLng pointToLatLng(CustomPoint point, double zoom) => + LatLng pointToLatLng(Point point, double zoom) => projection.unproject(_getTransformationByZoom(zoom) .untransform(point, scale(zoom).toDouble())); @@ -324,9 +324,9 @@ abstract class Projection { Bounds? get bounds; - CustomPoint project(LatLng latlng); + Point project(LatLng latlng); - LatLng unproject(CustomPoint point); + LatLng unproject(Point point); double _inclusive(double start, double end, double value) { if (value < start) return start; @@ -348,7 +348,7 @@ abstract class Projection { class _LonLat extends Projection { static final Bounds _bounds = Bounds( - const CustomPoint(-180, -90), const CustomPoint(180, 90)); + const Point(-180, -90), const Point(180, 90)); const _LonLat() : super(); @@ -356,12 +356,12 @@ class _LonLat extends Projection { Bounds get bounds => _bounds; @override - CustomPoint project(LatLng latlng) { - return CustomPoint(latlng.longitude, latlng.latitude); + Point project(LatLng latlng) { + return Point(latlng.longitude, latlng.latitude); } @override - LatLng unproject(CustomPoint point) { + LatLng unproject(Point point) { return LatLng( inclusiveLat(point.y as double), inclusiveLng(point.x as double)); } @@ -372,8 +372,8 @@ class SphericalMercator extends Projection { static const double maxLatitude = 85.0511287798; static const double _boundsD = r * math.pi; static final Bounds _bounds = Bounds( - const CustomPoint(-_boundsD, -_boundsD), - const CustomPoint(_boundsD, _boundsD), + const Point(-_boundsD, -_boundsD), + const Point(_boundsD, _boundsD), ); const SphericalMercator() : super(); @@ -382,18 +382,18 @@ class SphericalMercator extends Projection { Bounds get bounds => _bounds; @override - CustomPoint project(LatLng latlng) { + Point project(LatLng latlng) { const d = math.pi / 180; const max = maxLatitude; final lat = math.max(math.min(max, latlng.latitude), -max); final sin = math.sin(lat * d); - return CustomPoint( + return Point( r * latlng.longitude * d, r * math.log((1 + sin) / (1 - sin)) / 2); } @override - LatLng unproject(CustomPoint point) { + LatLng unproject(Point point) { const d = 180 / math.pi; return LatLng( inclusiveLat( @@ -416,15 +416,15 @@ class _Proj4Projection extends Projection { }) : epsg4326 = proj4.Projection.WGS84; @override - CustomPoint project(LatLng latlng) { + Point project(LatLng latlng) { final point = epsg4326.transform( proj4Projection, proj4.Point(x: latlng.longitude, y: latlng.latitude)); - return CustomPoint(point.x, point.y); + return Point(point.x, point.y); } @override - LatLng unproject(CustomPoint point) { + LatLng unproject(Point point) { final point2 = proj4Projection.transform( epsg4326, proj4.Point(x: point.x as double, y: point.y as double)); @@ -440,17 +440,17 @@ class Transformation { const Transformation(this.a, this.b, this.c, this.d); - CustomPoint transform(CustomPoint point, double? scale) { + Point transform(Point point, double? scale) { scale ??= 1.0; final x = scale * (a * point.x + b); final y = scale * (c * point.y + d); - return CustomPoint(x, y); + return Point(x, y); } - CustomPoint untransform(CustomPoint point, double? scale) { + Point untransform(Point point, double? scale) { scale ??= 1.0; final x = (point.x / scale - b) / a; final y = (point.y / scale - d) / c; - return CustomPoint(x, y); + return Point(x, y); } } diff --git a/lib/src/gestures/flutter_map_interactive_viewer.dart b/lib/src/gestures/flutter_map_interactive_viewer.dart index a955e0546..4c63fdc80 100644 --- a/lib/src/gestures/flutter_map_interactive_viewer.dart +++ b/lib/src/gestures/flutter_map_interactive_viewer.dart @@ -10,7 +10,7 @@ import 'package:flutter_map/src/gestures/multi_finger_gesture.dart'; import 'package:flutter_map/src/map/camera/camera.dart'; import 'package:flutter_map/src/map/internal_controller.dart'; import 'package:flutter_map/src/map/options.dart'; -import 'package:flutter_map/src/misc/point.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:flutter_map/src/misc/private/positioned_tap_detector_2.dart'; import 'package:latlong2/latlong.dart'; @@ -334,7 +334,7 @@ class FlutterMapInteractiveViewerState .clamp(minZoom, maxZoom); // Calculate offset of mouse cursor from viewport center final newCenter = _camera.focusedZoomCenter( - pointerSignal.localPosition.toCustomPoint(), + pointerSignal.localPosition.toPoint(), newZoom, ); widget.controller.move( @@ -558,8 +558,7 @@ class FlutterMapInteractiveViewerState final zoomDifference = oldFocalPt - newFocalPt; final moveDifference = _rotateOffset(_focalStartLocal - _lastFocalLocal); - final newCenterPt = - oldCenterPt + zoomDifference + moveDifference.toCustomPoint(); + final newCenterPt = oldCenterPt + zoomDifference + moveDifference.toPoint(); return _camera.unproject(newCenterPt, zoomAfterPinchZoom); } @@ -720,7 +719,7 @@ class FlutterMapInteractiveViewerState if (InteractiveFlag.hasDoubleTapZoom(_interactionOptions.flags)) { final newZoom = _getZoomForScale(_camera.zoom, 2); final newCenter = _camera.focusedZoomCenter( - tapPosition.relative!.toCustomPoint(), + tapPosition.relative!.toPoint(), newZoom, ); _startDoubleTapAnimation(newZoom, newCenter); @@ -803,7 +802,7 @@ class FlutterMapInteractiveViewerState } final newCenterPoint = _camera.project(_mapCenterStart) + - _flingAnimation.value.toCustomPoint().rotate(_camera.rotationRad); + _flingAnimation.value.toPoint().rotate(_camera.rotationRad); final newCenter = _camera.unproject(newCenterPoint); widget.controller.move( diff --git a/lib/src/layer/label.dart b/lib/src/layer/label.dart index 16387e7c5..af8fcfbd9 100644 --- a/lib/src/layer/label.dart +++ b/lib/src/layer/label.dart @@ -69,9 +69,6 @@ class Label { final labelPosition = polylabel([ points.map((p) => math.Point(p.dx, p.dy)).toList(), ]); - return Offset( - labelPosition.point.x.toDouble(), - labelPosition.point.y.toDouble(), - ); + return labelPosition.point.toOffset(); } } diff --git a/lib/src/layer/marker_layer.dart b/lib/src/layer/marker_layer.dart index 58bf9e7d0..28d7e7825 100644 --- a/lib/src/layer/marker_layer.dart +++ b/lib/src/layer/marker_layer.dart @@ -1,6 +1,8 @@ +import 'dart:math'; + import 'package:flutter/widgets.dart'; import 'package:flutter_map/src/map/camera/camera.dart'; -import 'package:flutter_map/src/misc/point.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:flutter_map/src/misc/private/bounds.dart'; import 'package:latlong2/latlong.dart'; @@ -16,6 +18,7 @@ class AnchorPos { final AnchorAlign? alignment; const AnchorPos.exactly(Anchor this.anchor) : alignment = null; + const AnchorPos.align(AnchorAlign this.alignment) : anchor = null; } @@ -49,7 +52,6 @@ enum AnchorAlign { topRight(1, 1), bottomLeft(-1, -1), bottomRight(1, -1), - center(0, 0), /// Top center @@ -206,12 +208,12 @@ class MarkerLayer extends StatelessWidget { final bottomPortion = marker.height - anchor.top; final topPortion = anchor.top; if (!map.pixelBounds.containsPartialBounds(Bounds( - CustomPoint(pxPoint.x + leftPortion, pxPoint.y - bottomPortion), - CustomPoint(pxPoint.x - rightPortion, pxPoint.y + topPortion)))) { + Point(pxPoint.x + leftPortion, pxPoint.y - bottomPortion), + Point(pxPoint.x - rightPortion, pxPoint.y + topPortion)))) { continue; } - final pos = pxPoint - map.pixelOrigin; + final pos = pxPoint.subtract(map.pixelOrigin); final markerWidget = (marker.rotate ?? rotate) ? Transform.rotate( angle: -map.rotationRad, diff --git a/lib/src/layer/overlay_image_layer.dart b/lib/src/layer/overlay_image_layer.dart index 2099ccb7f..c58299778 100644 --- a/lib/src/layer/overlay_image_layer.dart +++ b/lib/src/layer/overlay_image_layer.dart @@ -1,6 +1,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_map/src/geo/latlng_bounds.dart'; import 'package:flutter_map/src/map/camera/camera.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:flutter_map/src/misc/private/bounds.dart'; import 'package:latlong2/latlong.dart'; @@ -48,8 +49,8 @@ class OverlayImage extends BaseOverlayImage { Positioned buildPositionedForOverlay(MapCamera map) { // northWest is not necessarily upperLeft depending on projection final bounds = Bounds( - map.project(this.bounds.northWest) - map.pixelOrigin, - map.project(this.bounds.southEast) - map.pixelOrigin, + map.project(this.bounds.northWest).subtract(map.pixelOrigin), + map.project(this.bounds.southEast).subtract(map.pixelOrigin), ); return Positioned( left: bounds.topLeft.x.toDouble(), @@ -93,9 +94,11 @@ class RotatedOverlayImage extends BaseOverlayImage { @override Positioned buildPositionedForOverlay(MapCamera map) { - final pxTopLeft = map.project(topLeftCorner) - map.pixelOrigin; - final pxBottomRight = map.project(bottomRightCorner) - map.pixelOrigin; - final pxBottomLeft = map.project(bottomLeftCorner) - map.pixelOrigin; + final pxTopLeft = map.project(topLeftCorner).subtract(map.pixelOrigin); + final pxBottomRight = + map.project(bottomRightCorner).subtract(map.pixelOrigin); + final pxBottomLeft = + map.project(bottomLeftCorner).subtract(map.pixelOrigin); // calculate pixel coordinate of top-right corner by calculating the // vector from bottom-left to top-left and adding it to bottom-right final pxTopRight = (pxTopLeft - pxBottomLeft + pxBottomRight); @@ -107,7 +110,7 @@ class RotatedOverlayImage extends BaseOverlayImage { final vectorX = (pxTopRight - pxTopLeft) / bounds.size.x; final vectorY = (pxBottomLeft - pxTopLeft) / bounds.size.y; - final offset = pxTopLeft - bounds.topLeft; + final offset = pxTopLeft.subtract(bounds.topLeft); final a = vectorX.x.toDouble(); final b = vectorX.y.toDouble(); diff --git a/lib/src/layer/tile_layer/tile.dart b/lib/src/layer/tile_layer/tile.dart index cfaca4e98..48e2c025f 100644 --- a/lib/src/layer/tile_layer/tile.dart +++ b/lib/src/layer/tile_layer/tile.dart @@ -1,13 +1,14 @@ +import 'dart:math'; + import 'package:flutter/widgets.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_builder.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_image.dart'; -import 'package:flutter_map/src/misc/point.dart'; class Tile extends StatefulWidget { final TileImage tileImage; final TileBuilder? tileBuilder; final double scaledTileSize; - final CustomPoint currentPixelOrigin; + final Point currentPixelOrigin; const Tile({ super.key, diff --git a/lib/src/layer/tile_layer/tile_bounds/tile_bounds.dart b/lib/src/layer/tile_layer/tile_bounds/tile_bounds.dart index 7d44013dd..5606b48ce 100644 --- a/lib/src/layer/tile_layer/tile_bounds/tile_bounds.dart +++ b/lib/src/layer/tile_layer/tile_bounds/tile_bounds.dart @@ -2,6 +2,7 @@ import 'package:flutter_map/src/geo/crs.dart'; import 'package:flutter_map/src/geo/latlng_bounds.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_range.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:flutter_map/src/misc/private/bounds.dart'; import 'package:latlong2/latlong.dart'; diff --git a/lib/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart b/lib/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart index d89d856f7..3738b6908 100644 --- a/lib/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart +++ b/lib/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart @@ -1,6 +1,7 @@ +import 'dart:math'; + import 'package:flutter_map/src/layer/tile_layer/tile_coordinates.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_range.dart'; -import 'package:flutter_map/src/misc/point.dart'; abstract class TileBoundsAtZoom { const TileBoundsAtZoom(); @@ -101,7 +102,7 @@ class WrappedTileBoundsAtZoom extends TileBoundsAtZoom { bool _wrappedBothContains(TileCoordinates coordinates) { return tileRange.contains( - CustomPoint( + Point( _wrapInt(coordinates.x, wrapX!), _wrapInt(coordinates.y, wrapY!), ), diff --git a/lib/src/layer/tile_layer/tile_coordinates.dart b/lib/src/layer/tile_layer/tile_coordinates.dart index 35670fbc6..c1138e10b 100644 --- a/lib/src/layer/tile_layer/tile_coordinates.dart +++ b/lib/src/layer/tile_layer/tile_coordinates.dart @@ -1,8 +1,6 @@ import 'dart:math'; -import 'package:flutter_map/src/misc/point.dart'; - -class TileCoordinates extends CustomPoint { +class TileCoordinates extends Point { final int z; const TileCoordinates(super.x, super.y, this.z); diff --git a/lib/src/layer/tile_layer/tile_image_manager.dart b/lib/src/layer/tile_layer/tile_image_manager.dart index 847cbf85b..2f1a19ed6 100644 --- a/lib/src/layer/tile_layer/tile_image_manager.dart +++ b/lib/src/layer/tile_layer/tile_image_manager.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:collection/collection.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart'; @@ -6,7 +8,6 @@ import 'package:flutter_map/src/layer/tile_layer/tile_display.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_image.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_layer.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_range.dart'; -import 'package:flutter_map/src/misc/point.dart'; typedef TileCreator = TileImage Function(TileCoordinates coordinates); @@ -143,8 +144,7 @@ class TileImageManager { final c = tile.coordinates; if (tile.current && - (c.z != currentTileZoom || - !noPruneRange.contains(CustomPoint(c.x, c.y)))) { + (c.z != currentTileZoom || !noPruneRange.contains(Point(c.x, c.y)))) { tile.current = false; } } @@ -175,7 +175,7 @@ class TileImageManager { final c = tile.coordinates; if (tile.loadError && - (!tile.current || !tileRange.contains(CustomPoint(c.x, c.y)))) { + (!tile.current || !tileRange.contains(Point(c.x, c.y)))) { toRemove.add(entry.key); } } diff --git a/lib/src/layer/tile_layer/tile_layer.dart b/lib/src/layer/tile_layer/tile_layer.dart index d8718365f..0d43ad2b9 100644 --- a/lib/src/layer/tile_layer/tile_layer.dart +++ b/lib/src/layer/tile_layer/tile_layer.dart @@ -1,5 +1,6 @@ import 'dart:async'; -import 'dart:math' as math; +import 'dart:math' as math hide Point; +import 'dart:math' show Point; import 'package:collection/collection.dart' show MapEquality; import 'package:flutter/material.dart'; @@ -471,7 +472,7 @@ class _TileLayerState extends State with TickerProviderStateMixin { ), ); - final currentPixelOrigin = CustomPoint( + final currentPixelOrigin = Point( map.pixelOrigin.x.toDouble(), map.pixelOrigin.y.toDouble(), ); diff --git a/lib/src/layer/tile_layer/tile_layer_options.dart b/lib/src/layer/tile_layer/tile_layer_options.dart index 5668cb412..1e65364e2 100644 --- a/lib/src/layer/tile_layer/tile_layer_options.dart +++ b/lib/src/layer/tile_layer/tile_layer_options.dart @@ -90,7 +90,7 @@ class WMSTileLayerOptions { } String getUrl(TileCoordinates coords, int tileSize, bool retinaMode) { - final tileSizePoint = CustomPoint(tileSize, tileSize); + final tileSizePoint = Point(tileSize, tileSize); final nwPoint = coords.scaleBy(tileSizePoint); final sePoint = nwPoint + tileSizePoint; final nwCoords = crs.pointToLatLng(nwPoint, coords.z.toDouble()); diff --git a/lib/src/layer/tile_layer/tile_range.dart b/lib/src/layer/tile_layer/tile_range.dart index fa4b4a789..d6e0c8c5e 100644 --- a/lib/src/layer/tile_layer/tile_range.dart +++ b/lib/src/layer/tile_layer/tile_range.dart @@ -1,7 +1,8 @@ -import 'dart:math' as math; +import 'dart:math' as math hide Point; +import 'dart:math' show Point; import 'package:flutter_map/src/layer/tile_layer/tile_coordinates.dart'; -import 'package:flutter_map/src/misc/point.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:flutter_map/src/misc/private/bounds.dart'; abstract class TileRange { @@ -38,7 +39,7 @@ class DiscreteTileRange extends TileRange { } else { bounds = Bounds( (pixelBounds.min / tileSize).floor(), - (pixelBounds.max / tileSize).ceil() - const CustomPoint(1, 1), + (pixelBounds.max / tileSize).ceil() - const Point(1, 1), ); } @@ -51,12 +52,8 @@ class DiscreteTileRange extends TileRange { return DiscreteTileRange( zoom, _bounds - .extend( - CustomPoint(_bounds.min.x - count, _bounds.min.y - count), - ) - .extend( - CustomPoint(_bounds.max.x + count, _bounds.max.y + count), - ), + .extend(Point(_bounds.min.x - count, _bounds.min.y - count)) + .extend(Point(_bounds.max.x + count, _bounds.max.y + count)), ); } @@ -77,8 +74,8 @@ class DiscreteTileRange extends TileRange { return DiscreteTileRange( zoom, Bounds( - CustomPoint(math.max(min.x, minX), min.y), - CustomPoint(math.min(max.x, maxX), max.y), + Point(math.max(min.x, minX), min.y), + Point(math.min(max.x, maxX), max.y), ), ); } @@ -92,21 +89,21 @@ class DiscreteTileRange extends TileRange { return DiscreteTileRange( zoom, Bounds( - CustomPoint(min.x, math.max(min.y, minY)), - CustomPoint(max.x, math.min(max.y, maxY)), + Point(min.x, math.max(min.y, minY)), + Point(max.x, math.min(max.y, maxY)), ), ); } - bool contains(CustomPoint point) { + bool contains(Point point) { return _bounds.contains(point); } - CustomPoint get min => _bounds.min; + Point get min => _bounds.min; - CustomPoint get max => _bounds.max; + Point get max => _bounds.max; - CustomPoint get center => _bounds.center; + Point get center => _bounds.center; @override Iterable get coordinates sync* { diff --git a/lib/src/layer/tile_layer/tile_range_calculator.dart b/lib/src/layer/tile_layer/tile_range_calculator.dart index 9ea140fd9..4ce6f52cd 100644 --- a/lib/src/layer/tile_layer/tile_range_calculator.dart +++ b/lib/src/layer/tile_layer/tile_range_calculator.dart @@ -1,5 +1,6 @@ import 'package:flutter_map/src/layer/tile_layer/tile_range.dart'; import 'package:flutter_map/src/map/camera/camera.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:flutter_map/src/misc/private/bounds.dart'; import 'package:latlong2/latlong.dart'; diff --git a/lib/src/map/camera/camera.dart b/lib/src/map/camera/camera.dart index 3b7ed9a97..f38603f25 100644 --- a/lib/src/map/camera/camera.dart +++ b/lib/src/map/camera/camera.dart @@ -1,11 +1,12 @@ -import 'dart:math' as math; +import 'dart:math' as math hide Point; +import 'dart:math' show Point; import 'package:flutter/material.dart'; import 'package:flutter_map/src/geo/crs.dart'; import 'package:flutter_map/src/geo/latlng_bounds.dart'; import 'package:flutter_map/src/map/inherited_model.dart'; import 'package:flutter_map/src/map/options.dart'; -import 'package:flutter_map/src/misc/point.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:flutter_map/src/misc/private/bounds.dart'; import 'package:latlong2/latlong.dart'; @@ -19,7 +20,7 @@ class MapCamera { // in a subsequent build to the actual constraints. We set the size to this // impossible (negative) value initially and only change it once Flutter // provides real constraints. - static const kImpossibleSize = CustomPoint(-1, -1); + static const kImpossibleSize = Point(-1, -1); final Crs crs; final double? minZoom; @@ -40,17 +41,17 @@ class MapCamera { 'This getter has been changed to fix the capitalization. ' 'This getter is deprecated since v6.', ) - CustomPoint get nonrotatedSize => nonRotatedSize; + Point get nonrotatedSize => nonRotatedSize; /// The size of the map view ignoring rotation. This will be the size of the /// FlutterMap widget. - final CustomPoint nonRotatedSize; + final Point nonRotatedSize; // Lazily calculated fields. - CustomPoint? _cameraSize; + Point? _cameraSize; Bounds? _pixelBounds; LatLngBounds? _bounds; - CustomPoint? _pixelOrigin; + Point? _pixelOrigin; double? _rotationRad; @Deprecated( @@ -73,7 +74,7 @@ class MapCamera { /// rotation. When the rotation is zero this will equal [nonRotatedSize], /// otherwise it will be the size of the rectangle which contains this /// camera. - CustomPoint get size => + Point get size => _cameraSize ?? calculateRotatedSize( rotation, @@ -83,7 +84,7 @@ class MapCamera { /// The offset of the top-left corner of the bounding rectangle of this /// camera. This will not equal the offset of the top-left visible pixel when /// the map is rotated. - CustomPoint get pixelOrigin => + Point get pixelOrigin => _pixelOrigin ?? (_pixelOrigin = (project(center, zoom) - size / 2.0).round()); @@ -121,10 +122,10 @@ class MapCamera { required this.nonRotatedSize, this.minZoom, this.maxZoom, - CustomPoint? size, + Point? size, Bounds? pixelBounds, LatLngBounds? bounds, - CustomPoint? pixelOrigin, + Point? pixelOrigin, double? rotationRad, }) : _cameraSize = size ?? calculateRotatedSize(rotation, nonRotatedSize), _pixelBounds = pixelBounds, @@ -133,7 +134,7 @@ class MapCamera { _rotationRad = rotationRad; /// Returns a new instance of [MapCamera] with the given [nonRotatedSize]. - MapCamera withNonRotatedSize(CustomPoint nonRotatedSize) { + MapCamera withNonRotatedSize(Point nonRotatedSize) { if (nonRotatedSize == this.nonRotatedSize) return this; return MapCamera( @@ -203,9 +204,9 @@ class MapCamera { /// Calculates the size of a bounding box which surrounds a box of size /// [nonRotatedSize] which is rotated by [rotation]. - static CustomPoint calculateRotatedSize( + static Point calculateRotatedSize( double rotation, - CustomPoint nonRotatedSize, + Point nonRotatedSize, ) { if (rotation == 0.0) return nonRotatedSize; @@ -216,7 +217,7 @@ class MapCamera { final height = (nonRotatedSize.y * cosAngle) + (nonRotatedSize.x * sinAngle); - return CustomPoint(width, height); + return Point(width, height); } /// The current rotation value in radians. This is calculated and cached when @@ -225,15 +226,15 @@ class MapCamera { /// Calculates point value for the given [latLng] using this camera's /// [crs] and [zoom] (or the provided [zoom]). - CustomPoint project(LatLng latlng, [double? zoom]) => + Point project(LatLng latlng, [double? zoom]) => crs.latLngToPoint(latlng, zoom ?? this.zoom); /// Calculates the [LatLng] for the given [point] using this camera's /// [crs] and [zoom] (or the provided [zoom]). - LatLng unproject(CustomPoint point, [double? zoom]) => + LatLng unproject(Point point, [double? zoom]) => crs.pointToLatLng(point, zoom ?? this.zoom); - LatLng layerPointToLatLng(CustomPoint point) => unproject(point); + LatLng layerPointToLatLng(Point point) => unproject(point); /// Calculates the scale for a zoom from [fromZoom] to [toZoom] using this /// camera\s [crs]. @@ -248,14 +249,12 @@ class MapCamera { crs.getProjectedBounds(zoom ?? this.zoom); /// Calculates the [Offset] from the [pos] to this camera's [pixelOrigin]. - Offset getOffsetFromOrigin(LatLng pos) { - final delta = project(pos) - pixelOrigin; - return Offset(delta.x, delta.y); - } + Offset getOffsetFromOrigin(LatLng pos) => + project(pos).subtract(pixelOrigin).toOffset(); /// Calculates the pixel origin of this [MapCamera] at the given /// [center]/[zoom]. - CustomPoint getNewPixelOrigin(LatLng center, [double? zoom]) { + Point getNewPixelOrigin(LatLng center, [double? zoom]) { final halfSize = size / 2.0; return (project(center, zoom) - halfSize).round(); } @@ -266,7 +265,7 @@ class MapCamera { /// Calculates the pixel bounds of this [MapCamera] at the given [zoom]. Bounds pixelBoundsAtZoom(double zoom) { - CustomPoint halfSize = size / 2; + Point halfSize = size / 2; if (zoom != this.zoom) { final scale = getZoomScale(this.zoom, zoom); halfSize = size / (scale * 2); @@ -277,7 +276,7 @@ class MapCamera { // This will convert a latLng to a position that we could use with a widget // outside of FlutterMap layer space. Eg using a Positioned Widget. - CustomPoint latLngToScreenPoint(LatLng latLng) { + Point latLngToScreenPoint(LatLng latLng) { final nonRotatedPixelOrigin = (project(center, zoom) - nonRotatedSize / 2.0).round(); @@ -289,11 +288,11 @@ class MapCamera { point = rotatePoint(mapCenter, point, counterRotation: false); } - return point - nonRotatedPixelOrigin; + return point.subtract(nonRotatedPixelOrigin); } - LatLng pointToLatLng(CustomPoint localPoint) { - final localPointCenterDistance = CustomPoint( + LatLng pointToLatLng(Point localPoint) { + final localPointCenterDistance = Point( (nonRotatedSize.x / 2) - localPoint.x, (nonRotatedSize.y / 2) - localPoint.y, ); @@ -312,9 +311,9 @@ class MapCamera { // it needs to be reversed (pointToLatLng), and sometimes we want to use // the same rotation to create a new position (latLngToScreenpoint). // counterRotation just makes allowances this for this. - CustomPoint rotatePoint( - CustomPoint mapCenter, - CustomPoint point, { + Point rotatePoint( + Point mapCenter, + Point point, { bool counterRotation = true, }) { final counterRotationFactor = counterRotation ? -1 : 1; @@ -324,9 +323,9 @@ class MapCamera { ..rotateZ(rotationRad * counterRotationFactor) ..translate(-mapCenter.x, -mapCenter.y); - final tp = MatrixUtils.transformPoint(m, Offset(point.x, point.y)); + final tp = MatrixUtils.transformPoint(m, point.toOffset()); - return CustomPoint(tp.dx, tp.dy); + return Point(tp.dx, tp.dy); } /// Clamps the provided [zoom] to the range specified by [minZoom] and @@ -339,7 +338,7 @@ class MapCamera { LatLng offsetToCrs(Offset offset, [double? zoom]) { final focalStartPt = project(center, zoom ?? this.zoom); final point = - (offset.toCustomPoint() - (nonRotatedSize / 2.0)).rotate(rotationRad); + (offset.toPoint() - (nonRotatedSize / 2.0)).rotate(rotationRad); final newCenterPt = focalStartPt + point; return unproject(newCenterPt, zoom ?? this.zoom); @@ -347,7 +346,7 @@ class MapCamera { // Calculate the center point which would keep the same point of the map // visible at the given [cursorPos] with the zoom set to [zoom]. - LatLng focusedZoomCenter(CustomPoint cursorPos, double zoom) { + LatLng focusedZoomCenter(Point cursorPos, double zoom) { // Calculate offset of mouse cursor from viewport center final viewCenter = nonRotatedSize / 2; final offset = (cursorPos - viewCenter).rotate(rotationRad); diff --git a/lib/src/map/camera/camera_constraint.dart b/lib/src/map/camera/camera_constraint.dart index f192eaa79..eaeb92feb 100644 --- a/lib/src/map/camera/camera_constraint.dart +++ b/lib/src/map/camera/camera_constraint.dart @@ -1,9 +1,10 @@ -import 'dart:math' as math; +import 'dart:math' as math hide Point; +import 'dart:math' show Point; import 'package:flutter_map/src/geo/latlng_bounds.dart'; import 'package:flutter_map/src/map/camera/camera.dart'; import 'package:flutter_map/src/map/camera/camera_fit.dart'; -import 'package:flutter_map/src/misc/point.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:latlong2/latlong.dart'; /// Describes a boundary for a [MapCamera], that cannot be exceeded by movement @@ -122,7 +123,7 @@ class ContainCamera extends CameraConstraint { if (leftOkCenter > rightOkCenter || topOkCenter > botOkCenter) return null; final centerPix = camera.project(testCenter, testZoom); - final newCenterPix = CustomPoint( + final newCenterPix = Point( centerPix.x.clamp(leftOkCenter, rightOkCenter), centerPix.y.clamp(topOkCenter, botOkCenter), ); diff --git a/lib/src/map/camera/camera_fit.dart b/lib/src/map/camera/camera_fit.dart index 616da352c..3b0ca2738 100644 --- a/lib/src/map/camera/camera_fit.dart +++ b/lib/src/map/camera/camera_fit.dart @@ -1,10 +1,11 @@ -import 'dart:math' as math; +import 'dart:math' as math hide Point; +import 'dart:math' show Point; import 'package:flutter/widgets.dart'; import 'package:flutter_map/src/geo/latlng_bounds.dart'; import 'package:flutter_map/src/map/camera/camera.dart'; import 'package:flutter_map/src/map/camera/camera_constraint.dart'; -import 'package:flutter_map/src/misc/point.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:flutter_map/src/misc/private/bounds.dart'; import 'package:latlong2/latlong.dart'; @@ -102,8 +103,8 @@ class FitBounds extends CameraFit { /// Returns a new [MapCamera] which fits this classes configuration. @override MapCamera fit(MapCamera camera) { - final paddingTL = CustomPoint(padding.left, padding.top); - final paddingBR = CustomPoint(padding.right, padding.bottom); + final paddingTL = Point(padding.left, padding.top); + final paddingBR = Point(padding.right, padding.bottom); final paddingTotalXY = paddingTL + paddingBR; @@ -114,7 +115,7 @@ class FitBounds extends CameraFit { final swPoint = camera.project(bounds.southWest, newZoom); final nePoint = camera.project(bounds.northEast, newZoom); - final CustomPoint projectedCenter; + final Point projectedCenter; if (camera.rotation != 0.0) { final swPointRotated = swPoint.rotate(-camera.rotationRad); final nePointRotated = nePoint.rotate(-camera.rotationRad); @@ -135,13 +136,13 @@ class FitBounds extends CameraFit { double _getBoundsZoom( MapCamera camera, - CustomPoint pixelPadding, + Point pixelPadding, ) { final nw = bounds.northWest; final se = bounds.southEast; var size = camera.nonRotatedSize - pixelPadding; // Prevent negative size which results in NaN zoom value later on in the calculation - size = CustomPoint(math.max(0, size.x), math.max(0, size.y)); + size = Point(math.max(0, size.x), math.max(0, size.y)); var boundsSize = Bounds( camera.project(se, camera.zoom), camera.project(nw, camera.zoom), @@ -149,7 +150,7 @@ class FitBounds extends CameraFit { if (camera.rotation != 0.0) { final cosAngle = math.cos(camera.rotationRad).abs(); final sinAngle = math.sin(camera.rotationRad).abs(); - boundsSize = CustomPoint( + boundsSize = Point( (boundsSize.x * cosAngle) + (boundsSize.y * sinAngle), (boundsSize.y * cosAngle) + (boundsSize.x * sinAngle), ); @@ -216,8 +217,8 @@ class FitInsideBounds extends CameraFit { @override MapCamera fit(MapCamera camera) { - final paddingTL = CustomPoint(padding.left, padding.top); - final paddingBR = CustomPoint(padding.right, padding.bottom); + final paddingTL = Point(padding.left, padding.top); + final paddingBR = Point(padding.right, padding.bottom); final paddingTotalXY = paddingTL + paddingBR; final paddingOffset = (paddingBR - paddingTL) / 2; @@ -267,7 +268,7 @@ class FitInsideBounds extends CameraFit { LatLng _getCenter( MapCamera camera, { required double newZoom, - required CustomPoint paddingOffset, + required Point paddingOffset, }) { if (camera.rotation == 0.0) { final swPoint = camera.project(bounds.southWest, newZoom); @@ -421,8 +422,8 @@ class FitCoordinates extends CameraFit { /// Returns a new [MapCamera] which fits this classes configuration. @override MapCamera fit(MapCamera camera) { - final paddingTL = CustomPoint(padding.left, padding.top); - final paddingBR = CustomPoint(padding.right, padding.bottom); + final paddingTL = Point(padding.left, padding.top); + final paddingBR = Point(padding.right, padding.bottom); final paddingTotalXY = paddingTL + paddingBR; @@ -455,11 +456,11 @@ class FitCoordinates extends CameraFit { double _getCoordinatesZoom( MapCamera camera, - CustomPoint pixelPadding, + Point pixelPadding, ) { var size = camera.nonRotatedSize - pixelPadding; // Prevent negative size which results in NaN zoom value later on in the calculation - size = CustomPoint(math.max(0, size.x), math.max(0, size.y)); + size = Point(math.max(0, size.x), math.max(0, size.y)); final projectedPoints = [ for (final coord in coordinates) camera.project(coord) diff --git a/lib/src/map/internal_controller.dart b/lib/src/map/internal_controller.dart index 513b1ee90..5d7ea8dff 100644 --- a/lib/src/map/internal_controller.dart +++ b/lib/src/map/internal_controller.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_map/plugin_api.dart'; @@ -27,6 +29,7 @@ class FlutterMapInternalController extends ValueNotifier<_InternalState> { _interactiveViewerState = interactiveViewerState; MapOptions get options => value.options; + MapCamera get camera => value.camera; void linkMapController(MapControllerImpl mapControllerImpl) { @@ -58,7 +61,7 @@ class FlutterMapInternalController extends ValueNotifier<_InternalState> { newCenter = camera.unproject( camera.rotatePoint( newPoint, - newPoint - CustomPoint(offset.dx, offset.dy), + newPoint - Point(offset.dx, offset.dy), ), newZoom, ); @@ -139,7 +142,7 @@ class FlutterMapInternalController extends ValueNotifier<_InternalState> { // defaults. MoveAndRotateResult rotateAroundPoint( double degree, { - required CustomPoint? point, + required Point? point, required Offset? offset, required bool hasGesture, required MapEventSource source, @@ -172,7 +175,7 @@ class FlutterMapInternalController extends ValueNotifier<_InternalState> { final rotationCenter = camera.project(camera.center) + (point != null ? (point - (camera.nonRotatedSize / 2.0)) - : CustomPoint(offset!.dx, offset.dy)) + : Point(offset!.dx, offset.dy)) .rotate(camera.rotationRad); return MoveAndRotateResult( @@ -241,7 +244,7 @@ class FlutterMapInternalController extends ValueNotifier<_InternalState> { } bool setNonRotatedSizeWithoutEmittingEvent( - CustomPoint nonRotatedSize, + Point nonRotatedSize, ) { if (nonRotatedSize != MapCamera.kImpossibleSize && nonRotatedSize != camera.nonRotatedSize) { @@ -292,7 +295,7 @@ class FlutterMapInternalController extends ValueNotifier<_InternalState> { void dragUpdated(MapEventSource source, Offset offset) { final oldCenterPt = camera.project(camera.center); - final newCenterPt = oldCenterPt + offset.toCustomPoint(); + final newCenterPt = oldCenterPt + offset.toPoint(); final newCenter = camera.unproject(newCenterPt); move( diff --git a/lib/src/map/map_controller.dart b/lib/src/map/map_controller.dart index e29cecc0d..c5a6523a9 100644 --- a/lib/src/map/map_controller.dart +++ b/lib/src/map/map_controller.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_map/src/geo/latlng_bounds.dart'; @@ -10,7 +11,6 @@ import 'package:flutter_map/src/map/map_controller_impl.dart'; import 'package:flutter_map/src/misc/center_zoom.dart'; import 'package:flutter_map/src/misc/fit_bounds_options.dart'; import 'package:flutter_map/src/misc/move_and_rotate_result.dart'; -import 'package:flutter_map/src/misc/point.dart'; import 'package:latlong2/latlong.dart'; /// Controller to programmatically interact with [FlutterMap], such as @@ -113,7 +113,7 @@ abstract class MapController { /// [MoveAndRotateResult.rotateSuccess] are `true`. MoveAndRotateResult rotateAroundPoint( double degree, { - CustomPoint? point, + Point? point, Offset? offset, String? id, }); @@ -183,7 +183,7 @@ abstract class MapController { 'This method is now accessible via the camera. ' 'This method is deprecated since v6.', ) - LatLng pointToLatLng(CustomPoint screenPoint); + LatLng pointToLatLng(Point screenPoint); /// Convert a map coordinate (lat/lng) to its corresponding screen point (x/y), /// based on the map's current screen positioning @@ -192,16 +192,16 @@ abstract class MapController { 'This method is now accessible via the camera. ' 'This method is deprecated since v6.', ) - CustomPoint latLngToScreenPoint(LatLng mapCoordinate); + Point latLngToScreenPoint(LatLng mapCoordinate); @Deprecated( 'Prefer `controller.camera.rotatePoint()`. ' 'This method is now accessible via the camera. ' 'This method is deprecated since v6.', ) - CustomPoint rotatePoint( - CustomPoint mapCenter, - CustomPoint point, { + Point rotatePoint( + Point mapCenter, + Point point, { bool counterRotation = true, }); diff --git a/lib/src/map/map_controller_impl.dart b/lib/src/map/map_controller_impl.dart index 889cace42..5f6501943 100644 --- a/lib/src/map/map_controller_impl.dart +++ b/lib/src/map/map_controller_impl.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:math'; import 'package:flutter/widgets.dart'; import 'package:flutter_map/src/geo/latlng_bounds.dart'; @@ -10,7 +11,7 @@ import 'package:flutter_map/src/map/map_controller.dart'; import 'package:flutter_map/src/misc/center_zoom.dart'; import 'package:flutter_map/src/misc/fit_bounds_options.dart'; import 'package:flutter_map/src/misc/move_and_rotate_result.dart'; -import 'package:flutter_map/src/misc/point.dart'; +import 'package:flutter_map/src/misc/point_extensions.dart'; import 'package:latlong2/latlong.dart'; /// Implements [MapController] whilst exposing methods for internal use which @@ -58,7 +59,7 @@ class MapControllerImpl implements MapController { @override MoveAndRotateResult rotateAroundPoint( double degree, { - CustomPoint? point, + Point? point, Offset? offset, String? id, }) => @@ -162,7 +163,7 @@ class MapControllerImpl implements MapController { 'This method is now accessible via the camera. ' 'This method is deprecated since v6.', ) - LatLng pointToLatLng(CustomPoint screenPoint) => + LatLng pointToLatLng(Point screenPoint) => camera.pointToLatLng(screenPoint); @override @@ -171,7 +172,7 @@ class MapControllerImpl implements MapController { 'This method is now accessible via the camera. ' 'This method is deprecated since v6.', ) - CustomPoint latLngToScreenPoint(LatLng mapCoordinate) => + Point latLngToScreenPoint(LatLng mapCoordinate) => camera.latLngToScreenPoint(mapCoordinate); @override @@ -180,9 +181,9 @@ class MapControllerImpl implements MapController { 'This method is now accessible via the camera. ' 'This method is deprecated since v6.', ) - CustomPoint rotatePoint( - CustomPoint mapCenter, - CustomPoint point, { + Point rotatePoint( + Point mapCenter, + Point point, { bool counterRotation = true, }) => camera.rotatePoint( diff --git a/lib/src/map/widget.dart b/lib/src/map/widget.dart index 2a8430e24..e95bfc933 100644 --- a/lib/src/map/widget.dart +++ b/lib/src/map/widget.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/widgets.dart'; import 'package:flutter_map/src/gestures/flutter_map_interactive_viewer.dart'; import 'package:flutter_map/src/gestures/map_events.dart'; @@ -7,7 +9,6 @@ import 'package:flutter_map/src/map/internal_controller.dart'; import 'package:flutter_map/src/map/map_controller.dart'; import 'package:flutter_map/src/map/map_controller_impl.dart'; import 'package:flutter_map/src/map/options.dart'; -import 'package:flutter_map/src/misc/point.dart'; /// Renders an interactive geographical map as a widget /// @@ -164,7 +165,7 @@ class FlutterMapStateContainer extends State { } void _updateAndEmitSizeIfConstraintsChanged(BoxConstraints constraints) { - final nonRotatedSize = CustomPoint( + final nonRotatedSize = Point( constraints.maxWidth, constraints.maxHeight, ); diff --git a/lib/src/misc/point.dart b/lib/src/misc/point.dart deleted file mode 100644 index 2077bb6ee..000000000 --- a/lib/src/misc/point.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'dart:math' as math; -import 'dart:ui'; - -/// Data represenation of point located on map instance -/// where [x] is horizontal and [y] is vertical pixel value -class CustomPoint extends math.Point { - const CustomPoint(super.x, super.y); - - /// Create new [CustomPoint] where [x] and [y] values are added to [other] - /// point [x] and [y] values - @override - CustomPoint operator +(math.Point other) { - return CustomPoint((x + other.x) as T, (y + other.y) as T); - } - - /// Create new [CustomPoint] where [x] and [y] values are subtracted from - /// [other] point [x] and [y] values - @override - CustomPoint operator -(math.Point other) { - return CustomPoint((x - other.x) as T, (y - other.y) as T); - } - - /// Create new [CustomPoint] where [x] and [y] values are scaled by [point] - /// values - CustomPoint scaleBy(CustomPoint point) { - return CustomPoint((x * point.x) as T, (y * point.y) as T); - } - - /// Create new [CustomPoint] whose [x] and [y] values are divided by other - /// [point] values - CustomPoint unscaleBy(CustomPoint point) { - return CustomPoint(x / point.x, y / point.y); - } - - /// Create new [CustomPoint] where [x] and [y] values are multiplied by - /// [factor] - @override - CustomPoint operator *(num factor) { - return CustomPoint((x * factor) as T, (y * factor) as T); - } - - /// Create new [CustomPoint] where [x] and [y] values are divided by [factor] - CustomPoint operator /(num factor) { - return CustomPoint((x / factor) as T, (y / factor) as T); - } - - /// Create new [CustomPoint] where [x] and [y] is rounded to int - CustomPoint round() { - return CustomPoint(x.round(), y.round()); - } - - /// Create new [CustomPoint] where [x] and [y] values are rounded up to int - CustomPoint ceil() { - return CustomPoint(x.ceil(), y.ceil()); - } - - /// Create new [CustomPoint] where [x] and [y] values are rounded down to int - CustomPoint floor() { - return CustomPoint(x.floor(), y.floor()); - } - - /// Create new [CustomPoint] whose [x] and [y] values are rotated by [radians] - /// in clockwise fashion - CustomPoint rotate(num radians) { - if (radians != 0.0) { - final cos = math.cos(radians); - final sin = math.sin(radians); - final nx = (cos * x) + (sin * y); - final ny = (cos * y) - (sin * x); - - return CustomPoint(nx, ny); - } - - return CustomPoint(x.toDouble(), y.toDouble()); - } - - CustomPoint toIntPoint() => CustomPoint(x.toInt(), y.toInt()); - - CustomPoint toDoublePoint() => - CustomPoint(x.toDouble(), y.toDouble()); - - @override - String toString() => 'CustomPoint ($x, $y)'; -} - -extension OffsetToCustomPointExtension on Offset { - CustomPoint toCustomPoint() => CustomPoint(dx, dy); -} diff --git a/lib/src/misc/point_extensions.dart b/lib/src/misc/point_extensions.dart new file mode 100644 index 000000000..dd1568100 --- /dev/null +++ b/lib/src/misc/point_extensions.dart @@ -0,0 +1,130 @@ +import 'dart:math'; +import 'dart:ui'; + +@Deprecated( + 'Prefer `Point`. ' + 'This class has been deprecated in favor of adding extension methods to Point. ' + 'This class is deprecated since v6.', +) +typedef CustomPoint = Point; + +extension PointExtension on Point { + /// Create new [Point] whose [x] and [y] values are divided by the respective + /// values in [point]. + Point unscaleBy(Point point) { + return Point(x / point.x, y / point.y); + } + + /// Create a new [Point] where the [x] and [y] values are divided by [factor]. + Point operator /(num factor) { + return Point(x / factor, y / factor); + } + + /// Create a new [Point] where the [x] and [y] values are rounded to the + /// nearest integer. + Point round() { + return Point(x.round(), y.round()); + } + + /// Create a new [Point] where the [x] and [y] values are rounded up to the + /// nearest integer. + Point ceil() { + return Point(x.ceil(), y.ceil()); + } + + /// Create a new [Point] where the [x] and [y] values are rounded down to the + /// nearest integer. + Point floor() { + return Point(x.floor(), y.floor()); + } + + /// Create a new [Point] whose [x] and [y] values are rotated clockwise by + /// [radians]. + Point rotate(num radians) { + if (radians != 0.0) { + final cosTheta = cos(radians); + final sinTheta = sin(radians); + final nx = (cosTheta * x) + (sinTheta * y); + final ny = (cosTheta * y) - (sinTheta * x); + + return Point(nx, ny); + } + + return toDoublePoint(); + } + + Point toIntPoint() => Point(x.toInt(), y.toInt()); + + Point toDoublePoint() => Point(x.toDouble(), y.toDouble()); + + Offset toOffset() => Offset(x.toDouble(), y.toDouble()); +} + +/// This extension contains methods which, if defined on Point, +/// could cause a runtime error when called on a Point with a non-int +/// argument. An example: +/// +/// Point(1, 2).subtract(1.5) would cause a runtime error because the +/// resulting x/y values are doubles and the return value is a Point since +/// the method returns Point. +/// +/// Note that division methods (unscaleBy and the / operator) are defined on +/// Point with a Point return argument because division +/// always returns a double. +extension DoublePointExtension on Point { + /// Subtract [other] from this Point. + Point subtract(Point other) { + return Point(x - other.x, y - other.y); + } + + /// Add [other] to this Point. + Point add(Point other) { + return Point(x + other.x, y + other.y); + } + + /// Create a new [Point] where [x] and [y] values are scaled by the respective + /// values in [other]. + Point scaleBy(Point other) { + return Point(x * other.x, y * other.y); + } +} + +/// This extension contains methods which, if defined on Point, +/// could cause a runtime error when called on a Point with a non-int +/// argument. An example: +/// +/// Point(1, 2).subtract(1.5) would cause a runtime error because the +/// resulting x/y values are doubles and the return value is a Point since +/// the method returns Point. +/// +/// The methods in this extension only take Point arguments to prevent +/// this. +extension IntegerPointExtension on Point { + /// Subtract [other] from this Point. + Point subtract(Point other) { + return Point(x - other.x, y - other.y); + } + + /// Add [other] to this Point. + Point add(Point other) { + return Point(x + other.x, y + other.y); + } + + /// Create a new [Point] where [x] and [y] values are scaled by the respective + /// values in [other]. + Point scaleBy(Point other) { + return Point(x * other.x, y * other.y); + } +} + +extension OffsetToPointExtension on Offset { + @Deprecated( + 'Prefer `toPoint()`. ' + "This method has been renamed as a result of CustomPoint's removal. " + 'This method is deprecated since v6.', + ) + Point toCustomPoint() => toPoint(); + + /// Creates a [Point] representation of this offset. + Point toPoint() => Point(dx, dy); +} diff --git a/lib/src/misc/private/bounds.dart b/lib/src/misc/private/bounds.dart index aea499226..08c283be2 100644 --- a/lib/src/misc/private/bounds.dart +++ b/lib/src/misc/private/bounds.dart @@ -1,22 +1,21 @@ -import 'dart:math' as math; - -import 'package:flutter_map/src/misc/point.dart'; +import 'dart:math' as math hide Point; +import 'dart:math' show Point; /// Rectangular bound delimited by orthogonal lines passing through two /// points. class Bounds { - final CustomPoint min; - final CustomPoint max; + final Point min; + final Point max; const Bounds._(this.min, this.max); - factory Bounds(CustomPoint a, CustomPoint b) { + factory Bounds(Point a, Point b) { final bounds1 = Bounds._(a, b); final bounds2 = bounds1.extend(a); return bounds2.extend(b); } - static Bounds containing(Iterable> points) { + static Bounds containing(Iterable> points) { var maxX = double.negativeInfinity; var maxY = double.negativeInfinity; var minX = double.infinity; @@ -38,8 +37,8 @@ class Bounds { } final bounds = Bounds._( - CustomPoint(minX, minY), - CustomPoint(maxX, maxY), + Point(minX, minY), + Point(maxX, maxY), ); return bounds; @@ -47,13 +46,13 @@ class Bounds { /// Creates a new [Bounds] obtained by expanding the current ones with a new /// point. - Bounds extend(CustomPoint point) { + Bounds extend(Point point) { return Bounds._( - CustomPoint( + Point( math.min(point.x, min.x), math.min(point.y, min.y), ), - CustomPoint( + Point( math.max(point.x, max.x), math.max(point.y, max.y), ), @@ -61,29 +60,29 @@ class Bounds { } /// This [Bounds] central point. - CustomPoint get center => CustomPoint( + Point get center => Point( (min.x + max.x) / 2, (min.y + max.y) / 2, ); /// Bottom-Left corner's point. - CustomPoint get bottomLeft => CustomPoint(min.x, max.y); + Point get bottomLeft => Point(min.x, max.y); /// Top-Right corner's point. - CustomPoint get topRight => CustomPoint(max.x, min.y); + Point get topRight => Point(max.x, min.y); /// Top-Left corner's point. - CustomPoint get topLeft => min; + Point get topLeft => min; /// Bottom-Right corner's point. - CustomPoint get bottomRight => max; + Point get bottomRight => max; /// A point that contains the difference between the point's axis projections. - CustomPoint get size { + Point get size { return max - min; } - bool contains(CustomPoint point) { + bool contains(Point point) { final min = point; final max = point; return containsBounds(Bounds(min, max)); @@ -113,7 +112,7 @@ class Bounds { final bottomY = math.min(max.y, b.max.y); if (leftX <= rightX && topY <= bottomY) { - return Bounds(CustomPoint(leftX, topY), CustomPoint(rightX, bottomY)); + return Bounds(Point(leftX, topY), Point(rightX, bottomY)); } return null; diff --git a/test/core/bounds_test.dart b/test/core/bounds_test.dart index c05643d0b..fcb6e3746 100644 --- a/test/core/bounds_test.dart +++ b/test/core/bounds_test.dart @@ -1,4 +1,5 @@ -import 'package:flutter_map/src/misc/point.dart'; +import 'dart:math'; + import 'package:flutter_map/src/misc/private/bounds.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -9,7 +10,7 @@ void main() { test( 'should create bounds with minimum point equal to minimum argument ' 'if maximum argument point is positioned higher', () { - final bounds = Bounds(const CustomPoint(1, 2), const CustomPoint(3, 4)); + final bounds = Bounds(const Point(1, 2), const Point(3, 4)); expect(bounds.min.x, equals(1.0)); expect(bounds.min.y, equals(2.0)); @@ -18,7 +19,7 @@ void main() { test( 'should create bounds with minimum point equal to maximum argument ' 'if maximum argument point is positioned lower', () { - final bounds = Bounds(const CustomPoint(3, 4), const CustomPoint(1, 2)); + final bounds = Bounds(const Point(3, 4), const Point(1, 2)); expect(bounds.min.x, equals(1.0)); expect(bounds.min.y, equals(2.0)); @@ -27,8 +28,7 @@ void main() { test( 'should create bounds with maximum point equal to minimum argument ' 'if maximum argument point is positioned lower', () { - final bounds = - Bounds(const CustomPoint(1, 2), const CustomPoint(0.01, 0.02)); + final bounds = Bounds(const Point(1, 2), const Point(0.01, 0.02)); expect(bounds.max.x, equals(1.0)); expect(bounds.max.y, equals(2.0)); @@ -37,8 +37,7 @@ void main() { test( 'should create bounds with maximum point equal to maximum argument ' 'if maximum argument point is positioned higher', () { - final bounds = - Bounds(const CustomPoint(0.01, 0.02), const CustomPoint(1, 2)); + final bounds = Bounds(const Point(0.01, 0.02), const Point(1, 2)); expect(bounds.max.x, equals(1.0)); expect(bounds.max.y, equals(2.0)); @@ -46,8 +45,7 @@ void main() { test('should get center of bounds as a point with x position', () { expect( - Bounds(CustomPoint(5.5, randomDouble()), - CustomPoint(3.3, randomDouble())) + Bounds(Point(5.5, randomDouble()), Point(3.3, randomDouble())) .center .x, equals(4.4)); @@ -55,8 +53,7 @@ void main() { test('should get center of bounds as a point with y position', () { expect( - Bounds(CustomPoint(randomDouble(), 3.2), - CustomPoint(randomDouble(), 6.6)) + Bounds(Point(randomDouble(), 3.2), Point(randomDouble(), 6.6)) .center .y, equals(4.9)); @@ -66,8 +63,8 @@ void main() { 'should create bounds with size represented as point with position' 'x based on distance between top left and bottom right conrners', () { final size = Bounds( - CustomPoint(1.1, randomDouble()), - CustomPoint(3.3, randomDouble()), + Point(1.1, randomDouble()), + Point(3.3, randomDouble()), ).size; // avoid float precision problems @@ -78,8 +75,8 @@ void main() { 'should create bounds with size represented as point with position' 'y based on distance between top left and bottom right conrners', () { final size = Bounds( - CustomPoint(randomDouble(), 2.2), - CustomPoint(randomDouble(), 5.5), + Point(randomDouble(), 2.2), + Point(randomDouble(), 5.5), ).size; // avoid float precision problems @@ -91,8 +88,7 @@ void main() { 'should create bounds with bottom left corner\'s x position ' 'using minimum point x position', () { expect( - Bounds(CustomPoint(2.2, randomDouble()), - CustomPoint(1.1, randomDouble())) + Bounds(Point(2.2, randomDouble()), Point(1.1, randomDouble())) .bottomLeft .x, equals(1.1)); @@ -102,8 +98,7 @@ void main() { 'should create bounds with bottom left corner\'s y position ' 'using maximum point y position', () { expect( - Bounds(CustomPoint(randomDouble(), 1), - CustomPoint(randomDouble(), 5.5)) + Bounds(Point(randomDouble(), 1), Point(randomDouble(), 5.5)) .bottomLeft .y, equals(5.5)); @@ -113,8 +108,7 @@ void main() { 'should create bounds with top right corner\'s x position ' 'using maximum point x position', () { expect( - Bounds(CustomPoint(1, randomDouble()), - CustomPoint(8.8, randomDouble())) + Bounds(Point(1, randomDouble()), Point(8.8, randomDouble())) .topRight .x, equals(8.8)); @@ -124,8 +118,7 @@ void main() { 'should create bounds with top right corner\'s y position ' 'using minimum point y position', () { expect( - Bounds(CustomPoint(randomDouble(), 9.9), - CustomPoint(randomDouble(), 100)) + Bounds(Point(randomDouble(), 9.9), Point(randomDouble(), 100)) .topRight .y, equals(9.9)); @@ -135,8 +128,7 @@ void main() { 'should create bounds with top left corner\'s x position ' 'using minimum point x position', () { expect( - Bounds(CustomPoint(1.1, randomDouble()), - CustomPoint(2.2, randomDouble())) + Bounds(Point(1.1, randomDouble()), Point(2.2, randomDouble())) .topLeft .x, equals(1.1)); @@ -146,8 +138,7 @@ void main() { 'should create bounds with top left corner\'s y position ' 'using minimum point y position', () { expect( - Bounds(CustomPoint(randomDouble(), 4.4), - CustomPoint(randomDouble(), 3.3)) + Bounds(Point(randomDouble(), 4.4), Point(randomDouble(), 3.3)) .topLeft .y, equals(3.3)); @@ -157,8 +148,7 @@ void main() { 'should create bounds with bottom right corner\'s x position ' 'using maximum point x position', () { expect( - Bounds(CustomPoint(5.5, randomDouble()), - CustomPoint(4.4, randomDouble())) + Bounds(Point(5.5, randomDouble()), Point(4.4, randomDouble())) .bottomRight .x, equals(5.5)); @@ -168,8 +158,7 @@ void main() { 'should create bounds with bottom right corner\'s y position ' 'using maximum point y position', () { expect( - Bounds(CustomPoint(randomDouble(), 101.3), - CustomPoint(randomDouble(), 101.4)) + Bounds(Point(randomDouble(), 101.3), Point(randomDouble(), 101.4)) .bottomRight .y, equals(101.4)); @@ -177,74 +166,71 @@ void main() { }); test('should be convertable to string', () { - expect( - Bounds(const CustomPoint(1.1, 2.2), const CustomPoint(3.3, 4.4)) - .toString(), - equals('Bounds(CustomPoint (1.1, 2.2), CustomPoint (3.3, 4.4))')); + expect(Bounds(const Point(1.1, 2.2), const Point(3.3, 4.4)).toString(), + equals('Bounds(Point(1.1, 2.2), Point(3.3, 4.4))')); }); group('extend', () { test('should create new bounds with updated minimum x position', () { - final bounds = Bounds(CustomPoint(-10.1, randomDouble()), - CustomPoint(11.1, randomDouble())); - final extendedBounds = - bounds.extend(CustomPoint(-13.3, randomDouble())); + final bounds = + Bounds(Point(-10.1, randomDouble()), Point(11.1, randomDouble())); + final extendedBounds = bounds.extend(Point(-13.3, randomDouble())); expect(extendedBounds.min.x, -13.3); }); test('should create new bounds with updated minimum y position', () { - final bounds = Bounds(CustomPoint(randomDouble(), 3.5), - CustomPoint(randomDouble(), 101.3)); - final extendedBounds = bounds.extend(CustomPoint(randomDouble(), 2.1)); + final bounds = + Bounds(Point(randomDouble(), 3.5), Point(randomDouble(), 101.3)); + final extendedBounds = bounds.extend(Point(randomDouble(), 2.1)); expect(extendedBounds.min.y, equals(2.1)); }); test('should create new bounds with updated maximum x position', () { - final bounds = Bounds(CustomPoint(4.5, randomDouble()), - CustomPoint(16.3, randomDouble())); - final extendedBounds = bounds.extend(CustomPoint(18.9, randomDouble())); + final bounds = + Bounds(Point(4.5, randomDouble()), Point(16.3, randomDouble())); + final extendedBounds = bounds.extend(Point(18.9, randomDouble())); expect(extendedBounds.max.x, equals(18.9)); }); test('should create new bounds with updated maximum y position', () { - final bounds = Bounds(CustomPoint(randomDouble(), 3.5), - CustomPoint(randomDouble(), 34.3)); - final extendedBounds = bounds.extend(CustomPoint(randomDouble(), 38.3)); + final bounds = + Bounds(Point(randomDouble(), 3.5), Point(randomDouble(), 34.3)); + final extendedBounds = bounds.extend(Point(randomDouble(), 38.3)); expect(extendedBounds.max.y, equals(38.3)); }); test('should create new bounds and keep existing minimum x position', () { - final bounds = Bounds(CustomPoint(-10.1, randomDouble()), - CustomPoint(11.1, randomDouble())); - final extendedBounds = bounds.extend(CustomPoint(-7.7, randomDouble())); + final bounds = + Bounds(Point(-10.1, randomDouble()), Point(11.1, randomDouble())); + final extendedBounds = bounds.extend(Point(-7.7, randomDouble())); expect(extendedBounds.min.x, equals(bounds.min.x)); }); test('should create new bounds and keep existing minimum y position', () { - final bounds = Bounds(CustomPoint(randomDouble(), 3.3), - CustomPoint(randomDouble(), 12.7)); - final extendedBounds = bounds.extend(CustomPoint(randomDouble(), 4.4)); + final bounds = + Bounds(Point(randomDouble(), 3.3), Point(randomDouble(), 12.7)); + final extendedBounds = bounds.extend(Point(randomDouble(), 4.4)); expect(extendedBounds.min.y, equals(bounds.min.y)); }); test('should create new bounds and keep existing maximum x position', () { - final bounds = Bounds(CustomPoint(-15.5, randomDouble()), - CustomPoint(25.8, randomDouble())); - final extendedBounds = bounds.extend(CustomPoint(25.7, randomDouble())); + final bounds = + Bounds(Point(-15.5, randomDouble()), Point(25.8, randomDouble())); + final extendedBounds = bounds.extend(Point(25.7, randomDouble())); expect(extendedBounds.max.x, equals(bounds.max.x)); }); test('should create new bounds and keep existing maximum y position', () { - final bounds = Bounds( - CustomPoint(randomDouble(), 0), CustomPoint(randomDouble(), 15.5)); - final extendedBounds = bounds.extend(CustomPoint(randomDouble(), 15.4)); + final bounds = + Bounds(Point(randomDouble(), 0), Point(randomDouble(), 15.5)); + final extendedBounds = bounds.extend(Point(randomDouble(), 15.4)); expect(extendedBounds.max.y, equals(bounds.max.y)); }); @@ -254,62 +240,62 @@ void main() { test( 'should contain compared bounds if they are completely within ' 'the bounds', () { - final bounds = Bounds( - const CustomPoint(101.1, 88.1), const CustomPoint(133.1, 60.3)); + final bounds = + Bounds(const Point(101.1, 88.1), const Point(133.1, 60.3)); expect( - bounds.containsBounds(Bounds(const CustomPoint(110.1, 77.3), - const CustomPoint(128.3, 65.5))), + bounds.containsBounds( + Bounds(const Point(110.1, 77.3), const Point(128.3, 65.5))), isTrue); }); test( 'should NOT contain compared bounds if they are NOT completely ' 'within the bounds', () { - final bounds = Bounds( - const CustomPoint(101.1, 88.1), const CustomPoint(133.1, 60.3)); + final bounds = + Bounds(const Point(101.1, 88.1), const Point(133.1, 60.3)); expect( - bounds.containsBounds(Bounds(const CustomPoint(110.1, 77.3), - const CustomPoint(133.2, 65.5))), + bounds.containsBounds( + Bounds(const Point(110.1, 77.3), const Point(133.2, 65.5))), isFalse); }); test( 'should contain compared bounds partially if at least one edge ' 'overlaps within the bounds', () { - final bounds = Bounds( - const CustomPoint(101.1, 88.1), const CustomPoint(133.1, 60.3)); + final bounds = + Bounds(const Point(101.1, 88.1), const Point(133.1, 60.3)); expect( - bounds.containsPartialBounds(Bounds(const CustomPoint(200.22, 60.2), - const CustomPoint(133.1, 60.3))), + bounds.containsPartialBounds( + Bounds(const Point(200.22, 60.2), const Point(133.1, 60.3))), isTrue); }); test( 'should NOT contain compared bounds partially if not a single edge ' 'overlaps within the bounds', () { - final bounds = Bounds( - const CustomPoint(101.1, 88.1), const CustomPoint(133.1, 60.3)); + final bounds = + Bounds(const Point(101.1, 88.1), const Point(133.1, 60.3)); expect( - bounds.containsPartialBounds(Bounds(const CustomPoint(200.22, 60.2), - const CustomPoint(133.2, 60.3))), + bounds.containsPartialBounds( + Bounds(const Point(200.22, 60.2), const Point(133.2, 60.3))), isFalse); }); test('should contain given point within the bounds', () { expect( - Bounds(const CustomPoint(0, 50), const CustomPoint(50, 0)) - .contains(const CustomPoint(25, 25)), + Bounds(const Point(0, 50), const Point(50, 0)) + .contains(const Point(25, 25)), isTrue); }); test('should NOT contain given point within the bounds', () { expect( - Bounds(const CustomPoint(0, 50), const CustomPoint(50, 0)) - .contains(const CustomPoint(51, 51)), + Bounds(const Point(0, 50), const Point(50, 0)) + .contains(const Point(51, 51)), isFalse); }); }); diff --git a/test/layer/tile_layer/tile_bounds/crs_fakes.dart b/test/layer/tile_layer/tile_bounds/crs_fakes.dart index 6b2a02ab7..4465604c0 100644 --- a/test/layer/tile_layer/tile_bounds/crs_fakes.dart +++ b/test/layer/tile_layer/tile_bounds/crs_fakes.dart @@ -1,5 +1,6 @@ +import 'dart:math'; + import 'package:flutter_map/src/geo/crs.dart'; -import 'package:flutter_map/src/misc/point.dart'; import 'package:latlong2/latlong.dart'; class FakeInfiniteCrs extends Crs { @@ -23,7 +24,7 @@ class FakeInfiniteCrs extends Crs { /// Any projection just to get non-zero coordiantes. @override - CustomPoint latLngToPoint(LatLng latlng, double zoom) { + Point latLngToPoint(LatLng latlng, double zoom) { return const Epsg3857().latLngToPoint(latlng, zoom); } } diff --git a/test/layer/tile_layer/tile_bounds/tile_bounds_at_zoom_test.dart b/test/layer/tile_layer/tile_bounds/tile_bounds_at_zoom_test.dart index dd986bd6a..2ad38f20a 100644 --- a/test/layer/tile_layer/tile_bounds/tile_bounds_at_zoom_test.dart +++ b/test/layer/tile_layer/tile_bounds/tile_bounds_at_zoom_test.dart @@ -1,7 +1,8 @@ +import 'dart:math'; + import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_coordinates.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_range.dart'; -import 'package:flutter_map/src/misc/point.dart'; import 'package:flutter_map/src/misc/private/bounds.dart'; import 'package:test/test.dart'; @@ -18,7 +19,7 @@ void main() { int zoom, int minX, int minY, int maxX, int maxY) => DiscreteTileRange( zoom, - Bounds(CustomPoint(minX, minY), CustomPoint(maxX, maxY)), + Bounds(Point(minX, minY), Point(maxX, maxY)), ); test('InfiniteTileBoundsAtZoom', () { @@ -159,7 +160,7 @@ void main() { discreteTileRange(0, 0, 2, 12, 10).coordinates, ); - // Keeps all wrapped coordiantes, only non-wraped coordaintes in range. + // Keeps all wrapped coordinates, only non-wrapped coordinates in range. expect( tileBoundsAtZoom .validCoordinatesIn(discreteTileRange(0, 13, 0, 25, 12)), diff --git a/test/layer/tile_layer/tile_bounds/tile_bounds_test.dart b/test/layer/tile_layer/tile_bounds/tile_bounds_test.dart index e668f3235..152a91931 100644 --- a/test/layer/tile_layer/tile_bounds/tile_bounds_test.dart +++ b/test/layer/tile_layer/tile_bounds/tile_bounds_test.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter_map/plugin_api.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart'; @@ -35,8 +37,8 @@ void main() { (e) => e.tileRange, 'tileRange', isA() - .having((e) => e.min, 'min', const CustomPoint(11, 11)) - .having((e) => e.max, 'max', const CustomPoint(20, 20)), + .having((e) => e.min, 'min', const Point(11, 11)) + .having((e) => e.max, 'max', const Point(20, 20)), ), ); }); @@ -54,8 +56,8 @@ void main() { (e) => e.tileRange, 'tileRange', isA() - .having((e) => e.min, 'min', const CustomPoint(-180, -90)) - .having((e) => e.max, 'max', const CustomPoint(179, 89)), + .having((e) => e.min, 'min', const Point(-180, -90)) + .having((e) => e.max, 'max', const Point(179, 89)), ), ); }); @@ -74,8 +76,8 @@ void main() { (e) => e.tileRange, 'tileRange', isA() - .having((e) => e.min, 'min', const CustomPoint(0, 0)) - .having((e) => e.max, 'max', const CustomPoint(31, 31)), + .having((e) => e.min, 'min', const Point(0, 0)) + .having((e) => e.max, 'max', const Point(31, 31)), ) .having((e) => e.wrappedAxisIsAlwaysInBounds, 'wrappedAxisIsAlwaysInBounds', isTrue) @@ -103,8 +105,8 @@ void main() { (e) => e.tileRange, 'tileRange', isA() - .having((e) => e.min, 'min', const CustomPoint(16, 16)) - .having((e) => e.max, 'max', const CustomPoint(31, 31)), + .having((e) => e.min, 'min', const Point(16, 16)) + .having((e) => e.max, 'max', const Point(31, 31)), ) .having((e) => e.wrappedAxisIsAlwaysInBounds, 'wrappedAxisIsAlwaysInBounds', isFalse) diff --git a/test/layer/tile_layer/tile_range_test.dart b/test/layer/tile_layer/tile_range_test.dart index 6c28a1761..e6f3f83d6 100644 --- a/test/layer/tile_layer/tile_range_test.dart +++ b/test/layer/tile_layer/tile_range_test.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter_map/plugin_api.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_range.dart'; import 'package:test/test.dart'; @@ -9,12 +11,12 @@ void main() { final tileRange1 = DiscreteTileRange.fromPixelBounds( zoom: 0, tileSize: 1, - pixelBounds: Bounds(const CustomPoint(1, 1), const CustomPoint(2, 2)), + pixelBounds: Bounds(const Point(1, 1), const Point(2, 2)), ); final tileRange2 = DiscreteTileRange.fromPixelBounds( zoom: 0, tileSize: 1, - pixelBounds: Bounds(const CustomPoint(3, 3), const CustomPoint(4, 4)), + pixelBounds: Bounds(const Point(3, 3), const Point(4, 4)), ); final emptyTileRange = tileRange1.intersect(tileRange2); @@ -33,8 +35,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(25.0, 25.0), - const CustomPoint(25.0, 25.0), + const Point(25.0, 25.0), + const Point(25.0, 25.0), ), ); @@ -47,8 +49,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(0.0, 0.0), - const CustomPoint(0.1, 0.1), + const Point(0.0, 0.0), + const Point(0.1, 0.1), ), ); @@ -61,8 +63,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(0.0, 0.0), - const CustomPoint(9.99, 9.99), + const Point(0.0, 0.0), + const Point(9.99, 9.99), ), ); @@ -75,8 +77,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(19.99, 19.99), - const CustomPoint(30.1, 30.1), + const Point(19.99, 19.99), + const Point(30.1, 30.1), ), ); @@ -99,8 +101,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(25.0, 25.0), - const CustomPoint(25.0, 25.0), + const Point(25.0, 25.0), + const Point(25.0, 25.0), ), ); @@ -126,8 +128,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(25.0, 25.0), - const CustomPoint(25.0, 25.0), + const Point(25.0, 25.0), + const Point(25.0, 25.0), ), ); @@ -135,8 +137,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(35.0, 35.0), - const CustomPoint(35.0, 35.0), + const Point(35.0, 35.0), + const Point(35.0, 35.0), ), ); @@ -152,8 +154,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(25.0, 25.0), - const CustomPoint(35.0, 35.0), + const Point(25.0, 25.0), + const Point(35.0, 35.0), ), ); @@ -161,8 +163,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(35.0, 35.0), - const CustomPoint(45.0, 45.0), + const Point(35.0, 35.0), + const Point(45.0, 45.0), ), ); @@ -180,8 +182,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(25.0, 25.0), - const CustomPoint(35.0, 35.0), + const Point(25.0, 25.0), + const Point(35.0, 35.0), ), ); @@ -189,8 +191,8 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(15.0, 15.0), - const CustomPoint(45.0, 45.0), + const Point(15.0, 15.0), + const Point(45.0, 45.0), ), ); @@ -209,13 +211,13 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(35.0, 35.0), - const CustomPoint(45.0, 45.0), + const Point(35.0, 35.0), + const Point(45.0, 45.0), ), ); - expect(tileRange.min, (const CustomPoint(3, 3))); - expect(tileRange.max, (const CustomPoint(4, 4))); + expect(tileRange.min, (const Point(3, 3))); + expect(tileRange.max, (const Point(4, 4))); }); group('center', () { @@ -224,12 +226,12 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(35.0, 35.0), - const CustomPoint(35.0, 35.0), + const Point(35.0, 35.0), + const Point(35.0, 35.0), ), ); - expect(tileRange.center, const CustomPoint(3, 3)); + expect(tileRange.center, const Point(3, 3)); }); test('multiple tiles, even number of tiles', () { @@ -237,12 +239,12 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(35.0, 35.0), - const CustomPoint(45.0, 45.0), + const Point(35.0, 35.0), + const Point(45.0, 45.0), ), ); - expect(tileRange.center, const CustomPoint(3.5, 3.5)); + expect(tileRange.center, const Point(3.5, 3.5)); }); test('multiple tiles, odd number of tiles', () { @@ -250,12 +252,12 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(35.0, 35.0), - const CustomPoint(55.0, 55.0), + const Point(35.0, 35.0), + const Point(55.0, 55.0), ), ); - expect(tileRange.center, const CustomPoint(4, 4)); + expect(tileRange.center, const Point(4, 4)); }); }); @@ -264,20 +266,20 @@ void main() { zoom: 0, tileSize: 10, pixelBounds: Bounds( - const CustomPoint(35.0, 35.0), - const CustomPoint(35.0, 35.0), + const Point(35.0, 35.0), + const Point(35.0, 35.0), ), ); - expect(tileRange.contains(const CustomPoint(2, 2)), isFalse); - expect(tileRange.contains(const CustomPoint(3, 2)), isFalse); - expect(tileRange.contains(const CustomPoint(4, 2)), isFalse); - expect(tileRange.contains(const CustomPoint(2, 3)), isFalse); - expect(tileRange.contains(const CustomPoint(3, 3)), isTrue); - expect(tileRange.contains(const CustomPoint(4, 3)), isFalse); - expect(tileRange.contains(const CustomPoint(2, 4)), isFalse); - expect(tileRange.contains(const CustomPoint(3, 4)), isFalse); - expect(tileRange.contains(const CustomPoint(4, 4)), isFalse); + expect(tileRange.contains(const Point(2, 2)), isFalse); + expect(tileRange.contains(const Point(3, 2)), isFalse); + expect(tileRange.contains(const Point(4, 2)), isFalse); + expect(tileRange.contains(const Point(2, 3)), isFalse); + expect(tileRange.contains(const Point(3, 3)), isTrue); + expect(tileRange.contains(const Point(4, 3)), isFalse); + expect(tileRange.contains(const Point(2, 4)), isFalse); + expect(tileRange.contains(const Point(3, 4)), isFalse); + expect(tileRange.contains(const Point(4, 4)), isFalse); }); }); } diff --git a/test/misc/frame_constraint_test.dart b/test/misc/frame_constraint_test.dart index 3d02b91a4..0f034fdae 100644 --- a/test/misc/frame_constraint_test.dart +++ b/test/misc/frame_constraint_test.dart @@ -1,8 +1,9 @@ +import 'dart:math'; + import 'package:flutter_map/src/geo/crs.dart'; import 'package:flutter_map/src/geo/latlng_bounds.dart'; import 'package:flutter_map/src/map/camera/camera.dart'; import 'package:flutter_map/src/map/camera/camera_constraint.dart'; -import 'package:flutter_map/src/misc/point.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:latlong2/latlong.dart'; @@ -22,7 +23,7 @@ void main() { center: const LatLng(-90, -180), zoom: 1, rotation: 45, - nonRotatedSize: const CustomPoint(200, 300), + nonRotatedSize: const Point(200, 300), ); final clamped = mapConstraint.constrain(camera)!;