Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,365 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* TerrainProfileProcessor
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
// Own
|
||||
#include "terrain_profile_processor.h"
|
||||
|
||||
#include "map_impl.h"
|
||||
#include <GraphicalObjects/graphical_object_path.h>
|
||||
#include <Map/object_factory.h>
|
||||
#include <Map/situation_map_utils.h>
|
||||
#include <Map/coord_translation_functor.h>
|
||||
#include <MapImpl/layer_factory_impl.h>
|
||||
|
||||
|
||||
|
||||
// ESRI
|
||||
#include <arcgis/GeometryEngine.h>
|
||||
#include <arcgis/PolylineBuilder.h>
|
||||
|
||||
|
||||
// Qt
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class ViewshedBase
|
||||
//-----------------------------------------------------------------------------
|
||||
TerrainProfileProcessor::TerrainProfileProcessor(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_logger(getLogger("TerrainProfileProcessor"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
TerrainProfileProcessor::~TerrainProfileProcessor()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, id=" << m_id;
|
||||
removeUserInput();
|
||||
|
||||
// maybe clear the view of m_terrainProfileDialog here?
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, id=" << m_id;
|
||||
}
|
||||
|
||||
bool TerrainProfileProcessor::init(SituationMap::MapImpl *mapImpl, long id)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
m_id = id;
|
||||
|
||||
m_initialized = false;
|
||||
|
||||
m_mapImpl = mapImpl;
|
||||
m_srMap = m_mapImpl->getEsriSpatialReference();
|
||||
|
||||
LayerFactoryImpl &layerFactoryImpl = m_mapImpl->layerFactoryImpl();
|
||||
|
||||
m_toolsLayername = layerFactoryImpl.toolLayer();
|
||||
|
||||
if (!m_surface)
|
||||
m_surface = layerFactoryImpl.baseSurface();
|
||||
|
||||
if (m_surface && m_surface->loadStatus() == Esri::ArcGISRuntime::LoadStatus::Loaded)
|
||||
m_initialized = true;
|
||||
else
|
||||
{
|
||||
Esri::ArcGISRuntime::LoadStatus ls = Esri::ArcGISRuntime::LoadStatus::Unknown;
|
||||
if (m_surface)
|
||||
ls = m_surface->loadStatus();
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION
|
||||
<< " d->m_surface = " << m_surface
|
||||
<< " d->m_surface->loadStatus = " << ls;
|
||||
}
|
||||
|
||||
if (!m_locationToElevationBulk.init(m_mapImpl, m_surface))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " locationToElevationBulk.init() failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(&m_locationToElevationBulk, &LocationToElevationBulk::locationsToElevationsCompleted,
|
||||
this, &TerrainProfileProcessor::onLocationsToElevationsCompleted, Qt::UniqueConnection);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_initialized=" << m_initialized;
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
bool TerrainProfileProcessor::start(const TerrainProfileParameter &terrainProfileParameter)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " terrainProfileParameter=" << terrainProfileParameter
|
||||
<< " m_srMap.wkid=" << m_srMap.wkid();
|
||||
|
||||
// don´t allow more than one at once:
|
||||
if (m_inProgress)
|
||||
return false;
|
||||
|
||||
m_inProgress = true;
|
||||
|
||||
m_terrainProfileParameter = terrainProfileParameter;
|
||||
|
||||
removeUserInput();
|
||||
displayUserInput();
|
||||
|
||||
// densify
|
||||
const Esri::ArcGISRuntime::Polyline &polylineOut_Map = densifiy(m_terrainProfileParameter);
|
||||
|
||||
// calculate distance
|
||||
|
||||
// bulk location to elevation
|
||||
const Esri::ArcGISRuntime::ImmutablePart &immutablePart = polylineOut_Map.parts().part(0);
|
||||
const int size = immutablePart.pointCount();
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
const Esri::ArcGISRuntime::Point &esriMapLocation = immutablePart.point(i);
|
||||
// DEBUG_LOG(m_logger) << LOGFUNCTION << " esriMapLocation: " << QPointF(esriMapLocation.x(), esriMapLocation.y());
|
||||
m_locationToElevationBulk.addLocation(esriMapLocation);
|
||||
}
|
||||
m_locationToElevationBulk.start();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " m_viewshedInProgress=" << m_inProgress;
|
||||
return true;
|
||||
}
|
||||
|
||||
QVector<QPair<QPointF, double> > TerrainProfileProcessor::results() const
|
||||
{
|
||||
return m_locationToElevationBulk.results();
|
||||
}
|
||||
|
||||
void TerrainProfileProcessor::setTerrainProfileDialog(QPointer<TerrainProfileDialog> &terrainProfileDialog)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_terrainProfileDialog = terrainProfileDialog;
|
||||
|
||||
if (m_terrainProfileDialog)
|
||||
{
|
||||
m_terrainProfileDialog->setMap(m_mapImpl);
|
||||
|
||||
// mousePositionChanged
|
||||
connect(m_terrainProfileDialog.data(), &TerrainProfileDialog::mousePositionChanged,
|
||||
this, &TerrainProfileProcessor::onDialogMousePositionChanged, Qt::UniqueConnection);
|
||||
|
||||
// handle destruction of according dialog:
|
||||
connect(terrainProfileDialog.data(), &TerrainProfileDialog::destroyed,
|
||||
this, &TerrainProfileProcessor::deleteLater);
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
Esri::ArcGISRuntime::Polyline TerrainProfileProcessor::densifiy(TerrainProfileParameter &terrainProfileParameter)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " terrainProfileParameter=" << terrainProfileParameter;
|
||||
|
||||
//
|
||||
// PosCont to EsriPolyline:
|
||||
//
|
||||
Esri::ArcGISRuntime::PolylineBuilder polylineBuilder(m_srMap, this);
|
||||
|
||||
for (const Point3D &coord : qAsConst(terrainProfileParameter.m_coordinates))
|
||||
{
|
||||
// geo to map (polylineBuilder uses map also)
|
||||
const Point3D &p3D = m_mapImpl->coordTranslationFunctor()->geographicToMap(coord);
|
||||
polylineBuilder.addPoint(Esri::ArcGISRuntime::Point(p3D.x(), p3D.y(), p3D.z()));
|
||||
}
|
||||
|
||||
const Esri::ArcGISRuntime::Polyline &polylineIn = polylineBuilder.toPolyline();
|
||||
|
||||
terrainProfileParameter.m_length =
|
||||
Esri::ArcGISRuntime::GeometryEngine::lengthGeodetic(polylineIn,
|
||||
Esri::ArcGISRuntime::LinearUnit::meters(),
|
||||
Esri::ArcGISRuntime::GeodeticCurveType::Geodesic);
|
||||
const int numberCoords = 50;
|
||||
|
||||
double maxSegmenthLength = terrainProfileParameter.m_length / numberCoords;
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " lengthMeter=" << terrainProfileParameter.m_length
|
||||
<< " numberCoords=" << numberCoords
|
||||
<< " maxSegmenthLength=" << maxSegmenthLength;
|
||||
|
||||
const Esri::ArcGISRuntime::Geometry &geometryOut = Esri::ArcGISRuntime::GeometryEngine::densifyGeodetic(polylineIn,
|
||||
maxSegmenthLength,
|
||||
Esri::ArcGISRuntime::LinearUnit::meters(),
|
||||
Esri::ArcGISRuntime::GeodeticCurveType::Geodesic);
|
||||
const Esri::ArcGISRuntime::Polyline polylineOut(geometryOut);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " lengthMeter=" << terrainProfileParameter.m_length
|
||||
<< " numberCoords=" << numberCoords
|
||||
<< " maxSegmenthLength=" << maxSegmenthLength
|
||||
<< " polylineOut.parts().part(0).pointCount()=" << polylineOut.parts().part(0).pointCount();
|
||||
return polylineOut;
|
||||
}
|
||||
|
||||
void TerrainProfileProcessor::displayUserInput()
|
||||
{
|
||||
displayInputLine();
|
||||
displayInputVertices();
|
||||
}
|
||||
|
||||
void TerrainProfileProcessor::removeUserInput()
|
||||
{
|
||||
removeInputLine();
|
||||
removeInputVertices();
|
||||
removeCurrentMarker();
|
||||
}
|
||||
|
||||
void TerrainProfileProcessor::displayInputLine()
|
||||
{
|
||||
// create
|
||||
if (!m_polyline)
|
||||
{
|
||||
m_polyline = m_mapImpl->objectFactory().create<Polyline>(m_toolsLayername,
|
||||
QStringLiteral("TerrainProfileLineId%1").arg(m_id));
|
||||
m_polyline->setLineStyle(LineStyle(m_color, 3));
|
||||
m_polyline->setScaleEnable(true);
|
||||
m_polyline->setPickable(false);
|
||||
}
|
||||
|
||||
// apply data
|
||||
m_polyline->setPositions(m_terrainProfileParameter.m_coordinates);
|
||||
|
||||
// update
|
||||
if (!m_polyline->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " polyline::updateView failed";
|
||||
}
|
||||
void TerrainProfileProcessor::removeInputLine()
|
||||
{
|
||||
if (m_polyline)
|
||||
m_polyline->removeMySelf();
|
||||
m_polyline.reset();
|
||||
}
|
||||
|
||||
void TerrainProfileProcessor::displayInputVertices()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
PositionCont coordinates = m_terrainProfileParameter.m_coordinates;
|
||||
const int size = coordinates.size();
|
||||
if (size < 1)
|
||||
return;
|
||||
|
||||
m_markerCont.resize(size);
|
||||
|
||||
int idx = 0;
|
||||
QMutableVectorIterator<RefPointer<GeoImage>> it(m_markerCont);
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
RefPointer<GeoImage> &marker = it.next();
|
||||
if (!marker.valid())
|
||||
{
|
||||
marker = m_mapImpl->objectFactory().create<GeoImage>(m_toolsLayername,
|
||||
QStringLiteral("TerrainProfileLineId%1_idx%2").arg(m_id).arg(idx));
|
||||
marker->setProxyMarker(MarkerSymbolType::Circle);
|
||||
marker->setProxyMarkerColor(m_color);
|
||||
marker->setProxyMarkerSize(7);
|
||||
marker->setPickable(false);
|
||||
}
|
||||
marker->setOrigin(coordinates[idx]);
|
||||
|
||||
// update
|
||||
if (!marker->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " marker::updateView failed";
|
||||
|
||||
++idx;
|
||||
} // while
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
void TerrainProfileProcessor::removeInputVertices()
|
||||
{
|
||||
QMutableVectorIterator<RefPointer<GeoImage>> it(m_markerCont);
|
||||
while (it.hasNext())
|
||||
{
|
||||
RefPointer<GeoImage> &marker = it.next();
|
||||
if (marker)
|
||||
marker->removeMySelf();
|
||||
}
|
||||
m_markerCont.clear();
|
||||
}
|
||||
|
||||
void TerrainProfileProcessor::displayCurrentMarker(const Point3D &pointGeo)
|
||||
{
|
||||
// create
|
||||
if (!m_currentMarker)
|
||||
{
|
||||
m_currentMarker = m_mapImpl->objectFactory().create<GeoImage>(m_toolsLayername,
|
||||
QStringLiteral("TerrainProfileLineId%1_currentMarker").arg(m_id));
|
||||
m_currentMarker->setProxyMarker(MarkerSymbolType::Circle);
|
||||
m_currentMarker->setProxyMarkerColor(Qt::blue);
|
||||
m_currentMarker->setProxyMarkerSize(10);
|
||||
m_currentMarker->setPickable(false);
|
||||
}
|
||||
|
||||
// apply data
|
||||
m_currentMarker->setOrigin(pointGeo);
|
||||
|
||||
// update
|
||||
if (!m_currentMarker->updateView())
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " m_currentMarker::updateView failed";
|
||||
}
|
||||
|
||||
void TerrainProfileProcessor::removeCurrentMarker()
|
||||
{
|
||||
if (m_currentMarker)
|
||||
m_currentMarker->removeMySelf();
|
||||
m_currentMarker.reset();
|
||||
}
|
||||
|
||||
void TerrainProfileProcessor::onLocationsToElevationsCompleted()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " m_locationToElevationBulk.size()=" << m_locationToElevationBulk.size();
|
||||
|
||||
const QVector<QPair<QPointF, double>> &results = m_locationToElevationBulk.results();
|
||||
|
||||
if (m_logger.isDebugEnabled())
|
||||
for (const QPair<QPointF, double> &item : qAsConst(results))
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " location = " << item.first << " elevation = " << item.second;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " results.size()=" << results.size();
|
||||
|
||||
|
||||
// The caller should set TerrainProfileDialog on this signal:
|
||||
emit locationsToElevationsCompleted(m_id);
|
||||
|
||||
// maybe (better hopefully) the caller (via finishedCallback of TerrainProfileImpl)
|
||||
// has updated our m_terrainProfileParameter !?!
|
||||
if (m_terrainProfileDialog)
|
||||
{
|
||||
m_terrainProfileDialog->setData(this->results());
|
||||
|
||||
QVector<QPointF> marks;
|
||||
marks.reserve(m_terrainProfileParameter.m_coordinates.size());
|
||||
for (const Point3D &coord : qAsConst(m_terrainProfileParameter.m_coordinates))
|
||||
{
|
||||
// geo to map
|
||||
const Point3D &p3D = m_mapImpl->coordTranslationFunctor()->geographicToMap(coord);
|
||||
marks.append(p3D.toPointF());
|
||||
}
|
||||
m_terrainProfileDialog->setMarks(marks);
|
||||
} else {
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no dialog";
|
||||
}
|
||||
|
||||
m_inProgress = false;
|
||||
}
|
||||
|
||||
void TerrainProfileProcessor::onDialogMousePositionChanged(const QPointF &curPos)
|
||||
{
|
||||
const Point3D &curPosGeo = Point3D::fromQPointF( m_mapImpl->coordTranslationFunctor()->mapToGeographic(curPos) );
|
||||
displayCurrentMarker(curPosGeo);
|
||||
}
|
||||
|
||||
|
||||
} // namespace SituationMap
|
||||
Reference in new issue
Block a user