geoshape: картографические объекты

Тип визуализации geoshape в Vega и Vega-Lite предназначен для отображения географических объектов: стран, регионов, административных границ, морей, дорог, рек и любых произвольных геометрий в формате GeoJSON или TopoJSON.

В отличие от обычных графиков, где используются координаты x и y, картографические визуализации работают через географические проекции. Vega автоматически преобразует долготу и широту в экранные координаты.

geoshape используется для:

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

Базовая структура geoshape

Минимальный пример:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",

  "data": {
    "url": "data/world-110m.json",
    "format": {
      "type": "topojson",
      "feature": "countries"
    }
  },

  "mark": "geoshape"
}

В этом примере:

  • загружается TopoJSON-файл;
  • извлекается объект countries;
  • каждая страна отображается как геометрический объект.

GeoJSON и TopoJSON

GeoJSON

GeoJSON хранит геометрию напрямую.

Пример:

{
  "type": "Feature",
  "geometry": {
    "type": "Polygon",
    "coordinates": [...]
  },
  "properties": {
    "name": "Kazakhstan"
  }
}

Поддерживаются:

  • Point
  • LineString
  • Polygon
  • MultiPolygon
  • MultiLineString

TopoJSON

TopoJSON — оптимизированный формат поверх GeoJSON.

Особенности:

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

В Vega-Lite чаще используются именно TopoJSON-файлы.


Подключение TopoJSON

{
  "data": {
    "url": "data/world-110m.json",
    "format": {
      "type": "topojson",
      "feature": "countries"
    }
  },

  "mark": {
    "type": "geoshape",
    "fill": "#dcdcdc",
    "stroke": "#ffffff"
  }
}

Параметр feature

Указывает объект внутри TopoJSON:

"feature": "countries"

Если в файле несколько слоёв:

{
  "objects": {
    "countries": {},
    "rivers": {},
    "lakes": {}
  }
}

можно выбирать нужный слой.


Работа с проекциями

Без проекции геометрия не может быть корректно отображена.

Базовая проекция

{
  "projection": {
    "type": "mercator"
  }
}

Популярные типы проекций

Mercator

"projection": {
  "type": "mercator"
}

Особенности:

  • стандарт для веб-карт;
  • сильно искажает полярные области;
  • удобна для навигации.

Equal Earth

"projection": {
  "type": "equalEarth"
}

Особенности:

  • сохраняет площади;
  • подходит для тематических карт;
  • современная альтернатива Robinson.

Orthographic

"projection": {
  "type": "orthographic"
}

Создаёт эффект глобуса.


Natural Earth

"projection": {
  "type": "naturalEarth1"
}

Подходит для атласов и инфографики.


Albers

"projection": {
  "type": "albers"
}

Часто применяется для США.


Настройка проекции

Масштабирование

"projection": {
  "type": "mercator",
  "scale": 150
}

Центрирование

"projection": {
  "type": "mercator",
  "center": [67, 48]
}

Формат:

[longitude, latitude]

Поворот

"projection": {
  "type": "orthographic",
  "rotate": [-90, -30]
}

Смещение

"projection": {
  "translate": [400, 300]
}

Полный пример

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",

  "width": 800,
  "height": 500,

  "data": {
    "url": "data/world-110m.json",
    "format": {
      "type": "topojson",
      "feature": "countries"
    }
  },

  "projection": {
    "type": "equalEarth",
    "scale": 140
  },

  "mark": {
    "type": "geoshape",
    "fill": "#4c78a8",
    "stroke": "#ffffff",
    "strokeWidth": 0.5
  }
}

Работа с цветами

Однотонная карта

"mark": {
  "type": "geoshape",
  "fill": "#4682b4"
}

Цвет через поле данных

"encoding": {
  "color": {
    "field": "population",
    "type": "quantitative"
  }
}

Хороплетные карты

Хороплетная карта — карта, где регионы окрашиваются по значениям.

Пример:

{
  "encoding": {
    "color": {
      "field": "gdp",
      "type": "quantitative",
      "scale": {
        "scheme": "blues"
      }
    }
  }
}

Объединение геометрии и таблицы данных

Часто геометрия хранится отдельно от статистики.

Используется lookup.

Пример

{
  "transform": [
    {
      "lookup": "id",

      "from": {
        "data": {
          "url": "data/population.csv"
        },
        "key": "country_id",
        "fields": ["population"]
      }
    }
  ]
}

Полный пример хороплетной карты

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",

  "width": 900,
  "height": 500,

  "data": {
    "url": "data/world-110m.json",
    "format": {
      "type": "topojson",
      "feature": "countries"
    }
  },

  "transform": [
    {
      "lookup": "id",
      "from": {
        "data": {
          "url": "data/gdp.csv"
        },
        "key": "id",
        "fields": ["gdp"]
      }
    }
  ],

  "projection": {
    "type": "equalEarth"
  },

  "mark": {
    "type": "geoshape",
    "stroke": "#ffffff"
  },

  "encoding": {
    "color": {
      "field": "gdp",
      "type": "quantitative",
      "scale": {
        "scheme": "greens"
      }
    }
  }
}

Отображение границ

Только контуры

"mark": {
  "type": "geoshape",
  "fill": null,
  "stroke": "#000000"
}

Толщина границы

"mark": {
  "strokeWidth": 2
}

Пунктирные границы

"mark": {
  "strokeDash": [4, 2]
}

Работа с точками

Для координат используются поля:

  • longitude
  • latitude

Пример

{
  "data": {
    "url": "data/cities.csv"
  },

  "mark": "circle",

  "encoding": {
    "longitude": {
      "field": "lon",
      "type": "quantitative"
    },

    "latitude": {
      "field": "lat",
      "type": "quantitative"
    },

    "size": {
      "field": "population",
      "type": "quantitative"
    }
  }
}

Комбинирование слоёв

Карта обычно строится через layer.

Геометрия + точки

{
  "layer": [
    {
      "data": {
        "url": "data/world-110m.json",
        "format": {
          "type": "topojson",
          "feature": "countries"
        }
      },

      "mark": {
        "type": "geoshape",
        "fill": "#eeeeee",
        "stroke": "#ffffff"
      }
    },

    {
      "data": {
        "url": "data/cities.csv"
      },

      "mark": "circle",

      "encoding": {
        "longitude": {
          "field": "lon",
          "type": "quantitative"
        },

        "latitude": {
          "field": "lat",
          "type": "quantitative"
        },

        "size": {
          "field": "population",
          "type": "quantitative"
        }
      }
    }
  ]
}

Географические линии

Для маршрутов и дорог используются:

  • LineString
  • MultiLineString

Пример маршрута

{
  "data": {
    "values": [
      {
        "type": "Feature",
        "geometry": {
          "type": "LineString",
          "coordinates": [
            [71.43, 51.12],
            [76.95, 43.25]
          ]
        }
      }
    ]
  },

  "mark": {
    "type": "geoshape",
    "stroke": "red",
    "strokeWidth": 3
  }
}

Географические полигоны

Polygon используется для:

  • озёр;
  • районов;
  • парков;
  • административных зон.

MultiPolygon

Многие страны состоят из нескольких частей.

Например:

  • Индонезия;
  • Япония;
  • США;
  • Россия.

В этом случае используется:

"MultiPolygon"

Vega автоматически обрабатывает такие структуры.


Сфера (sphere)

Сфера представляет всю поверхность Земли.

Пример

{
  "data": {
    "sphere": true
  },

  "mark": {
    "type": "geoshape",
    "fill": "#dbefff"
  }
}

Graticule

Graticule — координатная сетка.

Генерация сетки

{
  "data": {
    "graticule": true
  },

  "mark": {
    "type": "geoshape",
    "stroke": "#cccccc"
  }
}

Слой карты с сеткой

{
  "layer": [
    {
      "data": {
        "sphere": true
      },

      "mark": {
        "type": "geoshape",
        "fill": "#ddeeff"
      }
    },

    {
      "data": {
        "graticule": true
      },

      "mark": {
        "type": "geoshape",
        "stroke": "#cccccc"
      }
    }
  ]
}

Подписи на карте

Текст можно выводить поверх карты.

Пример

{
  "mark": "text",

  "encoding": {
    "longitude": {
      "field": "lon",
      "type": "quantitative"
    },

    "latitude": {
      "field": "lat",
      "type": "quantitative"
    },

    "text": {
      "field": "city"
    }
  }
}

Tooltip

Интерактивные подсказки особенно важны для карт.

"encoding": {
  "tooltip": [
    {
      "field": "country",
      "type": "nominal"
    },

    {
      "field": "population",
      "type": "quantitative"
    }
  ]
}

Интерактивное выделение

Hover

{
  "params": [
    {
      "name": "hover",
      "select": {
        "type": "point",
        "on": "mouseover"
      }
    }
  ]
}

Изменение цвета при наведении

"encoding": {
  "fillOpacity": {
    "condition": {
      "param": "hover",
      "value": 1
    },
    "value": 0.5
  }
}

Zoom и pan в Vega

Vega-Lite ограниченно поддерживает навигацию по карте. Для полноценного zoom/pan обычно используется Vega.


Отличия Vega и Vega-Lite в картографии

Vega-Lite

Подходит для:

  • быстрых карт;
  • аналитики;
  • хороплетов;
  • статистических визуализаций.

Плюсы:

  • краткий синтаксис;
  • автоматическая обработка;
  • меньше кода.

Vega

Подходит для:

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

Работа с Vega напрямую

Пример Vega-спецификации:

{
  "$schema": "https://vega.github.io/schema/vega/v5.json",

  "width": 800,
  "height": 500,

  "projections": [
    {
      "name": "projection",
      "type": "mercator"
    }
  ],

  "data": [
    {
      "name": "world",
      "url": "data/world-110m.json",
      "format": {
        "type": "topojson",
        "feature": "countries"
      }
    }
  ],

  "marks": [
    {
      "type": "shape",

      "from": {
        "data": "world"
      },

      "transform": [
        {
          "type": "geoshape",
          "projection": "projection"
        }
      ],

      "encode": {
        "update": {
          "fill": {
            "value": "#4c78a8"
          },

          "stroke": {
            "value": "#ffffff"
          }
        }
      }
    }
  ]
}

Трансформация geoshape в Vega

В Vega используется отдельная трансформация:

{
  "type": "geoshape",
  "projection": "projection"
}

Она преобразует географическую геометрию в SVG path.


Производительность

При работе с большими картами возникают проблемы:

  • тысячи полигонов;
  • сложные MultiPolygon;
  • высокая детализация береговых линий.

Оптимизация

Использование TopoJSON

TopoJSON существенно уменьшает размер данных.


Упрощение геометрии

GIS-инструменты:

  • mapshaper;
  • GDAL;
  • QGIS.

Ограничение детализации

Для веба редко нужна сверхточная геометрия.


Частые ошибки

Неверная проекция

"projection": {
  "type": "identity"
}

Для обычных геоданных это почти всегда ошибка.


Перепутанные координаты

Правильный порядок:

[longitude, latitude]

Не наоборот.


Несовпадение ключей при lookup

"lookup": "id"

и

"key": "country_id"

должны содержать совместимые значения.


Практический пример: карта Казахстана

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",

  "width": 700,
  "height": 500,

  "data": {
    "url": "data/kazakhstan.json",
    "format": {
      "type": "topojson",
      "feature": "regions"
    }
  },

  "projection": {
    "type": "mercator",
    "center": [67, 48],
    "scale": 2500
  },

  "mark": {
    "type": "geoshape",
    "fill": "#87b5e5",
    "stroke": "#ffffff",
    "strokeWidth": 1
  },

  "encoding": {
    "tooltip": [
      {
        "field": "name",
        "type": "nominal"
      }
    ]
  }
}

Архитектура картографического рендеринга

Процесс построения карты:

  1. загрузка геометрии;
  2. преобразование TopoJSON/GeoJSON;
  3. применение проекции;
  4. вычисление path;
  5. рендеринг SVG или Canvas;
  6. наложение интерактивности.

SVG и Canvas

SVG

Плюсы:

  • высокое качество;
  • удобная интерактивность;
  • DOM-доступ.

Минусы:

  • хуже производительность на больших картах.

Canvas

Плюсы:

  • быстрее;
  • лучше для тысяч объектов.

Минусы:

  • сложнее интерактивность.

Использование Canvas

{
  "config": {
    "view": {
      "renderer": "canvas"
    }
  }
}

Комбинирование с другими визуализациями

Карты часто объединяются с:

  • heatmap;
  • scatter plot;
  • timeline;
  • dashboard;
  • histogram.

Генерация картограмм

Через вычисляемые поля можно строить тематические карты.

Пример:

{
  "transform": [
    {
      "calculate": "datum.population / datum.area",
      "as": "density"
    }
  ]
}

Поддержка анимации в Vega

Vega позволяет:

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

Это особенно важно для:

  • транспортных систем;
  • климатических моделей;
  • GPS-трекинга;
  • спутниковых данных.

Интеграция с D3 Geo

Внутри Vega используются многие механизмы D3 Geo:

  • проекции;
  • path generator;
  • геометрические преобразования.

Поэтому поддерживаются практически все основные географические проекции D3.


Когда использовать geoshape

geoshape оптимален для:

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