11part of 'circle_layer.dart' ;
22
3- /// The [CustomPainter] used to draw [CircleMarker] for the [CircleLayer] .
4- base class CirclePainter <R extends Object >
5- extends HitDetectablePainter <R , CircleMarker <R >> {
3+ /// The [CustomPainter] used to draw [CircleMarker] s for the [CircleLayer] .
4+ class CirclePainter <R extends Object > extends CustomPainter
5+ with HitDetectablePainter <R , CircleMarker <R >>, FeatureLayerUtils {
66 /// Reference to the list of [CircleMarker] s of the [CircleLayer] .
77 final List <CircleMarker <R >> circles;
88
9+ @override
10+ final MapCamera camera;
11+
12+ @override
13+ final LayerHitNotifier <R >? hitNotifier;
14+
915 /// Create a [CirclePainter] instance by providing the required
1016 /// reference objects.
1117 CirclePainter ({
1218 required this .circles,
13- required super .camera,
14- required super .hitNotifier,
19+ required this .camera,
20+ required this .hitNotifier,
1521 });
1622
17- static const _distance = Distance ();
18-
1923 @override
2024 bool elementHitTest (
2125 CircleMarker <R > element, {
2226 required Offset point,
2327 required LatLng coordinate,
2428 }) {
25- final worldWidth = _getWorldWidth ();
2629 final radius = _getRadiusInPixel (element, withBorder: true );
2730 final initialCenter = _getOffset (element.point);
2831
29- /// Returns null if invisible, true if hit, false if not hit.
30- bool ? checkIfHit (double shift) {
32+ WorldWorkControl checkIfHit (double shift) {
3133 final center = initialCenter + Offset (shift, 0 );
32- if (! _isVisible (
33- screenRect: _screenRect,
34- center: center,
35- radiusInPixel: radius,
36- )) {
37- return null ;
34+ if (! _isVisible (center: center, radiusInPixel: radius)) {
35+ return WorldWorkControl .invisible;
3836 }
3937
4038 return pow (point.dx - center.dx, 2 ) + pow (point.dy - center.dy, 2 ) <=
41- radius * radius;
39+ radius * radius
40+ ? WorldWorkControl .hit
41+ : WorldWorkControl .visible;
4242 }
4343
44- if (checkIfHit (0 ) ?? false ) {
45- return true ;
46- }
47-
48- // Repeat over all worlds (<--||-->) until culling determines that
49- // that element is out of view, and therefore all further elements in
50- // that direction will also be
51- if (worldWidth == 0 ) return false ;
52- for (double shift = - worldWidth;; shift -= worldWidth) {
53- final isHit = checkIfHit (shift);
54- if (isHit == null ) break ;
55- if (isHit) return true ;
56- }
57- for (double shift = worldWidth;; shift += worldWidth) {
58- final isHit = checkIfHit (shift);
59- if (isHit == null ) break ;
60- if (isHit) return true ;
61- }
62-
63- return false ;
44+ return workAcrossWorlds (checkIfHit);
6445 }
6546
6647 @override
6748 Iterable <CircleMarker <R >> get elements => circles;
6849
69- late Rect _screenRect;
70-
7150 @override
7251 void paint (Canvas canvas, Size size) {
73- _screenRect = Offset .zero & size;
74- canvas.clipRect (_screenRect);
75-
76- final worldWidth = _getWorldWidth ();
52+ super .paint (canvas, size);
53+ canvas.clipRect (viewportRect);
7754
7855 // Let's calculate all the points grouped by color and radius
7956 final points = < Color , Map <double , List <Offset >>> {};
@@ -84,17 +61,15 @@ base class CirclePainter<R extends Object>
8461 final radiusWithBorder = _getRadiusInPixel (circle, withBorder: true );
8562 final initialCenter = _getOffset (circle.point);
8663
87- bool checkIfVisible (double shift) {
88- bool result = false ;
64+ /// Draws on a "single-world"
65+ WorldWorkControl drawIfVisible (double shift) {
66+ WorldWorkControl result = WorldWorkControl .invisible;
8967 final center = initialCenter + Offset (shift, 0 );
9068
9169 bool isVisible (double radius) {
92- if (_isVisible (
93- screenRect: _screenRect,
94- center: center,
95- radiusInPixel: radius,
96- )) {
97- return result = true ;
70+ if (_isVisible (center: center, radiusInPixel: radius)) {
71+ result = WorldWorkControl .visible;
72+ return true ;
9873 }
9974 return false ;
10075 }
@@ -123,23 +98,11 @@ base class CirclePainter<R extends Object>
12398 .add (center);
12499 }
125100 }
101+
126102 return result;
127103 }
128104
129- checkIfVisible (0 );
130-
131- // Repeat over all worlds (<--||-->) until culling determines that
132- // that element is out of view, and therefore all further elements in
133- // that direction will also be
134- if (worldWidth == 0 ) continue ;
135- for (double shift = - worldWidth;; shift -= worldWidth) {
136- final isVisible = checkIfVisible (shift);
137- if (! isVisible) break ;
138- }
139- for (double shift = worldWidth;; shift += worldWidth) {
140- final isVisible = checkIfVisible (shift);
141- if (! isVisible) break ;
142- }
105+ workAcrossWorlds (drawIfVisible);
143106 }
144107
145108 // Now that all the points are grouped, let's draw them
@@ -203,21 +166,14 @@ base class CirclePainter<R extends Object>
203166 double _getRadiusInPixel (CircleMarker circle, {required bool withBorder}) =>
204167 (withBorder ? circle.borderStrokeWidth / 2 : 0 ) +
205168 (circle.useRadiusInMeter
206- ? (_getOffset (circle.point) -
207- _getOffset (
208- _distance.offset (circle.point, circle.radius, 180 )))
209- .distance
169+ ? metersToScreenPixels (circle.point, circle.radius)
210170 : circle.radius);
211171
212172 /// Returns true if a centered circle with this radius is on the screen.
213173 bool _isVisible ({
214- required Rect screenRect,
215174 required Offset center,
216175 required double radiusInPixel,
217176 }) =>
218- screenRect.overlaps (
219- Rect .fromCircle (center: center, radius: radiusInPixel),
220- );
221-
222- double _getWorldWidth () => camera.getWorldWidthAtZoom ();
177+ viewportRect
178+ .overlaps (Rect .fromCircle (center: center, radius: radiusInPixel));
223179}
0 commit comments