При работе с Turf.js большинство ошибок возникает не в самой библиотеке, а на уровне входных геоданных и предположений о структуре GeoJSON. Turf.js строго следует спецификации GeoJSON, поэтому любое отклонение от формата приводит к выбросам исключений или некорректным результатам вычислений.
Turf.js ожидает строго валидные объекты GeoJSON. Нарушение структуры
приводит к ошибкам вида TypeError,
Error: Invalid GeoJSON object или внутренним исключениям
функций обработки.
К типичным проблемам относятся:
typecoordinatesПример некорректного объекта:
const point = {
type: "Point",
coordinates: ["55.75", "37.61"]
};
Правильный вариант:
const point = {
type: "Point",
coordinates: [37.61, 55.75]
};
Даже незначительное отклонение, например строковые координаты, может
привести к NaN внутри геометрических операций.
Turf.js строго различает типы геометрий. Передача неподходящего типа приводит к логическим или runtime-ошибкам.
Например, функция turf.length ожидает
LineString или MultiLineString. Передача
Point не имеет геометрического смысла:
turf.length(point); // ошибка или бессмысленный результат
Для предотвращения подобных ситуаций используется проверка
geometry.type:
function assertLineString(feature) {
if (!feature || feature.geometry?.type !== "LineString") {
throw new Error("Ожидается LineString");
}
}
Большинство функций Turf.js не возвращают код ошибки — они
выбрасывают исключения. Поэтому стандартный механизм обработки строится
на try...catch.
import * as turf from "@turf/turf";
try {
const line = turf.lineString([[0, 0], [10, 10]]);
const result = turf.length(line);
} catch (err) {
console.error("Ошибка геообработки:", err.message);
}
Такой подход критически важен при работе с пользовательскими данными, API или внешними источниками GeoJSON.
Turf.js часто используется в виде цепочек трансформаций:
const buffered = turf.buffer(
turf.cleanCoords(
turf.lineString(coords)
),
5
);
При такой композиции ошибка может возникнуть на любом этапе. Для точной диагностики используется разбиение цепочки:
let line;
try {
line = turf.lineString(coords);
} catch (e) {
throw new Error("Ошибка создания LineString");
}
let cleaned;
try {
cleaned = turf.cleanCoords(line);
} catch (e) {
throw new Error("Ошибка очистки координат");
}
Такой подход упрощает локализацию проблем в геометрии.
Turf.js не всегда выполняет автоматическую валидацию топологии. Поэтому некорректные геометрии могут проходить через функции и давать неожиданные результаты.
Полигон с самопересечением может приводить к некорректным площадям и буферам.
Пример проблемного полигона:
const polygon = turf.polygon([[
[0, 0],
[10, 10],
[0, 10],
[10, 0],
[0, 0]
]]);
Такая геометрия пересекает сама себя.
Для выявления используются дополнительные проверки, например:
@turf/boolean-valid (в некоторых сборках)@turf/kinksПример:
import booleanValid from "@turf/boolean-valid";
if (!booleanValid(polygon)) {
throw new Error("Некорректный полигон");
}
Одной из частых причин скрытых ошибок является выход координат за допустимые пределы:
function validateCoord([lng, lat]) {
if (lng < -180 || lng > 180) {
throw new Error("Некорректная долгота");
}
if (lat < -90 || lat > 90) {
throw new Error("Некорректная широта");
}
}
Turf.js работает с географическими координатами и различными единицами измерения. Несоответствие единиц — частый источник логических ошибок.
Некоторые внутренние расчёты используют радианы, но входные данные всегда задаются в градусах.
Ошибка возникает, когда разработчик вручную передаёт радианы:
// ошибка: координаты в радианах
const point = turf.point([1.2, 0.8]);
Правильный подход — всегда использовать градусы.
Функция turf.buffer принимает расстояние и единицы
измерения:
turf.buffer(point, 5, { units: "kilometers" });
Ошибка:
turf.buffer(point, 5000); // неоднозначно: метры или километры
Явное указание единиц снижает риск неверной интерпретации.
Геометрические операции могут приводить к NaN, если
входные данные содержат:
function sanitizeCoords(coords) {
return coords.filter(c =>
Array.isArray(c) &&
Number.isFinite(c[0]) &&
Number.isFinite(c[1])
);
}
const area = turf.area(polygon);
if (!Number.isFinite(area)) {
throw new Error("Ошибка вычисления площади");
}
Наиболее нестабильный сценарий — загрузка GeoJSON из API, файлов или пользовательского ввода.
async function loadGeoJSON(url) {
const res = await fetch(url);
if (!res.ok) {
throw new Error("Ошибка загрузки данных");
}
const data = await res.json();
if (!data || data.type !== "FeatureCollection") {
throw new Error("Неверный формат GeoJSON");
}
return data;
}
После загрузки данные дополнительно проходят проверку перед передачей в Turf.js.
Turf.js работает в WGS84 (EPSG:4326). Использование данных в других системах координат без преобразования приводит к критическим искажениям.
Результат — некорректные дистанции и площади.
function assertWGS84(feature) {
const [lng, lat] = feature.geometry.coordinates;
if (Math.abs(lng) > 180 || Math.abs(lat) > 90) {
throw new Error("Ожидаются координаты WGS84");
}
}
Некоторые операции Turf.js изменяют структуру геометрии:
turf.bufferturf.dissolveturf.intersectturf.unionКаждая из них может вернуть null при отсутствии
результата пересечения.
nullconst result = turf.intersect(poly1, poly2);
if (!result) {
throw new Error("Пересечение отсутствует");
}
Игнорирование этого поведения приводит к ошибкам при последующих операциях.
Геометрические расчёты целесообразно выносить в отдельный слой:
function safeBuffer(feature, distance) {
try {
return turf.buffer(feature, distance, { units: "meters" });
} catch (e) {
return null;
}
}
При геообработке важно сохранять входные данные:
try {
const result = turf.area(polygon);
} catch (e) {
console.error("Ошибка вычисления площади", {
error: e.message,
feature: polygon
});
}
При использовании TypeScript часть ошибок устраняется на этапе компиляции:
import { Feature, Polygon } from "@turf/helpers";
function process(poly: Feature<Polygon>) {
return turf.area(poly);
}
Однако даже строгая типизация не защищает от некорректных координат.
При построении сложных систем (маршрутизация, кластеризация, анализ зон покрытия) ошибка в одной геометрии может распространяться по всей цепочке вычислений.
Типичная стратегия:
nullconst results = features
.map(f => {
try {
return turf.buffer(f, 1);
} catch {
return null;
}
})
.filter(Boolean);
Ошибки чаще проявляются как Uncaught Error, если
отсутствует глобальный обработчик:
window.addEventListener("error", (e) => {
console.error("Geo error:", e.message);
});
В Node.js возможна интеграция с централизованным логированием:
process.on("uncaughtException", (err) => {
console.error("Критическая геоошибка:", err);
});
При сложных полигонах полезно упрощать геометрию:
const simplified = turf.simplify(polygon, {
tolerance: 0.01,
highQuality: true
});
Ошибки часто исчезают после упрощения, что указывает на проблему исходной топологии.
Критические edge cases:
function isDegenerateLine(line) {
return line.geometry.coordinates.length < 2;
}
Такие проверки предотвращают большинство runtime-ошибок Turf.js.