mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
feat(mobile): map view (#3661)
* feat(mobile): map page - add map view * map: add map-markers * feat(map): add relative date filter * fix: do not let users scroll past map bounds * fix: fetch relative date from store to state on init * feat(mobile):re-fetch markers only on filter change * feat(mobile) - asset bottom sheet in map page * feat(mobile): display markers based on bottom sheet scroll * fix: exif-bottom-sheet - rebase conflict * feat(mobile): map-view - strongly typed map page events * feat(map): zoom to asset * chore: dart analyzer fixes * map-page move attribution to top-right * feat(mobile): map view - asset selection handling * feat(mobile): map-view display map in places row * fix: make asset marker icon responsive * optimise map page rebuilds * refactor(mobile): map page * feat(mobile): map-view: Go to location * map-view(mobile): minor refactor * fix(mobile): Handle invalid coords gracefully * small styling --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
305889f32b
commit
cb391342d7
37 changed files with 2268 additions and 139 deletions
67
mobile/lib/utils/flutter_map_extensions.dart
Normal file
67
mobile/lib/utils/flutter_map_extensions.dart
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'dart:math' as math;
|
||||
|
||||
extension MoveByBounds on MapController {
|
||||
// TODO: Remove this in favor of built-in method when upgrading flutter_map to 5.0.0
|
||||
LatLng? centerBoundsWithPadding(
|
||||
LatLng coordinates,
|
||||
Offset offset, {
|
||||
double? zoomLevel,
|
||||
}) {
|
||||
const crs = Epsg3857();
|
||||
final oldCenterPt = crs.latLngToPoint(coordinates, zoomLevel ?? zoom);
|
||||
final mapCenterPoint = _rotatePoint(
|
||||
oldCenterPt,
|
||||
oldCenterPt - CustomPoint(offset.dx, offset.dy),
|
||||
);
|
||||
return crs.pointToLatLng(mapCenterPoint, zoomLevel ?? zoom);
|
||||
}
|
||||
|
||||
CustomPoint<double> _rotatePoint(
|
||||
CustomPoint<double> mapCenter,
|
||||
CustomPoint<double> point, {
|
||||
bool counterRotation = true,
|
||||
}) {
|
||||
final counterRotationFactor = counterRotation ? -1 : 1;
|
||||
|
||||
final m = Matrix4.identity()
|
||||
..translate(mapCenter.x, mapCenter.y)
|
||||
..rotateZ(degToRadian(rotation) * counterRotationFactor)
|
||||
..translate(-mapCenter.x, -mapCenter.y);
|
||||
|
||||
final tp = MatrixUtils.transformPoint(m, Offset(point.x, point.y));
|
||||
|
||||
return CustomPoint(tp.dx, tp.dy);
|
||||
}
|
||||
|
||||
double getTapThresholdForZoomLevel() {
|
||||
const scale = [
|
||||
25000000,
|
||||
15000000,
|
||||
8000000,
|
||||
4000000,
|
||||
2000000,
|
||||
1000000,
|
||||
500000,
|
||||
250000,
|
||||
100000,
|
||||
50000,
|
||||
25000,
|
||||
15000,
|
||||
8000,
|
||||
4000,
|
||||
2000,
|
||||
1000,
|
||||
500,
|
||||
250,
|
||||
100,
|
||||
50,
|
||||
25,
|
||||
10,
|
||||
5,
|
||||
];
|
||||
return scale[math.max(0, math.min(20, zoom.round() + 2))].toDouble() / 6;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue