export default class PolylineUtility { private static encodeNum(num: number): string { let pnum: number = num << 1; if (num < 0) pnum = ~pnum; if (pnum == 0) { return String.fromCharCode(63); } else { let result: string = ''; while (pnum > 0x1f) { const c: number = ((pnum & 0x1f) | 0x20) + 63; result += String.fromCharCode(c); pnum = pnum >>> 5; } result += String.fromCharCode(63 + pnum); return result; } } public static decodeNums(str: string): { lon: number; lat: number; alt: number; radius: number } { const result: number[] = []; let current: number = 0; let pos: number = 0; for (const c of str) { const code: number = c.charCodeAt(0); const num: number = code - 63; current |= (num & 0x1f) << pos; pos += 5; if (num <= 0x1f) { let tmpres: number = current >>> 1; if ((current & 0x1) === 1) { tmpres = ~tmpres; } result.push(tmpres); current = 0; pos = 0; } } return { lon: result[0] / 1e5, lat: result[1] / 1e5, alt: result[2], radius: result[3] } } public static encodeCompetitionTurnpoint(lon: number, lat: number, alt: number, radius: number): string { const lonStr: string = PolylineUtility.encodeNum(Math.round(lon * 1e5)); const latStr: string = PolylineUtility.encodeNum(Math.round(lat * 1e5)); const altStr: string = PolylineUtility.encodeNum(alt); const radiusStr: string = PolylineUtility.encodeNum(radius); return lonStr + latStr + altStr + radiusStr; // For decoding just use decodeNums and assign numbers in correct order. // Do not forget divide coordinations by 1e5f } }