В этом посте исследуется angular-cesium, библиотека с открытым исходным кодом для работы с CesiumJS и Angular. angular-cesium позволяет обрабатывать несколько источников данных в реальном времени очень простым и интуитивно понятным способом.

Что такое угло-цезий?

angular-cesium сочетает в себе потрясающую мощь CesiumJS как движка карт и Angular как интерфейсного фреймворка. Основным преимуществом angular-cesium является его способность поддерживать вашу карту (или карты) в идеальной синхронизации со всеми вашими источниками данных, будь то источники динамических данных, которые отправляют много данных через веб-узел, или единственный источник данных HTTP, который извлекает данные один раз или действие пользователя, которое изменяет ваше внутреннее состояние приложения. Вы можете управлять всем этим, используя очень простые и удобочитаемые компоненты Angular, уделяя особое внимание высокой производительности и простоте использования.

Углово-цезиевые основные характеристики и возможности:

  • Синтаксис декларативного шаблона. Создайте приложение Cesium, используя компоненты Angular и синтаксис шаблонов Angular.
  • Дополнительные функции и возможности - angular-cesium поставляется с потрясающим набором инструментов, которые решают многие из распространенных проблем, с которыми обычно сталкиваются системы ГИС, и позволяют создавать систему очень быстро, включая обработку событий карты, камеру служебные программы и инструменты для рисования графики.
  • Plug and Play - angular-cesium позволяет легко интегрировать любой источник данных и отображать его на карте, используя потоки данных Angular RxJs (как показано на диаграмме ниже).

angular-cesium достигает этого с помощью RxJS, базовой библиотеки, используемой Angular для представления потоков данных. (Короче говоря, вы можете подписаться на поток и получать уведомления о поступлении новых данных. Если вы не знакомы с ним, вы можете прочитать больше здесь.) После того, как источник данных был обернут наблюдаемым Rx, он может быть передан в angular-cesium, и тогда происходит волшебство :) Все, что вам нужно сделать, это создать компонент Angular, который использует этот поток данных в своем шаблоне. Здесь вы опишите, как вы хотите, чтобы объекты в потоке отображались на карте. Позже мы увидим простой пример.

Важно отметить, что angular-cesium только расширяет и украшает CesiumJS API, но если вы хотите использовать обычный Cesium API, у вас всегда есть доступ к объекту Cesium Viewer.

Основы

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

Узнай здесь, как установить и создать новый угловой цезиевый проект.

Создайте свой цезиевый глобус

Компонент <ac-map> создает вашу программу просмотра Cesium. Просто добавьте его в свой app.component.html:

<ac-map></ac-map>

Теперь попробуйте запустить приложение в консоли: npm start или ng serve. Перейдите на localhost: 4200, и вы должны увидеть глобус цезия.

Добавьте пространственные данные на вашу карту

После создания средства просмотра Cesium мы захотим добавить пространственные данные в наше приложение. angular-cesium поддерживает все объекты цезия как компоненты. Смотрите полный список компонентов.

angular-cesium использует синтаксис сущностей цезия, поэтому полезно с ним ознакомиться. Итак, давайте начнем с добавления слоя самолетов в наше приложение. Наше приложение покажет список самолетов, которые можно обновлять. Допустим, каждый самолет будет состоять из этикетки и рекламного щита (значка).

Создадим новый компонент planes-layer.component.html:

<ac-layer acFor="let plane of planes$" [show]="showTracks" [context]="this">
    <ac-billboard-desc props="{
        image: plane.image,
        position: plane.position
    }">
    </ac-billboard-desc>

    <ac-label-desc props="{
        position: plane.position,
        text: plane.name,
        color: getColor(plane)
    }">
    </ac-label-desc>
</ac-layer>

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

Наш самолет состоит из ac-billboard-desc и ac-label-desc, которые являются компонентами-оболочками для Cesium LabelGraphics и BillboardGraphics соответственно.

угловой-цезий поддерживает все объекты цезия; Каждый компонент имеет суффикс -desc, сокращенно от описания, потому что компонент описывает, как должен выглядеть наш самолет.

Каждый компонент описания имеет атрибут props, который принимает те же параметры, что и соответствующий класс Cesium. В нашем случае ac-billboard-desc принимает те же члены, что и цезий BillboardGraphics. Таким образом, вы можете настроить свои объекты так, как хотите, например, установить положение, текст, изображение или любые параметры, которые вам нужны.

Слои и компонент ac-слоя

Хорошо, теперь мы определили, как должна выглядеть каждая плоскость. Далее мы хотим создать список самолетов или слой самолетов.

ac-layer представляет собой массив объектов, которые будут отображаться на карте в соответствии с компонентами описания. Он работает с RxJs Observables, что означает, что он совместим с рабочим процессом Angular.

Возможные атрибуты:

  • acFor принимает поток данных (RxJs Observable) в синтаксисе «let enityName of Observable $» (суффикс $ является общепринятым соглашением для именования наблюдаемых).

В нашем примере мы принимаем plane$ observable; ac-layer подпишется на наблюдаемое и будет обрабатывать все обновления за нас.

  • show показать или скрыть слой.

Подключиться к данным

Давайте посмотрим, как выглядит planes.component.ts (логика нашего компонента):

@Component({
  selector: 'plane-layer',
  templateUrl: 'plane-layer.component.html',
})

export class PlaneLayerComponent implements OnInit {
  planes$: Observable<AcNotification>;

  constructor(private planesService: PlanesService) {
  }

  ngOnInit() {
    this.planes$ = this.planesService.getPlanes().pipe(
      map(plane => ({
        id: plane.id,
        actionType: ActionType.ADD_UPDATE,
        entity: plane,
      }))
    );
  }

  getColor(plane) {
    if (plane.name.startsWith('Boeing')) {
      return Cesium.Color.Green;
    } else {
      return Cesium.Color.White;
    }
  }
}

// Example mock service

@Injectable({
  providedIn: 'root'
})

export class PlanesService {
  private planes = [
    {
      id: '1',
      position: Cesium.Cartesian3.fromDegrees(30, 30),
      name: 'Airbus a320',
      image: 'https://cdn3.iconfinder.com/data/icons/airport-collection/100/23-512.png'
    },
    {
      id: '2',
      position: Cesium.Cartesian3.fromDegrees(31, 31),
      name: 'Boeing 777',
      image: 'https://cdn1.iconfinder.com/data/icons/fly-airbus-and-aeroplane/154/fly-air-plane-airbus-aeroplane-512.png'
    }
  ];

  getPlanes() {
    // Or get it from a real updating data source
    return Observable.from(this.planes);
  }
}

Мы узнали, что вы должны предоставить источник данных для ac-layer для атрибута [acFor], а источником данных должен быть поток RxJs.

Следующее, что мы узнаем, это то, что каждое уведомление в потоке должно быть типа AcNotification:

interface AcNotification {
    id: string;
    actionType: ActionType;
    entity?: any;
}

id - уникальный ключ сущности,

entity- сами данные для сущности,

actionType - показывает, что случилось с сущностью. actionType может быть одним из следующих значений: ADD_UPDATE, DELETE.

Каждый AcNotification, который вы передаете plane$ Observable, заставит angular-cesium визуализировать желаемую плоскость в соответствии с компонентами описания, определенными внутри ac-layer. Можно добавить логику костюма для определения для каждого свойства. В нашем примере каждая плоскость color определяется getColor().

В случае передачи ADD_UPDATE объект будет создан или обновлен в зависимости от того, существует он или нет. В случае передачи DELETE объект будет удален с карты.

В нашем примере у нас есть PlanesService, который возвращает данные о самолетах в виде потока RxJs. Здесь это только жестко закодированные данные, но точно так же это могут быть данные из веб-сокета, HTTP-ответа или чего угодно.

В planes.component.ts мы получаем данные из planeService.getPlanes() и сопоставляем их с $plane, который передается слою ac. Каждая плоскость преобразуется в объект AcNotification. ac-layer подпишется на $plane и соответствующим образом будет рендерить наши самолеты.

Не забудьте добавить свой компонент в app.component.ts.

<ac-map>
    <plane-layer></plane-layer>
</ac-map>

Все слои карты углового цезия, которые вы создаете, должны находиться в иерархии ac-map. Таким образом, все компоненты и слои знают, на каком глобусе они должны быть визуализированы. Вы также получаете красивое декларативное представление слоев в вашем средстве просмотра.

Вот и все, теперь на глобусе должны появиться самолеты :)
Пример результата

Затем вы можете добавить больше слоев или сделать свои плоскости более подробными, добавив больше цезиевых объектов или установив другие свойства. Возможности безграничны.

Как это работает?

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

Мы передаем props в ac-billboard-desc как выражения, основанные на плоскости, которую мы определили ранее. Фактически мы говорим: «Уважаемый angular-cesium, пожалуйста, создайте billboard и управляйте им, используя эти выражения для каждого plane. Теперь, когда объект проходит через поток - на основе его id, actionType и entity, angular-cesium будет знать, что делать. Например, при передаче данных с одинаковыми id и actionType=ADD_UPDATE сущность будет обновляться на карте для каждого сообщения.

Виджеты и утилиты

Как упоминалось выше, angular-cesium имеет множество виджетов и утилит:

Инструменты рисования графики:

  • angular-cesium поставляется с набором утилит, которые можно использовать для рисования графики на карте.
  • Инструменты представляют собой настраиваемые службы для создания и редактирования различных геометрических фигур, таких как линии, окружности, многоугольники и эллипсы.
  • Хотите создать инструмент, который измеряет расстояние и азимут между двумя точками на карте? Сделайте небольшую настройку инструмента рисования полилиний, и все готово. Аккуратный :)
  • Попробуйте разные редакторы в нашей демонстрации, а для получения дополнительной информации загляните в doc.

Управление событиями мыши

  • Еще одно важное преимущество angular-cesium - это то, что мы называем «диспетчером событий карты». Это очень крутой инструмент, который позволяет вам полностью контролировать события мыши, происходящие на карте, такие как обычный щелчок левой кнопкой мыши, щелчок правой кнопкой мыши. , но также и такие события, как долгое нажатие левой кнопкой мыши или перетаскивание.
  • Разрешить выбор объекта - нажмите на рекламный щит, и вы получите связанный объект.
  • Расставьте приоритеты для API событий.
  • Handle Plonter: как обрабатывать выбор объектов, когда объекты находятся друг над другом.
  • Дополнительную информацию можно найти в документации.

Поддержка нескольких зрителей

  • angular-cesium позволяет с легкостью отображать несколько карт и синхронизировать отображаемые на них данные.

Привязка компонентов Angular к карте

  • Angular-Cesium позволяет использовать элементы HTML или компоненты Angular в качестве объектов карты и привязать их положение к географическим координатам карты. Это особенно полезно, когда вы хотите отображать такие вещи, как сложные формы с некоторыми CSS поверх них, чтобы получить красивый результат.

И многое другое…

Преимущества

После небольшого объяснения ас-слоя, мы надеемся, что вы сможете увидеть преимущества углового цезия:

  • Простое определение слоев данных.
  • Легко добавлять / обновлять / удалять объекты - все, что вам нужно сделать, это передать сообщение через поток, а angular-cesium будет отслеживать все остальное.
  • Читаемый и поддерживаемый код - при чтении HTML-кода, описывающего ваш слой, довольно легко понять, как ваш слой будет выглядеть.
  • Производительность - используйте все преимущества производительности цезия с нулевыми накладными расходами от обнаружения угловых изменений или манипуляций с DOM.
  • Получите полный контроль над событиями мыши с помощью настраиваемых событий, таких как перетаскивание.
  • Привяжите компоненты Angular к карте и обрабатывайте их, как объекты карты, используя ac-html.
  • Встроенные графические инструменты рисования.
  • Синхронизация нескольких зрителей.

Заключение

angular-cesium возник из-за необходимости обрабатывать несколько источников данных согласованным и эффективным способом, сохраняя при этом постоянно растущую базу кода в удобочитаемом состоянии. По нашему опыту, цезий - лучшее решение, когда речь идет о визуализации пространственных данных 3D + 2D. Благодаря angular-cesium мы расширили потрясающие возможности Cesium за счет быстрой интеграции источников данных и различных инструментов, сохранив при этом Cesium API полностью доступным.

Больше информации

Это всего лишь основы углового цезия. Для получения дополнительной информации ознакомьтесь с нашими API doc и angular-cesium Repository. Попробуйте клонировать проект и поиграйте с нашей демонстрацией. angular-cesium - проект с открытым исходным кодом. Не стесняйтесь открывать проблемы, задавать вопросы и открывать PR.

Наша дорожная карта включает поддержку других популярных фреймворков, таких как ReactJS, так что следите за обновлениями. Для получения дополнительной поддержки свяжитесь с нами: [email protected].