cesium.js中的相机旋转

时间:2015-11-18 13:34:59

标签: cesium

我想让我的Cesium相机遵循我创建的Line。请检查下图 enter image description here

我希望我的铯相机应该专注于图像中显示的红色汽车。 请查看以下链接以获取更多信息 http://cesiumjs.org/demos/Taipei3DCityNavigation.html

2 个答案:

答案 0 :(得分:2)

通常这些类型的应用程序使用汽车的Cesium实体,而该行是汽车随时间推移的路径。在这种情况下,使用相机进行跟踪只需将viewer.trackedEntity设置为适当的实体。

下面的代码片段只是为了让车辆越过桥梁,但重要的一行是在JS的底部,它设置trackedEntity

编辑:在下面的CZML中添加了一个新的"viewFrom"属性,用于控制用于跟踪实体的默认摄像机角度。

var viewer = new Cesium.Viewer('cesiumContainer', {
    navigationHelpButton: false
});


var builtInCzml = [{
    "id" : "document",
    "version" : "1.0",
    "clock" : {
      "interval" : "2012-08-04T16:00:00Z/2012-08-04T16:02:00Z",
      "currentTime" : "2012-08-04T16:00:00Z",
      "multiplier" : 1,
      "range" : "LOOP_STOP",
      "step" : "SYSTEM_CLOCK_MULTIPLIER"
    }
}, {
    "id" : "Vehicle",
    "availability" : "2012-08-04T16:00:00Z/2012-08-04T16:02:00Z",
    "viewFrom" : {
        "cartesian" : [ -200, 50, 50 ]
    },
    "billboard" : {
        "eyeOffset" : {
            "cartesian" : [0.0, 0.0, 0.0]
        },
        "horizontalOrigin" : "CENTER",
        "image" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEISURBVEhLvVXBDYQwDOuojHKj8LhBbpTbpBCEkZsmIVTXq1RVQGrHiWlLmTTqPiZBlyLgy/KSZQ5JSHDQ/mCYCsC8106kDU0AdwRnvYZArWRcAl0dcYJq1hWCb3hBrumbDAVMwAC82WoRvgMnVMDBnB0nYZFTbE6BBvdUGqVqCbjBIk3PyFFR/NU7EKzru+qZsau3ryPwwCRLKYOzutZuCL6fUmWeJGzNzL/RxAMrUmASSCkkAayk2IxPlwhAAYGpsiHQjbLccfdOY5gKkCXAMi7SscAwbQpAnKyctWyUZ6z8ja3OGMepwD8asz+9FnSvbhU8uVOHFIwQsI3/p0CfhuqCSQuxLqsN6mu8SS+N42MAAAAASUVORK5CYII=",
        "pixelOffset" : {
            "cartesian2" : [0.0, 0.0]
        },
        "scale" : 0.8,
        "show" : true,
        "verticalOrigin" : "BOTTOM"
    },
    "label" : {
        "fillColor" : {
            "rgba" : [255, 255, 0, 255]
        },
        "font" : "bold 10pt Segoe UI Semibold, sans-serif",
        "horizontalOrigin" : "LEFT",
        "outlineColor" : {
            "rgba" : [0, 0, 0, 255]
        },
        "pixelOffset" : {
            "cartesian2" : [10.0, 0.0]
        },
        "scale" : 1.0,
        "show" : true,
        "style" : "FILL",
        "text" : "Vehicle",
        "verticalOrigin" : "CENTER"
    },
    "path" : {
        "material" : {
            "solidColor" : {
                "color" : {
                    "rgba" : [255, 255, 0, 255]
                }
            }
        },
        "width" : 5.0,
        "show" : true
    },
    "position" : {
        "interpolationAlgorithm" : "LAGRANGE",
        "interpolationDegree" : 1,
        "epoch" : "2012-08-04T16:00:00Z",
        "cartesian" : [0.0, 1254962.0093268978, -4732330.528380746, 4074172.505865612,
                       120.0, 1256995.7322857284, -4732095.2154790815, 4073821.2249589274]
    }
}];

var dataSource = new Cesium.CzmlDataSource();
viewer.dataSources.add(dataSource);
dataSource.load(builtInCzml).then(function() {
  
    // Track with camera
    viewer.trackedEntity = dataSource.entities.getById('Vehicle');
    
});
html, body, #cesiumContainer {
  width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
  font-family: sans-serif;
}
<link href="http://cesiumjs.org/Cesium/Build/Cesium/Widgets/widgets.css" 
      rel="stylesheet"/>
<script src="http://cesiumjs.org/Cesium/Build/Cesium/Cesium.js"></script>
<div id="cesiumContainer"></div>

答案 1 :(得分:0)

这似乎是演示Multi-part CZML正在做的事情:

https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=Multi-part%20CZML.html&label=All

这是代码:

var viewer = new Cesium.Viewer('cesiumContainer', {
    shouldAnimate : true
});

var statusDisplay = document.createElement('div');
var fuelDisplay = document.createElement('div');
var czmlPath = '../../../../Apps/SampleData/';
var vehicleEntity;

// Add a blank CzmlDataSource to hold our multi-part entity/entities.
var dataSource = new Cesium.CzmlDataSource();
viewer.dataSources.add(dataSource);

// This demo shows how a single path can be broken up into several CZML streams.
var partsToLoad = [{
    url: 'MultipartVehicle_part1.czml',
    range: [0, 1500],
    requested: false,
    loaded: false
}, {
    url: 'MultipartVehicle_part2.czml',
    range: [1500, 3000],
    requested: false,
    loaded: false
}, {
    url: 'MultipartVehicle_part3.czml',
    range: [3000, 4500],
    requested: false,
    loaded: false
}];

function updateStatusDisplay() {
    var msg = '';
    partsToLoad.forEach(function(part) {
        msg += part.url + ' - ';
        if (part.loaded) {
            msg += 'Loaded.<br/>';
        } else if (part.requested) {
            msg += 'Loading now...<br/>';
        } else {
            msg += 'Not needed yet.<br/>';
        }
    });
    statusDisplay.innerHTML = msg;
}

// Helper function to mark a part as requested, and process it into the dataSource.
function processPart(part) {
    part.requested = true;
    updateStatusDisplay();
    dataSource.process(czmlPath + part.url).then(function() {
        part.loaded = true;
        updateStatusDisplay();

        // Follow the vehicle with the camera.
        if (!viewer.trackedEntity) {
            viewer.trackedEntity = vehicleEntity = dataSource.entities.getById('Vehicle');
        }
    });
}

// Load the first part up front.
processPart(partsToLoad[0]);

// Load a new section before the clock naturally gets there.
// Note this can't predict when a user may fast-forward to it.
var preloadTimeInSeconds = 100;

viewer.clock.onTick.addEventListener(function(clock) {
    // This example uses time offsets from the start to identify which parts need loading.
    var timeOffset = Cesium.JulianDate.secondsDifference(clock.currentTime, clock.startTime);

    // Filter the list of parts to just the ones that need loading right now.
    // Then, process each part that needs loading.
    partsToLoad.filter(function(part) {
        return (!part.requested) &&
            (timeOffset >= part.range[0] - preloadTimeInSeconds) &&
            (timeOffset <= part.range[1]);
    }).forEach(function(part) {
        processPart(part);
    });

    if (vehicleEntity) {
        var fuel = vehicleEntity.properties.fuel_remaining.getValue(clock.currentTime);
        if (Cesium.defined(fuel)) {
            fuelDisplay.textContent = 'Fuel: ' + fuel.toFixed(2) + ' gal';
        }
    }
});

// Add a reset button, for convenience.
Sandcastle.addToolbarButton('Reset demo', function() {
    // Put things back to the starting position.
    viewer.clock.currentTime = viewer.clock.startTime;
    viewer.clock.shouldAnimate = true;

    partsToLoad.forEach(function(part) {
        part.requested = false;
        part.loaded = false;
    });

    dataSource.entities.removeAll();
    processPart(partsToLoad[0]);
});

// Show the status display below the reset button.
statusDisplay.style.background = 'rgba(42, 42, 42, 0.7)';
statusDisplay.style.padding = '5px 10px';
document.getElementById('toolbar').appendChild(statusDisplay);

// Show a multi-part custom property being read from CZML.
fuelDisplay.style.background = 'rgba(42, 42, 42, 0.7)';
fuelDisplay.style.padding = '5px 10px';
fuelDisplay.style.marginTop = '5px';
document.getElementById('toolbar').appendChild(fuelDisplay);