flexible-polyline
flexible-polyline copied to clipboard
dart: Flutter web gives completely wrong results when decoding polyline
Decoding polylines on flutter web is completely wrong.
Using the provided example from https://pub.dev/packages/flexible_polyline, running on android works just fine and prints out the expected results
List<LatLngZ> decoded = FlexiblePolyline.decode("BFoz5xJ67i1B1B7PzIhaxL7Y");
results in the following on android/ios
LatLngZ [lat=50.10228, lng=8.69821, z=0.0]
LatLngZ [lat=50.10201, lng=8.69567, z=0.0]
LatLngZ [lat=50.10063, lng=8.6915, z=0.0]
LatLngZ [lat=50.09878, lng=8.68752, z=0.0]
But running the exact same code with flutter web gives the following:
LatLngZ [lat=50.10228, lng=8.69821, z=0]
LatLngZ [lat=21524.93849, lng=21483.53215, z=0]
LatLngZ [lat=42999.77359, lng=42958.36446, z=0]
LatLngZ [lat=64474.60822, lng=64433.19696, z=0]
The first address is correct, but subsequent addresses 2-4 are very large If there are any additional params/options available that fix the decoding scheme based on web vs mobile, that would be an acceptable workaround until a better solution can be found
i have same issue, is the problem have fix?
I have not found a fix using this package. I have switched to a completely different method, specifically, calling a server of mine which is responsible for getting directions/polyline, using google maps, and communicating that result via http. Not my favourite work around, but it works well for my use case
Sounds a bit like https://github.com/heremaps/flexible-polyline/issues/52
long: The long data type is a 64-bit two's complement integer. The signed long has a minimum value of -2^63 and a maximum value of 2^63-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 2^64-1. Use this data type when you need a range of values wider than those provided by int. The Long class also contains methods like compareUnsigned, divideUnsigned etc to support arithmetic operations for unsigned long.
int Integer values no larger than 64 bits, depending on the platform. On the Dart VM, values can be from -2^63 to 2^63 - 1. **Dart that’s compiled to JavaScript uses JavaScript numbers, allowing values from -2^53 to 2^53 - 1.**
The Dart Lib uses int in Dart for the equivalent of long in Java in https://github.com/heremaps/flexible-polyline/blob/master/dart/lib/converter.dart#L84 The issue is caused by Dart itself - as when code is compiled to JavaScript it loses Precision. You need to use precision 5 or need to use the JavaScript lib (Gist with BigInt lib) for decoding instead as recommended here: https://github.com/heremaps/flexible-polyline/issues/52#issuecomment-984941759
Theoretically a base-10 big-int would be relatively easy to implement, since the only operations needed are:
- addition (for summing up the deltas)
- division by a power of 10 (for outputting a coordinate)
At precision 15 we need log2(360 * 10^15) + 1 = 60 bits. That means that if you were to use Dart's 53 bit type only 2 variables are enough. You could e.g. work with 10^9 per variable (31 bits if signed). Addition would only need to take care of the carry (there's enough space to avoid overflow), and division by a power of ten shifts down the remainder (the equivalent of a bit-shift in base-2).
This approach could work for JS as well, and might be noticeably faster than base-2 BigInteger generic size BigInt library.
What do you think @moo24 / @haifeng2013 ?