@@ -81,39 +81,20 @@ class MapControllerImpl implements MapController {
81
81
}
82
82
83
83
@override
84
- LatLng ? pointToLatLng (CustomPoint localPoint) {
85
- if (_state.originalSize == null ) {
86
- return null ;
87
- }
88
-
89
- final width = _state.originalSize! .x;
90
- final height = _state.originalSize! .y;
91
-
92
- final localPointCenterDistance =
93
- CustomPoint ((width / 2 ) - localPoint.x, (height / 2 ) - localPoint.y);
94
- final mapCenter =
95
- _state.options.crs.latLngToPoint (_state.center, _state.zoom);
96
-
97
- var point = mapCenter - localPointCenterDistance;
98
-
99
- if (_state.rotation != 0.0 ) {
100
- point = rotatePoint (mapCenter, point);
101
- }
84
+ CustomPoint latLngToScreenPoint (LatLng latLng) {
85
+ return _state.latLngToScreenPoint (latLng);
86
+ }
102
87
103
- return _state.options.crs.pointToLatLng (point, _state.zoom);
88
+ @override
89
+ LatLng ? pointToLatLng (CustomPoint localPoint) {
90
+ return _state.pointToLatLng (localPoint);
104
91
}
105
92
106
93
CustomPoint <num > rotatePoint (
107
- CustomPoint <num > mapCenter, CustomPoint <num > point) {
108
- final m = Matrix4 .identity ()
109
- ..translate (mapCenter.x.toDouble (), mapCenter.y.toDouble ())
110
- ..rotateZ (- _state.rotationRad)
111
- ..translate (- mapCenter.x.toDouble (), - mapCenter.y.toDouble ());
112
-
113
- final tp = MatrixUtils .transformPoint (
114
- m, Offset (point.x.toDouble (), point.y.toDouble ()));
115
-
116
- return CustomPoint (tp.dx, tp.dy);
94
+ CustomPoint <num > mapCenter, CustomPoint <num > point,
95
+ {bool counterRotation = true }) {
96
+ return _state.rotatePoint (mapCenter, point,
97
+ counterRotation: counterRotation);
117
98
}
118
99
119
100
@override
@@ -648,6 +629,64 @@ class MapState {
648
629
return newCenter;
649
630
}
650
631
632
+ // This will convert a latLng to a position that we could use with a widget
633
+ // outside of FlutterMap layer space. Eg using a Positioned Widget.
634
+ CustomPoint latLngToScreenPoint (LatLng latLng) {
635
+ final nonRotatedPixelOrigin =
636
+ (project (getCenter (), zoom) - originalSize! / 2.0 ).round ();
637
+
638
+ var point = options.crs.latLngToPoint (latLng, zoom);
639
+
640
+ final mapCenter = options.crs.latLngToPoint (center, zoom);
641
+
642
+ if (rotation != 0.0 ) {
643
+ point = rotatePoint (mapCenter, point, counterRotation: false );
644
+ }
645
+
646
+ return point - nonRotatedPixelOrigin;
647
+ }
648
+
649
+ LatLng ? pointToLatLng (CustomPoint localPoint) {
650
+ if (originalSize == null ) {
651
+ return null ;
652
+ }
653
+
654
+ final width = originalSize! .x;
655
+ final height = originalSize! .y;
656
+
657
+ final localPointCenterDistance =
658
+ CustomPoint ((width / 2 ) - localPoint.x, (height / 2 ) - localPoint.y);
659
+ final mapCenter = options.crs.latLngToPoint (center, zoom);
660
+
661
+ var point = mapCenter - localPointCenterDistance;
662
+
663
+ if (rotation != 0.0 ) {
664
+ point = rotatePoint (mapCenter, point);
665
+ }
666
+
667
+ return options.crs.pointToLatLng (point, zoom);
668
+ }
669
+
670
+ // Sometimes we need to make allowances that a rotation already exists, so
671
+ // it needs to be reversed (pointToLatLng), and sometimes we want to use
672
+ // the same rotation to create a new position (latLngToScreenpoint).
673
+ // counterRotation just makes allowances this for this.
674
+ CustomPoint <num > rotatePoint (
675
+ CustomPoint <num > mapCenter, CustomPoint <num > point,
676
+ {bool counterRotation = true }) {
677
+ final counterRotationFactor = counterRotation ? - 1 : 1 ;
678
+
679
+ final m = Matrix4 .identity ()
680
+ ..translate (mapCenter.x.toDouble (), mapCenter.y.toDouble ())
681
+ ..rotateZ (rotationRad * counterRotationFactor)
682
+ ..translate (- mapCenter.x.toDouble (), - mapCenter.y.toDouble ());
683
+
684
+ final tp = MatrixUtils .transformPoint (
685
+ m, Offset (point.x.toDouble (), point.y.toDouble ()));
686
+
687
+ return CustomPoint (tp.dx, tp.dy);
688
+ }
689
+
651
690
static MapState ? maybeOf (BuildContext context, {bool nullOk = false }) {
652
691
final widget =
653
692
context.dependOnInheritedWidgetOfExactType <MapStateInheritedWidget >();
0 commit comments