Circle

Класс Circle в OpenLayers предназначен для представления геометрии окружности на карте. В отличие от многоугольников, состоящих из набора вершин, окружность определяется всего двумя параметрами:

  • координатами центра;
  • радиусом.

Геометрия окружности широко применяется для отображения зон покрытия, радиусов действия объектов, буферных областей, зон поиска, областей наблюдения и других пространственных объектов, имеющих круговую форму.

Класс располагается в модуле:

import Circle from 'ol/geom/Circle.js';

Создание окружности

Базовый конструктор принимает координаты центра и радиус.

const circle = new Circle(
    [4180000, 7500000],
    1000
);

Первый параметр:

[4180000, 7500000]

определяет центр окружности.

Второй параметр:

1000

задаёт радиус.


Добавление окружности на карту

Поскольку Circle является геометрией, её необходимо поместить внутрь объекта Feature.

import Feature from 'ol/Feature.js';
import Circle from 'ol/geom/Circle.js';

const circleFeature = new Feature({
    geometry: new Circle(
        [4180000, 7500000],
        5000
    )
});

Затем объект добавляется в источник данных:

vectorSource.addFeature(circleFeature);

Полный пример отображения окружности

import Map from 'ol/Map.js';
import View from 'ol/View.js';

import TileLayer from 'ol/layer/Tile.js';
import VectorLayer from 'ol/layer/Vector.js';

import OSM from 'ol/source/OSM.js';
import VectorSource from 'ol/source/Vector.js';

import Feature from 'ol/Feature.js';
import Circle from 'ol/geom/Circle.js';

const circleFeature = new Feature({
    geometry: new Circle(
        [4180000, 7500000],
        10000
    )
});

const vectorSource = new VectorSource({
    features: [circleFeature]
});

const map = new Map({
    target: 'map',
    layers: [
        new TileLayer({
            source: new OSM()
        }),
        new VectorLayer({
            source: vectorSource
        })
    ],
    view: new View({
        center: [4180000, 7500000],
        zoom: 8
    })
});

После загрузки карты будет отображена окружность радиусом 10 километров.


Получение центра окружности

Метод getCenter() возвращает координаты центра.

const center = circle.getCenter();

console.log(center);

Результат:

[4180000, 7500000]

Изменение центра

Для изменения положения окружности используется метод setCenter().

circle.setCenter([
    4200000,
    7600000
]);

После вызова метода центр окружности будет перенесён в новую точку.


Получение радиуса

Метод getRadius() возвращает текущий радиус.

const radius = circle.getRadius();

console.log(radius);

Результат:

5000

Изменение радиуса

Метод setRadius() позволяет изменять размер окружности.

circle.setRadius(15000);

Теперь радиус составит 15 километров.


Одновременное изменение центра и радиуса

Для полной замены параметров используется метод setCenterAndRadius().

circle.setCenterAndRadius(
    [4200000, 7600000],
    20000
);

Такой подход удобен при динамическом обновлении геометрии.


Получение экстента

Экстент представляет собой прямоугольную область, полностью содержащую окружность.

Метод:

circle.getExtent();

Пример:

const extent = circle.getExtent();

console.log(extent);

Результат:

[
    minX,
    minY,
    maxX,
    maxY
]

Экстенты используются:

  • для масштабирования карты;
  • пространственного поиска;
  • фильтрации объектов;
  • проверки пересечений.

Определение ближайшей точки

Метод getClosestPoint() возвращает точку окружности, ближайшую к указанным координатам.

const point = circle.getClosestPoint(
    [4190000, 7550000]
);

console.log(point);

Данный метод применяется в алгоритмах пространственного анализа и взаимодействия с объектами.


Проверка пересечения с экстентом

Для определения пересечения используется метод intersectsExtent().

const intersects = circle.intersectsExtent([
    4100000,
    7400000,
    4300000,
    7600000
]);

console.log(intersects);

Результат:

true

или

false

Вычисление площади

Класс Circle напрямую не содержит метода вычисления площади, однако она легко рассчитывается математически.

const radius = circle.getRadius();

const area = Math.PI * radius * radius;

console.log(area);

Формула:

S=r^2

Пример для радиуса 1000 метров:

const area = Math.PI * 1000 * 1000;

Вычисление длины окружности

Длина окружности вычисляется аналогичным образом.

const radius = circle.getRadius();

const length = 2 * Math.PI * radius;

console.log(length);

Формула:

L=2r


Перемещение окружности

Для перемещения используется метод translate().

circle.translate(
    1000,
    500
);

Первый параметр:

1000

смещение по оси X.

Второй:

500

смещение по оси Y.


Поворот окружности

Метод rotate() присутствует у всех геометрий OpenLayers.

circle.rotate(
    Math.PI / 4,
    [4180000, 7500000]
);

Однако для окружности результат визуально не изменяется, поскольку фигура обладает осевой симметрией.

Метод становится полезным при работе с производными геометриями или при использовании единого интерфейса преобразований.


Масштабирование окружности

Метод scale() изменяет размеры геометрии.

circle.scale(2);

После выполнения радиус увеличится в два раза.

Можно указать различные коэффициенты:

circle.scale(
    2,
    2
);

Для окружности одинаковые коэффициенты сохраняют её форму.


Клонирование окружности

Создание копии выполняется методом clone().

const copy = circle.clone();

Новая геометрия будет независимой от оригинала.

copy.setRadius(3000);

Исходная окружность останется без изменений.


Проверка наличия координат

Метод containsXY() отсутствует у класса Circle, поскольку OpenLayers рассматривает окружность как специализированную геометрию.

Для проверки принадлежности точки обычно используется вычисление расстояния до центра.

const center = circle.getCenter();
const radius = circle.getRadius();

const x = 4180500;
const y = 7500300;

const dx = x - center[0];
const dy = y - center[1];

const inside =
    Math.sqrt(dx * dx + dy * dy) <= radius;

console.log(inside);

Преобразование окружности в многоугольник

Многие операции OpenLayers ориентированы на полигоны. Для этого окружность может быть преобразована в объект Polygon.

Используется функция:

fromCircle()

из модуля:

ol/geom/Polygon

Пример:

import Polygon from 'ol/geom/Polygon.js';

const polygon = Polygon.fromCircle(
    circle,
    64
);

Параметры:

  • окружность;
  • количество сегментов.

Количество сегментов при преобразовании

Чем больше сегментов, тем точнее аппроксимация.

Polygon.fromCircle(circle, 8);

Получится восьмиугольник.

Polygon.fromCircle(circle, 32);

Получится значительно более плавная фигура.

Polygon.fromCircle(circle, 128);

Визуально будет практически неотличима от настоящей окружности.


Использование стилей

Окружность может отображаться с произвольным оформлением.

import Style from 'ol/style/Style.js';
import Stroke from 'ol/style/Stroke.js';
import Fill from 'ol/style/Fill.js';

circleFeature.setStyle(
    new Style({
        stroke: new Stroke({
            color: '#ff0000',
            width: 3
        }),
        fill: new Fill({
            color: 'rgba(255,0,0,0.2)'
        })
    })
);

Настраиваются:

  • цвет границы;
  • толщина границы;
  • цвет заливки;
  • прозрачность.

Создание зоны покрытия

Типичный пример использования — отображение радиуса действия объекта.

const tower = new Feature({
    geometry: new Circle(
        [4180000, 7500000],
        30000
    )
});

Такая окружность может обозначать:

  • покрытие базовой станции;
  • радиус действия датчика;
  • зону наблюдения;
  • область поиска;
  • допустимую территорию перемещения.

Динамическое изменение радиуса

Часто радиус зависит от пользовательского ввода.

radiusInput.addEventListener('input', (e) => {
    circle.setRadius(
        Number(e.target.value)
    );
});

После изменения значения геометрия автоматически обновится на карте.


Анимация расширения окружности

let radius = 0;

const timer = setInterval(() => {

    radius += 100;

    circle.setRadius(radius);

    if (radius >= 10000) {
        clearInterval(timer);
    }

}, 50);

Подобный эффект используется для:

  • визуализации распространения сигнала;
  • отображения зон поиска;
  • моделирования волн;
  • отображения радиолокационного сканирования.

Особенности класса Circle

Геометрия хранится как центр и радиус

В отличие от полигона окружность не содержит список вершин.

Экономное использование памяти

Для хранения требуется всего несколько числовых значений.

Быстрое изменение размеров

Изменение радиуса выполняется значительно быстрее, чем пересчёт большого количества координат.

Не является настоящей окружностью в геодезическом смысле

Радиус измеряется в единицах текущей проекции. В проекции Web Mercator это обычно метры, но на больших расстояниях возникают искажения.

Часто преобразуется в Polygon

Для сложных геометрических операций, экспорта и пространственного анализа окружность обычно переводится в многоугольник с заданным числом сегментов.


Основные методы Circle

Метод Назначение
getCenter() Получение центра
setCenter() Изменение центра
getRadius() Получение радиуса
setRadius() Изменение радиуса
setCenterAndRadius() Одновременное изменение центра и радиуса
getExtent() Получение экстента
translate() Перемещение
rotate() Поворот
scale() Масштабирование
clone() Создание копии
getClosestPoint() Поиск ближайшей точки
intersectsExtent() Проверка пересечения с экстентом
getType() Получение типа геометрии

Метод getType() возвращает строку:

console.log(circle.getType());

Результат:

Circle

Этот тип используется во внутренних механизмах OpenLayers для идентификации геометрии и обработки пространственных объектов различных классов.