Html Anchoring

Angular Cesium provides a ac-html-desc and ac-html, custom entity type for rendering and anchoring HTML over the map. Useful for creating context-menu components or any other elements that you can't create with normal Cesium entities API.

HTML anchored to the globe

First create your template:

<ac-layer acFor="let html of htmls$" [context]="this">
<ac-html-desc props="{position: html.position, show: html.show}">
<ng-template let-html>
<div>
<h1>This is ac-html {{html.name}}</h1>
<button (click)="changeText(html, 'Test')">change text</button>
</div>
</ng-template>
</ac-html-desc>
</ac-layer>
  • Supported props:

    • position - Cartesian3 position

    • show - boolean for hide/show html

  • Place your HTML in <ng-template let-html> directive.

  • The inner HTML works as any other Angular components supporting value and functions from the context

  • You can add any other cesium entities (Billboard, Label, etc ) to your layer as siblings to your html.

How does it work?

Angular Cesium will render your HTML component and will anchor it to the given Cartesian3 position. On every camera change the HTML will change his position according the Cartesian3 position, converting it to the screen position.

Please notice, ac-html does DOM manipulations for setting the right top and left positions of your HTML. Therefor it is less efficient then using the regular Entity API that uses WebGL.

Best Practice: Performance wise, for many entities prefer using the Entities API.

Full example

html-layer.html
html-layer.ts
html-layer.html
html-layer.t
<ac-layer acFor="let html of htmls$" [context]="this">
<ac-html-desc props="{position: html.position, show: html.show}">
<ng-template let-html>
<div>
<h1>This is ac-html {{html.name}}</h1>
<button (click)="changeText(html, 'Test')">change text</button>
</div>
</ng-template>
</ac-html-desc>
</ac-layer>
html-layer.ts
html-layer.ts
import { from, from as observableFrom, Observable, Subject } from 'rxjs';
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { AcLayerComponent, AcNotification, ActionType } from 'angular-cesium';
@Component({
selector: 'html-example-layer',
templateUrl: './html-example.component.html',
styleUrls: ['./html-example.component.css']
})
export class HtmlExampleComponent implements OnInit {
@ViewChild(AcLayerComponent, {static: false}) layer: AcLayerComponent;
htmls$: Observable<AcNotification>;
html1 = {
id: '0',
actionType: ActionType.ADD_UPDATE,
entity: {
id: '0',
show: true,
name: 'html 1',
position: Cesium.Cartesian3.fromDegrees(30, 30),
color: Cesium.Color.RED
},
};
html2 = {
id: '1',
actionType: ActionType.ADD_UPDATE,
entity: {
id: '1',
show: true,
name: 'html 2',
position: Cesium.Cartesian3.fromDegrees(35, 35),
color: Cesium.Color.RED
}
};
constructor() {
const htmlArray = [this.html1, this.html2];
this.htmls$ = from(htmlArray);
}
ngOnInit() {
}
updateHtml() {
if (this.html1) {
this.html1.entity.name = 'tsahi';
this.layer.update(this.html1.entity, this.html1.id);
}
this.html2.entity.name = 'gonen';
this.html2.entity.position = Cesium.Cartesian3.fromDegrees(44, 44);
this.layer.update(this.html2.entity, this.html2.id);
}
changeText(html: any, text: any) {
html.name = text;
this.layer.update(html, html.id);
}
pixelOffset(value) {
return new Cesium.Cartesian2(value[0], value[1]);
}
removeFirst() {
this.layer.remove('0');
this.html1 = null;
}
toggleShow() {
if (this.html1) {
this.html1.entity.show = !this.html1.entity.show;
this.layer.update(this.html1.entity, this.html1.id);
}
}
}