Issue with 3D Visualization (Angular + ol-cesium), flashes on change

Discussão em 'Angular' iniciado por coman, Dezembro 6, 2024.

  1. coman

    coman Guest

    I created a new Angular project that uses ol-cesium. Here are the versions I am working with:

    • Angular v19
    • olcs 2.22.1
    • Cesium 1.123
    • ol 10.3.1

    The problem is that any operation I perform while using the 3D view causes it to "flash". I have no problems in 2D view.

    Examples of such operations include: removing and adding a vector layer, changing the coordinates of a feature, or updating the style of a feature.

    The application is very simple: I have a main component (app.component.ts) with some buttons that trigger methods in another component (cesium.directive.ts), where all the logic resides.

    Has anyone encountered this issue?

    Below is the example of the two component, going to 3D and clicking on the button to move the icon the view flashes.

    import { Component, ViewChild, ViewChildren, QueryList, AfterViewInit} from '@angular/core';
    import { CesiumDirective } from './cesium.directive';

    @Component({
    selector: 'app-root',
    template: `
    <div class="map-container">
    <div
    id="map"
    appCesium
    #cesiumDirective
    ></div>
    <button class="toggle-view-button" (click)="toggleView()">Toggle 2D/3D View</button>
    <button class="move-button" (click)="moveButton()">move</button>
    </div>
    `,
    styles: [`
    .map-container {
    width: 100%;
    height: 100vh;
    position: relative;
    }
    #map {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    }
    .toggle-view-button {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 1000;
    }
    .move-button {
    position: absolute;
    top: 90px;
    right: 10px;
    z-index: 1000;
    }
    `],
    standalone: false
    })
    export class AppComponent implements AfterViewInit {
    @ViewChildren(CesiumDirective)
    cesiumDirectives!: QueryList<CesiumDirective>;
    private cesiumDirective!: CesiumDirective;

    ngAfterViewInit() {
    setTimeout(() => {
    this.cesiumDirective = this.cesiumDirectives.first;
    console.log('Cesium Directive found:', this.cesiumDirective);
    });
    }

    moveButton() {
    if(this.cesiumDirective) {
    this.cesiumDirective.moveButton();
    }
    }
    }


    import { Directive, ElementRef, OnInit } from '@angular/core';
    import OLCesium from 'olcs';
    import Map from 'ol/Map';
    import { Feature, View } from 'ol';
    import TileLayer from 'ol/layer/Tile';
    import { OSM } from 'ol/source';
    import { Point } from 'ol/geom';
    import {Fill, Icon, Stroke, Style, Text} from 'ol/style';
    import VectorSource from 'ol/source/Vector';
    import VectorLayer from 'ol/layer/Vector';


    @Directive({
    selector: '[appCesium]',
    standalone: false,
    })
    export class CesiumDirective implements OnInit {
    private map!: Map;
    private ol3d: any;
    private vectorLayer!: VectorLayer;
    private is3DEnabled: boolean = false;
    private icon1Feature!: any;

    constructor(private el: ElementRef) {
    }

    ngOnInit(): void {
    this.initMap();
    this.addFeature();
    }

    private addFeature(): void {
    // Creare le feature con icone
    this.icon1Feature = new Feature({
    geometry: new Point([700000, 200000, 10000])
    });
    this.icon1Feature.setStyle(new Style({
    image: new Icon({
    anchor: [0.5, 1],
    src: 'assets/icon.png'
    }),
    text: new Text({
    text: 'Icon with anchor on the bottom center',
    stroke: new Stroke({
    color: 'black',
    width: 3
    }),
    fill: new Fill({
    color: 'white'
    })
    })
    }));

    // Creare la sorgente e il layer vettoriale
    const vectorSource = new VectorSource({
    features: [this.icon1Feature]
    });

    this.vectorLayer = new VectorLayer({
    source: vectorSource
    });

    this.map.addLayer(this.vectorLayer);
    }

    private initMap(): void {

    try {
    this.map = new Map({
    target: this.el.nativeElement,
    layers: [
    new TileLayer({
    visible: true,
    preload: Infinity,
    source: new OSM(),
    })
    ],
    view: new View({
    zoom: 5,
    center: [6000000, 4000000]
    })
    });

    this.ol3d = new OLCesium({
    map: this.map,
    target: this.el.nativeElement,
    });

    const scene = this.ol3d.getCesiumScene();
    scene.debugShowFramesPerSecond = true;

    this.ol3d.setEnabled(false);

    } catch (error) {
    console.error('Error initializing map:', error);
    }
    }

    public toggleView(): void {
    try {
    this.is3DEnabled = !this.is3DEnabled;

    if (this.ol3d) {
    this.ol3d.setEnabled(this.is3DEnabled);
    }
    } catch (error) {
    console.error('Error in toggleView:', error);
    }
    }

    public moveButton() {
    const currentCoordinates = this.icon1Feature.getGeometry().getCoordinates();

    const deltaX = 100;
    const deltaY = 200;

    const newCoordinates = [currentCoordinates[0] + deltaX, currentCoordinates[1] + deltaY, currentCoordinates[2]];

    this.icon1Feature.setGeometry(new Point(newCoordinates));
    }

    }

    Continue reading...

Compartilhe esta Página