ClickHouse поддерживает словари полигонов. Данный словарь является одной из реализаций внешних словарей, у которого задана специфичная структура. Общий вид кофигурации выглядит следующим образом:
Ключом словаря является сам полигон, что довольно необычно. Все атрибуты являются опциональными, при желании туда можно добавить более подробную информацию. К примеру, может быть добавлен атрибут, содержащий информацию о числе людей, проживающих в данном регионе.
- POLYGON. Это наивная реализация, все полигоны хранятся в памяти и на каждый запрос делается линейный проход по памяти, и проверяется принадлежность точки текущему полигону с помощью алгоритма, реализованного в Boost Geometry.
- GRID_POLYGON. Данная реализация предлагает разбить рассматриваемую области на сетку, и внутри ячейки сетки использовать наивный линейный алгоритм. Для этого выбирается минимальный прямоугольник, содержащий рассматриваемую область, после чего он разбивается на k^2 равных ячеек, где k - конфигурируемый параметр. (TODO: написать как.)
- ONE_BUCKET_POLYGON. Вся плоскость разбивается на вертикальные полоски, проходящие через вершины полигонов. После этого для данной точки находися ее полоска, и из точки выпускается вертикальный луч. По четности числа пересечений ребер полигона определяется, внутри лежит точка или снаружи. В данный момент для хранения ребер используется дерево отрезков для сокращения используемой памяти - каждое ребро принадлежит отрезку полосок, из-за чего можно хранить каждое ребро не более чем в log(n) вершинах, где n - число полосок. Таким образом, потребление памяти есть n log n вместо n^2.
Пользователь может [загружать свои собственные данные](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-sources.md), представленные во всех поддерживаемых ClickHouse форматах.
Дальнейшие запросы к словарю осуществляются с помощью [dictGet](../../../sql-reference/functions/ext-dict-functions.md/#dictget), где ключами являются заданные точки. Один из возможных решений может быть использование таблицы ClickHouse:
В качестве источника данных таблицы можно указать все поддерживаемые ClickHouse форматы данных, к примеру можно передать в таблицу файл с точками в формате `TSV`.
В результате ее исполнения для каждой точки в таблице `points` будет найден полигон минимальной площади, содержащий данную точку. Для этого полигона будут выведены все атрибуты, указанные в запросе (в данном случае это `name` и `value`). Если точка не лежит ни в каком из полигонов, то для всех атрибутов будут возвращены их значения по умолчанию.