Skip to content
61 changes: 32 additions & 29 deletions example/lib/pages/many_circles.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_example/misc/tile_providers.dart';
import 'package:flutter_map_example/widgets/drawer/menu_drawer.dart';
import 'package:flutter_map_example/widgets/number_of_items_slider.dart';
import 'package:flutter_map_example/widgets/show_no_web_perf_overlay_snackbar.dart';
import 'package:flutter_map_example/widgets/perf_overlay.dart';
import 'package:latlong2/latlong.dart';

const _maxCirclesCount = 30000;
Expand All @@ -28,8 +28,28 @@ class _ManyCirclesPageState extends State<ManyCirclesPage> {
static double doubleInRange(Random source, num start, num end) =>
source.nextDouble() * (end - start) + start;

int numOfCircles = _maxCirclesCount ~/ 10;
List<CircleMarker> allCircles = [];
final randomGenerator = Random();
late List<CircleMarker> allCircles = List.generate(
_maxCirclesCount,
(i) => CircleMarker(
point: LatLng(
doubleInRange(randomGenerator, 37, 55),
doubleInRange(randomGenerator, -9, 30),
),
color: HSLColor.fromAHSL(
1,
i % 360,
1,
doubleInRange(randomGenerator, 0.3, 0.7),
).toColor(),
radius: 5,
useRadiusInMeter: false,
borderStrokeWidth: 0,
borderColor: Colors.black,
),
growable: false,
);
int displayedCirclesCount = _maxCirclesCount ~/ 10;

bool useBorders = false;
bool useRadiusInMeters = false;
Expand All @@ -38,26 +58,7 @@ class _ManyCirclesPageState extends State<ManyCirclesPage> {
@override
void initState() {
super.initState();

showNoWebPerfOverlaySnackbar(context);

Future.microtask(() {
final r = Random();
for (double x = 0; x < _maxCirclesCount; x++) {
allCircles.add(
CircleMarker(
point: LatLng(doubleInRange(r, 37, 55), doubleInRange(r, -9, 30)),
color: HSLColor.fromAHSL(1, x % 360, 1, doubleInRange(r, 0.3, 0.7))
.toColor(),
radius: 5,
useRadiusInMeter: false,
borderStrokeWidth: 0,
borderColor: Colors.black,
),
);
}
setState(() {});
});
PerfOverlay.showWebUnavailable(context);
}

@override
Expand Down Expand Up @@ -85,7 +86,9 @@ class _ManyCirclesPageState extends State<ManyCirclesPage> {
children: [
openStreetMapTileLayer,
CircleLayer(
circles: allCircles.take(numOfCircles).toList(growable: false),
circles: allCircles
.take(displayedCirclesCount)
.toList(growable: false),
optimizeRadiusInMeters: optimizeRadiusInMeters,
),
],
Expand All @@ -98,8 +101,8 @@ class _ManyCirclesPageState extends State<ManyCirclesPage> {
child: Column(
children: [
NumberOfItemsSlider(
number: numOfCircles,
onChanged: (v) => setState(() => numOfCircles = v),
number: displayedCirclesCount,
onChanged: (v) => setState(() => displayedCirclesCount = v),
maxNumber: _maxCirclesCount,
itemDescription: 'Circle',
),
Expand Down Expand Up @@ -187,11 +190,11 @@ class _ManyCirclesPageState extends State<ManyCirclesPage> {
),
),
if (!kIsWeb)
Positioned(
bottom: 16,
const Positioned(
bottom: 8,
left: 0,
right: 0,
child: PerformanceOverlay.allEnabled(),
child: PerfOverlay(),
),
],
),
Expand Down
100 changes: 63 additions & 37 deletions example/lib/pages/many_markers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_example/misc/tile_providers.dart';
import 'package:flutter_map_example/widgets/drawer/menu_drawer.dart';
import 'package:flutter_map_example/widgets/number_of_items_slider.dart';
import 'package:flutter_map_example/widgets/show_no_web_perf_overlay_snackbar.dart';
import 'package:flutter_map_example/widgets/perf_overlay.dart';
import 'package:latlong2/latlong.dart';

const _maxMarkersCount = 20000;
const _londonOrigin = LatLng(51.5074, -0.1278);

/// On this page, [_maxMarkersCount] markers are randomly generated
/// across europe, and then you can limit them with a slider
/// across London, and then you can limit them with a slider
///
/// This way, you can test how map performs under a lot of markers
///
/// The markers are quite expensive - an `Icon` is expensive itself, and adding
/// a `GestureDetector` makes things much slower.
class ManyMarkersPage extends StatefulWidget {
static const String route = '/many_markers';

Expand All @@ -25,32 +29,56 @@ class ManyMarkersPage extends StatefulWidget {
}

class ManyMarkersPageState extends State<ManyMarkersPage> {
double doubleInRange(Random source, num start, num end) =>
source.nextDouble() * (end - start) + start;
List<Marker> allMarkers = [];
final randomGenerator = Random(10);
late final allMarkers = List.generate(
_maxMarkersCount,
(_) {
final angle = randomGenerator.nextDouble() * 2 * pi;
final distance = randomGenerator.nextDouble() * 0.5;
final latOffset =
distance * sin(angle) * (0.7 + randomGenerator.nextDouble() * 0.6);
final lngOffset =
distance * cos(angle) * (0.7 + randomGenerator.nextDouble() * 0.6);
final position = LatLng(
_londonOrigin.latitude + latOffset,
_londonOrigin.longitude + lngOffset,
);

int numOfMarkers = _maxMarkersCount ~/ 10;
return Marker(
point: position,
width: 30,
height: 30,
child: GestureDetector(
onTap: () => ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Tapped existing marker (${position.latitude}, '
'${position.longitude})',
),
duration: const Duration(seconds: 1),
showCloseIcon: true,
),
),
child: Icon(
Icons.location_pin,
size: 30,
color: Color.fromARGB(
255,
randomGenerator.nextInt(256),
randomGenerator.nextInt(256),
randomGenerator.nextInt(256),
),
),
),
);
},
);
int displayedMarkersCount = _maxMarkersCount ~/ 10;

@override
void initState() {
super.initState();

showNoWebPerfOverlaySnackbar(context);

Future.microtask(() {
final r = Random();
for (var x = 0; x < _maxMarkersCount; x++) {
allMarkers.add(
Marker(
point: LatLng(doubleInRange(r, 37, 55), doubleInRange(r, -9, 30)),
height: 12,
width: 12,
child: ColoredBox(color: Colors.blue[900]!),
),
);
}
setState(() {});
});
PerfOverlay.showWebUnavailable(context);
}

@override
Expand All @@ -64,39 +92,37 @@ class ManyMarkersPageState extends State<ManyMarkersPage> {
options: MapOptions(
initialCameraFit: CameraFit.bounds(
bounds: LatLngBounds(
const LatLng(55, -9),
const LatLng(37, 30),
),
padding: const EdgeInsets.only(
left: 16,
right: 16,
top: 88,
bottom: 192,
const LatLng(50, -0.5),
const LatLng(53, 0.3),
),
),
),
children: [
openStreetMapTileLayer,
MarkerLayer(markers: allMarkers.take(numOfMarkers).toList()),
MarkerLayer(
markers: allMarkers
.take(displayedMarkersCount)
.toList(growable: false),
),
],
),
Positioned(
left: 16,
top: 16,
right: 16,
child: NumberOfItemsSlider(
number: numOfMarkers,
onChanged: (v) => setState(() => numOfMarkers = v),
number: displayedMarkersCount,
onChanged: (v) => setState(() => displayedMarkersCount = v),
maxNumber: _maxMarkersCount,
itemDescription: 'Marker',
),
),
if (!kIsWeb)
Positioned(
bottom: 16,
const Positioned(
bottom: 8,
left: 0,
right: 0,
child: PerformanceOverlay.allEnabled(),
child: PerfOverlay(),
),
],
),
Expand Down
10 changes: 5 additions & 5 deletions example/lib/pages/polygon_perf_stress.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_example/misc/tile_providers.dart';
import 'package:flutter_map_example/widgets/drawer/menu_drawer.dart';
import 'package:flutter_map_example/widgets/show_no_web_perf_overlay_snackbar.dart';
import 'package:flutter_map_example/widgets/perf_overlay.dart';
import 'package:flutter_map_example/widgets/simplification_tolerance_slider.dart';
import 'package:latlong2/latlong.dart';

Expand Down Expand Up @@ -40,7 +40,7 @@ class _PolygonPerfStressPageState extends State<PolygonPerfStressPage> {
@override
void initState() {
super.initState();
showNoWebPerfOverlaySnackbar(context);
PerfOverlay.showWebUnavailable(context);
}

@override
Expand Down Expand Up @@ -193,11 +193,11 @@ class _PolygonPerfStressPageState extends State<PolygonPerfStressPage> {
),
),
if (!kIsWeb)
Positioned(
bottom: 16,
const Positioned(
bottom: 8,
left: 0,
right: 0,
child: PerformanceOverlay.allEnabled(),
child: PerfOverlay(),
),
],
),
Expand Down
10 changes: 5 additions & 5 deletions example/lib/pages/polyline_perf_stress.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:flutter_map_example/misc/tile_providers.dart';
import 'package:flutter_map_example/widgets/drawer/menu_drawer.dart';
import 'package:flutter_map_example/widgets/show_no_web_perf_overlay_snackbar.dart';
import 'package:flutter_map_example/widgets/perf_overlay.dart';
import 'package:flutter_map_example/widgets/simplification_tolerance_slider.dart';
import 'package:latlong2/latlong.dart';

Expand All @@ -27,7 +27,7 @@ class _PolylinePerfStressPageState extends State<PolylinePerfStressPage> {
void initState() {
super.initState();

showNoWebPerfOverlaySnackbar(context);
PerfOverlay.showWebUnavailable(context);

final random = Random(1234);
for (int i = 1; i < 300000; i++) {
Expand Down Expand Up @@ -85,11 +85,11 @@ class _PolylinePerfStressPageState extends State<PolylinePerfStressPage> {
),
),
if (!kIsWeb)
Positioned(
bottom: 16,
const Positioned(
bottom: 8,
left: 0,
right: 0,
child: PerformanceOverlay.allEnabled(),
child: PerfOverlay(),
),
],
),
Expand Down
50 changes: 50 additions & 0 deletions example/lib/widgets/perf_overlay.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class PerfOverlay extends StatefulWidget {
const PerfOverlay({super.key});

static void showWebUnavailable(BuildContext context) {
if (kIsWeb) {
WidgetsBinding.instance.addPostFrameCallback(
(_) => ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Cannot show performance graph overlay on web'),
),
),
);
}
}

@override
State<PerfOverlay> createState() => _PerfOverlayState();
}

class _PerfOverlayState extends State<PerfOverlay> {
bool showPerformanceChart = false;

@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.only(right: 8),
child: IconButton.outlined(
onPressed: () => setState(
() => showPerformanceChart = !showPerformanceChart,
),
icon: const Icon(Icons.troubleshoot),
isSelected: showPerformanceChart,
tooltip: 'Show Performance Overlay',
),
),
if (showPerformanceChart)
Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: PerformanceOverlay.allEnabled(),
),
],
);
}
}
14 changes: 0 additions & 14 deletions example/lib/widgets/show_no_web_perf_overlay_snackbar.dart

This file was deleted.