В формате GeoJSON объект MultiPolygon представляет набор независимых полигонов, объединённых в одну геометрию. Каждый полигон может содержать внешний контур и произвольное количество внутренних контуров (отверстий).
Типичная структура выглядит следующим образом:
{
"type": "MultiPolygon",
"coordinates": [
[
[
[30, 10],
[40, 40],
[20, 40],
[10, 20],
[30, 10]
]
],
[
[
[60, 20],
[80, 20],
[80, 40],
[60, 40],
[60, 20]
]
]
]
}
Подобные объекты часто используются для описания:
В Turf.js мультиполигоны участвуют во всех основных булевых операциях наравне с обычными полигонами.
Для создания MultiPolygon используется функция
multiPolygon.
import * as turf from "@turf/turf";
const regions = turf.multiPolygon([
[
[
[0, 0],
[10, 0],
[10, 10],
[0, 10],
[0, 0]
]
],
[
[
[20, 0],
[30, 0],
[30, 10],
[20, 10],
[20, 0]
]
]
]);
Результатом становится объект GeoJSON Feature:
{
type: "Feature",
geometry: {
type: "MultiPolygon",
coordinates: [...]
}
}
Такой объект можно передавать в любые функции Turf.js, поддерживающие работу с полигонами.
Под булевыми операциями понимаются операции над геометриями, возвращающие новую геометрию либо логический результат.
Наиболее востребованы:
| Операция | Назначение |
|---|---|
| union | Объединение |
| intersect | Пересечение |
| difference | Вычитание |
| dissolve | Слияние смежных областей |
| booleanIntersects | Проверка пересечения |
| booleanContains | Проверка вложенности |
| booleanOverlap | Проверка наложения |
| booleanWithin | Проверка нахождения внутри |
При работе с MultiPolygon поведение этих операций имеет ряд особенностей.
Функция union() объединяет все области двух
геометрий.
const area1 = turf.multiPolygon([
[
[
[0, 0],
[10, 0],
[10, 10],
[0, 10],
[0, 0]
]
]
]);
const area2 = turf.multiPolygon([
[
[
[20, 0],
[30, 0],
[30, 10],
[20, 10],
[20, 0]
]
]
]);
const result = turf.union(
turf.featureCollection([area1, area2])
);
Результирующая геометрия также будет MultiPolygon.
Структурно:
MultiPolygon
├─ Polygon #1
└─ Polygon #2
Такой сценарий характерен для объединения удалённых территорий.
Если полигоны пересекаются, Turf.js строит единую область.
const poly1 = turf.polygon([
[
[0, 0],
[20, 0],
[20, 20],
[0, 20],
[0, 0]
]
]);
const poly2 = turf.polygon([
[
[10, 10],
[30, 10],
[30, 30],
[10, 30],
[10, 10]
]
]);
const merged = turf.union(
turf.featureCollection([poly1, poly2])
);
Полученная фигура уже может стать обычным Polygon, если
после объединения остаётся единый контур.
Это важная особенность: тип результата не всегда совпадает с типом входных данных.
Функция intersect() вычисляет общую область.
const overlap = turf.intersect(
turf.featureCollection([
multiPolyA,
multiPolyB
])
);
Если общих участков нет:
null
Если пересечение существует:
Feature<Polygon>
или
Feature<MultiPolygon>
в зависимости от количества образовавшихся фрагментов.
Предположим, первый мультиполигон содержит три отдельные области.
A1 A2 A3
Второй мультиполигон пересекает только две из них.
B
После выполнения:
const result = turf.intersect(
turf.featureCollection([multiA, multiB])
);
результатом станет новый MultiPolygon, содержащий только найденные зоны пересечения.
Intersection
├─ Part #1
└─ Part #2
Функция difference() удаляет из первой геометрии область
второй.
const result = turf.difference(
turf.featureCollection([
source,
mask
])
);
Логически операция выглядит так:
A - B
После вычитания могут возникать различные ситуации.
Если вычитаемая область полностью лежит внутри полигона:
██████████
██ ██
██ B ██
██ ██
██████████
результатом станет полигон с внутренним кольцом.
Polygon
├─ outer ring
└─ hole
GeoJSON автоматически хранит отверстия как дополнительные массивы координат.
Иногда вычитание разрывает исходную область.
████████████
████ BBB ███
████ BBB ███
████████████
После удаления центральной части остаются два независимых участка.
███ ███
███ ███
В этом случае Turf.js возвращает MultiPolygon.
{
type: "MultiPolygon"
}
Поэтому после выполнения difference() всегда
рекомендуется проверять тип результата.
if (result.geometry.type === "MultiPolygon") {
console.log("Область разделилась на части");
}
Для быстрой проверки без построения новой геометрии используется
функция booleanIntersects().
const intersects = turf.booleanIntersects(
multiPolygon1,
multiPolygon2
);
Результат:
true
или
false
Внутри Turf.js анализируются все полигоны, входящие в состав MultiPolygon.
Даже если пересекается только одна часть:
MP1
├─ P1
├─ P2
└─ P3
MP2
└─ пересекает P2
результат будет:
true
Функция booleanContains() определяет, полностью ли одна
геометрия содержит другую.
const contains = turf.booleanContains(
bigArea,
smallArea
);
Для мультиполигонов проверяются все составляющие области.
const contains = turf.booleanContains(
country,
islands
);
Возвращается:
true
только если каждая часть объекта islands находится
внутри country.
Обратная операция выполняется функцией
booleanWithin().
const within = turf.booleanWithin(
objectA,
objectB
);
Логически:
A внутри B
Для MultiPolygon это особенно полезно при анализе административных границ.
Например:
const isInside = turf.booleanWithin(
district,
region
);
Функция booleanOverlap() используется тогда, когда
объекты:
const overlap = turf.booleanOverlap(
multiPolygon1,
multiPolygon2
);
Пример:
AAAAAAA
AAABBBB
AAABBBB
Результат:
true
Если один объект полностью вложен в другой:
false
Поскольку это уже отношение включения, а не наложения.
Во многих проектах данные поступают в виде коллекций.
const collection = turf.featureCollection([
mp1,
mp2,
mp3,
mp4
]);
Для последовательного объединения применяется цикл.
let current = collection.features[0];
for (let i = 1; i < collection.features.length; i++) {
current = turf.union(
turf.featureCollection([
current,
collection.features[i]
])
);
}
После обработки получается единая геометрия.
Такой подход часто используется для:
После сложных вычислений тип результирующей геометрии может меняться.
Например:
Polygon
может превратиться в
MultiPolygon
или наоборот.
Без проверки типа дальнейшая обработка может завершиться ошибкой.
Рекомендуемый подход:
const geometryType =
result.geometry.type;
switch (geometryType) {
case "Polygon":
console.log("Один полигон");
break;
case "MultiPolygon":
console.log("Несколько полигонов");
break;
}
Подобная проверка особенно важна при:
После выполнения булевых операций нередко требуется обработать каждую часть отдельно.
Для этого используется flatten().
const flattened =
turf.flatten(multiPolygon);
Результатом будет:
FeatureCollection<Polygon>
Далее можно перебрать все полигоны.
flattened.features.forEach(poly => {
const area = turf.area(poly);
console.log(area);
});
Подход широко применяется после операций:
После булевых операций часто требуется определить площадь итоговой фигуры.
const area = turf.area(result);
Функция одинаково работает для:
Polygon
и
MultiPolygon
Например:
const merged = turf.union(
turf.featureCollection([
region1,
region2
])
);
const totalArea = turf.area(merged);
Если результат содержит несколько несвязанных частей, площадь будет вычислена как сумма площадей всех полигонов.
Булевы операции относятся к наиболее ресурсоёмким вычислениям в геоинформационных системах.
Основные факторы нагрузки:
Проблемы обычно возникают при обработке:
100+
полигонов
или
десятков тысяч вершин
Для повышения производительности используются следующие методы:
simplify().Пример предварительной проверки:
if (
turf.booleanIntersects(a, b)
) {
const result = turf.intersect(
turf.featureCollection([a, b])
);
}
Такой подход позволяет избежать дорогостоящих вычислений для объектов, не имеющих общих областей.
Районы
+
Области
+
Муниципалитеты
Объединяются и пересекаются для анализа административных границ.
Зоны доставки
+
Зоны обслуживания
Используются для построения общих территорий покрытия.
Лесные массивы
-
Запретные территории
Формируются новые области наблюдения.
Участок
-
Отчуждаемая часть
Вычисляется остаточная площадь земельного объекта.
Покрытие станции A
∩
Покрытие станции B
Определяются зоны перекрытия сигнала.
Во всех подобных задачах MultiPolygon выступает одной из ключевых геометрий, а булевы операции Turf.js позволяют выполнять сложные пространственные преобразования с сохранением структуры данных GeoJSON и автоматическим формированием корректных результирующих полигонов.