Работа с геометриями
Для манипуляций с GeoJSON рекомендуется использовать библиотеку turf.js. Ниже описывается использование данной библиотеки в связке с MapGL JS API.
Граничный прямоугольник (bbox)
Метод turf.bbox
рассчитывает прямоугольную область, в которой находятся заданные объекты или группа объектов.
const line = turf.lineString([
[34, 40],
[36, 41],
[41, 37],
[48, 42],
[42, 35],
]);
const bbox = turf.bbox(line); // [minX, minY, maxX, maxY]
Документация на метод: @turf/bbox
Примеры использования
-
Спозиционировать карту так, чтобы все объекты поместились на экран при помощи метода map.fitBounds.
map.fitBounds({ southWest: bbox.slice(0, 2), northEast: bbox.slice(2, 4) });
-
Запросить дополнительные данные к имеющимся. Например, имея полигоны муниципальных районов, запросить близлежащие объекты застройки.
Граничный прямоугольник является наиболее распространенным и быстрым способом определить границы нахождения объектов. Обратной стороной является то, что границы таким образом определяются достаточно грубо. Если нужна большая точность, воспользуйтесь выпуклой оболочкой.
Выпуклая оболочка (convex hull)
Метод turf.convex
принимает на вход объект или группу объектов и создаёт на их основе выпуклую оболочку.
const line = turf.lineString([
[34, 40],
[36, 41],
[41, 37],
[48, 42],
[42, 35],
]);
const convexHull = turf.convex(line);
Документация на метод: @turf/convex
Пример использования
Выпуклая оболочка — более точный по сравнению с граничным прямоугольником метод определения границ объекта. Обратной стороной является большая вычислительная сложность данного метода.
Буфер вокруг объекта (buffer)
Метод turf.buffer
позволяет пропорционально увеличить или уменьшить объект.
const line = turf.lineString([
[34, 40],
[36, 41],
[41, 37],
[48, 42],
[42, 35],
]);
const buffer = turf.buffer(line, 40);
Документация на метод: @turf/buffer
Примеры использования
- Отобразить различного рода охранные зоны, полосы отчуждения и т.п.
-
Показать на карте места, равноудаленные от какого-либо объекта.
Однако это работает хорошо только на малых расстояниях (до 50-100 м). При расчёте больших расстояний начинает сказываться тот факт, что
turf.buffer
рассчитывает удалённость чисто геометрически, а в действительности на кратчайшем геометрическом пути обычно содержатся препятствия: дома, реки, заборы, которые требуется обходить/объезжать. В этом случае нужно применять более точный и специализированный инструмент: изохроны.
Получение центра (centroid)
Методы turf.center
, turf.centroid
и turf.centerOfMass
позволяют получить тот или иной центр объекта или группы объектов.
const polygon = turf.polygon([
[
[34, 40],
[36, 41],
[41, 37],
[48, 42],
[42, 35],
[34, 40],
],
]);
const center = turf.center(polygon);
const centroid = turf.centroid(polygon);
const centerOfMass = turf.centerOfMass(polygon);
Документация на методы:
Примеры использования
Есть 3 метода получения центра:
center
получает центр граничного прямоугольника объекта или группы.centroid
вычисляет геометрический центр объекта или группы.centerOfMass
получает центр масс фигуры.
На правильных и симметричных полигонах между этими методами практически нет разницы. В случае невыпуклых полигонов или других полигонов неправильной формы лучше всего работает centerOfMass
.
Эти методы удобны для расстановки подписей объектов.
Ближайшая точка (nearestPoint)
Метод turf.nearestPoint
получает ближайшую точку из множества точек.
const line = turf.lineString([
[34, 40],
[36, 41],
[41, 37],
[48, 42],
[42, 35],
]);
const target = turf.point([38, 38]);
const points = turf.explode(line);
const nearest = turf.nearestPoint(target, points);
Документация на метод: @turf/nearestPoint
Особенностью метода является работа только с множеством точек. Чтобы преобразовать произвольный объект в множество точек, воспользуйтесь методом @turf/explode.
Пример использования
Найти ближайший к заданному объект.
Точка на линии (nearestPointOnLine)
Метод turf.nearestPointOnLine
получает ближайшую к заданной точку на линии или на группе линий.
const line = turf.lineString([
[34, 40],
[36, 41],
[41, 37],
[48, 42],
[42, 35],
]);
const target = turf.point([38, 38], { name: 'Target' });
const nearestOnLine = turf.nearestPointOnLine(line, target);
Документация на метод: @turf/nearestPointOnLine
Пример использования
Найти ближайшую точку на маршруте или дороге. Как и в случае с методом turf.buffer, это работает только в самых простых случаях, когда не требуется учитывать препятствия на местности. В остальных случаях воспользуйтесь API маршрутизации.
Объединение (union)
Метод turf.union
объединяет несколько фигур в одну.
const points = [
[10, 10],
[12, 10],
];
const circleA = turf.buffer(turf.point([10, 10]), 300);
const circleB = turf.buffer(turf.point([12, 10]), 300);
const united = turf.union(circleA, circleB);
Документация на метод: @turf/union
Примеры использования
- Отобразить на карте область, которую составляют несколько объектов, как один объект.
- Собрать излишне фрагментированные объекты, что иногда случается при обработке геоданных.
Пересечение (intersect)
Метод turf.intersect
находит фигуру, образованную пересечением заданных фигур.
const points = [
[10, 10],
[12, 10],
];
const circleA = turf.buffer(turf.point([10, 10]), 300);
const circleB = turf.buffer(turf.point([12, 10]), 300);
const intersected = turf.intersect(circleA, circleB);
Документация на метод: @turf/intersect
Пример использования
Отобразить на карте область, являющуюся пересечением других областей. Например, бесплатную парковку в пределах заданного радиуса от объекта.
Маска (mask)
Метод turf.mask
позволяет «вывернуть наизнанку» полигон: превратить остальное пространство вокруг него в полигон.
const poly = turf.polygon([
[
[0, 0],
[0, 2],
[2, 2],
[2, 0],
[0, 0],
],
]);
turf.mask(poly);
Документация на метод: @turf/mask
Пример использования
Акцентировать внимание на одной или нескольких областях карты и затенить остальное пространство.
Упрощение (simplify)
Метод turf.simplify
упрощает геометрию при помощи алгоритма Рамера-Дугласа-Пекера.
const gpsTrack = turf.lineString([
[0, 0],
[0, 0.1],
[0.5, 0.5],
[1, 0.5],
]);
const simplifiedTrack = turf.simplify(gpsTrack, { tolerance: 0.2 });
// { ... geometry: { ..., coordinates: [[0, 0], [0.5, 0.5], [1, 0.5]] } }
Степень упрощения геометрии определяется параметром tolerance
, который обозначает максимальную ошибку, которую может допустить алгоритм при упрощении. Величина tolerance
имеет ту же размерность, что и исходные данные. То есть, если геокоординаты указываются в градусах, то и tolerance
будет в градусах.
Документация на метод: @turf/simplify
Примеры использования
- Получить менее сложные геометрии, которые будут отрисовываться быстрее.
- Отфильтровать данные, когда изв естно, что их точность не может превышать определённое значение.
- Отобразить точные данные на большом масштабе: упрощённые геометрии имеют более эстетичный внешний вид и плавные линии без визуального шума.