При клике по точке города на карте будем выполнять запрос к методу API, который возвращает подробную информацию о городе. Здесь мы работаем с асинхронностью самостоятельно.
<Card title='За что обычно отвечает первый блок <code>.then</code> в цепочке <code>fetch...then</code> при запросе данных с сервера?'>
<MultipleChoice>
<Option>
логирование данных в консоль
</Option>
<Option>
обработка возможных ошибок
</Option>
<Option isCorrect>
извлечение данных из ответа сервера
</Option>
</MultipleChoice>
<details>
<summary>Узнать ответ</summary>
В первом блоке `then` нам доступен специальный объект ответа (Response), но мы ещё не имеем доступа к данным, поэтому мы должны их извлечь их, например, методом `response.json()` или `response.text()`.
</details>
</Card>
```js title=main.js
map.on("load", () => {
...
@ -352,9 +371,9 @@ map.on("load", () => {
При желании посмотрите [полный код](https://github.com/gtitov/flask-maplibre-map) и [возможный результат](https://gtitov.github.io/flask-maplibre-map/).
Эта карта отличается от предыдущих. Здесь мы сами разработали логику работы серверной части, другими словами, разработали бэкенд:
В первой карте мы брали данные с сервера *как есть*, поэтому карта относилась к статическим. Во второй карте мы использовали готовый бэкенд и обращались к нему по API.
> В первой карте мы брали данные с сервера *как есть*, поэтому карта относилась к статическим. Во второй карте мы использовали готовый бэкенд и обращались к нему по API.
Для этой карты мы сами разработали логику работы серверной части, другими словами, разработали бэкенд:
1. Фронтенд обращается к методу API, который предоставляет данные о городах (этот метод мы объявили самостоятельно)
1. Обращение к методу API инициирует выполнение серверной функции (эту функцию мы написали самостоятельно)
В рамках практической части создадим карту ойконимов Московского региона по векторным тайлам, генерирующимся на лету приложением Martin из базы данных PostGIS.
В рамках практической части создадим карту ойконимов Московского региона по векторным тайлам, генерирующимся на лету приложением Martin из базы данных PostGIS. При желании посмотрите [полный код](https://github.com/gtitov/martin-maplibre-map) и [возможный результат](https://gtitov.github.io/martin-maplibre-map/).
## Что такое тайлы
В прошлом упражнении мы сами разработали бэкенд для передачи пространственных данных из базы в браузер пользователю. Обычно для таких операций пользуются готовыми инструментами и устоявшимися подходами. Одним из таких подходов является применение тайлов.
В прошлом упражнении мы сами разработали бэкенд для передачи пространственных данных из базы в браузер пользователю. Чаще для таких операций пользуются готовыми инструментами и устоявшимися подходами. Одним из таких подходов является применение тайлов.

Пространственные данные могут быть большими по объёму. Если пользователь хочет посмотреть на веб-карту передавать ему гигабайты данных, мягко говоря, неоптимально. Это приведёт к длительной загрузке веб-страницы, избыточному трафику, медленной работе веб-карты или падению браузера.
Пространственные данные могут быть большими по объёму. Если пользователь хочет посмотреть веб-карту, передавать ему все данные сразу (а это могут быть гигабайты) не нужно. Это приведёт к длительной загрузке веб-страницы, избыточному трафику, медленной работе веб-карты или падению браузера.
Данные можно поделить на кусочки и передавать пользователю только *нужные кусочки* с *нужной детальностью*. Данные можно поделить на кусочки по-разному. Пространственные данные ожидаемо удобно делить на географические кусочки — тайлы. *Нужные кусочки* -- те, что попадают на экран. *Нужная детальность* -- та, что соответствует текущему масштабу карты.
Тайл привязан к глобальной системе координат одной точкой, геометрии внутри тайла храняться во внутренней системе координат тайла. Тайлы бывают векторными и растровыми. В векторных тайлах содержание одного тайла составляют точки, линии и полигоны, [особым образом](https://docs.mapbox.com/data/tilesets/guides/vector-tiles-standards/#encoding-attributes) кодируются атрибуты. В растровых тайлах содержание одного тайла составляют пиксели.
Тайл привязан к глобальной системе координат одной точкой. Геометрии внутри тайла хранятся во внутренней системе координат тайла. Тайлы бывают векторными и растровыми. В векторных тайлах содержание одного тайла составляют точки, линии и полигоны, [особым образом](https://docs.mapbox.com/data/tilesets/guides/vector-tiles-standards/#encoding-attributes) кодируются атрибуты. В растровых тайлах содержание одного тайла составляют пиксели.
Растровые тайлы можно использовать как для растровых данных, например, снимков, ЦМР, индексных изображений, так и для векторных, когда на тайлы будет нарезаться подготовленное изображение карты. Векторные тайлы, в большинстве случаев, оказываются удачным решением для векторных наборов данных.
Растровые тайлы можно использовать как для растровой модели данных, например, снимков, ЦМР, индексных изображений, так и для векторной, когда на тайлы будет нарезаться подготовленное изображение карты. Векторные тайлы оказываются удачным решением для векторных наборов данных.
<LinkCard title="Тайлы растровые и векторные" href="/chapters/98-extra/#тайлы-векторные-и-растровые" description="Что лучше 🤨"/>
## Использование тайлов
Познакомимся c возможностями практического применения тайлов. Для этого загрузим наборы пространственных данных в базу пространственных данных. Подключим к ней сервер векторных тайлов. Получим векторные тайлы на клиентской стороне веб-приложения средствами картографической библиотеки.
Познакомимся c возможностями практического применения тайлов. Для этого сделаем следующее.
1. Загрузим наборы пространственных данных в базу пространственных данных.
1. Подключим к ней сервер векторных тайлов.
1. Получим векторные тайлы на клиентской стороне веб-приложения средствами картографической JavaScript-библиотеки.
### База пространственных данных
Используем сервер баз данных Postres с расширением для пространственных данных PostGIS.
Используем сервер баз данных Postgres с расширением для пространственных данных PostGIS.
<LinkCard title="Postgres + PostGIS = ♥" href="/chapters/98-extra/#PostGIS" description="Решение для хранения пространственных данных"/>
#### Установка
Дистрибутив для сервера баз данных загрузим [здесь](https://www.postgresql.org/download/). При установке следует обратить внимание на порт, который будет занимать сервер баз данных, и пароль для пользователя `postgres`.
> Сервер баз данных запускается локально. Доступ к локальному серверу баз данных осуществляется по заданному при установке порту -- обычно 5432. Если установщик предлагает другой порт, возможно, что у вас уже установлен сервер баз данных, который этот порт занимает.
> Сервер баз данных запускается локально. Доступ к локальному серверу баз данных осуществляется по заданному при установке порту -- обычно 5432. Если установщик предлагает другой порт, возможно, сервер баз данных уже установлен на компьютер и занимает этот порт.
После установки сервера баз данных Postgres можно установить расширение для работы с пространственными данными PostGIS. Дистрибутив доступен [тут](https://postgis.net/documentation/getting_started/#installing-postgis).
Мы не будем обращаться к базе данных напрямую. Мы добавим прослойку, которая будет формировать векторные тайлы на основе загруженных в базу данных.
Мы не будем обращаться к базе данных напрямую. Мы добавим прослойку, которая будет формировать векторные тайлы из пространственных данных, хранящихся в базе.
#### Сервер векторных тайлов
@ -141,6 +146,12 @@ martin postgresql://postgres:password@localhost:5432/oikonyms
> `/catalog`, `/grid`, `/grid/{z}/{x}/{y}` -- это всё эндпоинты API, которое для нас автоматически формирует Martin. Он же выполняет нужные серверные функции, за счёт которых мы получаем ответы, обращаясь к этим эндпоинтам. И ничего не пришлось писать самим, как в прошлом упражнении!
При обращении `{z}/{x}/{y}` заменяются на индекс запрашиваемого тайла, например, `0/0/0` для запроса тайла на весь мир при уровне зума `0` или `1/1/0` для тайла в верхнем правом углу при уровне зума 1. Некоторые тайлы могут быть пустыми.
Когда тайл запрашивается, сервер векторных тайлов выполняет серверную функцию, которая вырезает соответствующий кусочек из исходного набора пространственных данных. Сервер векторных тайлов Martin обеспечивает подготовку тайла за счёт запроса к базе данных, то есть вырезанием и кодированием атрибутов и геометрии объектов, попадающих в тайл, занимается PostGIS.
<LinkCard title="Производительность векторных тайлов" href="/chapters/98-extra/#производительность-векторных-тайлов" description="Как быстро PostGIS нарезает тайлы"/>
#### Векторные тайлы на карте
Остаётся принять эти векторные тайлы на карте. Заготовку для карты формируем как обычно.
В рамках инструмента в MBTiles в растровые тайлы превращается отрисованное изображение, которые мы видим в основном окне QGIS, с применёнными параметрами оформления, а не исходное изображение. Можно добавить к этому изображению и векторные слои.
#### Подключение в Martin
Запустим Martin, подключив его к MBTiles.
Объединим запуск подключения к Postgres и подключения к MBTiles.
Запустим подключение к Postgres с сохранением файла конфигурации.
Затем запустим подключение к MBTiles с сохранением файла конфигурации.
Объединим файлы.
Запустим Martin с применением объединённого файла конфигурации.
#### Растровые тайлы на карте
Для подключения растровых тайлов укажем тип источника `raster`
При добавлении слоя параметры оформления не указываем.
*/}
## Что мы получили
Получилась просто отличная карта!
При желании посмотрите [полный код](https://github.com/gtitov/martin-maplibre-map) и [возможный результат](https://gtitov.github.io/martin-maplibre-map/).
## Упраженения
Повторим основные моменты работы веб-карты, использующей векторные тайлы:
1. Пользователь открывает веб-карту при определённом зуме в определённом охвате.
1. Картографическая библиотека определяет, какие тайлы попадают в охват при заданном зуме.
1. Картографическая библиотека выполняет запрашивает векторные тайлы, выполняя запрос к API сервера векторных тайлов.
1. Сервер векторных тайлов получает запрос и выполняет серверную функцию, отвечающую за формирование тайла. Входным параметром для этой функции является индекс тайла Z/X/Y.
1. Серверная функция выполняет запрос к базе данных. Этот запрос вырезает из слоя пространственных данных объекты, попадающие в тайл, кодирует их атрибуты и геометрию.
1. Тайлы приходят в клиентскую часть картографического веб-приложения, где картографическая библиотека извлекает нужный слой из тайлов, сшивает объекты, попадающие в несколько тайлов, отрисовывает пространственные данные как картографический слой.
1. С данными полученного слоя мы можем спокойно работать: показывать попап с атрибутами при клике на объект, менять курсор при наведении на слой, интерактивно фильтровать данные.
Такая карта применима в разнообразных задачах. Фокусом использования векторных тайлов является визуализация больших объёмов пространственных данных. На этом каркасе построены популярные картографические сервисы, подсистемы визуализации пространственных данных в аналитических платформах. Векторные тайлы -- это проверенный, функциональный инструмент, но для его успешного применения надо понимать, из каких частей состоит этот механизм и за что отвечает каждая из этих частей.
## Упражнения
1. Сделайте так, чтобы при наведении курсора на точку из слоя ойконимов она становилась немного больше
1. Добавьте на карту инструмент фильтрации населённых пунктов по первой букве названия
1. Добавьте обводку в 3 пикселя ячейке, на которую был выполнен клик. Сделайте так, чтобы обводка исчезала при зуме меньше 9.
## Контрольные вопросы
1. Какое программное обеспечение предоставляет API для запроса тайлов в нашей веб-карте?
1. За какой параметр отвечает индекс `Z` в схеме векторных тайлов `Z/X/Y`?
1. Из чего формируется геометрическая составляющая векторного тайла?
1. Какой тип источника применяется для использования векторных тайлов в MapLibre GL JS?
1. За что отвечает параметр `source-layer` в коде функций MapLibre GL JS?
В рамках практической части создадим карту ойконимов Московского региона по векторным тайлам, генерирующимся на лету приложением Martin из базы данных PostGIS.
##
### Растровые тайлы
Загрузим файл с каналом Ландсата на Москву
#### Подготовка набора тайлов
Через QGIS превратим в MBTiles.
В рамках инструмента в MBTiles в растровые тайлы превращается отрисованное изображение, которые мы видим в основном окне QGIS, с применёнными параметрами оформления, а не исходное изображение. Можно добавить к этому изображению и векторные слои.
#### Подключение в Martin
Запустим Martin, подключив его к MBTiles.
Объединим запуск подключения к Postgres и подключения к MBTiles.
Запустим подключение к Postgres с сохранением файла конфигурации.
Затем запустим подключение к MBTiles с сохранением файла конфигурации.
Объединим файлы.
Запустим Martin с применением объединённого файла конфигурации.
#### Растровые тайлы на карте
Для подключения растровых тайлов укажем тип источника `raster`
При добавлении слоя параметры оформления не указываем.
Любая карта -- это инструмент для решения конкретной задачи. Знание того, какие карты бывают, позволяет принять взвешенное и разумное решение.
Любая карта -- это инструмент для решения конкретной задачи. Знание того, какие карты бывают, позволяет принять взвешенное и разумное решение. Иногда нужно быстро показать, где расположена пара объектов. А иногда надо организовать эффективное отображение постоянно меняющихся полигонов по всему миру.
Мы познакомились только с несколькими походами из большого разнообьразия. Зато эти подходы хорошо показывают принципы функционирование веб-карт. Понимание этих принципов даст возможность ориентироваться в многообразхии существуюзщих подходов, успешно осваивать новые подходы и осознанно их применять.
Сквозь призму практических упражнений мы рассмотрели основные принципы функционирования картографических веб-приложений. К сожалению, а, скорее, всё же к счастью, сфера веб-картографии крайне разнообразна. Освоенный вами материал станет опорой на любом из путей развития в сфере веб-картографии.
У векторных и растровых тайлов есть свои достоинства и недостатки. Выбор конкретного варианта зависит от отображаемых данных, назначения веб-карты, требований к безопасности данных. Векторные тайлы хорошо подходят для объектно-ориентированного картографирования: изображения точек интереса, дорог, границ. Растровые тайлы незаменимый вариант для отображения спутниковых снимков, непрерывных покрытий, данных без возможности прямого доступа к объектам.
## PostGIS
Связка Postgres + PostGIS -- это зарекомендовавшее себя открытое решение для работы с пространственными данными в сети.
PostGIS популярен. Легко найти информацию в сети. Давно используется, соответственно модели будут давать нормальные ответы. Используется как для веб-картографии, так и для аналитики.
PostGIS универсален. Для большинства случаев связка Postgres + PostGIS оказывается подходящим вариантом. Она проста в обращении, поэтому используется на небольших проектах. Она может работать под нагрузкой с большими объёмами данных, поэтому используется на крупных предприятиях.
PostGIS избыточен. В случаях, когда к пространственным данным не нужно совершать пространственных запросов, такая связка избыточна, например, нам в первом упражнении было достаточно статических GeoJSON файлов.
PostGIS не хватает. Не хватает связки Postgres + PostGIS в краевых случаях, например,при необходимости агрегации на лету особо больших объёмов слабоструктурированных данных (десятки и сотни миллионов строк) https://github.com/ClickHouse/adsb.exposed/ или необходимости особо быстрого ответа (Redis)
<!-- ## Как PostGIS формирует тайл -->
## Производительность векторных тайлов
Формирование тайла представляет собой запрос кусочка из полного набора пространственных данных, его перепроецирование и кодирование в векторных тайл.