Поместите элемент HTML в позицию Cesium Entity.

Мне нужно определить местоположение элемента html на основе местоположения объекта Cesium. Я использовал положение мыши (Cesium.Cartesian3.clone(movement.endPosition)), которое находится в координатах окна, в качестве теста, и оно работает. Поэтому мне нужно получить позицию объекта, преобразовать ее в координаты WGS84, преобразовать их в координаты окна и использовать их для element.style.left = window_coord.x и element.style.top = window_coord.y.
Итак, я получаю entity.position и значения x, y и z правильные. Однако, когда я хочу преобразовать их в координаты WGS84, что-то идет не так, и я получаю NaN для широты, долготы и высоты.

Вот варианты, которые я пробовал, оба приводят к NaN для широты, долготы и высоты:

var carto = Cesium.Ellipsoid.WGS84.cartesianToCartographic(entity.position);
or
var carto = Cesium.Cartographic.fromCartesian(entity.position);
or
var ellipsoid = viewer.scene.globe.ellipsoid;
var cartesian = viewer.camera.pickEllipsoid(entity.position, ellipsoid);
var carto = ellipsoid.cartesianToCartographic(cartesian);


var entity_pos = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, carto);
element.style.left = entity_pos.x;
element.style.top = entity_pos.y;

Журнал консоли, показывающий entity.position, carto и entity_pos

Моя другая идея заключалась в ручном вычислении координат WGS84, но это было бы таким глупым обходным путем. Любые идеи о том, как я мог бы сделать это, не влияя на пользовательский опыт.


person Jan-Pieter Van Parys    schedule 13.09.2019    source источник


Ответы (1)


Получение положения сущности должно выполняться с помощью функции entity.position.getValue(clock.currentTime), поскольку сущности могут быть движущимися объектами с изменяющимися позициями.

Вот демо из HTML-элемента после позиции объекта .

// Create Cesium Viewer
var viewer = new Cesium.Viewer('cesiumContainer');

// Create a sample HTML element in the document.
var testElement = document.createElement('div');
testElement.style.position = 'absolute';
testElement.style.border = '2px solid #444';
testElement.style.font = '16px sans-serif';
testElement.innerHTML = 'Testing';
viewer.container.appendChild(testElement);
var isEntityVisible = true;

// Create a sample entity
var entity = viewer.entities.add({
    position : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
    point : {
        pixelSize : 10,
        color : Cesium.Color.YELLOW
    }
});

// Pre-allocate memory once.  Don't re-allocate for each animation frame.
var scratch3dPosition = new Cesium.Cartesian3();
var scratch2dPosition = new Cesium.Cartesian2();

// Every animation frame, update the HTML element position from the entity.
viewer.clock.onTick.addEventListener(function(clock) {
    var position3d;
    var position2d;

    // Not all entities have a position, need to check.
    if (entity.position) {
        position3d = entity.position.getValue(clock.currentTime, scratch3dPosition);
    }

    // Moving entities don't have a position for every possible time, need to check.
    if (position3d) {
        position2d = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
            viewer.scene, position3d, scratch2dPosition);
    }

    // Having a position doesn't guarantee it's on screen, need to check.
    if (position2d) {
        // Set the HTML position to match the entity's position.
        testElement.style.left = position2d.x + 'px';
        testElement.style.top = position2d.y + 'px';

        // Reveal HTML when entity comes on screen
        if (!isEntityVisible) {
            isEntityVisible = true;
            testElement.style.display = 'block';
        }
    } else if (isEntityVisible) {
        // Hide HTML when entity goes off screen or loses its position.
        isEntityVisible = false;
        testElement.style.display = 'none';
    }
});
person emackey    schedule 13.09.2019
comment
Спасибо за entity.position.getValue(clock.currentTime). Твой лишний код тоже меня очень сильно озадачил! - person Jan-Pieter Van Parys; 17.09.2019