В итоге использовал следующий шаги для сжатия координат. Сразу о результатах до этих действий:
Было:
10 секунд загрузки
7.5 мб данных
Стало:
2 секунды загрузки
540 кб
Пример:
python
1. Shapely.simplify() для сглаживания координат (показатель подбирал для себя)
2. Дельта кодирования, для уменьшения объема данных
polygon = Polygon(coords).simplify(0.00015)
coords = list(polygon.exterior.coords)
lng_list = list()
last_lng = None
lat_list = list()
last_lat = None
for val in coords:
if not last_lng:
lng_list.append(val[0])
lat_list.append(val[1])
else:
lng_list.append(round(val[0] - last_lng, 6))
lat_list.append(round(val[1] - last_lat, 6))
last_lng = val[0]
last_lat = val[1]
return {
'lat': lat_list,
'lng': lng_list
}
3. Компрессия данных:
Делается в одну строку
b64encode(zlib.compress(json.dumps(data).encode('utf-8')))
JavaScript
4. Приведение к объекту JS из сжатой строки
let newData = atob(data)
newData = newData.split('').map(function (e) {
return e.charCodeAt(0)
})
newData = new Uint8Array(newData)
newData = pako.inflate(newData)
newData = new TextDecoder().decode(newData)
return JSON.parse(newData)
5. Преобразование к нормальному виду координат из дельта-закодированных данных
let lastLat = null
let lastLng = null
let result = []
coords.forEach(val => {
let newCoords = []
for (const [index, el] of val.lat.entries()) {
if (!index) {
lastLat = val.lat[0]
lastLng = val.lng[0]
} else {
lastLng += val.lng[index]
lastLat += val.lat[index]
}
newCoords.push([lastLng, lastLat])
}
result.push(newCoords)
})