275 lines
6.5 KiB
C++
Executable File
275 lines
6.5 KiB
C++
Executable File
/**
|
|
* @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<SceneQuickView>("Esri.Samples", 1, 0, "SceneView");
|
|
// qmlRegisterType<ViewshedLocation>("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();
|
|
}
|
|
}
|
|
|
|
|