本节演示选中3dtiles的模型,选中模型与ceisum基本一致。通过鼠标左键单击模型并将选中的模型进行高亮。使用上一节的示例,再添加鼠标左键单击事件用于选中模型。
1、修改Handler类,添加静态函数onLeftClick,参数与右键单击函数一样。单击时获取鼠标位置然后获取选中的要素再将其高亮。
static void onLeftClick(void *handler, Cesium::ScreenEvent *event) { Handler *aggregator = (Handler *) handler; glm::dvec2 position = event->position;// 获取鼠标屏幕位置 //获取选中要素 Cesium::Feature *feature = aggregator->viewer->_scene->pick(position); if (feature == NULL) { if (aggregator->feautre != NULL) { glm::dvec4 co(1.0, 1.0, 1.0, 1.0); aggregator->feautre->color(co);//取消高亮 } } else { if (feature->instanceof("Cesium3DTileFeature")) { Cesium::Cesium3DTileFeature *tfeautre = (Cesium::Cesium3DTileFeature *) feature;// 强制类型转换 aggregator->feautre = tfeautre; glm::dvec4 co(1.5, 0.0, 0.0, 0.5); tfeautre->color(co);//高亮模型 aggregator->attrname.clear(); tfeautre->getPropertyNames(&aggregator->attrname); std::string id = tfeautre->getProperty("batchId"); for (int i = 0; i < aggregator->attrname.size(); i++) { std::cout << aggregator->attrname[i] << std::endl;//打印属性 } } } }
2、主函数中添加鼠标左键函数
_eventHandler>setInputAction(&Handler::onLeftClick,
Cesium::ScreenSpaceEventType::LEFT_CLICK);
3、鼠标右键函数是添加3dtiles模型,并平移到模型位置。
4、运行即可,鼠标右键添加模型后,使用左键单击一个模型即可选中模型并高亮,点击地图其他地方就取消高亮。过程与web端cesium基本一致。
完整代码
/** * Created by IBM on 2021/3/3. */ #include <iostream> #include <Widgets/Viewer/Viewer.h> #include <Scene/Cesium3DTileset.h> class Handler { public: Cesium::Viewer *viewer; Cesium::Cesium3DTileset *tileset = NULL; Cesium::Cesium3DTileFeature *feautre = NULL; std::vector<std::string> attrname; /** * 鼠标右键加载tileset模型 * @param handler * @param event 鼠标指针位置,屏幕坐标,与ceisum中的基本一致 */ static void mouseUp(void *handler, Cesium::ScreenEvent *event) { Handler *aggregator = (Handler *) handler; if (aggregator->tileset == NULL) { std::string url = "../data/BatchedColors/tileset.json"; aggregator->tileset = new Cesium::Cesium3DTileset(url); aggregator->viewer->_scene->primitives()->add(aggregator->tileset); Cesium::HeadingPitchRoll *orientation = new Cesium::HeadingPitchRoll(0.0, -1.5707963267948966, 0.0); //因为已经有glm库使用没有写cesium的Cartesian3,但是Cartesian3的很多方法是写了的,也可以用glm库提供的 glm::dvec3 initialPosition1 = Cesium::Cartesian3::fromDegrees(-75.60908200128681, 40.04159868719826, 1000); aggregator->viewer->_scene->_camera->setView(orientation, initialPosition1); } } static void onLeftClick(void *handler, Cesium::ScreenEvent *event) { Handler *aggregator = (Handler *) handler; glm::dvec2 position = event->position;// 获取鼠标屏幕位置 //获取选中要素 Cesium::Feature *feature = aggregator->viewer->_scene->pick(position); if (feature == NULL) { if (aggregator->feautre != NULL) { glm::dvec4 co(1.0, 1.0, 1.0, 1.0); aggregator->feautre->color(co);//取消高亮 } } else { if (feature->instanceof("Cesium3DTileFeature")) { Cesium::Cesium3DTileFeature *tfeautre = (Cesium::Cesium3DTileFeature *) feature;// 强制类型转换 aggregator->feautre = tfeautre; glm::dvec4 co(1.5, 0.0, 0.0, 0.5); tfeautre->color(co);//高亮模型 aggregator->attrname.clear(); tfeautre->getPropertyNames(&aggregator->attrname); std::string id = tfeautre->getProperty("batchId"); for (int i = 0; i < aggregator->attrname.size(); i++) { std::cout << aggregator->attrname[i] << std::endl;//打印属性 } } } } }; int main(int argc, char *argv[]) { Handler *handler = new Handler(); Cesium::Viewer viewer = Cesium::Viewer(500, 300); handler->viewer = &viewer; std::string url = "https://dev.virtualearth.net"; std::string key = "AmXdbd8UeUJtaRSn7yVwyXgQlBBUqliLbHpgn2c76DfuHwAXfRrgS5qwfHU6Rhm8"; Cesium::BingMapsImageryProvider *imageryProvider1 = new Cesium::BingMapsImageryProvider(url, key); viewer.imageryLayers()->addImageryProvider(imageryProvider1); //创建事件 Cesium::ScreenSpaceEventHandler *_eventHandler = new Cesium::ScreenSpaceEventHandler(handler); _eventHandler->setInputAction(&Handler::mouseUp, Cesium::ScreenSpaceEventType::RIGHT_CLICK);//设置鼠标点击事件 _eventHandler->setInputAction(&Handler::onLeftClick, Cesium::ScreenSpaceEventType::LEFT_CLICK); viewer.startAnimating(true);//启动opengl循环 system("pause"); return 0; }
返回目录