Skip to content

Commit

Permalink
feat!: migrate Point<double> to Offset internally (#1996)
Browse files Browse the repository at this point in the history
* initial commit, started work, going well

* more insane progress, still going well

* compiler happy

* deprecate notices, only really needed because of bounds and tilecoordinates

* this definitely touches an externally accessible API:

mapController.camera.pointToLatLng

* dart format

* remove stuff

* more stuffffffffff

* oops

* fix tests

* use double.negativeInfinity no Offset.negitiveInfinity exists

* rename pointToLatLng to offsetToLatLng

* remove unused duplicate function

* remove todo

* Update lib/src/map/camera/camera.dart

Co-authored-by: Luka S <[email protected]>

* format change

* replace helper function

* start migration guide

* mark as internal

* Update lib/src/layer/shared/layer_interactivity/internal_hit_detectable.dart

Co-authored-by: Luka S <[email protected]>

* rename

* re-phrase things

* rotateAroundPoint fix

* convert doublepoint to offset

* dart format

* fix visible scope lol

* Update flutter_map.dart

* Update internal_hit_detectable.dart

* fix straggling Point

* convert to use size

* migrate easy Bounds<double> to Rect

* dart format .

* migrate most methods that use Bounds

* dart format .

* Update CHANGELOG.md

* more complete migration of Rect

* dart format

* convert Bounds to IntegerBounds and made internal

most methods on integer bounds are not used

* fix lints

* fix test

* fix bug introduced in commit b6d2d95

b6d2d95

* fix lint

* rename method

* fix some nits

* Update lib/src/geo/crs.dart

Co-authored-by: Luka S <[email protected]>

* Update lib/src/geo/crs.dart

Co-authored-by: Luka S <[email protected]>

* Update lib/src/geo/crs.dart

Co-authored-by: Luka S <[email protected]>

* dart format

* rename project method

* dart format .

* fix unused import

---------

Co-authored-by: Luka S <[email protected]>
  • Loading branch information
mootw and JaffaKetchup authored Dec 5, 2024
1 parent 4dc3bca commit 60d9846
Show file tree
Hide file tree
Showing 50 changed files with 675 additions and 779 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ Please consider [donating](https://docs.fleaflet.dev/supporters#support-us) or [

This CHANGELOG does not include every commit and/or PR - it is a hand picked selection of the most important ones. For a full list of changes, please check the GitHub repository releases/tags.

## [8.0.0] - 2024/07/02

Migration from `Point` class internally, but this also affects the external API.

Migration Guide:
- any methods that previously required `Point<double>` now require `Offset`, `Size`, or `Rect` as return values and parameters
- `pointToLatLng` -> `offsetToLatLng`
- `PointExtension` and `OffsetToPointExtension` marked as internal
- `MapController.rotateAroundPoint` now only accepts an Offset


Contains the following user-affecting bug fixes:


## [7.0.2] - 2024/07/02

> Note that this version causes a technically breaking change by removing `PolygonLayer.useDynamicUpdate` & `PolylineLayer.useDynamicUpdate`, introduced in v7.0.1. However, the implementations for these was broken on introduction, and their intended purpose no longer exists. Therefore, these should not have been used in any capacity, and should not affect any projects.
Expand Down
18 changes: 9 additions & 9 deletions benchmark/crs.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'dart:async';
import 'dart:math' as math;
import 'dart:ui';

import 'package:flutter_map/src/geo/crs.dart';
import 'package:latlong2/latlong.dart';
Expand Down Expand Up @@ -49,14 +49,14 @@ Future<void> main() async {
return x + y;
}));

results.add(await timedRun('Concrete type: ${crs.code}.latLngToPoint()', () {
results.add(await timedRun('Concrete type: ${crs.code}.latLngToOffset()', () {
double x = 0;
double y = 0;
for (int i = 0; i < N; ++i) {
final latlng = LatLng((i % 90).toDouble(), (i % 180).toDouble());
final p = crs.latLngToPoint(latlng, 1);
x += p.x;
y += p.y;
final p = crs.latLngToOffset(latlng, 1);
x += p.dx;
y += p.dy;
}
return x + y;
}));
Expand Down Expand Up @@ -84,9 +84,9 @@ Future<void> main() async {
double y = 0;
for (int i = 0; i < N; ++i) {
final latlng = LatLng((i % 90).toDouble(), (i % 180).toDouble());
final point = crs.latLngToPoint(latlng, 1);
x += point.x;
y += point.y;
final point = crs.latLngToOffset(latlng, 1);
x += point.dx;
y += point.dy;
}
return x + y;
}));
Expand All @@ -95,7 +95,7 @@ Future<void> main() async {
double x = 0;
double y = 0;
for (int i = 0; i < N; ++i) {
final latlng = crs.pointToLatLng(math.Point<double>(x, y), 1);
final latlng = crs.offsetToLatLng(Offset(x, y), 1);
x += latlng.longitude;
y += latlng.latitude;
}
Expand Down
4 changes: 2 additions & 2 deletions benchmark/point_in_polygon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Future<void> main() async {
final circle = makeCircle(1000, 1, 0);

results.add(await timedRun('In circle', () {
const point = math.Point(0, 0);
const point = Offset.zero;

bool yesPlease = true;
for (int i = 0; i < N; ++i) {
Expand All @@ -61,7 +61,7 @@ Future<void> main() async {
}));

results.add(await timedRun('Not in circle', () {
const point = math.Point(4, 4);
const point = Offset(4, 4);

bool noSir = false;
for (int i = 0; i < N; ++i) {
Expand Down
6 changes: 3 additions & 3 deletions example/lib/pages/epsg3996_crs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class EPSG3996PageState extends State<EPSG3996Page> {
128,
];

final epsg3413Bounds = Bounds<double>(
const Point<double>(-4511619, -4511336),
const Point<double>(4510883, 4510996),
final epsg3413Bounds = Rect.fromPoints(
const Offset(-4511619, -4511336),
const Offset(4510883, 4510996),
);

maxZoom = resolutions.length - 1;
Expand Down
12 changes: 5 additions & 7 deletions example/lib/pages/latlng_to_screen_point.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_map/flutter_map.dart';
Expand All @@ -23,7 +21,7 @@ class _LatLngToScreenPointPageState extends State<LatLngToScreenPointPage> {
final mapController = MapController();

LatLng? tappedCoords;
Point<double>? tappedPoint;
Offset? tappedPoint;

@override
void initState() {
Expand Down Expand Up @@ -52,8 +50,8 @@ class _LatLngToScreenPointPageState extends State<LatLngToScreenPointPage> {
),
onTap: (_, latLng) {
final point = mapController.camera
.latLngToScreenPoint(tappedCoords = latLng);
setState(() => tappedPoint = Point(point.x, point.y));
.latLngToScreenOffset(tappedCoords = latLng);
setState(() => tappedPoint = Offset(point.dx, point.dy));
},
),
children: [
Expand All @@ -77,8 +75,8 @@ class _LatLngToScreenPointPageState extends State<LatLngToScreenPointPage> {
),
if (tappedPoint != null)
Positioned(
left: tappedPoint!.x - 60 / 2,
top: tappedPoint!.y - 60 / 2,
left: tappedPoint!.dx - 60 / 2,
top: tappedPoint!.dy - 60 / 2,
child: const IgnorePointer(
child: Icon(
Icons.center_focus_strong_outlined,
Expand Down
7 changes: 3 additions & 4 deletions example/lib/pages/screen_point_to_latlng.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_example/misc/tile_providers.dart';
Expand Down Expand Up @@ -95,8 +93,9 @@ class PointToLatlngPage extends State<ScreenPointToLatLngPage> {
);
}

void updatePoint(BuildContext context) => setState(() => latLng =
mapController.camera.pointToLatLng(Point(_getPointX(context), pointY)));
void updatePoint(BuildContext context) =>
setState(() => latLng = mapController.camera
.screenOffsetToLatLng(Offset(_getPointX(context), pointY)));

double _getPointX(BuildContext context) =>
MediaQuery.sizeOf(context).width / 2;
Expand Down
2 changes: 0 additions & 2 deletions lib/flutter_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,3 @@ export 'package:flutter_map/src/map/options/cursor_keyboard_rotation.dart';
export 'package:flutter_map/src/map/options/interaction.dart';
export 'package:flutter_map/src/map/options/options.dart';
export 'package:flutter_map/src/map/widget.dart';
export 'package:flutter_map/src/misc/bounds.dart';
export 'package:flutter_map/src/misc/extensions.dart';
88 changes: 43 additions & 45 deletions lib/src/geo/crs.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:math' as math hide Point;
import 'dart:math' show Point;
import 'dart:ui';

import 'package:flutter_map/src/misc/bounds.dart';
import 'package:flutter_map/src/misc/simplify.dart';
import 'package:flutter_map/src/misc/extensions.dart';
import 'package:latlong2/latlong.dart';
import 'package:meta/meta.dart';
import 'package:proj4dart/proj4dart.dart' as proj4;
Expand Down Expand Up @@ -51,14 +51,14 @@ abstract class Crs {
/// scaled map point.
(double, double) latLngToXY(LatLng latlng, double scale);

/// Similar to [latLngToXY] but converts the XY coordinates to a [Point].
Point<double> latLngToPoint(LatLng latlng, double zoom) {
/// Similar to [latLngToXY] but converts the XY coordinates to an [Offset].
Offset latLngToOffset(LatLng latlng, double zoom) {
final (x, y) = latLngToXY(latlng, scale(zoom));
return Point<double>(x, y);
return Offset(x, y);
}

/// Converts a map point to the sphere coordinate (at a certain zoom).
LatLng pointToLatLng(Point point, double zoom);
LatLng offsetToLatLng(Offset point, double zoom);

/// Zoom to Scale function.
double scale(double zoom) => 256.0 * math.pow(2, zoom);
Expand All @@ -67,7 +67,7 @@ abstract class Crs {
double zoom(double scale) => math.log(scale / 256) / math.ln2;

/// Rescales the bounds to a given zoom value.
Bounds<double>? getProjectedBounds(double zoom);
Rect? getProjectedBounds(double zoom);

/// Returns true if we want the world to be replicated, longitude-wise.
bool get replicatesWorldLongitude => false;
Expand Down Expand Up @@ -108,26 +108,26 @@ abstract class CrsWithStaticTransformation extends Crs {
}

@override
LatLng pointToLatLng(Point point, double zoom) {
LatLng offsetToLatLng(Offset point, double zoom) {
final (x, y) = _transformation.untransform(
point.x.toDouble(),
point.y.toDouble(),
point.dx,
point.dy,
scale(zoom),
);
return projection.unprojectXY(x, y);
}

@override
Bounds<double>? getProjectedBounds(double zoom) {
Rect? getProjectedBounds(double zoom) {
if (infinite) return null;

final b = projection.bounds!;
final s = scale(zoom);
final (minx, miny) = _transformation.transform(b.min.x, b.min.y, s);
final (maxx, maxy) = _transformation.transform(b.max.x, b.max.y, s);
return Bounds<double>(
Point<double>(minx, miny),
Point<double>(maxx, maxy),
final (minx, miny) = _transformation.transform(b.min.dx, b.min.dy, s);
final (maxx, maxy) = _transformation.transform(b.max.dx, b.max.dy, s);
return Rect.fromPoints(
Offset(minx, miny),
Offset(maxx, maxy),
);
}
}
Expand Down Expand Up @@ -171,13 +171,13 @@ class Epsg3857 extends CrsWithStaticTransformation {
);

@override
Point<double> latLngToPoint(LatLng latlng, double zoom) {
Offset latLngToOffset(LatLng latlng, double zoom) {
final (x, y) = _transformation.transform(
SphericalMercator.projectLng(latlng.longitude),
SphericalMercator.projectLat(latlng.latitude),
scale(zoom),
);
return Point<double>(x, y);
return Offset(x, y);
}

@override
Expand Down Expand Up @@ -222,7 +222,7 @@ class Proj4Crs extends Crs {
required String code,
required proj4.Projection proj4Projection,
List<Point<double>>? origins,
Bounds<double>? bounds,
Rect? bounds,
List<double>? scales,
List<double>? resolutions,
}) {
Expand Down Expand Up @@ -282,30 +282,29 @@ class Proj4Crs extends Crs {

/// Converts a map point to the sphere coordinate (at a certain zoom).
@override
LatLng pointToLatLng(Point point, double zoom) {
LatLng offsetToLatLng(Offset point, double zoom) {
final (x, y) = _getTransformationByZoom(zoom).untransform(
point.x.toDouble(),
point.y.toDouble(),
point.dx,
point.dy,
scale(zoom),
);
return projection.unprojectXY(x, y);
}

/// Rescales the bounds to a given zoom value.
@override
Bounds<double>? getProjectedBounds(double zoom) {
Rect? getProjectedBounds(double zoom) {
if (infinite) return null;

final b = projection.bounds!;
final zoomScale = scale(zoom);

final transformation = _getTransformationByZoom(zoom);
final (minx, miny) = transformation.transform(b.min.x, b.min.y, zoomScale);
final (maxx, maxy) = transformation.transform(b.max.x, b.max.y, zoomScale);
return Bounds<double>(
Point<double>(minx, miny),
Point<double>(maxx, maxy),
);
final (minx, miny) =
transformation.transform(b.min.dx, b.min.dy, zoomScale);
final (maxx, maxy) =
transformation.transform(b.max.dx, b.max.dy, zoomScale);
return Rect.fromPoints(Offset(minx, miny), Offset(maxx, maxy));
}

/// Zoom to Scale function.
Expand Down Expand Up @@ -371,18 +370,18 @@ class Proj4Crs extends Crs {
/// Inherit from this class if you want to create or implement your own CRS.
@immutable
abstract class Projection {
/// The [Bounds] for the coordinates of this [Projection].
final Bounds<double>? bounds;
/// The bounds for the coordinates of this [Projection].
final Rect? bounds;

/// Base constructor for the abstract [Projection] class that sets the
/// required fields.
const Projection(this.bounds);

/// Converts a [LatLng] to a coordinates and returns them as [Point] object.
/// Converts a [LatLng] to a coordinates and returns them as an [Offset].
@nonVirtual
Point<double> project(LatLng latlng) {
Offset project(LatLng latlng) {
final (x, y) = projectXY(latlng);
return Point<double>(x, y);
return Offset(x, y);
}

/// Converts a [LatLng] to geometry coordinates.
Expand Down Expand Up @@ -418,10 +417,10 @@ abstract class Projection {
/// 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<DoublePoint> projectList(List<LatLng> points, {LatLng? referencePoint}) {
List<Offset> projectList(List<LatLng> points, {LatLng? referencePoint}) {
late double previousX;
final worldWidth = getWorldWidth();
return List<DoublePoint>.generate(
return List<Offset>.generate(
points.length,
(j) {
if (j == 0 && referencePoint != null) {
Expand All @@ -436,18 +435,15 @@ abstract class Projection {
}
}
previousX = x;
return DoublePoint(x, y);
return Offset(x, y);
},
growable: false,
);
}
}

class _LonLat extends Projection {
static const _bounds = Bounds<double>.unsafe(
Point<double>(-180, -90),
Point<double>(180, 90),
);
static const _bounds = Rect.fromLTRB(-180, -90, 180, 90);

const _LonLat() : super(_bounds);

Expand All @@ -472,9 +468,11 @@ class SphericalMercator extends Projection {
static const double _boundsD = r * math.pi;

/// The constant Bounds of the [SphericalMercator] projection.
static const Bounds<double> _bounds = Bounds<double>.unsafe(
Point<double>(-_boundsD, -_boundsD),
Point<double>(_boundsD, _boundsD),
static const Rect _bounds = Rect.fromLTRB(
-_boundsD,
-_boundsD,
_boundsD,
_boundsD,
);

/// Constant constructor for the [SphericalMercator] projection.
Expand Down Expand Up @@ -518,7 +516,7 @@ class _Proj4Projection extends Projection {

_Proj4Projection({
required this.proj4Projection,
required Bounds<double>? bounds,
required Rect? bounds,
}) : epsg4326 = proj4.Projection.WGS84,
super(bounds);

Expand Down
Loading

0 comments on commit 60d9846

Please sign in to comment.