heremaps / flexible-polyline

Flexible Polyline encoding: a lossy compressed representation of a list of coordinate pairs or triples
MIT License
91 stars 77 forks source link

Different Longitude values from decoder in android and ios web view cordova - Using Javascript #52

Open bmunjal opened 2 years ago

bmunjal commented 2 years ago

Hi there

I love your algorithm and it was working great for me on android but did not seem to be providing right coordinates for the same polyline on ios.

One of the examples: Polyline: BHmv3jsdxtq2spCxgDw6E15Bj1C

Results returned on browser and android webview: lat: 49.2891891, lng: -123.1394009 lat: 49.2890346, lng: -123.1391537 lat: 49.2889423, lng: -123.1392899

However results returned on iphone webview have different longitude values (latitudes are same): lat: 49.2891891, lng: 91.6089639 lat: 49.2890346, lng: 91.60921110000001 lat: 49.2889423, lng: 91.60907490000001

Please help. I have tried debugging it but to no avail.

vyatsyk commented 2 years ago

The issue happens because as it seams iPhone's WebView does not support BigInt JS type and library falls back to Number. And since Number is double it can't represent large integer numbers and algorithm fails when decodes polyline.

The solution could be to encode polyline with lower precision. For example 5.

poly.encode({
  precision: 5,
  thirdDim: 0,
  thirdDimPrecision: 0,
  polyline: [
    [ 49.2891891, -123.1394009 ],
    [ 49.2890346, -123.1391537 ],
    [ 49.2889423, -123.1392899 ]
  ]
})

The result would be BFu56sJn1yvXfyBRb. When you decode it you will have

{
  precision: 5,
  thirdDim: 0,
  thirdDimPrecision: 0,
  polyline: [
    [ 49.28919, -123.1394 ],
    [ 49.28903, -123.13915 ],
    [ 49.28894, -123.13929 ]
  ]
}

If you need higher precision then another solution can be to rewrite the flexpolyline library with big-integer (https://www.npmjs.com/package/big-integer).

Here is an example with big-integer and bignumber.js https://gist.github.com/vyatsyk/9d879cca78f945bf64eb9962dd1ce9dc