Работа с пространственными объектами в приложениях на базе HERE Technologies и HERE Maps JavaScript API часто выходит за рамки простого отображения фигур на карте. При построении аналитических слоёв, зон покрытия, территориальных правил и геофенсинга возникает необходимость выполнять булевы операции над геометрией: объединение (union), пересечение (intersection), вычитание (difference).
В стандартном клиентском API базовые геометрические классы (например, полигоны и линии) предназначены для визуализации и простых проверок принадлежности точки области, но не предоставляют полноценного набора геометрических операций. Поэтому на практике используются внешние геометрические библиотеки, чаще всего Turf.js, либо серверные геосервисы.
Полигон в HERE Maps JavaScript API обычно создаётся через набор точек:
const polygon = new H.map.Polygon(
new H.geo.LineString([
52.51, 13.40,
52.52, 13.41,
52.50, 13.42
]),
{
style: { strokeColor: 'blue', lineWidth: 2 }
}
);
Внутренне объект хранит геометрию в формате
H.geo.LineString или H.geo.Polygon. Эти
структуры предназначены для отображения и базовых вычислений (например,
площадь или проверка точки внутри области), но не поддерживают операции
объединения нескольких полигонов напрямую.
Для выполнения булевой геометрии необходимо преобразование в универсальный формат, чаще всего GeoJSON.
Перед выполнением операций union/intersection полигон переводится в GeoJSON:
function herePolygonToGeoJSON(polygon) {
const strip = polygon.getGeometry();
const coordinates = [];
strip.eachLatLngAlt((lat, lng) => {
coordinates.push([lng, lat]);
});
return {
type: "Polygon",
coordinates: [coordinates]
};
}
Ключевой момент заключается в порядке координат: GeoJSON использует
[longitude, latitude], тогда как HERE API —
[latitude, longitude].
Для операций объединения используется библиотека геообработки Turf.js.
import union from '@turf/union';
const poly1 = herePolygonToGeoJSON(polygonA);
const poly2 = herePolygonToGeoJSON(polygonB);
const result = union(poly1, poly2);
Результат представляет собой новый GeoJSON-объект, содержащий объединённую геометрию.
Далее он может быть обратно преобразован в объект карты:
function geoJSONToHerePolygon(geojson) {
const lineString = new H.geo.LineString();
geojson.coordinates[0].forEach(([lng, lat]) => {
lineString.pushPoint({ lat, lng });
});
return new H.map.Polygon(lineString, {
style: { strokeColor: 'red', lineWidth: 3 }
});
}
Операция пересечения используется для вычисления общей области двух геометрий. Это критично при анализе зон доставки, наложении административных границ или фильтрации пространственных данных.
import intersect from '@turf/intersect';
const poly1 = herePolygonToGeoJSON(polygonA);
const poly2 = herePolygonToGeoJSON(polygonB);
const result = intersect(poly1, poly2);
Если пересечение отсутствует, результат будет null.
При моделировании зон доставки часто требуется:
Пример логики:
const warehouseZone = herePolygonToGeoJSON(zoneA);
const deliveryZone = herePolygonToGeoJSON(zoneB);
const overlap = intersect(warehouseZone, deliveryZone);
const merged = union(warehouseZone, deliveryZone);
Полученные результаты затем отображаются как отдельные слои карты.
При объединении сложных областей результат часто становится мультиполигоном:
{
type: "MultiPolygon",
coordinates: [
[[[lng, lat], ...]],
[[[lng, lat], ...]]
]
}
При конвертации обратно в HERE-объекты требуется обработка каждого полигона отдельно:
function geoJSONToMultiHere(geojson) {
const objects = [];
geojson.coordinates.forEach(polygon => {
const line = new H.geo.LineString();
polygon[0].forEach(([lng, lat]) => {
line.pushPoint({ lat, lng });
});
objects.push(new H.map.Polygon(line));
});
return objects;
}
Перед выполнением операций необходимо учитывать геометрические ошибки:
Turf.js в большинстве случаев автоматически нормализует входные данные, однако при интеграции с HERE-структурами требуется явная проверка:
function isValidRing(coords) {
return coords.length > 3 &&
coords[0][0] === coords[coords.length - 1][0] &&
coords[0][1] === coords[coords.length - 1][1];
}
При работе с большим количеством полигонов геометрические операции становятся затратными по времени. Используются следующие подходы:
Упрощение через Turf.js:
import simplify from '@turf/simplify';
const simplified = simplify(polygon, {
tolerance: 0.001,
highQuality: false
});
При визуализации результатов операций важно учитывать порядок отрисовки:
map.addObject(new H.map.Polygon(shape1));
map.addObject(new H.map.Polygon(shape2));
map.addObject(new H.map.Polygon(result));
При этом последняя добавленная фигура перекрывает предыдущие, что используется для выделения пересечений.
В реальных сценариях операции часто комбинируются:
const unionZones = union(zoneA, zoneB);
const finalZone = intersect(unionZones, restrictionZone);
Такая цепочка используется для моделирования сложных пространственных ограничений, включая:
HERE Maps использует WGS84, как и GeoJSON. Однако при интеграции с внешними системами необходимо учитывать:
Для критичных систем применяется нормализация координат до фиксированного количества знаков:
function normalizeCoord([lng, lat]) {
return [
parseFloat(lng.toFixed(6)),
parseFloat(lat.toFixed(6))
];
}