Географическая визуализация в Vega и Vega-Lite строится вокруг преобразования пространственных данных в экранные координаты. Для этой задачи используются специализированные трансформации:
geopathgeopointgeoshapeОни работают совместно с географическими проекциями
(projection) и позволяют отображать:
Vega использует несколько распространённых форматов:
| Формат | Назначение |
|---|---|
| GeoJSON | Геометрические объекты |
| TopoJSON | Оптимизированные карты |
| Latitude/Longitude | Координаты точек |
| FeatureCollection | Коллекция геообъектов |
Типичный GeoJSON-объект:
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [37.6173, 55.7558]
},
"properties": {
"name": "Москва"
}
}
Все географические трансформации используют
projection.
Без проекции Vega не знает, как перевести координаты Земли в координаты экрана.
Пример:
{
"projections": [
{
"name": "myProjection",
"type": "mercator"
}
]
}
Поддерживаются десятки проекций:
| Проекция | Назначение |
|---|---|
| mercator | Веб-карты |
| albers | США |
| equalEarth | Равновеликая карта |
| orthographic | Глобус |
| naturalEarth1 | Атласы |
| azimuthalEqualArea | Полярные карты |
geopath преобразует геометрические объекты GeoJSON в SVG
path.
Именно эта трансформация используется для:
На вход подаётся геометрия:
{
"type": "Polygon",
"coordinates": [...]
}
На выходе получается:
M120,40L140,60L...
То есть строка SVG path.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 800,
"height": 500,
"data": [
{
"name": "world",
"url": "world.geojson",
"format": {
"type": "geojson"
}
}
],
"projections": [
{
"name": "projection",
"type": "mercator",
"scale": 130,
"translate": [400, 250]
}
],
"marks": [
{
"type": "shape",
"from": {
"data": "world"
},
"transform": [
{
"type": "geopath",
"projection": "projection"
}
],
"encode": {
"update": {
"stroke": {
"value": "#333"
},
"fill": {
"value": "#d8e2dc"
}
}
}
}
]
}
{
"type": "Polygon"
}
{
"projection": "projection"
}
M120,40L...
{
"type": "shape"
}
| Параметр | Описание |
|---|---|
| projection | Используемая проекция |
| field | Поле с геометрией |
Иногда геометрия хранится во вложенном поле:
{
"geometry": {
"type": "Polygon"
}
}
Тогда:
{
"type": "geopath",
"field": "datum.geometry",
"projection": "projection"
}
TopoJSON значительно компактнее GeoJSON.
Пример подключения:
{
"data": [
{
"name": "countries",
"url": "world-110m.json",
"format": {
"type": "topojson",
"feature": "countries"
}
}
]
}
Далее используется обычный geopath.
Частая задача — рисование только контуров.
"encode": {
"update": {
"fill": {
"value": null
},
"stroke": {
"value": "#000"
}
}
}
Карта обычно состоит из нескольких наборов данных:
Пример:
"marks": [
{
"type": "shape",
"from": {"data": "countries"}
},
{
"type": "shape",
"from": {"data": "rivers"}
}
]
geopoint преобразует географические координаты:
longitude, latitude
в экранные координаты:
x, y
Используется для:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 800,
"height": 500,
"data": [
{
"name": "cities",
"values": [
{
"city": "Москва",
"lon": 37.6173,
"lat": 55.7558
},
{
"city": "Париж",
"lon": 2.3522,
"lat": 48.8566
}
]
}
],
"projections": [
{
"name": "projection",
"type": "mercator",
"scale": 130,
"translate": [400, 250]
}
],
"marks": [
{
"type": "symbol",
"from": {
"data": "cities"
},
"transform": [
{
"type": "geopoint",
"projection": "projection",
"fields": ["lon", "lat"]
}
],
"encode": {
"update": {
"x": {"field": "x"},
"y": {"field": "y"},
"size": {"value": 100},
"fill": {"value": "red"}
}
}
}
]
}
37.6173, 55.7558
mercator
x = 512
y = 220
"x": {"field": "x"},
"y": {"field": "y"}
| Параметр | Назначение |
|---|---|
| projection | Географическая проекция |
| fields | Поля longitude и latitude |
| as | Названия результирующих полей |
По умолчанию:
x
y
Можно изменить:
{
"type": "geopoint",
"projection": "projection",
"fields": ["lon", "lat"],
"as": ["screenX", "screenY"]
}
| geopath | geopoint |
|---|---|
| Геометрии | Координаты |
| Polygon | Point |
| Shape | Symbol |
| SVG path | x/y |
| Карты | Маркеры |
geoshape — специализированный shorthand для отрисовки
геометрии.
Фактически это более компактный способ использования
geopath.
geopath:
{
"transform": [
{
"type": "geopath",
"projection": "projection"
}
]
}
geoshape:
{
"type": "geoshape",
"projection": "projection"
}
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width": 800,
"height": 500,
"data": {
"url": "world.geojson",
"format": {
"type": "geojson"
}
},
"projection": {
"type": "mercator"
},
"mark": {
"type": "geoshape",
"fill": "#bde0fe",
"stroke": "#333"
}
}
В Vega-Lite geoshape используется значительно чаще, чем
geopath.
Причины:
GeoJSON Feature:
{
"type": "Feature",
"geometry": {
"type": "Polygon"
},
"properties": {
"name": "Country"
}
}
geoshape автоматически извлекает geometry.
Очень распространённый сценарий:
geoshape;geopoint.{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 900,
"height": 500,
"data": [
{
"name": "countries",
"url": "world.geojson",
"format": {
"type": "geojson"
}
},
{
"name": "cities",
"values": [
{
"name": "Москва",
"lon": 37.6173,
"lat": 55.7558
},
{
"name": "Берлин",
"lon": 13.4050,
"lat": 52.5200
}
]
}
],
"projections": [
{
"name": "projection",
"type": "mercator",
"scale": 140,
"translate": [450, 250]
}
],
"marks": [
{
"type": "shape",
"from": {
"data": "countries"
},
"transform": [
{
"type": "geopath",
"projection": "projection"
}
],
"encode": {
"update": {
"fill": {
"value": "#dde5b6"
},
"stroke": {
"value": "#606c38"
}
}
}
},
{
"type": "symbol",
"from": {
"data": "cities"
},
"transform": [
{
"type": "geopoint",
"projection": "projection",
"fields": ["lon", "lat"]
}
],
"encode": {
"update": {
"x": {"field": "x"},
"y": {"field": "y"},
"size": {"value": 80},
"fill": {"value": "red"}
}
}
}
]
}
geopath и geoshape поддерживают:
| Тип | Описание |
|---|---|
| Point | Точка |
| MultiPoint | Набор точек |
| LineString | Линия |
| MultiLineString | Несколько линий |
| Polygon | Полигон |
| MultiPolygon | Несколько полигонов |
| GeometryCollection | Коллекция геометрий |
Пример маршрута:
{
"type": "LineString",
"coordinates": [
[37.6173, 55.7558],
[2.3522, 48.8566]
]
}
{
"type": "shape",
"transform": [
{
"type": "geopath",
"projection": "projection"
}
],
"encode": {
"update": {
"stroke": {
"value": "blue"
},
"strokeWidth": {
"value": 2
},
"fill": {
"value": null
}
}
}
}
Проекция поддерживает:
| Параметр | Назначение |
|---|---|
| center | Центр карты |
| translate | Смещение |
| scale | Масштаб |
| rotate | Вращение |
{
"type": "mercator",
"center": [30, 50],
"scale": 500
}
Vega может автоматически масштабировать карту:
{
"name": "projection",
"type": "mercator",
"fit": {
"signal": "data('countries')"
}
}
Масштабирование карты:
{
"signals": [
{
"name": "zoom",
"value": 150,
"bind": {
"input": "range",
"min": 50,
"max": 500
}
}
]
}
{
"name": "projection",
"type": "mercator",
"scale": {
"signal": "zoom"
}
}
GeoJSON-файлы могут быть очень большими.
Основные методы оптимизации:
Разные проекции:
Например:
| Проекция | Искажение |
|---|---|
| Mercator | Сильное увеличение полюсов |
| EqualEarth | Искажение формы |
| Orthographic | Только полушарие |
Ошибка:
Cannot read property projection
Причина:
{
"type": "geopath"
}
Без:
"projection": "projection"
Правильно:
[longitude, latitude]
Неправильно:
[latitude, longitude]
Ошибка:
coordinates must be numbers
Причина:
"lat": "55.75"
Вместо:
"lat": 55.75
Пример choropleth-карты:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width": 800,
"height": 500,
"data": {
"url": "world.geojson",
"format": {
"type": "geojson"
}
},
"projection": {
"type": "equalEarth"
},
"mark": "geoshape",
"encoding": {
"color": {
"field": "population",
"type": "quantitative"
}
}
}
Часто карта объединяется с внешними данными.
Пример:
{
"transform": [
{
"lookup": "id",
"from": {
"data": {
"url": "stats.csv"
},
"key": "country_id",
"fields": ["population"]
}
}
]
}
geopath — полноценная transform-операция.
Её можно комбинировать с:
{
"type": "filter",
"expr": "datum.properties.population > 10000000"
}
Подписи городов:
{
"type": "text",
"encode": {
"update": {
"text": {
"field": "city"
}
}
}
}
Совместно с geopoint:
"x": {"field": "x"},
"y": {"field": "y"}
Поддерживаются:
"tooltip": {
"signal": "datum.properties.name"
}
Типичная архитектура:
| Слой | Технология |
|---|---|
| Подложка | geoshape |
| Границы | geopath |
| Города | geopoint |
| Подписи | text |
| Маршруты | LineString |
Подходит для:
Подходит для:
Подходит для: