Как декодировать полилинию Google, когда побитовое ИЛИ является разрушительным?

Я хочу декодировать закодированную полилинию Google:

`~oia@

Однако, чтобы отменить один из шагов, необходимо отменить побитовую операцию ИЛИ, что является деструктивным.

Я вижу, что это сделано здесь: Как декодировать алгоритм Google Polyline?, но я могу не вижу, как это сделать в Javascript.

Вот что у меня есть до сих пор:

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

console.log(partialDecodedPolyline)

Следующий шаг — инвертировать побитовое ИЛИ... как это возможно?


person Pureferret    schedule 14.07.2021    source источник


Ответы (1)


Для этого есть библиотека 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@"));

person vanowm    schedule 14.07.2021
comment
хотелось бы понять как это работает - person Pureferret; 14.07.2021
comment
Я уже довольно давно пытаюсь найти (недокументированную) инверсию (документированного) алгоритма кодирования в Swift. Спасибо за ссылку на JavaScript, но вывод идентичен всем моим другим портам и неверен. Автобусные линии (от НЕКОТОРЫХ провайдеров) срезают углы и блуждают по улицам. ОП не должен расстраиваться из-за решения Java: Swift заботится о знаке и размере типов переменных, а Java - нет, что приводит к серьезному злу. Я узнал, что отслеживание бинарных промежуточных продуктов — это кроличья нора. Любые другие предложения? - person Fritz Anderson; 29.07.2021