Created
November 29, 2021 13:03
-
-
Save datadavev/9af52380c13cb5a0c1031b2611b1f4de to your computer and use it in GitHub Desktop.
Cesium - Draw BB with mouse by holding down Alt.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Draw a bounding box. | |
Hold down ALT and drag to draw a bounding box rectangle. | |
Multiple BBs may be shown. | |
Select a BB and Delete to remove. | |
*/ | |
class BBSelector { | |
constructor() { | |
// holds the selection rectangle when drawing | |
this.r = new Cesium.Rectangle(); | |
// starting point | |
this.p0 = null; | |
// current point | |
this.p1 = null; | |
// callback that updates the entity coordinates | |
this.cb = null; | |
// entity, a RectangleGeometry | |
this.entity = null; | |
} | |
get rect() { | |
return Cesium.Rectangle.clone(this.r); | |
} | |
/** | |
* Start drawing the bounding rectangle | |
* | |
* Returns an entity that should be added to the viewer entity collection | |
*/ | |
startDrawing(cartesian, name=null) { | |
this.entity = new Cesium.Entity({ | |
show: true, | |
rectangle: { | |
coordinates: new Cesium.Rectangle(), | |
material: Cesium.Color.YELLOW.withAlpha(0.5), | |
}, | |
name: name, | |
}); | |
this.p0 = Cesium.Cartographic.fromCartesian(cartesian); | |
this.p1 = Cesium.Cartographic.clone(this.p0); | |
this.r.west = this.p0.longitude; | |
this.r.east = this.p1.longitude; | |
this.r.south = this.p0.latitude; | |
this.r.north = this.p1.latitude; | |
this.cb = new Cesium.CallbackProperty((time, result) => { | |
return Cesium.Rectangle.clone(this.r); | |
}, false); | |
this.entity.rectangle.coordinates = this.cb; | |
return this.entity; | |
} | |
/** | |
* Update the rectangle with the provided cartesian | |
*/ | |
draw(cartesian) { | |
this.p1 = Cesium.Cartographic.fromCartesian(cartesian); | |
this.r.east = Math.max(this.p0.longitude, this.p1.longitude); | |
this.r.west = Math.min(this.p0.longitude, this.p1.longitude); | |
this.r.north = Math.max(this.p0.latitude, this.p1.latitude); | |
this.r.south = Math.min(this.p0.latitude, this.p1.latitude); | |
} | |
/** | |
* Stop drawing. | |
* | |
* The callback is removed, and the entity coordinates become static | |
*/ | |
stopDrawing() { | |
this.entity.rectangle.coordinates = this.rect; | |
this.entity = null; | |
this.p0 = null; | |
this.p1 = null; | |
this.cb = null; | |
} | |
toString() { | |
return `${this.r.west}, ${this.r.south}, ${this.r.east}, ${this.r.north},`; | |
} | |
} | |
/*****************************************/ | |
// Create the viewer with terrain | |
var viewer = new Cesium.Viewer('cesiumContainer', { | |
terrainProvider: Cesium.createWorldTerrain(), | |
}); | |
// Get a ScreenSpaceEventHandler | |
// https://cesium.com/learn/cesiumjs/ref-doc/ScreenSpaceEventHandler.html | |
let screenEventHandler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); | |
// set to an instance of BBSelector when drawing | |
let _selector = null; | |
let bbIDs = []; | |
let selectedID = null; | |
// Handle Alt + left_down | |
// Start drawing the selector | |
screenEventHandler.setInputAction((event) => { | |
// Determine the Cesium cartesian coordinates from the mouse position | |
const cartesian = viewer.scene.pickPosition(event.position); | |
if (cartesian !== undefined) { | |
// Start drawing if we have a valid starting point. | |
_selector = new BBSelector(); | |
// get the entity to display | |
const bb = _selector.startDrawing(cartesian, "Bounding Box"); | |
// display the entity by adding it to the viewer entity collection | |
bbIDs.push(bb.id); | |
viewer.entities.add(bb); | |
} | |
}, Cesium.ScreenSpaceEventType.LEFT_DOWN, Cesium.KeyboardEventModifier.ALT); | |
// Handle Alt+move | |
// Draw the selector between the first and current points. | |
screenEventHandler.setInputAction((event) => { | |
if (_selector === null) { | |
return; | |
} | |
const cartesian = viewer.scene.pickPosition(event.endPosition); | |
if (cartesian !== undefined) { | |
_selector.draw(cartesian); | |
} | |
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE, Cesium.KeyboardEventModifier.ALT); | |
// Handle Alt + left up | |
// Drawing is finished, create the rectangle and add to entities | |
screenEventHandler.setInputAction((event) => { | |
if (_selector !== null) { | |
_selector.stopDrawing(); | |
} | |
_selector = null; | |
}, Cesium.ScreenSpaceEventType.LEFT_UP, Cesium.KeyboardEventModifier.ALT); | |
// Info, log the screen coords and corresponding longitude, latitude | |
screenEventHandler.setInputAction((event) => { | |
console.log(event.position); | |
const pc = viewer.scene.pickPosition(event.position); | |
if (pc !== undefined) { | |
const P = Cesium.Cartographic.fromCartesian(pc); | |
console.log(`${Cesium.Math.toDegrees(P.longitude)}, ${Cesium.Math.toDegrees(P.latitude)}`); | |
} | |
}, Cesium.ScreenSpaceEventType.LEFT_DOWN); | |
viewer.selectedEntityChanged.addEventListener(function(entity) { | |
if (Cesium.defined(entity)) { | |
if (bbIDs.includes(entity.id)) { | |
console.log(entity.id); | |
if (selectedID !== null) { | |
const csel = viewer.entities.getById(selectedID); | |
if (csel !== undefined) { | |
csel.rectangle.material = Cesium.Color.YELLOW.withAlpha(0.5); | |
} | |
} | |
selectedID = entity.id; | |
entity.rectangle.material = Cesium.Color.RED.withAlpha(0.3); | |
} | |
} else { | |
if (selectedID !== null) { | |
const csel = viewer.entities.getById(selectedID); | |
if (csel !== undefined) { | |
csel.rectangle.material = Cesium.Color.YELLOW.withAlpha(0.5); | |
} | |
selectedID = null; | |
console.log("unselected"); | |
} | |
} | |
}); | |
viewer.canvas.setAttribute('tabindex', '0'); | |
viewer.canvas.onclick = function () { | |
viewer.canvas.focus(); | |
}; | |
document.getElementById("cesiumContainer").addEventListener('keydown', function(e){ | |
if (e.key === "Delete") { | |
if (selectedID !== null) { | |
viewer.entities.removeById(selectedID); | |
let newbbs = []; | |
bbIDs.forEach(bb => { | |
if (bb !== selectedID) { | |
newbbs.push(bb); | |
} | |
}); | |
bbIDs = newbbs; | |
} | |
} | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment