-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathshared.dart
390 lines (275 loc) · 9.88 KB
/
shared.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
// ignore_for_file: constant_identifier_names
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'core/core.dart';
import 'layer/layer.dart';
/// Equator radius in meter (WGS84 ellipsoid)
const double EQUATOR_RADIUS = 6378137.0;
/// Polar radius in meter (WGS84 ellipsoid)
const double POLAR_RADIUS = 6356752.314245;
/// WGS84
const double FLATTENING = 1 / 298.257223563;
/// Earth radius in meter
const double EARTH_RADIUS = EQUATOR_RADIUS;
/// The PI constant.
const double PI = math.pi;
/// Minimun velocity of fling gesture to make the map fling
const double kMinFlingVelocity = 800.0;
/// Converts degree to radian
double degToRadian(double deg) => deg * (PI / 180.0);
/// Radian to degree
double radianToDeg(double rad) => rad * (180.0 / PI);
/// Normalize the rotation value to be between -180 and +180 degrees
double normalizeDeg(double deg) {
deg = deg % 360.0;
if (deg > 180.0) {
deg = deg - 360.0;
}
return deg;
}
/// Rounds [value] to given number of [decimals]
double round(double value, {int decimals = 6}) =>
(value * math.pow(10, decimals)).round() / math.pow(10, decimals);
/// Convert a bearing to be within the 0 to +360 degrees range.
/// Compass bearing is in the rangen 0° ... 360°
double normalizeBearing(double bearing) => (bearing + 360) % 360;
/// Converts a decimal coordinate value to sexagesimal format
///
/// String sex = decimal2sexagesimal(51.519475);
/// expect(sex, '51° 31\' 10.11"');
///
String decimal2sexagesimal(double decimal) {
List<int> split(double value) {
// Force NumberFormat to create digit after comma
// if the value has no decimal point
double roundedValue = round(value, decimals: 10);
List<String> values =
NumberFormat("0.0#####").format(roundedValue).split('.');
return [int.parse(values[0]).abs(), int.parse(values[1])];
}
List parts = split(decimal);
int degree = parts[0];
int fraction = parts[1];
double minutes = double.parse("0.$fraction") * 60;
List minParts = split(minutes);
int minFraction = minParts[1];
double seconds = (double.parse("0.$minFraction") * 60);
seconds = round(seconds, decimals: 2);
return "$degree° ${minutes.floor()}' ${seconds.toStringAsFixed(2)}\"";
}
/// Parses string subdomain into a list of char subdomains.
List<String> parseSubdomains(dynamic subdomains) {
if (subdomains is List<String>) return subdomains;
if (subdomains is String) return subdomains.split('');
return [];
}
/// Template pattern to be used for converting map tile url
final _templatePattern = RegExp(r'\{ *([\w_-]+) *\}');
/// Replaces the templating placeholders with the provided data map.
///
/// Throws an [Exception] if any placeholder remains unresolved.
String urlFromTemplate(String str, Map<String, dynamic> data) {
return str.replaceAllMapped(_templatePattern, (Match match) {
var value = data[match.group(1)!];
if (value == null) {
throw Exception('No value provided for variable ${match.group(1)}');
} else {
return value;
}
});
}
/// wrap value to be inside the range
double wrap(double value, List<num>? range, [bool includeMax = false]) {
if (range == null || range.length != 2) {
return value;
}
final min = math.min(range[0], range[1]);
final max = math.max(range[0], range[1]);
final d = max - min;
if (value == max && includeMax) {
return value;
}
return ((value - min) % d + d) % d + min;
}
/// Calculate projected map size on the screen when it's rotated
Size projectedSize(Size size, double angle) {
if (angle == 0.0) {
return size;
}
final oWidth = size.width;
final oHeight = size.height;
const rad90 = PI / 2;
final sinangle = math.sin(angle).abs();
final sinrest = math.sin(rad90 - angle).abs();
final width = (oWidth * sinrest) + (oHeight * sinangle) + 20;
final height = (oHeight * sinrest) + (oWidth * sinangle) + 20;
return Size(width, height).round();
}
/// Calculate projected point on the screen when the map is rotated
Offset projectedPoint(Offset point, Size size, double angle) {
if (angle == 0.0) {
return point;
}
Size nSize = projectedSize(size, angle);
Size halfSize = size / 2;
Offset pointFromCenter = Offset(
point.dx - halfSize.width,
halfSize.height - point.dy,
);
final cos = math.cos(-angle);
final sin = math.sin(-angle);
final pcx = pointFromCenter.dx;
final pcy = pointFromCenter.dy;
pointFromCenter = Offset(
pcx * cos + pcy * sin,
pcy * cos - pcx * sin,
);
Size sizeOffset = (nSize - size) / 2;
final x = halfSize.width + pointFromCenter.dx + sizeOffset.x;
final y = halfSize.height - pointFromCenter.dy + sizeOffset.y;
return Offset(x, y);
}
/// default parameter values
///
/// default opacity
const double opacityDef = 1.0;
/// default is paint stroke
const bool strokeDef = true;
/// default is paint stroke for Polygon
const bool strokePolygonDef = false;
/// default is paint stroke for Rectangle
const bool strokeRectangleDef = strokePolygonDef;
/// default stroke color
const Color strokeColorDef = Colors.lightBlue;
/// default stroke width
const double strokeWidthDef = 3.0;
/// default stroke width for Circle
const double strokeWidthCircleDef = 2.0;
/// default stroke width for Polygon
const double strokeWidthPolygonDef = 2.0;
/// default stroke width for Rectangle
const double strokeWidthRectangleDef = strokeWidthPolygonDef;
/// default stroke opacity
const double strokeOpacityDef = opacityDef;
/// default stroke opacity for Polygon
const double strokeOpacityPolygonDef = 0.9;
/// default stroke opacity for Rectangle
const double strokeOpacityRectangleDef = strokeOpacityPolygonDef;
/// default styles to use for stroke line endings
const StrokeCap strokeCapDef = StrokeCap.round;
/// default styles to use for stroke line segment joins
const StrokeJoin strokeJoinDef = StrokeJoin.round;
/// default is paint fill
const bool fillDef = true;
/// default is paint fill for Circle
const bool fillCircleDef = true;
/// default fill opacity
const double fillOpacityDef = 0.5;
/// default [PathFillType]
const PathFillType pathFillTypeDef = PathFillType.evenOdd;
/// default is stroke use dotted style
const bool isDottedDef = false;
/// default gradient colors
const List<Color> gradientColorsDef = [];
/// default gradient stops
const List<double> gradientStopsDef = [];
/// default smooth factor
const double smoothFactorDef = 1.0;
/// default is paint Polygon with holes
const bool withHolesDef = true;
/// default is culling
const bool cullingDef = true;
/// default interactive value
const bool interactiveDef = true;
/// default attribution
const String attributionDef = '';
/// default need to slide on boundaries
const bool slideOnBoundariesDef = false;
/// default is adaptive boundaries
const bool adaptiveBoundariesDef = false;
/// default tile size used at TileLayer
const double tileSizeDef = 256.0;
/// default zoom
const double zoomDef = 13.0;
/// default min zoom
const double minZoomDef = 0.0;
/// default max zoom
const double maxZoomDef = 18.0;
/// default delta changes of zoom
const double zoomDeltaDef = 1.0;
/// default initial rotation
const double rotationDef = 0.0;
/// default is rotation disabled
const bool disableRotationDef = false;
/// default show center marker
const bool showCenterMarkerDef = false;
/// default is live map
const bool liveDef = false;
/// default needs to move when live
const bool moveWhenLiveDef = true;
/// default is show locator
const bool showLocatorDef = true;
/// default is show location marker
const bool showLocationMarkerDef = false;
/// default is show location indicator
const bool showLocationIndicatorDef = false;
/// default is show compass
const bool showCompassDef = true;
/// default is show scale
const bool showScaleDef = true;
/// default is zoom changes needs to be reversed
const bool zoomReverseDef = false;
/// default zoom offset
const double zoomOffsetDef = 0.0;
/// default additional options for [TileLayerOptions]
const Map<String, dynamic> additionalOptionsDef = <String, dynamic>{};
/// default subdomains for [TileLayer]
const List<String> subdomainsDef = <String>['a', 'b', 'c'];
/// default number of buffer to keep
const int keepBufferDef = 2;
/// default tile opacity
const double tileOpacityDef = opacityDef;
/// default is update when zooming
const bool updateWhenZoomingDef = true;
/// default update tile interval
const int updateTileIntervalDef = 200;
/// default tile fade in duration
const int tileFadeInDurationDef = 50;
/// default tile fade in curve
const Curve tileFadeInCurveDef = Curves.easeOutQuint;
/// default tile fade in initial value
const double tileFadeInStartDef = 0.0;
/// default tile fade in initial value when override
const double tileFadeInStartWhenOverrideDef = 0.25;
/// default is override tiles when url changes
const bool overrideTilesWhenUrlChangesDef = true;
/// default Tile Provider
const TileProvider tileProviderDef = NetworkRetryTileProvider();
/// default retina mode
const bool retinaModeDef = false;
/// default tms map
const bool tmsDef = false;
/// default hide attribution
const bool hideAttributionDef = false;
/// default overlay opacity
const double overlayOpacityDef = 0.75;
/// default overlay initial rotation
const double overlayRotationDef = 0.0;
/// default [BoxFit] type of overlay
const BoxFit overlayFitDef = BoxFit.contain;
/// default gapless playback of overlay
const bool overlayGaplessPlaybackDef = true;
/// default marker size
const double markerSizeDef = 42;
/// default marker local alignment
const MarkerAlignment markerAlignDef = MarkerAlignment.top;
/// default marker color
const Color markerColorDef = Colors.lightBlue;
/// default marker
const MarkerSvg markerDef = MarkerSvg('packages/universe/assets/marker.svg');
/// default is looping playback of video overlay
const bool loopingVideoDef = true;
/// Attribution for OpenStreetMap
const String osmAttrDef = 'Map Data © OpenStreetMap contributors';
const double zoomDiffToUpdateTiles = 0.6;