#413 map: fit to most recent items if all items cannot fit on screen

This commit is contained in:
Thibault Deckers 2022-12-02 20:04:06 +01:00
parent 22b42be605
commit 1e7690d5a4
3 changed files with 45 additions and 6 deletions

View file

@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
### Changed
- Viewer: allow setting default outside video player
- Map: fit to most recent items if all items cannot fit on screen
## <a id="v1.7.7"></a>[v1.7.7] - 2022-11-27

View file

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:math';
import 'dart:ui';
import 'package:aves/model/entry.dart';
import 'package:aves/model/entry_images.dart';
@ -320,18 +321,25 @@ class _GeoMapState extends State<GeoMap> {
}
}
if (bounds == null) {
// fit map to located items
LatLng? centerToSave;
final initialCenter = widget.initialCenter;
final points = initialCenter != null ? {initialCenter} : entries.map((v) => v.latLng!).toSet();
if (points.isNotEmpty) {
if (initialCenter != null) {
// fit map for specified center and user zoom
bounds = ZoomedBounds.fromPoints(
points: points,
points: {initialCenter},
collocationZoom: settings.infoMapZoom,
);
final center = bounds.projectedCenter;
centerToSave = initialCenter;
} else {
// fit map for all located items if possible, falling back to most recent items
bounds = _initBoundsForEntries(entries: entries);
centerToSave = bounds?.projectedCenter;
}
if (centerToSave != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
settings.mapDefaultCenter = center;
settings.mapDefaultCenter = centerToSave;
});
}
}
@ -353,6 +361,29 @@ class _GeoMapState extends State<GeoMap> {
);
}
ZoomedBounds? _initBoundsForEntries({required List<AvesEntry> entries, int? recentCount}) {
if (recentCount != null) {
entries = List.of(entries)..sort(AvesEntry.compareByDate);
entries = entries.take(recentCount).toList();
}
if (entries.isEmpty) return null;
final points = entries.map((v) => v.latLng!).toSet();
var bounds = ZoomedBounds.fromPoints(
points: points,
collocationZoom: settings.infoMapZoom,
);
bounds = bounds.copyWith(zoom: max(minInitialZoom, bounds.zoom.floorToDouble()));
final availableSize = window.physicalSize / window.devicePixelRatio;
final neededSize = bounds.toDisplaySize();
if (neededSize.longestSide > availableSize.shortestSide) {
return _initBoundsForEntries(entries: entries, recentCount: (recentCount ?? 10000) ~/ 10);
}
return bounds;
}
void _onCollectionChanged() {
_defaultMarkerCluster = _buildFluster();
_slowMarkerCluster = null;

View file

@ -1,4 +1,5 @@
import 'dart:math';
import 'dart:ui';
import 'package:aves_map/src/geo_utils.dart';
import 'package:equatable/equatable.dart';
@ -89,4 +90,10 @@ class ZoomedBounds extends Equatable {
}
bool contains(LatLng point) => GeoUtils.contains(sw, ne, point);
Size toDisplaySize() {
final swPoint = _crs.latLngToPoint(sw, zoom);
final nePoint = _crs.latLngToPoint(ne, zoom);
return Size((swPoint.x - nePoint.x).abs().toDouble(), (swPoint.y - nePoint.y).abs().toDouble());
}
}