Расчет веса точек

В системах визуализации пространственных данных вес точки используется как числовой показатель значимости объекта, влияющий на его вклад в итоговое представление слоя. В Mapbox GL JS механизм веса применяется в нескольких контекстах: тепловые карты, кластеризация, динамическое стилизование символов и вычисление плотности распределения данных.

Вес точки представляет собой числовое значение ( w_i ), связанное с геометрическим объектом. При агрегации множества точек в пределах пиксельной области или кластера итоговая характеристика вычисляется как взвешенная сумма:

[ W = _{i=1}^{n} w_i]

При необходимости нормализации используется деление на суммарный вес:

[ W_{norm} = ]

В контексте визуализации это позволяет управлять интенсивностью отображения данных без изменения геометрической структуры источника.

Вес точки в heatmap-слое

В Mapbox GL JS тепловые карты используют свойство heatmap-weight, которое определяет вклад каждой точки в итоговую интенсивность пикселя.

Базовая логика заключается в следующем:

  • каждая точка влияет на пиксели в радиусе влияния;
  • вклад точки масштабируется по её весу;
  • итоговая интенсивность определяется суммой вкладов всех точек в области.

Пример:

map.addLayer({
  id: 'heatmap-layer',
  type: 'heatmap',
  source: 'points',
  paint: {
    'heatmap-weight': [
      'interpolate',
      ['linear'],
      ['get', 'weight'],
      0, 0,
      6, 1
    ]
  }
});

Здесь атрибут weight из данных управляет вкладом каждой точки. Низкие значения практически не влияют на плотность, высокие — усиливают локальную интенсивность.

Нормализация веса и диапазоны значений

Практическая проблема при работе с весами — неоднородность входных данных. Если значения сильно варьируются, визуализация становится непропорциональной.

Используются следующие стратегии:

Линейная нормализация

[ w’ = ]

Применяется при равномерных распределениях.

Логарифмическое масштабирование

[ w’ = (1 + w)]

Используется при наличии выбросов и экспоненциальных распределений.

Квантование

Разбиение диапазона на фиксированные интервалы, например:

  • 0–10 → 0.1
  • 10–100 → 0.5
  • 100+ → 1

В Mapbox GL JS такие преобразования часто выполняются через expression API.

Данные и вычисление веса на уровне источника

Вес может быть заранее встроен в GeoJSON-объекты:

const geojson = {
  type: 'FeatureCollection',
  features: [
    {
      type: 'Feature',
      properties: {
        weight: 2
      },
      geometry: {
        type: 'Point',
        coordinates: [71.4304, 51.1281]
      }
    }
  ]
};

В таком случае слой получает уже подготовленные значения, что снижает вычислительную нагрузку на рендеринг.

Вес в зависимости от масштаба (zoom-dependent weighting)

Одной из ключевых возможностей является изменение веса точки в зависимости от масштаба карты.

В Mapbox GL JS это реализуется через выражения:

'heatmap-weight': [
  'interpolate',
  ['linear'],
  ['zoom'],
  0, 0.2,
  10, 1,
  15, 2
]

Такой подход позволяет:

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

Использование веса в кластеризации

При включённой кластеризации точки объединяются в группы, где вес кластера вычисляется как сумма весов входящих объектов.

Типовая логика:

[ W_{cluster} = _{i=1}^{n} w_i]

Mapbox GL JS автоматически добавляет свойства:

  • point_count — количество точек;
  • cluster — признак принадлежности к кластеру;
  • cluster_id — идентификатор группы.

Пример стилизации кластера по весу:

'circle-radius': [
  'step',
  ['get', 'point_count'],
  10,
  10, 15,
  50, 25
]

Хотя здесь используется количество точек, вместо него может применяться агрегированный вес через clusterProperties.

Кастомные агрегаты веса через clusterProperties

Более гибкий механизм позволяет вычислять суммарные или средние значения прямо в процессе кластеризации:

clusterProperties: {
  totalWeight: ['+', ['get', 'weight']]
}

Это позволяет:

  • суммировать пользовательские метрики;
  • вычислять средние значения;
  • строить многомерные кластеры.

Пример использования:

'circle-color': [
  'interpolate',
  ['linear'],
  ['get', 'totalWeight'],
  0, '#2DC4B2',
  100, '#3BB3C3',
  500, '#F1F075',
  1000, '#F28CB1'
]

Влияние веса на визуальные свойства слоя

Вес точки может напрямую влиять на несколько параметров отображения:

  • радиус (circle-radius);
  • прозрачность (circle-opacity);
  • цвет (circle-color);
  • размытие в heatmap (heatmap-radius, heatmap-intensity).

Пример:

'circle-radius': [
  'interpolate',
  ['linear'],
  ['get', 'weight'],
  0, 3,
  10, 20
],

'circle-opacity': [
  'interpolate',
  ['linear'],
  ['get', 'weight'],
  0, 0.3,
  10, 1
]

Такой подход превращает вес в универсальный управляющий параметр визуального поведения объекта.

Композиция нескольких факторов веса

В реальных системах вес редко является одиночной величиной. Обычно он формируется как композиция факторов:

[ w = a + b + c]

где:

  • ( a ) — базовая метрика (например, количество событий);
  • ( b ) — временной коэффициент;
  • ( c ) — бизнес-важность;
  • ( , , ) — коэффициенты влияния.

Такой подход позволяет строить адаптивные модели отображения данных без изменения геометрии источника.

Ошибки при работе с весами

При проектировании визуализаций в Mapbox GL JS часто возникают типовые проблемы:

  • отсутствие нормализации приводит к доминированию отдельных точек;
  • линейное масштабирование искажает восприятие плотности;
  • чрезмерные веса создают визуальные артефакты в heatmap;
  • некорректные clusterProperties приводят к несогласованным агрегатам.

Корректная настройка весов требует согласования диапазонов данных, логики агрегации и визуальных ограничений слоя.