How to select multiple entities with a rectangle?

Hi all,

I found this example on the internet, but I want to select multiple entities ( not tileset) with a rectangle. How can i do ?

https://lh3.googleusercontent.com/-p-VLitJdjjo/WUwBO5cEV2I/AAAAAAAACEo/5WinTpL-J64-xZpnGrExh0kdERwvhGEWgCLcBGAs/s1600/selection.gif

Can you link to where you found this example? Did it have code to go with it? You could potentially do the same type of selection with entities as you can with tiles.

this is source for selection tiles. I don’t know of any way to do it works as tiles. Can you support me ?

// Click to start selection, move mouse, then click again to end selection

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var boxElement = document.getElementById(‘box’);

var scene = viewer.scene;

var camera = scene.camera;

var url = ‘…/…/…/Specs/Data/Cesium3DTiles/Tilesets/Tileset/’;

var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({

url : url,

debugShowContentBoundingVolume : true

}));

tileset.readyPromise.then(function() {

var boundingSphere = tileset.boundingSphere;

viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.0, -1.0, boundingSphere.radius));

viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

});

var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);

var start;

var end;

handler.setInputAction(function(movement) {

if (!Cesium.defined(start)) {

start = Cesium.Cartesian2.clone(movement.position, new Cesium.Cartesian2());

return;

}

if (Cesium.defined(start)) {

end = Cesium.Cartesian2.clone(movement.position, new Cesium.Cartesian2());

selectTiles(start, end);

start = undefined;

end = undefined;

boxElement.style.width = ‘0px’;

boxElement.style.height = ‘0px’;

}

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

handler.setInputAction(function(movement) {

if (Cesium.defined(start)) {

var end = movement.endPosition;

var rectangle = getRectangle(start, end);

boxElement.style.left = rectangle.x + ‘px’;

boxElement.style.top = rectangle.y + ‘px’;

boxElement.style.width = rectangle.width + ‘px’;

boxElement.style.height = rectangle.height + ‘px’;

}

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

function getRectangle(start, end) {

var xMin = Math.min(start.x, end.x);

var xMax = Math.max(start.x, end.x);

var yMin = Math.min(start.y, end.y);

var yMax = Math.max(start.y, end.y);

var width = xMax - xMin;

var height = yMax - yMin;

return new Cesium.BoundingRectangle(xMin, yMin, width, height);

}

function getCenter(rectangle) {

return new Cesium.Cartesian2(rectangle.x + rectangle.width / 2.0, rectangle.y + rectangle.height / 2.0);

}

function selectTiles(start, end) {

start = Cesium.SceneTransforms.transformWindowToDrawingBuffer(scene, start, start);

end = Cesium.SceneTransforms.transformWindowToDrawingBuffer(scene, end, end);

var rectangle = getRectangle(start, end);

var center = getCenter(rectangle);

var cullingVolume = getCullingVolume(center, rectangle.width, rectangle.height);

var selected = ;

traverseTileset(tileset._root, cullingVolume, selected);

var color = Cesium.Color.fromRandom({alpha:1.0});

var length = selected.length;

for (var i = 0; i < length; ++i) {

selected[i].color = color;

}

}

function traverseTileset(tile, cullingVolume, selected) {

var boundingVolume = tile._boundingVolume;

var contentBoundingVolume = tile._contentBoundingVolume;

if (!intersectsBoundingVolume(cullingVolume, boundingVolume)) {

// Stop traversal early since children won’t be visible either

return;

}

if (!Cesium.defined(contentBoundingVolume) || intersectsBoundingVolume(cullingVolume, contentBoundingVolume)) {

// Test intersection with the content bounding volume

selected.push(tile);

}

var children = tile.children;

var length = children.length;

for (var i = 0; i < length; ++i) {

traverseTileset(children[i], cullingVolume, selected);

}

}

function intersectsBoundingVolume(cullingVolume, boundingVolume) {

return cullingVolume.computeVisibility(boundingVolume) !== Cesium.Intersect.OUTSIDE;

}

function getCullingVolume(center, width, height) {

// Adapted from getPickPerspectiveCullingVolume in Scene.js

var screenWidth = scene.drawingBufferWidth;

var screenHeight = scene.drawingBufferHeight;

var frustum = camera.frustum;

var near = frustum.near;

var far = frustum.far;

var tanPhi = Math.tan(frustum.fovy * 0.5);

var tanTheta = frustum.aspectRatio * tanPhi;

var x = 2.0 * center.x / screenWidth - 1.0;

var y = 2.0 * (screenHeight - center.y) / screenHeight - 1.0;

var xDir = x * near * tanTheta;

var yDir = y * near * tanPhi;

var pixelSize = frustum.getPixelDimensions(screenWidth, screenHeight, near, new Cesium.Cartesian2());

var pickWidth = pixelSize.x * width * 0.5;

var pickHeight = pixelSize.y * height * 0.5;

var offCenter = new Cesium.PerspectiveOffCenterFrustum();

offCenter.top = yDir + pickHeight;

offCenter.bottom = yDir - pickHeight;

offCenter.right = xDir + pickWidth;

offCenter.left = xDir - pickWidth;

offCenter.near = near;

offCenter.far = far;

return offCenter.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC);

}

Vào 19:40:16 UTC+7 Thứ Hai, ngày 08 tháng 7 năm 2019, Omar Shehata đã viết:

I think you may be using an older version of CesiumJS. I was unable to get this code to work in Sandcastle (https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html). Looks like the URL should end with tileset.json, and it’s missing the HTML box element.

In any case, you should be able to apply the same logic for entities by computing the entity’s bounding sphere. There’s some discussion on doing that here: https://groups.google.com/d/msg/cesium-dev/BSXl9QhzlXs/KMQ_1rXzBwAJ

Thanks ! I did it. i create a rectangle like example and use drillPick ( ex: let pickedObjects = viewer.scene.drillPick(centerRectangle, null, rectangle.width, rectangle.height);
) to get entity collection

Vào 01:18:20 UTC+7 Thứ Tư, ngày 10 tháng 7 năm 2019, Omar Shehata đã viết: