Задать вопрос
@bubaley

Как сжать массив координат?

В базе данных есть полигоны с большим количеством координат. Когда пользователь заходит в web-приложение происходит запрос к этим полигонам и отрисовка их на карте. Вес ответа составляет 7мб+, где почти вся часть этого веса это координаты.
Часто эти полигоны редактируются, поэтому постоянно кешировать их не вариант. Хотелось бы представить координаты полигонов в виде строк (чтобы уменьшить вес, надеюсь есть какие-то алгоритмы для этого), а потом на фронте их распарсить обратно в массивы координат.
Я понимаю, что при запросе и так работает gzip, но этого все равно мало.
Как можно решить это задачу?
  • Вопрос задан
  • 424 просмотра
Подписаться 1 Средний 7 комментариев
Решения вопроса 1
@bubaley Автор вопроса
В итоге использовал следующий шаги для сжатия координат. Сразу о результатах до этих действий:
Было:
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)
        })
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
fox_12
@fox_12 Куратор тега Python
Расставляю биты, управляю заряженными частицами
Прочитайте про protobuff - возможно это вам поможет.
Ответ написан
Комментировать
MayorPlay
@MayorPlay
!developer
Если передавать их в виде строки, которую можно будет распарсить, то передавай данные через JSON
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
Rocket Смоленск
от 80 000 до 130 000 ₽
Wanted. Москва
от 250 000 до 400 000 ₽
Wanted. Санкт-Петербург
До 220 000 ₽
22 янв. 2025, в 22:30
5000 руб./за проект
22 янв. 2025, в 22:26
200000 руб./за проект
22 янв. 2025, в 22:25
50000 руб./за проект