diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 87c20252..ed7c91e0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -103,7 +103,7 @@ INCLUDE_DIRECTORIES( if(MSVC) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi") #/Od + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi /Od") #/Od set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF") foreach(var @@ -183,7 +183,7 @@ endif() SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ProjectDIR}/bin) TARGET_LINK_LIBRARIES(${PROJECT_NAME}) -#SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE") add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD diff --git a/src/effects/ConeWave.cpp b/src/effects/ConeWave.cpp index d6a003d0..63d34061 100644 --- a/src/effects/ConeWave.cpp +++ b/src/effects/ConeWave.cpp @@ -116,7 +116,7 @@ void ConeWave::CreateTexturedCone(osg::Geode* geode) { fragmentShader->setShaderSource(fragSource); osg::StateSet* stateset = coneDrawable_->getOrCreateStateSet(); - stateset->setRenderBinDetails(10000, "RenderBin"); + stateset->setRenderBinDetails(13, "DepthSortedBin"); osg::ref_ptr blendFunc = new osg::BlendFunc(); stateset->setAttributeAndModes(blendFunc, osg::StateAttribute::ON); osg::ref_ptr program = new osg::Program(); diff --git a/src/entities/MeshComponent.cpp b/src/entities/MeshComponent.cpp index c2eb95bc..a6b12f45 100644 --- a/src/entities/MeshComponent.cpp +++ b/src/entities/MeshComponent.cpp @@ -52,6 +52,7 @@ bool MeshComponent::LoadNode(const char* mesh) { } } mt_ = mt; + //mt_->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); UpdateLocationAndRotation(); return true; } diff --git a/src/scene/OEScene.cpp b/src/scene/OEScene.cpp index a314b27f..73e44aa3 100644 --- a/src/scene/OEScene.cpp +++ b/src/scene/OEScene.cpp @@ -19,6 +19,7 @@ #include "scene/ScopedTimer.h" #include "viewer/OsgView.h" #include "viewer/OsgCameraManipulator.h" +#include "scene/ScaleBarHandler.h" const osgEarth::SpatialReference* g_srs_{ nullptr }; diff --git a/src/scene/OEScene.h b/src/scene/OEScene.h index 7039fb02..2ce39485 100644 --- a/src/scene/OEScene.h +++ b/src/scene/OEScene.h @@ -10,6 +10,9 @@ //#include "scene/SkyDome.h" +#include "common/SpdLogger.h" +#include "config.h" + class OsgView; class OEScene : public osg::Referenced { @@ -32,6 +35,11 @@ public: return earthMapNode_.get(); } + osgEarth::MapNode* GetMapNode(void) const { + dyt_check(earthMapNode_.valid()); + return earthMapNode_; + } + void AddToScene(osg::Node* node); private: diff --git a/src/scene/ScaleBarHandler.cpp b/src/scene/ScaleBarHandler.cpp new file mode 100644 index 00000000..1170c034 --- /dev/null +++ b/src/scene/ScaleBarHandler.cpp @@ -0,0 +1,18 @@ +#include "scene/ScaleBarHandler.h" + +#include + +bool ScaleBarHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { + if (nullptr == delegate_) { + return false; + } + + osgViewer::View* view = dynamic_cast(&aa); + if (view) { + if (ea.getEventType() == ea.SCROLL || ea.getEventType() == ea.KEYDOWN) { + delegate_->OnComputeScale(); + return false; + } + } + return false; +} diff --git a/src/scene/ScaleBarHandler.h b/src/scene/ScaleBarHandler.h new file mode 100644 index 00000000..d54d29e1 --- /dev/null +++ b/src/scene/ScaleBarHandler.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +class ScaleBarHandler : public osgGA::GUIEventHandler { +public: + class Delegate { + public: + enum class Units { + UNITS_METERS, + UNITS_INTL_FEET, + UNITS_US_SURVEY_FEET, + UNITS_NAUTICAL_MILES + }; + public: + virtual ~Delegate() {} + virtual void OnComputeScale() = 0; + }; + +public: + ScaleBarHandler(Delegate* delegate) : delegate_(delegate) {} + bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa); + Delegate* delegate_; +}; diff --git a/src/translations/Dyt_zh_CN.ts b/src/translations/Dyt_zh_CN.ts index 30a28039..0ceb91ed 100644 --- a/src/translations/Dyt_zh_CN.ts +++ b/src/translations/Dyt_zh_CN.ts @@ -634,6 +634,11 @@ Matlab File + + + name: 5year 0412 + + ModelBrowser @@ -1262,18 +1267,18 @@ QtOsgViewWidget - - + + warning 警告 - + default workspace failed 加载默认空间失败 - + open dyt file failed 打开空间文件失败 diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp index eed403af..3b5e1d34 100644 --- a/src/ui/MainWindow.cpp +++ b/src/ui/MainWindow.cpp @@ -204,7 +204,7 @@ void MainWindow::InitUI() { matlabFileDlg_->AttachDock(matlabDock); m_mapDockWidget.insert("Matlab", matlabDock); - //ui->discript->setText(tr("name: 5year 0412")); + ui->discript->setText(tr("name: 5year 0412")); //ui->status->setText(tr("start: no start")); InitDockLayout(); diff --git a/src/viewer/QtOsgViewWidget.cpp b/src/viewer/QtOsgViewWidget.cpp index 190f45d3..e8516841 100644 --- a/src/viewer/QtOsgViewWidget.cpp +++ b/src/viewer/QtOsgViewWidget.cpp @@ -15,6 +15,7 @@ #include #include +#include #include "config.h" #include "app/Application.h" @@ -26,8 +27,146 @@ #include "scene/OsgScene.h" #include "workspace/WorkSpace.h" #include "workspace/WorkSpaceManager.h" +#include "scene/SceneContent.h" #include "ui/MainFrame.h" + +double normalizeScaleMeters(double meters) { + if (meters <= 3) { + meters = 1; + } else if (meters <= 7.5) { + meters = 5; + } else if (meters <= 15) { + meters = 10; + } else if (meters <= 35) { + meters = 20; + } else if (meters <= 75) { + meters = 50; + } else if (meters <= 150) { + meters = 100; + } else if (meters <= 350) { + meters = 200; + } else if (meters <= 750) { + meters = 500; + } else if (meters <= 1500) { + meters = 1000; + } else if (meters <= 3500) { + meters = 2000; + } else if (meters <= 7500) { + meters = 5000; + } else if (meters <= 15000) { + meters = 10000; + } else if (meters <= 35000) { + meters = 20000; + } else if (meters <= 55000) { + meters = 50000; + } else if (meters <= 150000) { + meters = 100000; + } else if (meters <= 350000) { + meters = 200000; + } else if (meters <= 750000) { + meters = 500000; + } else if (meters <= 1500000) { + meters = 1000000; + } else { + meters = 2000000; + } + return meters; +} + +double normalizeScaleFeet(double feet) { + double feetPerMile = 5280.0; + if (feet <= 7.5) { + feet = 5; + } else if (feet <= 15) { + feet = 10; + } else if (feet <= 35) { + feet = 20; + } else if (feet <= 75) { + feet = 50; + } else if (feet <= 150) { + feet = 100; + } else if (feet <= 350) { + feet = 200; + } else if (feet <= 750) { + feet = 500; + } else if (feet <= 1500) { + feet = 1000; + } else if (feet <= 3640) { + feet = 2000; + } else if (feet <= 1.5 * feetPerMile) { + feet = 1 * feetPerMile; + } else if (feet <= 3.5 * feetPerMile) { + feet = 2 * feetPerMile; + } else if (feet <= 7.5 * feetPerMile) { + feet = 5 * feetPerMile; + } else if (feet <= 15 * feetPerMile) { + feet = 10 * feetPerMile; + } else if (feet <= 35 * feetPerMile) { + feet = 20 * feetPerMile; + } else if (feet <= 75 * feetPerMile) { + feet = 50 * feetPerMile; + } else if (feet <= 150 * feetPerMile) { + feet = 100 * feetPerMile; + } else if (feet <= 350 * feetPerMile) { + feet = 200 * feetPerMile; + } else if (feet <= 750 * feetPerMile) { + feet = 500 * feetPerMile; + } else if (feet <= 1500 * feetPerMile) { + feet = 1000 * feetPerMile; + } else { + feet = 2000 * feetPerMile; + } + return feet; +} + +double normalizeScaleNauticalMiles(double nmi) { + //double feetPerMile = 6076.12; + if (nmi <= 0.0015) { + nmi = 0.001; + } else if (nmi <= 0.0035) { + nmi = 0.002; + } else if (nmi <= 0.0075) { + nmi = 0.005; + } else if (nmi <= 0.015) { + nmi = 0.01; + } else if (nmi <= 0.035) { + nmi = 0.02; + } else if (nmi <= 0.075) { + nmi = 0.05; + } else if (nmi <= 0.15) { + nmi = 0.1; + } else if (nmi <= 0.35) { + nmi = 0.2; + } else if (nmi <= 0.75) { + nmi = 0.5; + } else if (nmi <= 1.5) { + nmi = 1; + } else if (nmi <= 3.5) { + nmi = 2; + } else if (nmi <= 7.5) { + nmi = 5; + } else if (nmi <= 15) { + nmi = 10; + } else if (nmi <= 35) { + nmi = 20; + } else if (nmi <= 75) { + nmi = 50; + } else if (nmi <= 150) { + nmi = 100; + } else if (nmi <= 350) { + nmi = 200; + } else if (nmi <= 750) { + nmi = 500; + } else if (nmi <= 1500) { + nmi = 1000; + } else { + nmi = 2000; + } + return nmi; +} + + QtOsgViewWidget::QtOsgViewWidget(QWidget* parent) : QWidget(parent) { LOG_INFO("actor, self={}", fmt::ptr(this)); @@ -55,6 +194,131 @@ void QtOsgViewWidget::keyReleaseEvent(QKeyEvent* event) { view_->KeyRelease(event); } +void QtOsgViewWidget::OnComputeScale() { + osgEarth::MapNode* mapNode = activeScene_->GetMapNode(); + if (nullptr == mapNode || nullptr == mapNode->getTerrain()) { + return; + } + dyt_check(nullptr != view_); + + float x = 0.0f, y = 0.0f; + osg::Vec3d world1, world2; + if (!mapNode->getTerrain()->getWorldCoordsUnderMouse(view_->GetView(), x, y, world1)) { + emit signalScaleBarInfo(""); + return; + } + x += devicePixelRatio_; + if (!mapNode->getTerrain()->getWorldCoordsUnderMouse(view_->GetView(), x, y, world2)) { + emit signalScaleBarInfo(""); + return; + } + +#if 0 + TRACE("w1: %g %g %g w2: %g %g %g", + world1.x(), world1.y(), world1.z(), + world2.x(), world2.y(), world2.z()); +#endif + + double meters; + double radius = 6378137.0; + dyt_check(nullptr != g_srs_); + radius = g_srs_->getEllipsoid().getRadiusEquator(); + + if (!g_srs_->isGeocentric() ) { + // TRACE("Map is geographic"); + // World cords are already lat/long + // Compute great circle distance + meters = osgEarth::GeoMath::distance(world1, world2, g_srs_); + } else { + osgEarth::GeoPoint mapPoint1, mapPoint2; + mapPoint1.fromWorld(g_srs_, world1); + mapPoint1.makeGeographic(); + mapPoint2.fromWorld(g_srs_, world2); + mapPoint2.makeGeographic(); + // Compute great circle distance + meters = osgEarth::GeoMath::distance(osg::DegreesToRadians(mapPoint1.y()), + osg::DegreesToRadians(mapPoint1.x()), + osg::DegreesToRadians(mapPoint2.y()), + osg::DegreesToRadians(mapPoint2.x()), + radius); + } + + double scale = meters / devicePixelRatio_; + double pixelWidth = devicePixelRatio_ * 2.0; + // 1mi = 5280 feet + //double scaleMiles = scale / 1609.344; // International mile = 1609.344m + //double scaleNauticalMiles = scale / 1852.0; // nautical mile = 1852m + //double scaleUSSurveyMiles = scale / 1609.347218694; // US survey mile = 5280 US survey feet + //double scaleUSSurveyFeet = scale * 3937.0/1200.0; // US survey foot = 1200/3937 m +#if 0 + TRACE("m: %g px: %g m/px: %g", meters, pixelWidth, scale); +#endif + /* switch (scaleUnits_) { + case ScaleBarHandler::Delegate::Units::UNITS_NAUTICAL_MILES: { + double nmi = meters / 1852.0; + scale = nmi / devicePixelRatio_; + nmi = normalizeScaleNauticalMiles(nmi); + pixelWidth = nmi / scale; + if (_scaleLabel.valid()) { + _scaleLabel->setText(osgEarth::Stringify() + << nmi + << " nmi"); + } + } break; + case ScaleBarHandler::Delegate::Units::UNITS_US_SURVEY_FEET: { + double feet = meters * 3937.0 / 1200.0; + scale = feet / pixelWidth; + feet = normalizeScaleFeet(feet); + pixelWidth = feet / scale; + if (_scaleLabel.valid()) { + if (feet >= 5280) { + _scaleLabel->setText(osgEarth::Stringify() + << feet / 5280.0 + << " miUS"); + } else { + _scaleLabel->setText(osgEarth::Stringify() + << feet + << " ftUS"); + } + } + } break; + case ScaleBarHandler::Delegate::Units::UNITS_INTL_FEET: { + double feet = 5280.0 * meters / 1609.344; + scale = feet / pixelWidth; + feet = normalizeScaleFeet(feet); + pixelWidth = feet / scale; + if (_scaleLabel.valid()) { + if (feet >= 5280) { + _scaleLabel->setText(osgEarth::Stringify() + << feet / 5280.0 + << " mi"); + } else { + _scaleLabel->setText(osgEarth::Stringify() + << feet + << " ft"); + } + } + } break; + case ScaleBarHandler::Delegate::Units::UNITS_METERS: + default: { + meters = normalizeScaleMeters(meters); + pixelWidth = meters / scale; + if (_scaleLabel.valid()) { + if (meters >= 1000) { + _scaleLabel->setText(osgEarth::Stringify() + << meters / 1000.0 + << " km"); + } else { + _scaleLabel->setText(osgEarth::Stringify() + << meters + << " m"); + } + } + } break; + } + */ +} + void QtOsgViewWidget::Initialize(void) { if (view_) { LOG_INFO("view is created"); @@ -102,6 +366,8 @@ void QtOsgViewWidget::Initialize(void) { OsgCameraManipulator* cameraManipulator = new OsgCameraManipulator(manipulator, this); view_->Initialize(cameraManipulator); + + //activeScene_ } void QtOsgViewWidget::Uninitialize(void) { @@ -151,8 +417,8 @@ void QtOsgViewWidget::resizeEvent(QResizeEvent* event) { return; } - double pixelRatio = screen()->devicePixelRatio(); + devicePixelRatio_ = screen()->devicePixelRatio(); const QSize& size = event->size(); - view_->Resize(0, 0, size.width() * pixelRatio, size.height() * pixelRatio); + view_->Resize(0, 0, size.width() * devicePixelRatio_, size.height() * devicePixelRatio_); } diff --git a/src/viewer/QtOsgViewWidget.h b/src/viewer/QtOsgViewWidget.h index 21970ff6..02a153e9 100644 --- a/src/viewer/QtOsgViewWidget.h +++ b/src/viewer/QtOsgViewWidget.h @@ -4,6 +4,7 @@ #include #include "scene/OEScene.h" +#include "scene/ScaleBarHandler.h" class QMouseEvent; @@ -12,7 +13,7 @@ class QKeyEvent; class QInputEvent; class QResizeEvent; -class QtOsgViewWidget : public QWidget { +class QtOsgViewWidget : public QWidget, public ScaleBarHandler::Delegate { Q_OBJECT public: explicit QtOsgViewWidget(QWidget* parent = nullptr); @@ -23,6 +24,8 @@ public: return nullptr; } + void OnComputeScale() override; + void Initialize(void); void Uninitialize(void); @@ -33,6 +36,7 @@ public: signals: void signalResetWorkSpace(); + void signalScaleBarInfo(const QString&); protected: @@ -45,4 +49,6 @@ private: class OsgView* view_{ nullptr }; osg::ref_ptr activeScene_; class WorkSpace* workspace_{ nullptr }; + ScaleBarHandler::Delegate::Units scaleUnits_{ ScaleBarHandler::Delegate::Units::UNITS_METERS }; + float devicePixelRatio_{ 1.0f }; }; \ No newline at end of file