Single click highlight effect of cesium 3dfiles model

Preface

Address of api documents on cesium official website cesium official website api , which details the introduction of each class of cesium, as well as the online example: cesium official website online example This is also a good material for learning cesium.

cesium official website online example

https://sandcastle.cesium.com/?src=3D+Tiles+Feature+Picking.html

The general idea is as follows:

  • Load 3dfiles model
var tileset = new Cesium.Cesium3DTileset({
url: Cesium.IonResource.fromAssetId(75343),
});
viewer.scene.primitives.add(tileset);

 

  • Create html elements, mouse movement and click model highlighting
// HTML overlay for showing feature name on mouseover
var nameOverlay = document.createElement("div");
viewer.container.appendChild(nameOverlay);
nameOverlay.className = "backdrop";
nameOverlay.style.display = "none";
nameOverlay.style.position = "absolute";
nameOverlay.style.bottom = "0";
nameOverlay.style.left = "0";
nameOverlay.style["pointer-events"] = "none";
nameOverlay.style.padding = "4px";
nameOverlay.style.backgroundColor = "black";
  • Style selected features and create selected models
// Information about the currently selected feature
var selected = {
feature: undefined,
originalColor: new Cesium.Color(),
};
 
// An entity object which will hold info about the currently selected feature for infobox display
var selectedEntity = new Cesium.Entity();
  • Mouse response event interaction
// Gets the default left click handler for not picking features when left clicking
var clickHandler = viewer.screenSpaceEventHandler.getInputAction(
Cesium.ScreenSpaceEventType.LEFT_CLICK
);
 
// If silhouette is supported, the silhouette function above the mouse is blue, and the silhouette function of mouse click is green
// If contour is not supported, change the feature color to yellow when hovering and green when clicking
if (
Cesium.PostProcessStageLibrary.isSilhouetteSupported(viewer.scene)
) {
// Support profile
var silhouetteBlue = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
silhouetteBlue.uniforms.color = Cesium.Color.BLUE;//blue
silhouetteBlue.uniforms.length = 0.01;
silhouetteBlue.selected = [];
 
var silhouetteGreen = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
silhouetteGreen.uniforms.color = Cesium.Color.LIME;
silhouetteGreen.uniforms.length = 0.01;
silhouetteGreen.selected = [];
 
viewer.scene.postProcessStages.add(
Cesium.PostProcessStageLibrary.createSilhouetteStage([
silhouetteBlue,
silhouetteGreen,
])
);
 
// Outline blue in hover
viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(
movement
) {
// If a feature was previously highlighted, undo the highlight
silhouetteBlue.selected = [];
 
//Click on new elements
var pickedFeature = viewer.scene.pick(movement.endPosition);
if (!Cesium.defined(pickedFeature)) {
nameOverlay.style.display = "none";
return;
}
 
//Element is clicked to show its coverage
nameOverlay.style.display = "block";
nameOverlay.style.bottom =
viewer.canvas.clientHeight - movement.endPosition.y + "px";
nameOverlay.style.left = movement.endPosition.x + "px";
var name = pickedFeature.getProperty("BIN");
nameOverlay.textContent = name;
 
// Highlight features that have not been selected
if (pickedFeature !== selected.feature) {
silhouetteBlue.selected = [pickedFeature];
}
},
Cesium.ScreenSpaceEventType.MOUSE_MOVE);
 
// Show selection and metadata in info box
viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(
movement
) {
// If you previously selected a feature, unhighlight it
silhouetteGreen.selected = [];
 
// Click on new elements
var pickedFeature = viewer.scene.pick(movement.position);
if (!Cesium.defined(pickedFeature)) {
clickHandler(movement);
return;
}
 
// Select the feature if it's not already selected
if (silhouetteGreen.selected[0] === pickedFeature) {
return;
}
 
// Saves the original color of the selected feature
var highlightedFeature = silhouetteBlue.selected[0];
if (pickedFeature === highlightedFeature) {
silhouetteBlue.selected = [];
}
 
// Highlight new selection feature
silhouetteGreen.selected = [pickedFeature];
 
// Set feature information box description
var featureName = pickedFeature.getProperty("name");
selectedEntity.name = featureName;
selectedEntity.description =
'Loading <div class="cesium-infoBox-loading"></div>';
viewer.selectedEntity = selectedEntity;
selectedEntity.description =
'<table class="cesium-infoBox-defaultTable"><tbody>' +
"<tr><th>BIN</th><td>" +
pickedFeature.getProperty("BIN") +
"</td></tr>" +
"<tr><th>DOITT ID</th><td>" +
pickedFeature.getProperty("DOITT_ID") +
"</td></tr>" +
"<tr><th>SOURCE ID</th><td>" +
pickedFeature.getProperty("SOURCE_ID") +
"</td></tr>" +
"</tbody></table>";
},
Cesium.ScreenSpaceEventType.LEFT_CLICK);
} else {
// Profile is not supported. Instead, change the feature color
// Information about currently highlighted features
var highlighted = {
feature: undefined,
originalColor: new Cesium.Color(),
};
 
// Mouse movement in yellow
viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(
movement
) {
// If a feature was previously highlighted, undo the highlight
if (Cesium.defined(highlighted.feature)) {
highlighted.feature.color = highlighted.originalColor;
highlighted.feature = undefined;
}
// Click on new elements
var pickedFeature = viewer.scene.pick(movement.endPosition);
if (!Cesium.defined(pickedFeature)) {
nameOverlay.style.display = "none";
return;
}
// Element is clicked to show its coverage
nameOverlay.style.display = "block";
nameOverlay.style.bottom =
viewer.canvas.clientHeight - movement.endPosition.y + "px";
nameOverlay.style.left = movement.endPosition.x + "px";
var name = pickedFeature.getProperty("name");
if (!Cesium.defined(name)) {
name = pickedFeature.getProperty("id");
}
nameOverlay.textContent = name;
// Highlight the feature if it's not already selected.
if (pickedFeature !== selected.feature) {
highlighted.feature = pickedFeature;
Cesium.Color.clone(
pickedFeature.color,
highlighted.originalColor
);
pickedFeature.color = Cesium.Color.YELLOW;
}
},
Cesium.ScreenSpaceEventType.MOUSE_MOVE);
 
//Color the selection and display metadata in the message box
viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(
movement
) {
// If you previously selected a feature, unhighlight it
if (Cesium.defined(selected.feature)) {
selected.feature.color = selected.originalColor;
selected.feature = undefined;
}
// Click on new elements
var pickedFeature = viewer.scene.pick(movement.position);
if (!Cesium.defined(pickedFeature)) {
clickHandler(movement);
return;
}
// Select the feature if it's not already selected
if (selected.feature === pickedFeature) {
return;
}
selected.feature = pickedFeature;
// Save the selected feature's original color
if (pickedFeature === highlighted.feature) {
Cesium.Color.clone(
highlighted.originalColor,
selected.originalColor
);
highlighted.feature = undefined;
} else {
Cesium.Color.clone(pickedFeature.color, selected.originalColor);
}
// Highlight newly selected feature
pickedFeature.color = Cesium.Color.LIME;
// Set feature infobox description
var featureName = pickedFeature.getProperty("name");
selectedEntity.name = featureName;
selectedEntity.description =
'Loading <div class="cesium-infoBox-loading"></div>';
viewer.selectedEntity = selectedEntity;
selectedEntity.description =
'<table class="cesium-infoBox-defaultTable"><tbody>' +
"<tr><th>BIN</th><td>" +
pickedFeature.getProperty("BIN") +
"</td></tr>" +
"<tr><th>DOITT ID</th><td>" +
pickedFeature.getProperty("DOITT_ID") +
"</td></tr>" +
"<tr><th>SOURCE ID</th><td>" +
pickedFeature.getProperty("SOURCE_ID") +
"</td></tr>" +
"<tr><th>Longitude</th><td>" +
pickedFeature.getProperty("longitude") +
"</td></tr>" +
"<tr><th>Latitude</th><td>" +
pickedFeature.getProperty("latitude") +
"</td></tr>" +
"<tr><th>Height</th><td>" +
pickedFeature.getProperty("height") +
"</td></tr>" +
"<tr><th>Terrain Height (Ellipsoid)</th><td>" +
pickedFeature.getProperty("TerrainHeight") +
"</td></tr>" +
"</tbody></table>";
},
Cesium.ScreenSpaceEventType.LEFT_CLICK);

Other small column examples: 3dfiles monomer

https://xiaozhuanlan.com/topic/3241096587
See the above link article for details

This article effect example: unifies the geoserver to realize the 3dtiles incline model monomer Click to highlight

The implementation idea is as follows: click the tilt model to obtain the corresponding click coordinate points; then according to the coordinate points obtained by pick, combined with wfs service published by geoserver, carry out spatial query to match the corresponding geojson data; finally, draw the highlight effect according to the obtained geojson data source, and pop up the corresponding bubble window.

design sketch:

  • Monitor mouse click events:
this.handler.setInputAction(function (evt) { //Single machine start drawing
var picks = viewer.scene.drillPick(evt.position);
viewer.scene.render();
var cartesian;
var isOn3dtiles = false;
for (var i = 0; i < picks.length; i++) {
if ((picks[i] && picks[i].primitive) || picks[i] instanceof Cesium.Cesium3DTileFeature) { //Pick on Model
isOn3dtiles = true;
}
}
if (isOn3dtiles) {
cartesian = viewer.scene.pickPosition(evt.position);
var lnglat = cUtil.cartesianToLnglat(cartesian);//coordinate transformation 
that.queryWFSData([lnglat]);
} else {
console.warn("Please pick it up on the model!");
return;
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
queryWFSData: function (lnglats) {
if (!lnglats || lnglats.length < 1) return;
var that = this;
queryWFSData({
typeName: typeName,
propertyName: propertyName,
url: mapUrl,
queryData: {
type: '1',
coors: lnglats
},
success: function (data) {
if (!data.features || data.features.length == 0) {
console.warn("No data found!");
return;
}
that.loadGeojson(data);//Query results highlight
}
})
}
  • Highlight:
loadGeojson: function (data) {
if (!data) return;
var that = this;
Cesium.GeoJsonDataSource.load(data, {
stroke: Cesium.Color.HOTPINK,
fill: Cesium.Color.YELLOW.withAlpha(.8),
clampToGround: true,
strokeWidth: 3
}).then(function (dataSource) {
that.quyerDataSourceArr.push(dataSource);
viewer.dataSources.add(dataSource);
var entities = dataSource.entities.values;
that.bindPopup(entities);
viewer.flyTo(entities, {
offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90.0), 100)
});
});
}

 

  • Bubble window display:
bindPopup: function (entities) {
if (!entities || entities.length < 1) return;
var that = this;
entities.forEach(function (ent) {
ent.attr = "loadgeojson";
var properties = ent._properties;
var contentStr = "";
for (var i in properties) {
var name = ppObj[i];
var value = properties[i]._value;
if (name && value) {
contentStr +=
`
<tr>
<td>${name}</td>
<td>${value}</td>
</tr>
`;
}
}
var content =
`
<table style='width:200px;'>
${contentStr}
</table>
`;
//Bound pop ups
var hierarchy = ent.polygon.hierarchy._value.positions;
var center = cUtil.getCenterByPositions(hierarchy);
var lnglat = cUtil.cartesianToLnglat(center);
var tileH = viewer.scene.sampleHeight(Cesium.Cartographic.fromDegrees(lnglat[0], lnglat[1]));
var popupCartesian = Cesium.Cartesian3.fromDegrees(lnglat[0], lnglat[1], tileH);
var popup = new MovePrompt(viewer, {
type: 2,
content: content,
popupCartesian: popupCartesian,
offset: {
y: -30
}
})
that.popupArr.push(popup);
ent.popup = popup;
});
}

For more excellent articles, see the following cesium column:

GIS home / Cesium special column xiaozhuang.com

Posted on Tue, 05 May 2020 07:57:44 -0400 by ztron