Сортировка географических объектов в пространственных данных является одной из ключевых операций при работе с анализом и визуализацией на карте. В контексте JavaScript и геопространственных вычислений библиотека Turf.js предоставляет набор инструментов, позволяющих выполнять сортировку не только по атрибутам объектов, но и по пространственным характеристикам: координатам, расстояниям, площадям и относительному положению объектов.
В Turf.js данные обычно представлены в формате GeoJSON. Коллекции
объектов могут содержать точки, линии и полигоны, объединённые в
FeatureCollection. Сортировка таких коллекций часто
начинается с преобразования их в массив и применения стандартного
JavaScript-метода Array.prototype.sort.
const points = {
type: "FeatureCollection",
features: [
{ type: "Feature", properties: { name: "A" }, geometry: { type: "Point", coordinates: [10, 10] } },
{ type: "Feature", properties: { name: "B" }, geometry: { type: "Point", coordinates: [5, 5] } },
{ type: "Feature", properties: { name: "C" }, geometry: { type: "Point", coordinates: [20, 20] } }
]
};
points.features.sort((a, b) => a.properties.name.localeCompare(b.properties.name));
Такой подход применим только для атрибутивной сортировки и не учитывает географию объектов.
При работе с точечными данными часто требуется упорядочить объекты по оси X или Y. Это может быть полезно при построении упорядоченных маршрутов или подготовке данных для кластеризации.
points.features.sort((a, b) => a.geometry.coordinates[0] - b.geometry.coordinates[0]);
Здесь сортировка производится по долготе. Аналогично можно использовать широту:
points.features.sort((a, b) => a.geometry.coordinates[1] - b.geometry.coordinates[1]);
Такой метод прост, но не отражает реальной географической близости объектов.
Одним из наиболее практичных сценариев является сортировка объектов
по расстоянию до заданной опорной точки. Для этого используется функция
distance из Turf.js.
import distance from "@turf/distance";
import { point } from "@turf/helpers";
const origin = point([10, 10]);
points.features.sort((a, b) => {
return distance(origin, a) - distance(origin, b);
});
В этом случае каждый объект сравнивается по географическому расстоянию до заданной точки. По умолчанию расстояние рассчитывается в километрах с использованием геодезической модели.
Функция расстояния в Turf.js учитывает кривизну Земли, что делает результаты более точными по сравнению с евклидовой метрикой. Это особенно важно при работе на больших расстояниях.
При сортировке больших коллекций повторные вычисления расстояний могут стать узким местом. Оптимальным подходом является предварительное вычисление метрик и их сохранение в свойствах объектов.
const origin = point([10, 10]);
const enriched = points.features.map(feature => {
return {
...feature,
properties: {
...feature.properties,
dist: distance(origin, feature)
}
};
});
enriched.sort((a, b) => a.properties.dist - b.properties.dist);
Такой подход уменьшает количество вычислений в функции сортировки и повышает производительность.
Для полигональных данных часто требуется упорядочивание по площади.
Turf.js предоставляет функцию area, позволяющую вычислять
площадь геометрии.
import area from "@turf/area";
const polygons = {
type: "FeatureCollection",
features: [
{ type: "Feature", geometry: { type: "Polygon", coordinates: [[[0,0],[0,1],[1,1],[1,0],[0,0]]] } },
{ type: "Feature", geometry: { type: "Polygon", coordinates: [[[0,0],[0,2],[2,2],[2,0],[0,0]]] } }
]
};
polygons.features.sort((a, b) => area(a) - area(b));
Сортировка по площади применяется в задачах анализа территорий, кадастровых систем и визуализации регионов.
Иногда требуется сортировка объектов не по исходным координатам, а по
их геометрическому центру. Для этого используется
centroid.
import centroid from "@turf/centroid";
const sorted = polygons.features.sort((a, b) => {
const ca = centroid(a).geometry.coordinates;
const cb = centroid(b).geometry.coordinates;
return ca[0] - cb[0];
});
Такой подход особенно полезен при работе с полигонами сложной формы, где исходные координаты не отражают реального положения объекта.
В сложных сценариях применяется комбинированная сортировка, учитывающая несколько факторов: расстояние, площадь, атрибуты.
const origin = point([10, 10]);
features.sort((a, b) => {
const distA = distance(origin, a);
const distB = distance(origin, b);
if (distA !== distB) return distA - distB;
return a.properties.name.localeCompare(b.properties.name);
});
Такая стратегия позволяет формировать устойчивый порядок при равных значениях первичного критерия.
Для линейных объектов используется функция length.
import length from "@turf/length";
lines.features.sort((a, b) => length(a) - length(b));
Этот метод часто применяется в транспортных задачах, анализе маршрутов и сетевых структурах.
При выполнении пространственной сортировки важно учитывать систему координат данных. Turf.js предполагает использование WGS84 (EPSG:4326). При работе с проекционными координатами результаты расстояний и площадей могут быть некорректными.
При необходимости данные должны быть предварительно приведены к географической системе координат.
JavaScript-метод sort не всегда гарантирует стабильность
во всех средах выполнения, поэтому при работе с геоданными, где важен
детерминированный результат, используется дополнительный индекс.
features.forEach((f, i) => f.properties.index = i);
features.sort((a, b) => {
const diff = distance(origin, a) - distance(origin, b);
return diff !== 0 ? diff : a.properties.index - b.properties.index;
});
Такой подход сохраняет исходный порядок при равенстве ключей сортировки.
После кластеризации данных часто возникает задача упорядочивания кластеров по их характеристикам: размеру, плотности или среднему расстоянию до центра.
clusters.sort((a, b) => b.features.length - a.features.length);
В более сложных сценариях можно использовать центроиды кластеров и сортировку по расстоянию между ними.
Сортировка является вспомогательной операцией в ряде алгоритмов:
В каждом из этих случаев выбор критерия сортировки определяет качество конечного результата.
При необходимости можно комбинировать несколько пространственных характеристик в единую функцию оценки.
const score = (feature, origin) => {
return distance(origin, feature) * 0.7 + area(feature) * 0.3;
};
features.sort((a, b) => score(a, origin) - score(b, origin));
Такой подход позволяет строить многокритериальные модели упорядочивания, адаптированные под конкретные задачи анализа геоданных.