Географические запросы
RethinkDB поддерживает пространственные и географические запросы благодаря поддержке объектов геометрии.
Объекты геометрии реализованы с помощью географической системы координат, где точки и фигуры нанесены на поверхность сферы в трехмерном пространстве. Кроме того, объекты геометрии ReQL могут быть преобразованы в GeoJSON и из GeoJSON с некоторыми ограничениями.
Это обзор системы. Для получения более подробной информации обратитесь к документации API для отдельных команд пространственных запросов.
Начало работы
Эти команды можно выполнить в Data Explorer, чтобы опробовать поддержку пространственных запросов RethinkDB.
Создайте новую таблицу:
r.tableCreate('geo')
Добавьте несколько точек:
r.table('geo').insert([
{
id: 1,
name: 'San Francisco',
location: r.point(-122.423246,37.779388)
},
{
id: 2,
name: 'San Diego',
location: r.point(-117.220406,32.719464)
}
])
Получите расстояние между двумя точками в Сан-Франциско и Сан-Диего:
r.table('geo').get(1)('location').distance(r.table('geo').get(2)('location'))
Добавьте пространственный индекс в таблицу (необходимый для определённых операций, таких как getNearest):
r.table('geo').indexCreate('location', {geo: true})
Получите ближайшую точку в таблице к заданной, используя индекс:
var point = r.point(-122.422876,37.777128); // San Francisco
r.table('geo').getNearest(point, {index: 'location'})
Система координат
Координаты точек на поверхности сферы задаются парой чисел с плавающей точкой, обозначающих долготу и широту. Диапазон долготы составляет от −180 до 180, что охватывает всю сферу: −180 и 180 обозначают одну и ту же линию. Диапазон широты составляет от −90 (южный полюс) до 90 (северный полюс).
Для более подробного объяснения обратитесь к статье Википедии о географической системе координат.
Линии и расстояния
При заданных двух конечных точках линия в ReQL представляет собой кратчайший путь между этими конечными точками на поверхности сферы, известный как геодезическая линия. Линии могут быть определены с помощью нескольких точек, в этом случае каждый отрезок линии будет геодезической линией; аналогично, стороны многоугольника будут геодезическими линиями. Геодезические линии рассчитываются, предполагая идеальную сферу.
Обратите внимание, что линия между северным и южным полюсами (от широты −90 до широты 90) не может быть вычислена, так как все возможные пути между ними являются «кратчайшими»; это может вызвать ошибку в ReQL, или он выберет произвольный (но технически правильный) путь.
Расстояния в ReQL (по умолчанию) рассчитываются не по идеальной сфере, а по эллипсоиду, используя точный и относительно быстрый алгоритм, разработанный Чарльзом Карни. Используемый эталонный эллипсоид — WGS84, стандарт, используемый для GPS. По умолчанию расстояния указываются в метрах, но вы можете передать необязательный аргумент в функции вычисления расстояния, чтобы указать километры, мили, морские мили и футы.
Типы данных
Пространственные функции реализуются набором новых типов данных для объектов геометрии:
- Точки: одна пара координат
- Линии: последовательность из двух или более пар координат
- Многоугольники: многоточечная линия (по крайней мере, три пары координат), которая не пересекает сама себя и у которой первая и последняя пары координат совпадают. Внутренняя область многоугольника считается заполненной, то есть частью многоугольника. Многоугольники с «дырами» в них, где дыра представляет собой другой многоугольник, содержащийся в первом, можно создать с помощью команды [polygonSub].
Кроме того, есть «псевдотип» под названием геометрия, который появляется в документации, чтобы указать, что любой из геометрических объектов может быть использован с этими командами.
Линии и многоугольники могут быть заданы с помощью объектов точек или последовательности массивов из двух чисел:
r.line(r.point(0,0), r.point(0,5), r.point(5,5), r.point(5,0), r.point(0,0))
r.line([0,0], [0,5], [5,5], [5,0], [0,0])
Оба этих определения представляют собой квадрат. Если polygon было указано вместо line, они бы определяли заполненный квадрат.
Хотя существует команда [circle], она аппроксимирует окружность, определяя линию или многоугольник. Не существует истинного кругового типа данных.
Пространственные индексы
Для создания индексов на полях, содержащих объекты геометрии, просто используйте стандартную команду indexCreate, установив необязательный аргумент geo в значение true. На JavaScript это будет выглядеть так:
r.table('sites').indexCreate('locations', {geo: true})
Так же, как и другие индексы ReQL, вы можете создать индекс с помощью анонимной функции вместо простого имени поля, а также создать многоиндексный индекс, используя флаг multi с geo . Подробнее см. в документации API indexCreate.
Использование GeoJSON
Объекты геометрии ReQL не являются объектами GeoJSON, но вы можете преобразовывать их друг в друга с помощью команд geojson и toGeojson.
RethinkDB разрешает только преобразование объектов GeoJSON, которые имеют эквиваленты в ReQL: Point, LineString и Polygon; MultiPoint, MultiLineString и MultiPolygon не поддерживаются. (Однако вы можете хранить несколько точек, линий и многоугольников в массиве и использовать с ними многомерный пространственный индекс.)
Поддерживаются только координаты долготы/широты. Объекты GeoJSON, использующие декартовы координаты, указывающие высоту или свою собственную систему координат, будут отклонены.
Часто задаваемые вопросы
-
Сколько измерений поддерживается?
Два (широта и долгота). Высота не поддерживается.
-
Какие проекции поддерживаются?
RethinkDB поддерживает эллипсоид и географическую систему координат (GCS) WGS84. Он не поддерживает непосредственно никакие проекции координат (PCS), но существует множество инструментов для выполнения таких проекций.
-
RethinkDB выполняет правильную интерполяцию градусов в метры вдоль пути?
Да. Расчеты расстояний выполняются на геодезической линии (либо эталонный эллипсоид WGS84, либо единичная сфера).
-
Можно ли экспортировать в WKT или WKB?
Нет. Однако вы можете экспортировать в GeoJSON и обработать его другими инструментами.
Команды пространственных запросов
- geojson: преобразует объект GeoJSON в объект геометрии
- toGeojson/to_geojson: преобразует объект геометрии в объект GeoJSON
- point: создаёт объект точки
- line: создаёт объект линии
- polygon: создаёт объект многоугольника
- circle: создаёт линию или многоугольник, аппроксимирующий окружность
- distance: вычисляет расстояние между точкой и другим объектом геометрии
- intersects: определяет, пересекаются ли два объекта геометрии
- includes: определяет, полностью ли один объект геометрии содержится в объекте многоугольника
- getIntersecting: возвращает документы из последовательности, у которых поле с пространственным индексом имеет значения, пересекающиеся с заданным объектом геометрии
- getNearest: возвращает документы из последовательности, у которых поле с пространственным индексом имеет значения, находящиеся на заданном расстоянии от заданной точки
- polygonSub: использует один многоугольник, полностью содержащийся внутри другого, чтобы вырезать «дыру» в охватывающем многоугольнике
© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/docs/geo-support/javascript/