В геоанализе работа ведётся не с одиночными объектами, а с наборами
геометрий, оформленных как FeatureCollection. В рамках
Turf.js фильтрация коллекций строится вокруг трёх типов операций:
properties)Структурно коллекция имеет вид:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": { ... },
"properties": { ... }
}
]
}
Фильтрация всегда сводится к созданию новой
FeatureCollection, так как исходные данные считаются
неизменяемыми.
Базовый механизм обхода реализован через модуль meta. Он
предоставляет функции, позволяющие обходить геометрию и свойства без
ручного перебора массива.
Позволяет обработать каждый объект коллекции:
import { featureEach } from "@turf/meta";
featureEach(points, (feature, index) => {
console.log(index, feature.properties);
});
Используется как фундамент для любых пользовательских фильтров.
Применяется для анализа координат внутри геометрий:
import { coordEach } from "@turf/meta";
coordEach(polygon, (coord) => {
console.log(coord);
});
Подходит для низкоуровневой геометрической фильтрации, например:
Работа только с атрибутами:
import { propEach } from "@turf/meta";
propEach(collection, (properties) => {
console.log(properties.type);
});
Используется для быстрой фильтрации без геометрических вычислений.
Атрибутивные фильтры строятся поверх стандартного массива
features.
const filtered = {
type: "FeatureCollection",
features: collection.features.filter(f =>
f.properties.population > 100000
)
};
Типовые сценарии:
const filtered = {
type: "FeatureCollection",
features: collection.features.filter(f =>
f.properties.type === "park" &&
f.properties.area > 5000
)
};
Пространственная фильтрация — ключевая особенность Turf.js, основанная на геометрических предикатах.
import booleanPointInPolygon from "@turf/boolean-point-in-polygon";
const filtered = {
type: "FeatureCollection",
features: points.features.filter(point =>
booleanPointInPolygon(point, polygon)
)
};
Используется для:
import booleanIntersects from "@turf/boolean-intersects";
const filtered = lines.features.filter(line =>
booleanIntersects(line, polygon)
);
import booleanDisjoint from "@turf/boolean-disjoint";
const filtered = points.features.filter(point =>
booleanDisjoint(point, polygon)
);
Разделение на:
import booleanWithin from "@turf/boolean-within";
const filtered = points.features.filter(point =>
booleanWithin(point, polygon)
);
Используется для строгой проверки вложенности геометрий.
Один из самых быстрых способов предварительного отбора — проверка bounding box.
import bbox from "@turf/bbox";
import booleanPointInPolygon from "@turf/boolean-point-in-polygon";
const box = bbox(polygon);
const filtered = points.features.filter(p => {
const [x, y] = p.geometry.coordinates;
return (
x >= box[0] &&
x <= box[2] &&
y >= box[1] &&
y <= box[3]
);
});
Преимущество:
Маскирование применяется, когда нужно обрезать или ограничить геометрию по области.
import mask from "@turf/mask";
const result = mask(points, polygon);
Используется для:
Фильтрация часто строится как цепочка шагов:
const result = {
type: "FeatureCollection",
features: points.features
.filter(p => p.properties.type === "school")
.filter(p => p.properties.students > 500)
.filter(p => booleanPointInPolygon(p, district))
};
Характерные этапы:
Разделение коллекции на несколько групп:
const inside = [];
const outside = [];
points.features.forEach(p => {
if (booleanPointInPolygon(p, polygon)) {
inside.push(p);
} else {
outside.push(p);
}
});
Результат:
const insideLines = lines.features.filter(line =>
booleanWithin(line, polygon)
);
const crossingLines = lines.features.filter(line =>
booleanIntersects(line, polygon)
);
Комбинация пространственных и атрибутивных условий:
const result = {
type: "FeatureCollection",
features: collection.features.filter(f =>
f.properties.category === "road" &&
booleanIntersects(f, boundaryPolygon) &&
f.properties.length > 1000
)
};
Типовые сценарии:
При работе с большими коллекциями критичны следующие принципы:
Атрибутивные проверки дешевле:
features.filter(f => f.properties.active)
Сокращает количество дорогих проверок:
Плохой подход:
features.filter(f => booleanPointInPolygon(f, poly))
features.filter(f => booleanPointInPolygon(f, poly))
Правильный:
const precomputed = features.filter(f =>
booleanPointInPolygon(f, poly)
);
Иногда фильтрация требуется внутри структур:
const result = geojson.features
.map(layer => ({
...layer,
features: layer.features.filter(f =>
f.properties.value > 10
)
}));
Используется в:
При больших наборах данных фильтрация через перебор становится неэффективной. В таких случаях используется предварительная индексация (например, R-tree), поверх которой Turf.js применяет предикаты.
Типичный паттерн:
Фильтрация коллекций в Turf.js всегда строится как композиция:
featureEach, filter)properties)boolean*)bbox)FeatureCollectionТакая структура обеспечивает предсказуемость, масштабируемость и совместимость с геопространственными вычислениями любого уровня сложности