0

I'm looking to decode an encoded google polyline:

`~oia@

However to reverse one of the steps requires reversing the bitwise OR operation, which is destructive.

I see it's done here: How to decode Google's Polyline Algorithm? but I can't see how to do that in Javascript.

Here is what I have so far:

const partialDecodedPolyline = "`~oia@".split('').map(char => (char.codePointAt()-63).toString(2))

console.log(partialDecodedPolyline)

The next step is to reverse the bitwise OR... how is that possible?

AncientSwordRage
  • 7,086
  • 19
  • 90
  • 173

1 Answers1

0

There is a libriary for that https://github.com/mapbox/polyline/blob/master/src/polyline.js

/*
  https://github.com/mapbox/polyline/blob/master/src/polyline.js
*/
const decode = function(str, precision) {
    var index = 0,
        lat = 0,
        lng = 0,
        coordinates = [],
        shift = 0,
        result = 0,
        byte = null,
        latitude_change,
        longitude_change,
        factor = Math.pow(10, Number.isInteger(precision) ? precision : 5);

    // Coordinates have variable length when encoded, so just keep
    // track of whether we've hit the end of the string. In each
    // loop iteration, a single coordinate is decoded.
    while (index < str.length) {

        // Reset shift, result, and byte
        byte = null;
        shift = 0;
        result = 0;

        do {
            byte = str.charCodeAt(index++) - 63;
            result |= (byte & 0x1f) << shift;
            shift += 5;
        } while (byte >= 0x20);

        latitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));

        shift = result = 0;

        do {
            byte = str.charCodeAt(index++) - 63;
            result |= (byte & 0x1f) << shift;
            shift += 5;
        } while (byte >= 0x20);

        longitude_change = ((result & 1) ? ~(result >> 1) : (result >> 1));

        lat += latitude_change;
        lng += longitude_change;

        coordinates.push([lat / factor, lng / factor]);
    }

    return coordinates;
};

console.log(decode("`~oia@"));
vanowm
  • 9,466
  • 2
  • 21
  • 37
  • I would like to understand how that works – AncientSwordRage Jul 14 '21 at 01:12
  • 1
    I've been trying to find the (undocumented) inversion of the (documented) encoding algorithm, in Swift, for quite some time. Thanks for the JavaScript link, but the output is identical to all my other ports, and wrong. Bus lines (from SOME providers) cut corners and wander off streets. OP needn't feel bad about the Java "solution:" Swift cares about sign and size of variable types, Java doesn't, resulting in serious evil. I've learned that tracing binary intermediates is a rabbit hole. Any other suggestions? – Fritz Anderson Jul 29 '21 at 18:16