Feature и свойства объектов

В OpenLayers объект Feature представляет отдельную географическую сущность на карте. Это может быть точка, линия, полигон, круг, маршрут, здание, земельный участок, дорожный знак или любой другой пространственный объект.

Класс Feature служит контейнером для двух основных компонентов:

  • геометрии;
  • набора пользовательских свойств.

Типичная структура объекта выглядит следующим образом:

const city = new ol.Feature({
    geometry: new ol.geom.Point([4187345, 7501234]),
    name: 'Караганда',
    population: 500000
});

В данном примере объект содержит:

  • геометрию типа Point;
  • свойство name;
  • свойство population.

Feature объединяет пространственную информацию и атрибутивные данные в единую сущность.


Создание объекта Feature

Создание пустого объекта

Feature может быть создан без параметров.

const feature = new ol.Feature();

После создания свойства и геометрия добавляются отдельно.

feature.setGeometry(
    new ol.geom.Point([0, 0])
);

feature.set('name', 'Test Point');

Создание через объект конфигурации

Наиболее распространённый способ.

const feature = new ol.Feature({
    geometry: new ol.geom.Point([100, 200]),
    name: 'Marker',
    type: 'point'
});

Все поля, кроме geometry, автоматически становятся пользовательскими свойствами.


Создание из GeoJSON

Часто объекты создаются после загрузки данных.

const features = new ol.format.GeoJSON().readFeatures(geojsonData);

Каждый элемент массива будет экземпляром класса Feature.


Геометрия объекта

Каждый Feature может содержать одну активную геометрию.

Пример:

const feature = new ol.Feature({
    geometry: new ol.geom.LineString([
        [0, 0],
        [100, 100]
    ])
});

Получение геометрии:

const geometry = feature.getGeometry();

Изменение геометрии:

feature.setGeometry(
    new ol.geom.Point([50, 50])
);

Удаление геометрии:

feature.setGeometry(null);

После удаления объект остаётся существовать, но перестаёт отображаться на карте.


Пользовательские свойства

Feature может хранить любое количество атрибутов.

const feature = new ol.Feature({
    geometry: point,
    id: 15,
    title: 'Школа',
    category: 'education',
    students: 1200
});

Свойства часто используются для:

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

Получение свойства

Для получения одного свойства используется метод get().

const title = feature.get('title');

Пример:

console.log(
    feature.get('students')
);

Результат:

1200

Если свойство отсутствует:

console.log(
    feature.get('address')
);

Результат:

undefined

Установка свойства

Для записи значения применяется метод set().

feature.set('title', 'Гимназия');

Если свойства не существовало, оно будет создано.

feature.set('director', 'Иванов');

Теперь объект содержит новое поле.


Изменение существующего свойства

feature.set('students', 1300);

Новое значение полностью заменяет старое.


Удаление свойства

Для удаления используется метод unset().

feature.unset('director');

После удаления:

console.log(
    feature.get('director')
);

Результат:

undefined

Получение всех свойств

Метод getProperties() возвращает объект со всеми атрибутами.

const properties =
    feature.getProperties();

Пример результата:

{
    geometry: Point,
    id: 15,
    title: 'Школа',
    category: 'education'
}

Важно помнить, что геометрия также входит в список свойств.


Исключение геометрии из набора свойств

Часто требуется получить только атрибуты.

const props = feature.getProperties();

delete props.geometry;

После этого остаются только пользовательские данные.


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

if (feature.get('name')) {
    console.log('Свойство существует');
}

Более надёжный вариант:

const props = feature.getProperties();

if ('name' in props) {
    console.log('Свойство найдено');
}

Установка нескольких свойств одновременно

Метод setProperties() позволяет записать сразу несколько значений.

feature.setProperties({
    name: 'Park',
    area: 3500,
    status: 'active'
});

Аналогично последовательным вызовам:

feature.set('name', 'Park');
feature.set('area', 3500);
feature.set('status', 'active');

Но выполняется компактнее и удобнее.


Идентификатор объекта

Помимо обычных свойств существует специальный идентификатор Feature.

Назначение идентификатора

feature.setId(1001);

Получение значения:

const id = feature.getId();

Удаление:

feature.setId(undefined);

Отличие ID от обычного свойства

Обычное свойство:

feature.set('id', 1001);

Специальный идентификатор:

feature.setId(1001);

Это разные значения.

console.log(feature.get('id'));
console.log(feature.getId());

Могут возвращаться разные результаты.

Многие внутренние механизмы OpenLayers используют именно Feature ID, а не свойство с именем id.


Работа с именем геометрии

По умолчанию OpenLayers ожидает геометрию в свойстве geometry.

Иногда данные содержат другое поле.

Например:

const feature = new ol.Feature({
    shape: new ol.geom.Point([0, 0]),
    name: 'Object'
});

В этом случае необходимо указать имя геометрического свойства.

feature.setGeometryName('shape');

Теперь OpenLayers будет использовать поле shape как геометрию объекта.


Получение имени геометрии

const geometryName =
    feature.getGeometryName();

Результат:

geometry

или

shape

в зависимости от настроек.


Наблюдение за изменениями свойств

Feature наследует механизм событий OpenLayers.

Изменение любого свойства вызывает событие.

feature.on('change', function () {
    console.log('Объект изменён');
});

Пример:

feature.set('name', 'New Name');

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


Событие изменения конкретного свойства

Можно отслеживать определённое поле.

feature.on('change:name', function () {
    console.log('Имя изменилось');
});

Пример:

feature.set('name', 'School');

Консоль:

Имя изменилось

Получение старого и нового значения

Обработчик может получать информацию о событии.

feature.on('change:status', function (event) {
    console.log(event);
});

Событие содержит сведения об изменённом свойстве и объекте Feature.


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

Очень часто атрибуты определяют внешний вид объектов.

const styleFunction = function(feature) {

    const type = feature.get('type');

    if (type === 'city') {

        return cityStyle;

    } else {

        return villageStyle;
    }
};

Назначение стиля:

vectorLayer.setStyle(styleFunction);

Таким образом свойства становятся основой тематического отображения данных.


Использование свойств для фильтрации

Допустим, имеется набор объектов.

const features =
    vectorSource.getFeatures();

Выбор только активных объектов:

const activeFeatures =
    features.filter(feature => {
        return feature.get('status') === 'active';
    });

Выбор объектов определённого типа:

const schools =
    features.filter(feature => {
        return feature.get('category') === 'school';
    });

Использование свойств в всплывающих окнах

При выборе объекта обычно отображается информация из его атрибутов.

map.on('click', function(event) {

    map.forEachFeatureAtPixel(
        event.pixel,
        function(feature) {

            console.log(
                feature.get('name')
            );

            console.log(
                feature.get('description')
            );
        }
    );

});

Так реализуются карточки объектов, подсказки и информационные панели.


Клонирование Feature

Для создания копии используется метод clone().

const copy =
    feature.clone();

После клонирования:

console.log(
    copy.get('name')
);

вернёт те же данные, что и исходный объект.

Копия содержит:

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

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

copy.set('name', 'Copy');

console.log(feature.get('name'));

Исходное значение останется без изменений.


Feature как модель пространственного объекта

В архитектуре OpenLayers объект Feature играет роль полноценной модели географической сущности. Он объединяет координатную информацию, атрибутивные данные, идентификаторы и события изменения состояния. Благодаря универсальному механизму свойств один и тот же объект может одновременно использоваться для визуализации на карте, хранения бизнес-данных, поиска, фильтрации, тематического оформления и взаимодействия с пользователем. Именно поэтому класс Feature является центральным элементом работы с векторными данными практически во всех приложениях на основе OpenLayers.