/** * @RDE_HEADER@ * Declaration/Definition * $Id$ * $HeadURL$ * $Author$ */ // [WriteFile Name=ViewshedLocation, Category=Analysis] // [Legal] // Copyright 2017 Esri. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // [Legal] #include "ViewshedLocation.h" #include "ArcGISTiledElevationSource.h" #include "Scene.h" #include "SceneGraphicsView.h" #include "LocationViewshed.h" #include "Camera.h" #include "Point.h" #include "AnalysisOverlay.h" #include "QColor" using namespace Esri::ArcGISRuntime; ViewshedLocation::ViewshedLocation(QObject* parent /* = nullptr */): QObject(parent) { } void ViewshedLocation::init(Esri::ArcGISRuntime::SceneGraphicsView* sceneView) { m_sceneView = sceneView; // Register classes for QML // qmlRegisterType("Esri.Samples", 1, 0, "SceneView"); // qmlRegisterType("Esri.Samples", 1, 0, "ViewshedLocationSample"); Surface* surface = new Surface(this); surface->elevationSources()->append( new ArcGISTiledElevationSource( QUrl(QStringLiteral("http://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer")), this)); m_sceneView->arcGISScene()->setBaseSurface(surface); // set initial viewpoint setInitialViewpoint(); // connect signals connectSignals(); } void ViewshedLocation::setInitialViewpoint() { // Set a viewpoint double x = 6.86088; double y = 45.3604; double z = 3582.55; Point point(x, y, z, SpatialReference(4326)); double heading = 345; double pitch = 70; double roll = 0; Camera camera(point, heading, pitch, roll); m_sceneView->setViewpointCamera(camera); } void ViewshedLocation::connectSignals() { // on mouse click perform the location viewshed connect(m_sceneView, &SceneGraphicsView::mouseClicked, this, [this](QMouseEvent& event) { if (!m_locationViewshed[0]) createViewshed(event.x(), event.y()); else { for (int i = 0; i < 3; ++i) { const Point pt = m_sceneView->screenToBaseSurface(event.x(), event.y()); m_locationViewshed[i]->setLocation(pt); } } }); connect(m_sceneView, &SceneGraphicsView::mousePressedAndHeld, this, [this](QMouseEvent& event) { if (!m_locationViewshed[0]) createViewshed(event.x(), event.y()); m_calculating = true; }); connect(m_sceneView, &SceneGraphicsView::mouseMoved, this, [this](QMouseEvent& event) { if (m_calculating) { for (int i = 0; i < 3; ++i) { const Point pt = m_sceneView->screenToBaseSurface(event.x(), event.y()); m_locationViewshed[i]->setLocation(pt); } } }); connect(m_sceneView, &SceneGraphicsView::mouseReleased, this, [this](QMouseEvent) { m_calculating = false; }); } void ViewshedLocation::createViewshed(double x, double y) { m_analysisOverlay = new AnalysisOverlay(this); m_sceneView->analysisOverlays()->append(m_analysisOverlay); const Point pt = m_sceneView->screenToBaseSurface(x, y); qCritical() << " pt="; qCritical() << " pt=" << pt.x(); qCritical() << " pt=" << pt.y(); qCritical() << " pt=" << pt.z(); for (int i = 0; i < 3; ++i) { double heading = i * 120.0; m_locationViewshed[i] = new LocationViewshed(pt , heading , 90.0 // pitch , 120.0 // horizontalAngle , 90.0 // verticalAngle , 10.0 // minDistance , 20000 , this); m_locationViewshed[i]->setVisible(m_viewshedVisible); // Add the Viewshed to the Analysis Overlay m_analysisOverlay->analyses()->append(m_locationViewshed[i]); m_locationViewshed[i]->setFrustumOutlineVisible(true); // QColor frustumColor(0, 0, 0, 255); // m_locationViewshed->setFrustumOutlineColor(frustumColor); } return; } // Getters/Setters for each Q_PROPERTY bool ViewshedLocation::isViewshedVisible() const { return m_viewshedVisible; } void ViewshedLocation::setViewshedVisible(bool viewshedVisible) { for (int i = 0; i < 3; ++i) { if (m_locationViewshed[i]) { if (m_locationViewshed[i]->isVisible() == viewshedVisible) { continue; } m_locationViewshed[i]->setVisible(viewshedVisible); } } if (m_viewshedVisible != viewshedVisible) { m_viewshedVisible = viewshedVisible; emit viewshedVisibleChanged(); } } bool ViewshedLocation::isFrustumOutlineVisible() const { return m_locationViewshed[0] ? m_locationViewshed[0]->isFrustumOutlineVisible() : m_frustumVisible; } void ViewshedLocation::setFrustumOutlineVisible(bool frustumVisible) { for (int i = 0; i < 3; ++i) { if (m_locationViewshed[i]) { if (m_locationViewshed[i]->isFrustumOutlineVisible() == frustumVisible) { continue; } m_frustumVisible = frustumVisible; m_locationViewshed[i]->setFrustumOutlineVisible(frustumVisible); } } if (m_frustumVisible != frustumVisible) { m_frustumVisible = frustumVisible; emit frustumVisibleChanged(); } } double ViewshedLocation::minDistance() const { return m_locationViewshed[0] ? m_locationViewshed[0]->minDistance() : m_minDistance; } void ViewshedLocation::setMinDistance(double minDistance) { for (int i = 0; i < 3; ++i) { if (m_locationViewshed[i]) { if (m_locationViewshed[i]->minDistance() == minDistance) { continue; } m_locationViewshed[i]->setMinDistance(minDistance); } } if (m_minDistance != minDistance) { m_minDistance = minDistance; emit minDistanceChanged(); } } double ViewshedLocation::maxDistance() const { return m_locationViewshed[0] ? m_locationViewshed[0]->maxDistance() : m_maxDistance; } void ViewshedLocation::setMaxDistance(double maxDistance) { for (int i = 0; i < 3; ++i) { if (m_locationViewshed[i]) { if (m_locationViewshed[i]->maxDistance() == maxDistance) { continue; } m_locationViewshed[i]->setMaxDistance(maxDistance); } } if (m_maxDistance != maxDistance) { m_maxDistance = maxDistance; emit maxDistanceChanged(); } }