324 lines
10 KiB
C++
Executable File
324 lines
10 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* GraphicalObjectPath
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
// Own
|
|
#include "graphical_object_multi_path.h"
|
|
#include <Map/situation_map_utils.h> // operator<<
|
|
|
|
|
|
// ESRI
|
|
#include <arcgis/GraphicsOverlay.h>
|
|
#include <arcgis/PolygonBuilder.h>
|
|
#include <arcgis/PolylineBuilder.h>
|
|
#include <arcgis/SimpleLineSymbol.h>
|
|
#include <arcgis/SimpleFillSymbol.h>
|
|
#include <arcgis/GeoView.h>
|
|
#include <arcgis/GeometryEngine.h>
|
|
|
|
|
|
// Qt
|
|
|
|
|
|
namespace SituationMap
|
|
{
|
|
|
|
|
|
GraphicalObjectMultiPath::GraphicalObjectMultiPath(const GraphicalObjectPathType type
|
|
, const Esri::ArcGISRuntime::GeoView *geoView
|
|
, Esri::ArcGISRuntime::GraphicsOverlay *graphicsLayer
|
|
, const QString &debugInfo
|
|
, UniqueMapId uniqueMapId)
|
|
: BaseClass(geoView, graphicsLayer, debugInfo, uniqueMapId)
|
|
, m_pathType(type)
|
|
, m_logger(getLogger("GraphicalObjectMultiPath"))
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"
|
|
<< " m_pathType=" << m_pathType;
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"
|
|
<< " m_pathType=" << m_pathType;
|
|
}
|
|
|
|
GraphicalObjectMultiPath::~GraphicalObjectMultiPath()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"
|
|
<< " m_pathType=" << m_pathType;
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"
|
|
<< " m_pathType=" << m_pathType;
|
|
}
|
|
|
|
PositionCont GraphicalObjectMultiPath::path(int pathIndex) const
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"
|
|
<< " pathIndex=" << pathIndex;
|
|
if (hasPosCont(pathIndex))
|
|
return getPosCont(pathIndex).value();
|
|
return {};
|
|
}
|
|
void GraphicalObjectMultiPath::setPath(int pathIndex, const PositionCont &positions)
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"
|
|
<< " pathIndex=" << pathIndex
|
|
<< " positions=" << positions;
|
|
m_positionsCont[pathIndex] = positions;
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'";
|
|
}
|
|
|
|
void GraphicalObjectMultiPath::clearPath(int pathIndex)
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"
|
|
<< " pathIndex=" << pathIndex;
|
|
if (pathIndex == -1)
|
|
{
|
|
m_positions.refValue().clear();
|
|
m_positionsCont.clear();
|
|
}
|
|
else
|
|
{
|
|
if (hasPosCont(pathIndex))
|
|
{
|
|
// Do not remove the whole entry to let changed() work
|
|
m_positionsCont[pathIndex].refValue().clear();
|
|
}
|
|
}
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'";
|
|
}
|
|
|
|
void GraphicalObjectMultiPath::clearAllPaths()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'";
|
|
m_positions.refValue().clear();
|
|
m_positionsCont.clear();
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'";
|
|
}
|
|
|
|
void GraphicalObjectMultiPath::reduceTo(const QList<int> &remainingPathIndexes)
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"
|
|
<< " remainingPathIndexes=" << remainingPathIndexes;
|
|
QList<int> keys = m_positionsCont.keys();
|
|
for (int key : qAsConst(keys))
|
|
{
|
|
if (!remainingPathIndexes.contains(key))
|
|
{
|
|
// Do not remove the whole entry to let chanded() work
|
|
m_positionsCont[key].refValue().clear();
|
|
}
|
|
}
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'";
|
|
}
|
|
|
|
QList<int> GraphicalObjectMultiPath::pathIndexInUse()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'";
|
|
QList<int> ret;
|
|
///// ret << 0; // pathIndex=0 -> m_positions
|
|
|
|
QMapIterator<int, SimpleValue<PositionCont> > mapIt(m_positionsCont);
|
|
while (mapIt.hasNext())
|
|
{
|
|
mapIt.next();
|
|
const SimpleValue<PositionCont> &posData = mapIt.value();
|
|
const PositionCont &posCont = posData.value();
|
|
if (! posCont.isEmpty())
|
|
ret += mapIt.key();
|
|
} // while
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'";
|
|
return ret;
|
|
}
|
|
|
|
|
|
bool GraphicalObjectMultiPath::create()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'";
|
|
|
|
bool success = BaseClass::create();
|
|
if (!success)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'"
|
|
<< " create failed";
|
|
return false;
|
|
}
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'";
|
|
return success;
|
|
}
|
|
|
|
|
|
bool GraphicalObjectMultiPath::updateViewImpl()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'";
|
|
|
|
bool success = create();
|
|
if (!success)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'"
|
|
<< " create failed";
|
|
return false;
|
|
}
|
|
|
|
success = BaseClass::updateViewImpl();
|
|
if (!success)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'"
|
|
<< " updateView failed";
|
|
return false;
|
|
}
|
|
|
|
success = updatePositions();
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"
|
|
<< " success = " << success
|
|
<< " drawOrder = " << m_graphic->zIndex();
|
|
return success;
|
|
}
|
|
|
|
bool GraphicalObjectMultiPath::updatePositions()
|
|
{
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'";
|
|
|
|
bool success = true;
|
|
|
|
int pathIdxToInsert = 0;
|
|
const int minPoints = this->pathType() == GraphicalObjectPathType::Polyline ? 2 : 3;
|
|
|
|
QSharedPointer<Esri::ArcGISRuntime::MultipartBuilder> builder;
|
|
|
|
// some preparations: ( do no check isMultiPoint / isArea: m_positions should typically be empty!!!
|
|
switch (m_pathType)
|
|
{
|
|
case GraphicalObjectPathType::Polyline:
|
|
builder = QSharedPointer<Esri::ArcGISRuntime::PolylineBuilder>(new Esri::ArcGISRuntime::PolylineBuilder(spatialReference()));
|
|
|
|
break;
|
|
case GraphicalObjectPathType::Polygon:
|
|
builder = QSharedPointer<Esri::ArcGISRuntime::PolygonBuilder>(new Esri::ArcGISRuntime::PolygonBuilder(spatialReference()));
|
|
break;
|
|
} // switch
|
|
|
|
QSharedPointer<Esri::ArcGISRuntime::PartCollection> partCollection =
|
|
QSharedPointer<Esri::ArcGISRuntime::PartCollection>(new Esri::ArcGISRuntime::PartCollection(builder->spatialReference()));
|
|
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"
|
|
<< ", m_positionsCont.size() /#rings=" << m_positionsCont.size();
|
|
|
|
QMutableMapIterator<int, SimpleValue<PositionCont> > mapIt(m_positionsCont);
|
|
//
|
|
// LOOP PER SINGLE POLY
|
|
//
|
|
while (mapIt.hasNext())
|
|
{
|
|
mapIt.next();
|
|
const int key = mapIt.key();
|
|
|
|
const SimpleValue<PositionCont> &posData = mapIt.value();
|
|
const PositionCont &posCont = posData.value();
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"
|
|
<< ", key / #ring=" << key
|
|
<< ", rings.size()=" << posCont.size();
|
|
|
|
// maybe some pathIdx are cleared by clearPath() or similar:
|
|
if (posCont.isEmpty())
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION
|
|
<< " posCont empty, cleared? -> remove/cleanup"
|
|
<< " pathIdxToInsert = " << pathIdxToInsert
|
|
<< " mapIt.key() = " << key;
|
|
mapIt.remove();
|
|
continue;
|
|
}
|
|
|
|
if (posCont.count() < minPoints)
|
|
{
|
|
ERROR_LOG(m_logger) << LOGFUNCTION
|
|
<< " incorrect number of positions"
|
|
<< " (" << posCont.count() << ")"
|
|
<< ", minPoints=" << minPoints
|
|
<< ", pathIdxToInsert = " << pathIdxToInsert
|
|
<< ", mapIt.key() = " << key
|
|
<< ", m_debugInfo = " << m_debugInfo;
|
|
|
|
success = false;
|
|
}
|
|
else
|
|
{
|
|
Esri::ArcGISRuntime::Part part(builder->spatialReference());
|
|
|
|
//
|
|
// LOOP PER POINT
|
|
//
|
|
for (auto pos : qAsConst(posCont))
|
|
{
|
|
part.addPoint(pos.x(), pos.y(), pos.z());
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " START, debugInfo='" << m_debugInfo << "'"
|
|
<< ", key / #ring=" << key
|
|
<< ", addPoint=" << pos;
|
|
|
|
}
|
|
|
|
partCollection->addPart(&part);
|
|
} // if (posCont.count() < minPoints)
|
|
|
|
} // while
|
|
|
|
builder->setParts(partCollection.get());
|
|
|
|
//
|
|
// builder to geometry;
|
|
//
|
|
switch (m_pathType)
|
|
{
|
|
case GraphicalObjectPathType::Polyline:
|
|
{
|
|
const Esri::ArcGISRuntime::Polyline &multipartPolyline =
|
|
static_cast<Esri::ArcGISRuntime::PolylineBuilder *>(builder.data())->toPolyline();
|
|
m_graphic->setGeometry(multipartPolyline);
|
|
assignLineStyleToGraphic();
|
|
}
|
|
break;
|
|
case GraphicalObjectPathType::Polygon:
|
|
{
|
|
const Esri::ArcGISRuntime::Polygon &multipartPolygon =
|
|
static_cast<Esri::ArcGISRuntime::PolygonBuilder *>(builder.data())->toPolygon();
|
|
m_graphic->setGeometry(multipartPolygon);
|
|
//assignLineStyleToGraphic();
|
|
assignFillStyleToGraphic();
|
|
}
|
|
break;
|
|
} // switch
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << m_debugInfo << "'";
|
|
success = addUpdateGraphic();
|
|
|
|
|
|
TRACE_LOG(m_logger) << LOGFUNCTION << " END, debugInfo='" << m_debugInfo << "'"
|
|
<< " success = " << success
|
|
<< " drawOrder = " << m_graphic->zIndex();
|
|
return success;
|
|
}
|
|
|
|
bool GraphicalObjectMultiPath::hasPosCont(int idx) const
|
|
{
|
|
return m_positionsCont.contains(idx);
|
|
}
|
|
|
|
SimpleValue<PositionCont> &GraphicalObjectMultiPath::getPosCont(int idx)
|
|
{
|
|
return m_positionsCont[idx];
|
|
}
|
|
|
|
const SimpleValue<PositionCont> GraphicalObjectMultiPath::getPosCont(int idx) const
|
|
{
|
|
return m_positionsCont[idx];
|
|
}
|
|
|
|
|
|
} // namespace SituationMap
|