Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make flutter_map v8 possible #230

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions example/lib/clustering_many_markers_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ class ClusteringManyMarkersPage extends StatefulWidget {
const ClusteringManyMarkersPage({super.key});

@override
State<ClusteringManyMarkersPage> createState() =>
_ClusteringManyMarkersPageState();
State<ClusteringManyMarkersPage> createState() => _ClusteringManyMarkersPageState();
}

class _ClusteringManyMarkersPageState extends State<ClusteringManyMarkersPage> {
Expand Down Expand Up @@ -61,8 +60,7 @@ class _ClusteringManyMarkersPageState extends State<ClusteringManyMarkersPage> {
drawer: buildDrawer(context, ClusteringManyMarkersPage.route),
body: FlutterMap(
options: MapOptions(
initialCenter: LatLng((maxLatLng.latitude + minLatLng.latitude) / 2,
(maxLatLng.longitude + minLatLng.longitude) / 2),
initialCenter: LatLng((maxLatLng.latitude + minLatLng.latitude) / 2, (maxLatLng.longitude + minLatLng.longitude) / 2),
initialZoom: 6,
maxZoom: 15,
),
Expand All @@ -81,9 +79,7 @@ class _ClusteringManyMarkersPageState extends State<ClusteringManyMarkersPage> {
markers: markers,
builder: (context, markers) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.blue),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: Colors.blue),
child: Center(
child: Text(
markers.length.toString(),
Expand Down
3 changes: 1 addition & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ class MyApp extends StatelessWidget {
home: const ClusteringPage(),
routes: <String, WidgetBuilder>{
ClusteringPage.route: (context) => const ClusteringPage(),
ClusteringManyMarkersPage.route: (context) =>
const ClusteringManyMarkersPage(),
ClusteringManyMarkersPage.route: (context) => const ClusteringManyMarkersPage(),
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_map: ">=7.0.0 <8.0.0"
flutter_map: ^8.0.0
flutter_map_marker_cluster:
path: ../
cupertino_icons: ^1.0.6
Expand Down
8 changes: 4 additions & 4 deletions lib/src/animated_map_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ class AnimatedMapWidget extends MapWidget {
final Widget child;
final Size size;
final AnimationController animationController;
final Animation<Point<double>>? _translateAnimation;
final Animation<Offset>? _translateAnimation;
final Rotate? rotate;
final Point<double>? _position;
final Offset? _position;
final Animation<double>? _fadeAnimation;

AnimatedMapWidget({
Expand Down Expand Up @@ -44,8 +44,8 @@ class AnimatedMapWidget extends MapWidget {
return Positioned(
width: size.width,
height: size.height,
left: _position?.x ?? _translateAnimation!.value.x,
top: _position?.y ?? _translateAnimation!.value.y,
left: _position?.dx ?? _translateAnimation!.value.dx,
top: _position?.dy ?? _translateAnimation!.value.dy,
child: _fadeAnimation == null
? childWithRotation!
: Opacity(
Expand Down
35 changes: 10 additions & 25 deletions lib/src/cluster_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,8 @@ class ClusterManager {
required int maxClusterRadius,
}) {
final len = maxZoom - minZoom + 1;
final gridClusters = List<DistanceGrid<MarkerClusterNode>>.generate(
len, (_) => DistanceGrid(maxClusterRadius),
growable: false);
final gridUnclustered = List<DistanceGrid<MarkerNode>>.generate(
len, (_) => DistanceGrid(maxClusterRadius),
growable: false);
final gridClusters = List<DistanceGrid<MarkerClusterNode>>.generate(len, (_) => DistanceGrid(maxClusterRadius), growable: false);
final gridUnclustered = List<DistanceGrid<MarkerNode>>.generate(len, (_) => DistanceGrid(maxClusterRadius), growable: false);

final topClusterLevel = MarkerClusterNode(
alignment: alignment,
Expand All @@ -66,22 +62,18 @@ class ClusterManager {
);
}

void addLayer(MarkerNode marker, int disableClusteringAtZoom, int maxZoom,
int minZoom) {
void addLayer(MarkerNode marker, int disableClusteringAtZoom, int maxZoom, int minZoom) {
for (var zoom = maxZoom; zoom >= minZoom; zoom--) {
final markerPoint =
mapCalculator.project(marker.point, zoom: zoom.toDouble());
final markerPoint = mapCalculator.project(marker.point, zoom: zoom.toDouble());
if (zoom <= disableClusteringAtZoom) {
// try find a cluster close by
final cluster =
_gridClusters[zoom - minZoom].getNearObject(markerPoint);
final cluster = _gridClusters[zoom - minZoom].getNearObject(markerPoint);
if (cluster != null) {
cluster.addChild(marker, marker.point);
return;
}

final closest =
_gridUnclustered[zoom - minZoom].getNearObject(markerPoint);
final closest = _gridUnclustered[zoom - minZoom].getNearObject(markerPoint);
if (closest != null) {
final parent = closest.parent!;
parent.removeChild(closest);
Expand Down Expand Up @@ -139,23 +131,16 @@ class ClusterManager {
_topClusterLevel.addChild(marker, marker.point);
}

void _removeFromNewPosToMyPosGridUnclustered(
MarkerNode marker, int zoom, int minZoom) {
void _removeFromNewPosToMyPosGridUnclustered(MarkerNode marker, int zoom, int minZoom) {
for (; zoom >= minZoom; zoom--) {
if (!_gridUnclustered[zoom - minZoom].removeObject(marker)) {
break;
}
}
}

void recalculateTopClusterLevelProperties() =>
_topClusterLevel.recalculate(recursively: true);
void recalculateTopClusterLevelProperties() => _topClusterLevel.recalculate(recursively: true);

void recursivelyFromTopClusterLevel(
int zoomLevel,
int disableClusteringAtZoom,
LatLngBounds recursionBounds,
Function(MarkerOrClusterNode) fn) =>
_topClusterLevel.recursively(
zoomLevel, disableClusteringAtZoom, recursionBounds, fn);
void recursivelyFromTopClusterLevel(int zoomLevel, int disableClusteringAtZoom, LatLngBounds recursionBounds, Function(MarkerOrClusterNode) fn) =>
_topClusterLevel.recursively(zoomLevel, disableClusteringAtZoom, recursionBounds, fn);
}
18 changes: 9 additions & 9 deletions lib/src/core/distance_grid.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:collection';
import 'dart:math';
import 'dart:ui';

class CellEntry<T> {
final T obj;
Expand All @@ -16,8 +17,7 @@ class GridKey {
const GridKey(this.row, this.col);

@override
bool operator ==(Object other) =>
other is GridKey && other.row == row && other.col == col;
bool operator ==(Object other) => other is GridKey && other.row == row && other.col == col;

@override
int get hashCode => (col << 26) ^ row;
Expand All @@ -39,15 +39,15 @@ class DistanceGrid<T> {
_objectPoint.clear();
}

void addObject(T obj, Point<double> point) {
final key = GridKey(_getCoord(point.y), _getCoord(point.x));
void addObject(T obj, Offset point) {
final key = GridKey(_getCoord(point.dy), _getCoord(point.dx));
final cell = _grid[key] ??= [];

_objectPoint[obj] = key;
cell.add(CellEntry<T>(point.x, point.y, obj));
cell.add(CellEntry<T>(point.dx, point.dy, obj));
}

void updateObject(T obj, Point<double> point) {
void updateObject(T obj, Offset point) {
removeObject(obj);
addObject(obj, point);
}
Expand All @@ -74,9 +74,9 @@ class DistanceGrid<T> {
}
}

T? getNearObject(Point<double> point) {
final px = point.x;
final py = point.y;
T? getNearObject(Offset point) {
final px = point.dx;
final py = point.dy;

final x = _getCoord(px), y = _getCoord(py);
double closestDistSq = _sqCellSize;
Expand Down
18 changes: 8 additions & 10 deletions lib/src/core/spiderfy.dart
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
import 'dart:math';
import 'dart:ui';

class Spiderfy {
static const pi2 = pi * 2;
static const spiralFootSeparation =
28; //related to size of spiral (experiment!)
static const spiralFootSeparation = 28; //related to size of spiral (experiment!)
static const spiralLengthStart = 11;
static const spiralLengthFactor = 5;

static const circleStartAngle = 0;

static List<Point?> spiral(int distanceMultiplier, int count, Point center) {
static List<Offset?> spiral(int distanceMultiplier, int count, Offset center) {
num legLength = distanceMultiplier * spiralLengthStart;
final separation = distanceMultiplier * spiralFootSeparation;
final lengthFactor = distanceMultiplier * spiralLengthFactor * pi2;
num angle = 0;

final result = List<Point?>.filled(count, null, growable: false);
final result = List<Offset?>.filled(count, null, growable: false);

// Higher index, closer position to cluster center.
for (var i = count; i >= 0; i--) {
// Skip the first position, so that we are already farther from center and we avoid
// being under the default cluster icon (especially important for Circle Markers).
if (i < count) {
result[i] = Point(center.x + legLength * cos(angle),
center.y + legLength * sin(angle));
result[i] = Offset(center.dx + legLength * cos(angle), center.dy + legLength * sin(angle));
}
angle += separation / legLength + i * 0.0005;
legLength += lengthFactor / angle;
}
return result;
}

static List<Point?> circle(int radius, int count, Point center) {
static List<Offset?> circle(int radius, int count, Offset center) {
final angleStep = pi2 / count;

return List<Point>.generate(count, (index) {
return List<Offset>.generate(count, (index) {
final angle = circleStartAngle + index * angleStep;

return Point<double>(
center.x + radius * cos(angle), center.y + radius * sin(angle));
return Offset(center.dx + radius * cos(angle), center.dy + radius * sin(angle));
});
}
}
9 changes: 4 additions & 5 deletions lib/src/core/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import 'dart:math';

import 'package:flutter/material.dart';

Point<double> removeAlignment(
Point pos, double width, double height, Alignment alignment) {
Offset removeAlignment(Offset pos, double width, double height, Alignment alignment) {
final left = 0.5 * width * (alignment.x + 1);
final top = 0.5 * height * (alignment.y + 1);
final x = pos.x - (width - left);
final y = pos.y - (height - top);
return Point(x, y);
final x = pos.dx - (width - left);
final y = pos.dy - (height - top);
return Offset(x, y);
}
12 changes: 6 additions & 6 deletions lib/src/map_calculator.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:math';
import 'dart:ui';

import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
Expand All @@ -8,13 +9,12 @@ class MapCalculator {

MapCalculator(this.mapState);

Point<double> getPixelFromPoint(LatLng point) {
return mapState.project(point) - mapState.pixelOrigin.toDoublePoint();
Offset getPixelFromPoint(LatLng point) {
final Offset pxPoint = mapState.projectAtZoom(point);
return Offset(pxPoint.dx - mapState.pixelOrigin.dx, pxPoint.dy - mapState.pixelOrigin.dy);
}

Point<double> project(LatLng latLng, {double? zoom}) =>
mapState.project(latLng, zoom);
Offset project(LatLng latLng, {double? zoom}) => mapState.projectAtZoom(latLng, zoom);

LatLng unproject(Point point, {double? zoom}) =>
mapState.unproject(point, zoom);
LatLng unproject(Offset point, {double? zoom}) => mapState.unprojectAtZoom(point, zoom);
}
Loading