Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+14
View File
@@ -0,0 +1,14 @@
#
# $Id$
# $HeadURL$
# $Author$
#
ADD_SUBDIRECTORY(SituationMap)
IF(BUILD_SITMAP_UNIT_TESTS)
# ADD_SUBDIRECTORY(SitMapTestApp)
ADD_SUBDIRECTORY(exampleSvgRenderer)
ADD_SUBDIRECTORY(LineOfSightEvaluation)
ENDIF()
@@ -0,0 +1,392 @@
/*
**
** @RDE_HEADER@
** Shows a crash when using QGraphicsItems and ESRI-Graphics in same scene
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Linux, Qt 5.7. ArcGISRuntimeQt 100
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 16.01.2017, JT : Initial
**
** -----------------------------------------------------------------------------------------------
*/
#include <QtCore/QDir>
#include <QtCore/QUrl>
#include <QtCore/QDebug>
#include <QtGui/QSurface>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/QGraphicsPathItem>
#include <QtWidgets/QMainWindow>
#include <arcgis/Map.h>
#include <arcgis/MapGraphicsView.h>
#include <arcgis/DictionarySymbolStyle.h>
#include <arcgis/Basemap.h>
#include <arcgis/ArcGISTiledLayer.h>
#include <arcgis/Layer.h>
#include <arcgis/GraphicsOverlay.h>
#include <arcgis/MultipointBuilder.h>
#include <arcgis/SimpleMarkerSymbol.h>
#include <arcgis/PolygonBuilder.h>
#include <arcgis/Point.h>
#include <arcgis/SimpleFillSymbol.h>
#include <arcgis/DictionaryRenderer.h>
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* The class MapWindow creates a tiled base map from an UTM based TPK from Bremen. Loading the map will be done
* by clicking the "Load Map" button. When the map is loaded, you can click button "Symbol Failure" to create a
* MIL2525D symbol on map. With the combobox left of this button you can setup the geometry that will be use to
* build the symbol. The symbol with sidc="10012500002713000000" will cause always a crash. Other symbols can
* cause a crash some times if not choosing the fitting geometry.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
class MapWindow : public QWidget
{
Esri::ArcGISRuntime::ArcGISTiledLayer * m_tiledLayer;
Esri::ArcGISRuntime::Basemap * m_basemap;
Esri::ArcGISRuntime::Map * m_map;
Esri::ArcGISRuntime::MapGraphicsView * m_mapView;
QComboBox * m_cbGeometry;
QPushButton * m_pbSymbolFailure;
Esri::ArcGISRuntime::DictionarySymbolStyle * m_dictionarySymbolStyle;
public:
MapWindow() : QWidget(), m_tiledLayer(nullptr), m_dictionarySymbolStyle(nullptr)
{
m_basemap = new Esri::ArcGISRuntime::Basemap(this);
m_map = new Esri::ArcGISRuntime::Map(this);
m_map->setAutoFetchLegendInfos(true);
m_mapView = new Esri::ArcGISRuntime::MapGraphicsView(this);
m_mapView->setObjectName(QLatin1String("EsriMapView"));
m_mapView->setFrameShape(QFrame::NoFrame);
m_mapView->setWrapAroundMode(Esri::ArcGISRuntime::WrapAroundMode::Disabled);
m_mapView->setFixedSize(900,900);
m_cbGeometry = new QComboBox( this );
m_cbGeometry->addItem( "Point" );
m_cbGeometry->addItem( "Linear" );
m_cbGeometry->addItem( "Areal" );
m_cbGeometry->setCurrentIndex(0);
m_cbGeometry->setEditable(false);
QPushButton * pbLoadMap = new QPushButton(QStringLiteral("Load Map"), this);
m_pbSymbolFailure = new QPushButton(QStringLiteral("Symbol Failure"), this);
m_pbSymbolFailure -> setEnabled(false);
connect( pbLoadMap , &QPushButton::clicked, this, [this](bool) { initMap(); });
connect( m_pbSymbolFailure, &QPushButton::clicked, this, [this](bool) { buildDictSymbol(); });
QVBoxLayout * layout = new QVBoxLayout(this);
QHBoxLayout * hLayout = new QHBoxLayout();
hLayout->addStretch(2);
hLayout->addWidget(m_cbGeometry);
hLayout->addSpacing(10);
hLayout->addWidget(m_pbSymbolFailure);
hLayout->addStretch(2);
layout->addWidget(pbLoadMap);
layout->addLayout(hLayout);
layout->addWidget(m_mapView,2);
connect(m_map, &Esri::ArcGISRuntime::Map::doneLoading, this, [this](Esri::ArcGISRuntime::Error loadError)
{
if (!loadError.isEmpty())
{
qCritical() << loadError.message();
qCritical() << loadError.additionalMessage();
Esri::ArcGISRuntime::ErrorDomainType errorDomain = loadError.domain();
Esri::ArcGISRuntime::ExtendedErrorType extendedErr = loadError.extendedErrorType();
Q_UNUSED(errorDomain);
Q_UNUSED(extendedErr);
}
if (Esri::ArcGISRuntime::LoadStatus::Loaded == m_map->loadStatus())
{
if (m_dictionarySymbolStyle && (Esri::ArcGISRuntime::LoadStatus::Loaded == m_dictionarySymbolStyle->loadStatus()))
{
m_pbSymbolFailure->setEnabled(true);
}
}
});
} // MapWindow()
void initMap()
{
#define BremenMap
#ifdef BremenMap
// m_tiledLayer = new Esri::ArcGISRuntime::ArcGISTiledLayer(QUrl("http://192.168.133.90:6080/arcgis/rest/services/BremenGeoTiffUTM/MapServer"));
Esri::ArcGISRuntime::TileCache * tpkCache = new Esri::ArcGISRuntime::TileCache("Topographic.tpk", this);
m_tiledLayer = new Esri::ArcGISRuntime::ArcGISTiledLayer(tpkCache);
#else
Esri::ArcGISRuntime::TileCache * tpkCache = new Esri::ArcGISRuntime::TileCache("/usr/share/arcgis/resources/Topographic.tpk", this);
m_tiledLayer = new Esri::ArcGISRuntime::ArcGISTiledLayer(tpkCache);
#endif
m_basemap->baseLayers()->append(m_tiledLayer);
m_map->setBasemap(m_basemap);
Esri::ArcGISRuntime::GraphicsOverlayListModel * graphicsOverlayListModel = m_mapView->graphicsOverlays();
Esri::ArcGISRuntime::GraphicsOverlay * graphicalOverlay = new Esri::ArcGISRuntime::GraphicsOverlay();
graphicalOverlay->setSelectionColor(Qt::magenta);
graphicsOverlayListModel->append(graphicalOverlay);
m_mapView->setMap(m_map);
loadDictionary();
} // void initMap()
void loadDictionary()
{
#ifdef BremenMap
QString stylxPath = "C:/Program Files (x86)/ArcGIS SDKs/Qt100.0/resources/symbols/mil2525d/mil2525d.stylx"; // warning must be stylx file path
#else // if path is wrong --> crash (only Windows)
QString stylxPath = "/usr/share/arcgis/resources/symbols/mil2525d/mil2525d.stylx";
#endif
m_dictionarySymbolStyle = new Esri::ArcGISRuntime::DictionarySymbolStyle("mil2525d", stylxPath, this);
connect(m_dictionarySymbolStyle, &Esri::ArcGISRuntime::DictionarySymbolStyle::loadStatusChanged, this, [this]( Esri::ArcGISRuntime::LoadStatus loadStatus )
{
if ((Esri::ArcGISRuntime::LoadStatus::Loaded == loadStatus) && (Esri::ArcGISRuntime::LoadStatus::Loaded == m_map->loadStatus()))
{
m_pbSymbolFailure->setEnabled(true);
}
} );
m_dictionarySymbolStyle->load();
} // void loadDictionary()
~MapWindow() = default;
void buildDictSymbol()
{
Esri::ArcGISRuntime::GraphicsOverlay * layer = new Esri::ArcGISRuntime::GraphicsOverlay(this);
Esri::ArcGISRuntime::DictionaryRenderer * dictRenderer = new Esri::ArcGISRuntime::DictionaryRenderer( m_dictionarySymbolStyle, this);
connect( dictRenderer, &Esri::ArcGISRuntime::DictionaryRenderer::errorOccurred, this, [this]( const Esri::ArcGISRuntime::Error & error )
{
qCritical() << "Error loading dictionary: " << error.message() << endl;
} );
//layer->setRenderingMode(Esri::ArcGISRuntime::GraphicsRenderingMode::Static);
layer->setRenderingMode(Esri::ArcGISRuntime::GraphicsRenderingMode::Dynamic);
layer->setRenderer( dictRenderer );
QVariantMap rawAttributes;
rawAttributes["sidc"] = "10012500002713000000"; // --> always crash
// rawAttributes["sidc"] = "10012500001521000000"; // as polygon geometry --> failed to generate sequences for graphics
// or crash if swap coordinate 3 and 4 (see #define CRASH_25152100)
// as multipoint --> ok, with strange behaviour under zoom
// rawAttributes["sidc"] = "10012500003419000000"; // --> failed to generate sequences for graphics
setWindowTitle( "Crash Dictionary Symbol - Symbol Code " + rawAttributes["sidc"].toString() );
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* see mil2525d.pdf, page 600 (25 271300)
* , page 459 (25 152100)
* coordinate sequenze as follows:
*
* (3) ------------------------------------------->(4)
* green orange
*
*
*
* (1) ------------------------------------------->(2)
* red blue
*
* or page 649 (25 341900):
*
* (4)<------------------------------------------- (3)
* orange green
* ^
* |
* |
* (1) ------------------------------------------->(2)
* red blue
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* for Bremen map:
QPointF p1 = QPointF( 493200,5878900 ); // UTM Bremen 493200,5878900
QPointF p2 = QPointF( 495200,5878900 ); // UTM Bremen 495200,5878900
QPointF p3 = QPointF( 493200,5880900 ); // UTM Bremen 493200,5880900
QPointF p4 = QPointF( 495200,5880900 ); // UTM Bremen 495200,5880900
*/
QPointF p1 = QPointF( 0, 0 );
QPointF p2 = QPointF( 3000000, 0 );
QPointF p3 = QPointF( 0, 5890000 );
QPointF p4 = QPointF( 3000000, 5800000 );
// first show coordinate in map
auto drawPictureMarker = [this](const QPointF & p, const QColor & c) -> Esri::ArcGISRuntime::Graphic *
{
Esri::ArcGISRuntime::Graphic * graphic = new Esri::ArcGISRuntime::Graphic();
Esri::ArcGISRuntime::SimpleMarkerSymbol * marker = new Esri::ArcGISRuntime::SimpleMarkerSymbol();
marker->setSize(8);
marker->setStyle( Esri::ArcGISRuntime::SimpleMarkerSymbolStyle::Circle );
marker->setColor(c);
graphic->setGeometry( Esri::ArcGISRuntime::Point( p.x(), p.y(), m_map->spatialReference() ) );
graphic->setSymbol( marker );
return graphic;
}; // drawPictureMarker
if (rawAttributes["sidc"] == "10012500003419000000")
{
// swap coordinate 3 and 4 in case of Relief in Place symbol (25 341900) stay compatible with MIL2525D
QPointF swap = p3; p3 = p4; p4 = swap;
}
#define CRASH_25152100
#ifdef CRASH_25152100
if ((m_cbGeometry->currentIndex() == 2) && (rawAttributes["sidc"] == "10012500001521000000"))
{
// swap coordinate 3 and 4 in case of Suppoprt by Fire Position symbol show crash
QPointF swap = p3; p3 = p4; p4 = swap;
}
#endif
layer->graphics()->append( drawPictureMarker(p1,QColor("red" )) );
layer->graphics()->append( drawPictureMarker(p2,QColor("blue" )) );
layer->graphics()->append( drawPictureMarker(p3,QColor("green" )) );
layer->graphics()->append( drawPictureMarker(p4,QColor("orange")) );
Esri::ArcGISRuntime::Graphic * graphic = new Esri::ArcGISRuntime::Graphic();
switch(m_cbGeometry->currentIndex())
{
case 0:
case 1:
{
qWarning() << " use 4 coordinates - MultipointBuilder";
Esri::ArcGISRuntime::MultipointBuilder pointsBuilder( m_map->spatialReference() );
Esri::ArcGISRuntime::PointCollection points( m_map->spatialReference() );
points.addPoint( p1.x(),p1.y() ); // 1
points.addPoint( p2.x(),p2.y() ); // 2
points.addPoint( p3.x(),p3.y() ); // 3
points.addPoint( p4.x(),p4.y() ); // 4
pointsBuilder.setPoints( &points );
graphic->setGeometry( pointsBuilder.toGeometry() );
} break;
case 2:
{
qWarning() << " use 4 coordinates - PolygonBuilder";
Esri::ArcGISRuntime::PolygonBuilder polygonBuilder( m_map->spatialReference() );
polygonBuilder.addPoint( Esri::ArcGISRuntime::Point(p1.x(),p1.y(),m_map->spatialReference()) ); // 1
polygonBuilder.addPoint( Esri::ArcGISRuntime::Point(p2.x(),p2.y(),m_map->spatialReference()) ); // 2
polygonBuilder.addPoint( Esri::ArcGISRuntime::Point(p3.x(),p3.y(),m_map->spatialReference()) ); // 3
polygonBuilder.addPoint( Esri::ArcGISRuntime::Point(p4.x(),p4.y(),m_map->spatialReference()) ); // 4
graphic->setGeometry( polygonBuilder.toPolygon() );
}
}
qWarning() << " rawAttributes[sidc] = '" << rawAttributes[QLatin1String("sidc")] << "'";
graphic->attributes()->setAttributesMap(rawAttributes);
//add the graphic to the graphics overlay
layer->graphics()->append(graphic);
m_mapView->graphicsOverlays()->append(layer);
qWarning() << " END of buildDictSymbol";
} // void buildDictSymbol()
}; // MapWindow
int main(int argc, char* argv[])
{
QApplication app(argc,argv);
// ESRI :
#ifdef Q_OS_WIN
// Force usage of OpenGL ES through ANGLE on Windows
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#endif
// : ESRI
MapWindow * mapWin = new MapWindow();
QDesktopWidget wid;
int width = mapWin->frameGeometry().width();
int height = mapWin->frameGeometry().height();
int screenWidth = wid.screen()->width();
int screenHeight = wid.screen()->height();
mapWin->setGeometry((screenWidth / 2) - (width / 2), (screenHeight / 2) - (height / 2), width, height);
mapWin->setWindowTitle( "Crash Dictionary Symbol" );
mapWin->show();
app.setQuitOnLastWindowClosed(true);
int retval = app.exec();
delete mapWin;
return retval;
} // main
@@ -0,0 +1,47 @@
#-------------------------------------------------
# Copyright 2015 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.
#-------------------------------------------------
mac {
cache()
}
CONFIG += c++11 esri_runtime_qt100_0_0
QT += core gui opengl xml network positioning sensors
QMAKE_CXXFLAGS += -std=c++0x
# $$(ENVVAR)
# $(ENVVAR)
INCLUDEPATH += /XXX
LIBPATH += /XXX
LIBS += -lEsriCommonQt
LIBS += -lEsriRuntimeQt
LIBS += -lc++
win32:CONFIG += \
embed_manifest_exe
TARGET = CrashDictSymbol
TEMPLATE = app
SOURCES += \
CrashDictSymbol.cpp
HEADERS +=
@@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.4)
SET(QT_MIN_VERSION 5.4.0)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
FILE ( GLOB sourceFiles *.h *.cpp )
FIND_PACKAGE(OpenGL)
FIND_PACKAGE(Qt5 COMPONENTS Core Gui Location OpenGL Positioning Sensors Widgets REQUIRED)
INCLUDE_DIRECTORIES ( ${Qt5Widgets_INCLUDE_DIRS}, "C:/Program Files (x86)/ArcGIS SDKs/Qt10.2.6/sdk/windows/include" )
add_definitions(${Qt5Widgets_DEFINITIONS})
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
ADD_EXECUTABLE( EsriMapTouchTest WIN32 ${sourceFiles} )
TARGET_LINK_LIBRARIES( EsriMapTouchTest Qt5::Core Qt5::Gui Qt5::Location Qt5::OpenGL Qt5::Sensors Qt5::Widgets )
TARGET_LINK_LIBRARIES( EsriMapTouchTest debug "C:/Program Files (x86)/ArcGIS SDKs/Qt10.2.6/sdk/windows/x86/lib/EsriRuntimeQtd.lib" )
TARGET_LINK_LIBRARIES( EsriMapTouchTest optimized "C:/Program Files (x86)/ArcGIS SDKs/Qt10.2.6/sdk/windows/x86/lib/EsriRuntimeQt.lib" )
@@ -0,0 +1,311 @@
/**
**
** @RDE_HEADER@
** Abstract Event Dispatcher for Qt5
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 28.04.2003, JT : First edition for use with Qt4 in START Feature Editor fee
** 25.03.2015, JT : Refactoring for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#include "abstract_event_dispatcher.h"
#include "gestures.h"
#include <assert.h>
#include <math.h>
#include <QtGui/QBitmap>
#include <QtGui/QKeyEvent>
#include <QtGui/QMouseEvent>
#include <QtGui/QWheelEvent>
#include <QtWidgets/QWidget>
#include <QtWidgets/QApplication>
#include <QtCore/QDebug> // for debugging only
namespace SituationMap { namespace RB
{
QGestureRecognizer * AbstractEventDispatcher::_applyGestureDetection = nullptr;
unsigned int AbstractEventDispatcher::_applyGestureID = 0;
AbstractEventDispatcher::AbstractEventDispatcher( QWidget * getEventsFrom )
: QObject(getEventsFrom)
, _getEventsFrom(getEventsFrom)
, _cursorIsInWidget(false)
, _ignoreMouseMoveTimestamp()
, _synthesisTouchFromMouseEvents(false)
, _deleteRequested(false)
, _hasGrab(false)
, _finishFlag(false)
, _activeEvent(false)
, _dispatcherCursor()
, _whatsThisBackup()
, _eventActions(nullptr)
{
initDispatcher();
} /* AbstractEventDispatcher::AbstractEventDispatcher */
AbstractEventDispatcher::AbstractEventDispatcher( QWidget * getEventsFrom, EventActionInterface * eventActions )
: QObject(getEventsFrom)
, _getEventsFrom(getEventsFrom)
, _cursorIsInWidget(false)
, _ignoreMouseMoveTimestamp()
, _synthesisTouchFromMouseEvents(false)
, _deleteRequested(false)
, _hasGrab(false)
, _finishFlag(false)
, _activeEvent(false)
, _dispatcherCursor()
, _whatsThisBackup()
, _eventActions(eventActions)
{
initDispatcher();
} /* AbstractEventDispatcher::AbstractEventDispatcher */
void AbstractEventDispatcher::initDispatcher()
{
_restoreCursor = true;
/* The methode QWidget::ownCursor doesn't exist any more.
* Try to find out if the inherited from parent
*/
// _restoreCursor = getEventsFrom->ownCursor();
if (_restoreCursor)
{
_cursorToRestore = getCursorFromWidget();
}
_restoreMouseTracking = _getEventsFrom->hasMouseTracking();
// just a test exe, but remove process Events
// QCoreApplication::process Events ( ); /// removePostedEvents( _getEventsFrom );
_getEventsFrom->setMouseTracking(true);
_getEventsFrom->raise();
_getEventsFrom->installEventFilter(this);
_synthesisTouchFromMouseEvents = QCoreApplication::testAttribute( Qt::AA_SynthesizeTouchForUnhandledMouseEvents );
QCoreApplication::setAttribute( Qt::AA_SynthesizeTouchForUnhandledMouseEvents, false );
QCoreApplication::setAttribute( Qt::AA_SynthesizeMouseForUnhandledTouchEvents, true );
#ifdef NEVER
static const Qt::GestureType gestures[] = { Qt::GestureType::TapGesture
, Qt::GestureType::TapAndHoldGesture
, Qt::GestureType::PanGesture
, Qt::GestureType::PinchGesture
, Qt::GestureType::SwipeGesture };
for (auto gestureType : gestures) _getEventsFrom->grabGesture(gestureType);
if (_applyGestureDetection == nullptr)
{
_applyGestureDetection = new ApplyGestureRecognizer();
_applyGestureID = QGestureRecognizer::registerRecognizer( _applyGestureDetection );
}
_getEventsFrom->grabGesture( (Qt::GestureType)_applyGestureID );
_getEventsFrom->setAttribute( Qt::WA_AcceptTouchEvents, true );
#endif
} /* AbstractEventDispatcher::initDispatcher */
AbstractEventDispatcher::~AbstractEventDispatcher()
{
_finishFlag = true;
if (_getEventsFrom)
{
_getEventsFrom->removeEventFilter(this);
_getEventsFrom->setMouseTracking( _restoreMouseTracking );
ungrab();
if (!_whatsThisBackup.isNull())
{
_getEventsFrom->setWhatsThis(_whatsThisBackup);
}
}
QCoreApplication::setAttribute( Qt::AA_SynthesizeTouchForUnhandledMouseEvents, _synthesisTouchFromMouseEvents );
} /* AbstractEventDispatcher::~AbstractEventDispatcher */
void AbstractEventDispatcher::onDo_delete()
{
if (_deleteRequested) return;
_deleteRequested = true;
QObject::deleteLater();
} /* AbstractEventDispatcher::onDo_delete */
void AbstractEventDispatcher::KickTheBucket()
{
if (_getEventsFrom == nullptr) return;
_finishFlag = true;
unlinkEventDispatcher();
_getEventsFrom->removeEventFilter(this);
_getEventsFrom->setMouseTracking( _restoreMouseTracking );
ungrab();
if (!_whatsThisBackup.isNull())
{
_getEventsFrom->setWhatsThis(_whatsThisBackup);
}
_getEventsFrom = nullptr;
emit signalKickTheBucket();
QCoreApplication::flush();
// just a test exe, but remove process Events
// QCoreApplication::process Events(); // dispatch window system events
onDo_delete();
} /* AbstractEventDispatcher::KickTheBucket */
void AbstractEventDispatcher::onDo_kickTheBucket() { KickTheBucket(); }
void AbstractEventDispatcher::setWhatsThis(const QString & whatsThis)
{
if (_whatsThisBackup.isNull())
{
_whatsThisBackup = _getEventsFrom->whatsThis();
}
_getEventsFrom->setWhatsThis(whatsThis);
} /* AbstractEventDispatcher::setWhatsThis */
void AbstractEventDispatcher::grab()
{
if (_hasGrab) return;
_hasGrab = true;
setCursorToWidget( _dispatcherCursor );
_getEventsFrom -> setFocus();
} /* AbstractEventDispatcher::Grab */
void AbstractEventDispatcher::ungrab()
{
if (!_hasGrab) return;
_hasGrab = false;
if (_restoreCursor)
{
setCursorToWidget( _cursorToRestore );
}
// else _getEventsFrom -> unsetCursor();
_getEventsFrom -> clearFocus();
} /* AbstractEventDispatcher::Ungrab */
bool AbstractEventDispatcher::eventFilter( QObject * widget, QEvent * e )
{
if (widget != ((QObject*)_getEventsFrom)) return false;
return false;
} /* AbstractEventDispatcher::eventFilter */
void AbstractEventDispatcher::setCursorToWidget( const QCursor & cursor )
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* The cursor handling of QGraphicView are not free of bugs. If it tries to restore the default cursor after setting a special cursor for one item
* it can happend that the restored cursor is not the last cursor that was set with setCursor function because the internal stored restore cursor is
* not updated with setCursor function. As work around a mouse move event is send to the widget to reset cursor handling.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
const QPoint & currentCursorPosition = _getEventsFrom->mapFromGlobal( QCursor::pos() );
#ifdef ShowBug
QMouseEvent && mouseEvent = QMouseEvent( QEvent::Type::MouseMove, QPointF(-1,-1), Qt::MouseButton::NoButton, Qt::MouseButtons(), Qt::KeyboardModifier::NoModifier );
_ignoreMouseMoveTimestamp = mouseEvent.timestamp();
QCoreApplication::sendEvent(_getEventsFrom, &mouseEvent );
QCoreApplication::process Events();
_getEventsFrom -> setCursor( cursor );
if (_cursorIsInWidget)
{
mouseEvent = QMouseEvent( QEvent::Type::MouseMove, currentCursorPosition, Qt::MouseButton::NoButton, Qt::MouseButtons(), Qt::KeyboardModifier::NoModifier );
QCoreApplication::sendEvent(_getEventsFrom, &mouseEvent );
}
QCoreApplication::process Events();
_getEventsFrom -> update();
#else
_getEventsFrom -> setCursor( cursor );
#endif
} /* AbstractEventDispatcher::setCursorToWidget */
QCursor AbstractEventDispatcher::getCursorFromWidget()
{
const QPoint & currentCursorPosition = _getEventsFrom->mapFromGlobal( QCursor::pos() );
#ifdef ShowBug
QMouseEvent && mouseEvent = QMouseEvent( QEvent::Type::MouseMove, QPointF(-1,-1), Qt::MouseButton::NoButton, Qt::MouseButtons(), Qt::KeyboardModifier::NoModifier );
_ignoreMouseMoveTimestamp = mouseEvent.timestamp();
QCoreApplication::sendEvent(_getEventsFrom, &mouseEvent );
QCoreApplication::process Events();
const QCursor & currentCursor = _getEventsFrom->cursor();
if (_cursorIsInWidget)
{
mouseEvent = QMouseEvent( QEvent::Type::MouseMove, currentCursorPosition, Qt::MouseButton::NoButton, Qt::MouseButtons(), Qt::KeyboardModifier::NoModifier );
QCoreApplication::sendEvent(_getEventsFrom, &mouseEvent );
}
QCoreApplication::process Events();
_getEventsFrom -> update();
#else
const QCursor & currentCursor = _getEventsFrom->cursor();
#endif
return currentCursor;
} /* AbstractEventDispatcher::getCursorFromWidget */
} } /* namespace SituationMap::RB */
@@ -0,0 +1,232 @@
/**
**
** @RDE_HEADER@
** Abstract Event Dispatcher for Qt5
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 28.04.2003, JT : First edition for use with Qt4 in START Feature Editor fee
** 25.03.2015, JT : Refactoring for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#pragma once
#include <functional>
#include <QtCore/QObject>
#include <QtCore/QEvent>
#include <QtCore/QList>
#include <QtCore/QString>
#include <QtCore/QTime>
#include <QtGui/QCursor>
class QWidget;
class QWheelEvent;
class QGestureRecognizer;
namespace SituationMap { namespace RB
{
/**
@class AbstractEventDispatcher abstract_event_dispatcher.h
@brief Base class of Qt event filter implementations to handle user interactions of map window
An EventDispatcher installs an event filter on a QWidget to receive all events that are send to
the widget. Depending on the type of event and the state of the event dispatcher the event will
be processed by the dispatcher and stopped or forwarded to the QWidget. In case of processing
the event methodes of the EventActionInterface are called to controll a rubberband.
@see EventDelegater, EventDispatcher, EventMouseNavigator
*/
class AbstractEventDispatcher : public QObject
{
friend class EventDelegater;
Q_OBJECT
public:
/**
@brief Logical interface between EventDispatcher and Rubberband
Defines interface functions the EventDispatcher will call to control a rubberband. The rubberband class
is derived from EventActionInterface and overrides the interface functions to implement them. The mapping
user interaction to interface action is defined the derived classes of AbstractEventDispatcher.
*/
class EventActionInterface
{
public:
EventActionInterface() = default;
virtual ~EventActionInterface() = default;
virtual void unlinkEventDispatcher( AbstractEventDispatcher * causer ) = 0;
virtual bool selectAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool multiSelectAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool setCoordinateAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool moveAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool movePickedAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual void resetAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool contextMenuAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool completeStateAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool deleteAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool undoAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool applyAndEndAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
virtual bool abortAction ( AbstractEventDispatcher * causer, int x, int y ) = 0;
}; /* EventActionInterface */
/**
@name Construction & Destruction
@{
*/
AbstractEventDispatcher( QWidget * getEventsFrom );
AbstractEventDispatcher( QWidget * getEventsFrom, EventActionInterface* );
virtual ~AbstractEventDispatcher();
AbstractEventDispatcher(const AbstractEventDispatcher &) = delete;
AbstractEventDispatcher & operator = (const AbstractEventDispatcher &) = delete;
/** @} */
/**
Conceal deleteLater slot. Use onDo_delete() instead to avoid "QCoreApplication::postEvent: Unexpected null receiver" warning.
*/
void deleteLater() = delete;
inline void setEventActions(EventActionInterface * eventActions) { _eventActions = eventActions; }
inline bool hasGrab() const { return _hasGrab; }
inline void setCursor(const QCursor & cursor) { _dispatcherCursor = cursor; }
void setWhatsThis(const QString & whatsThis);
virtual void grab();
virtual void ungrab();
public slots:
/**
@brief Slot calling internal \c KickTheBucket methode
Calls internal methode \c KickTheBucket. Be careful using this function. Should only be used
from implementations of \c EventActionInterface methodes or \c EventDelegater class.
*/
void onDo_kickTheBucket();
/**
@brief Slot calling \c deleteLater function of QObject
Never use \c delete directly for EventDispatcher class. Instead of use \c onDo_delete() function.
*/
void onDo_delete();
protected:
QWidget * _getEventsFrom;
bool _cursorIsInWidget;
inline bool hasFinished() { return _finishFlag; }
inline bool hasActiveEvent() { return _activeEvent; }
inline void setActiveEvent(bool val) { _activeEvent = val; }
/**
@brief Destroying EventDispatcher as result of an incoming event.
As result of an incomming event (e.g. Keypress ESC) the EventDispatcher will stop, emiting signal \c signalKickTheBucket()
and calls methode \c EventActionInterface::unlinkEventDispatcher() before setup \c deleteLater() call to destroy it self.
*/
virtual void KickTheBucket();
inline void unlinkEventDispatcher()
{
if (_eventActions)
{
_eventActions -> unlinkEventDispatcher( this );
_eventActions = nullptr;
}
} /* unlinkEventDispatcher */
inline bool callEventAction( bool( EventActionInterface::*actionMethodePtr)( AbstractEventDispatcher*,int,int), int x, int y )
{
if (_eventActions == nullptr) return false;
return (_eventActions->*actionMethodePtr)( this, x, y );
} /* callEventAction */
/**
Event filter function to override to implement event handling. To workaround a cursor handling bug in QGraphicsView it is
necessary to call the eventFilter function of this base class, which will monitor enter and leave events.
*/
virtual bool eventFilter( QObject * widget, QEvent * e );
inline EventActionInterface * getEventActions() const { return _eventActions; }
void setCursorToWidget( const QCursor & cursor );
QCursor getCursorFromWidget();
ulong _ignoreMouseMoveTimestamp;
bool _synthesisTouchFromMouseEvents;
static unsigned int _applyGestureID;
private:
void initDispatcher();
bool _deleteRequested;
bool _hasGrab;
bool _finishFlag;
bool _restoreCursor;
bool _restoreMouseTracking;
QCursor _cursorToRestore;
bool _activeEvent;
QCursor _dispatcherCursor;
QString _whatsThisBackup;
EventActionInterface * _eventActions;
static QGestureRecognizer * _applyGestureDetection;
signals:
void signalKickTheBucket();
}; /* EventDispatcher */
} } /* namespace SituationMap::RB */
@@ -0,0 +1,495 @@
/**
**
** @RDE_HEADER@
** Event Dispatcher for Qt5 to delegate mouse and keyboard event to another event dispatcher
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 15.04.2015, JT : First edition
**
** -----------------------------------------------------------------------------------------------
*/
#include "event_mouse_navigator.h"
#include <assert.h>
#include <math.h>
#include <QtGui/QMouseEvent>
#include <QtGui/QWheelEvent>
#include <QtWidgets/QApplication>
#include <QtWidgets/QGesture>
#include <QtWidgets/QGraphicsSceneMouseEvent>
#include <QtWidgets/QWidget>
#include <QtCore/QDebug> // for debugging only
#include <QtCore/QCoreApplication>
#include <Map.h>
#include <Layer.h>
#include <FeatureLayer.h>
#include <GraphicsLayer.h>
#include <MessageGroupLayer.h>
#include <Graphic.h>
namespace SituationMap { namespace RB
{
int EventMouseNavigator::_pickTolerance = 20;
EventMouseNavigator::EventMouseNavigator(QWidget * getEventsFrom, EsriRuntimeQt::Map * esriMap )
: AbstractEventDispatcher(getEventsFrom)
, _esriMap(esriMap)
, _selectionMode()
, _selectedIdList()
, _idConnectionCount(0)
, _mousePanningActive(false)
{
} /* EventMouseNavigator::EventMouseNavigator */
bool EventMouseNavigator::eventFilter(QObject * watched, QEvent * e)
{
Q_UNUSED(watched);
QString debugString(QLatin1String("unhandled event"));
if (hasFinished()) return true; // don't accept new events if dispatcher is going to finish
if (hasActiveEvent()) return true; // don't accept new events before last event has been handled completly
if (e)
{
bool handled( false );
setActiveEvent( true );
switch( e->type() )
{
case QEvent::MouseButtonPress :
{
debugString = QLatin1String("mouse button press event");
QMouseEvent * mouseEvent = static_cast<QMouseEvent*>(e);
_mousePanningActive = false;
_mouseMoveRefPos = mouseEvent->pos();
_restoreMouseCursor = getCursorFromWidget();
if (Qt::LeftButton == mouseEvent->button())
{
handled = false;
if (mouseEvent->modifiers() == Qt::KeyboardModifier::ControlModifier)
{
_selectionMode = SelectionMode::MultiSelection;
setCursorToWidget( QCursor(Qt::CursorShape::PointingHandCursor) );
}
else if (mouseEvent->modifiers().testFlag( Qt::KeyboardModifier::ShiftModifier ))
{
_selectionMode = SelectionMode::FrameSelection;
if (mouseEvent->modifiers().testFlag(Qt::KeyboardModifier::ControlModifier))
{
_selectionMode &= SelectionMode::MultiSelection;
}
else
{
_selectionMode &= SelectionMode::SingleSelection;
}
setCursorToWidget( QCursor(Qt::CursorShape::SizeAllCursor) );
}
else
{
setCursorToWidget( QCursor(Qt::CursorShape::ArrowCursor) );
_selectionMode = SelectionMode::SingleSelection;
}
}
if (Qt::MidButton == mouseEvent->button())
{
handled = (Qt::MidButton == mouseEvent->button());
_mousePanningActive = true;
setCursorToWidget( QCursor(Qt::CursorShape::ClosedHandCursor) );
}
} break;
case QEvent::MouseButtonRelease :
{
debugString = QLatin1String("mouse button release event");
QMouseEvent * mouseEvent = static_cast<QMouseEvent*>(e);
if (Qt::LeftButton == mouseEvent->button())
{
handled = false;
if (!_mousePanningActive)
{
setCursorToWidget( _restoreMouseCursor );
selectionRequested( mouseEvent->pos() );
_selectionMode = SelectionMode::NoSelection;
// do not handled = true; because some buttons in GraphicsView needs to get the event later.
}
}
if (Qt::RightButton == mouseEvent->button())
{
handled = true;
pickRequested( mouseEvent->pos() );
}
if ((_mousePanningActive) || (Qt::MidButton == mouseEvent->button()))
{
handled = (Qt::MidButton == mouseEvent->button());
setCursorToWidget( _restoreMouseCursor );
}
_mousePanningActive = false;
} break;
case QEvent::MouseMove :
{
debugString = QLatin1String("mouse button move event");
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e);
if (mouseEvent->timestamp() != _ignoreMouseMoveTimestamp)
{
if (isSignalConnected(QMetaMethod::fromSignal(&EventMouseNavigator::mouseMovedEvent)))
{
mouseMovedEvent( mouseEvent->pos().x(), mouseEvent->pos().y() );
}
if ((!_mousePanningActive) && mouseEvent->buttons().testFlag(Qt::LeftButton))
{
QPoint deltaMove = mouseEvent->pos()-_mouseMoveRefPos;
if (deltaMove.manhattanLength() > 3)
{
_mousePanningActive = true;
setCursorToWidget( QCursor(Qt::CursorShape::ClosedHandCursor) );
}
}
if ((_mousePanningActive) || mouseEvent->buttons().testFlag(Qt::MidButton))
{
handled = true;
EsriRuntimeQt::AnimationMode mode = _esriMap->animationMode();
QPoint deltaMove = mouseEvent->pos()-_mouseMoveRefPos;
QPoint winCenter = QPoint( _getEventsFrom->width() / 2, _getEventsFrom->height() / 2 );
QPoint newCenter = winCenter-deltaMove;
const EsriRuntimeQt::Point & mapCenter = _esriMap->toMapPoint(newCenter.x(), newCenter.y());
_esriMap -> setAnimationMode( EsriRuntimeQt::AnimationMode::NoAnimation );
_esriMap -> panTo( mapCenter );
_esriMap -> setAnimationMode(mode);
_getEventsFrom -> update();
_mouseMoveRefPos = mouseEvent->pos();
}
}
} break;
case QEvent::Wheel :
{
debugString = QLatin1String("mouse wheel event");
// QWheelEvent * wheelEvent = static_cast<QWheelEvent*>(e);
// handled = true;
handled = false;
} break;
case QEvent::Gesture:
{
QGestureEvent * gestureEvent = static_cast<QGestureEvent*>(e);
if (gestureEvent)
{
const QList<QGesture*> & gestureList = gestureEvent->gestures();
for (auto gesture : gestureList)
{
Qt::GestureType gestureType = gesture->gestureType();
Qt::GestureState gestureState = gesture->state();
QTapGesture * tapGesture = nullptr;
QTapAndHoldGesture * tapAndHoldGesture = nullptr;
QPanGesture * panGesture = nullptr;
QPinchGesture * pinchGesture = nullptr;
QSwipeGesture * swipeGesture = nullptr;
QString typeName;
QString stateName;
switch (gestureType)
{
case Qt::TapGesture : tapGesture = (QTapGesture *)gesture; typeName = QLatin1String("TapGesture"); break;
case Qt::TapAndHoldGesture : tapAndHoldGesture = (QTapAndHoldGesture*)gesture; typeName = QLatin1String("TapAndHoldGesture"); break;
case Qt::PanGesture : panGesture = (QPanGesture *)gesture; typeName = QLatin1String("PanGesture"); break;
case Qt::PinchGesture : pinchGesture = (QPinchGesture *)gesture; typeName = QLatin1String("PinchGesture"); break;
case Qt::SwipeGesture : swipeGesture = (QSwipeGesture *)gesture; typeName = QLatin1String("SwipeGesture"); break;
default: break;
}
switch (gestureState)
{
case Qt::NoGesture : stateName = QLatin1String("NoGesture"); break;
case Qt::GestureStarted : stateName = QLatin1String("GestureStarted"); break;
case Qt::GestureUpdated : stateName = QLatin1String("GestureUpdated"); break;
case Qt::GestureFinished : stateName = QLatin1String("GestureFinished"); break;
case Qt::GestureCanceled : stateName = QLatin1String("GestureCanceled"); break;
}
// tapGesture = nullptr;
panGesture = nullptr;
if (panGesture)
{
EsriRuntimeQt::AnimationMode mode = _esriMap->animationMode();
QPointF deltaMove = panGesture->delta();
QPoint winCenter = QPoint( _getEventsFrom->width() / 2, _getEventsFrom->height() / 2 );
QPoint newCenter = winCenter-QPoint((int)deltaMove.x(),(int)deltaMove.y());
const EsriRuntimeQt::Point & mapCenter = _esriMap->toMapPoint(newCenter.x(), newCenter.y());
_esriMap -> setAnimationMode( EsriRuntimeQt::AnimationMode::NoAnimation );
_esriMap -> panTo( mapCenter );
_esriMap -> setAnimationMode(mode);
_getEventsFrom -> update();
if (gestureState == Qt::GestureStarted) gestureEvent -> setAccepted(panGesture, true);
}
if (pinchGesture)
{
EsriRuntimeQt::AnimationMode mode = _esriMap->animationMode();
QPinchGesture::ChangeFlags changeFlags = pinchGesture->changeFlags();
_esriMap -> setAnimationMode( EsriRuntimeQt::AnimationMode::NoAnimation );
if (changeFlags & QPinchGesture::RotationAngleChanged)
{
qreal deltaPhi = pinchGesture->rotationAngle() - pinchGesture->lastRotationAngle();
_esriMap -> setRotation( _esriMap->rotation()-deltaPhi );
}
if (changeFlags & QPinchGesture::ScaleFactorChanged) _esriMap -> zoom( 1.0/pinchGesture->scaleFactor() );
_esriMap -> setAnimationMode(mode);
_getEventsFrom -> update();
if (gestureState == Qt::GestureStarted) gestureEvent -> setAccepted(pinchGesture, true);
}
}
}
} break;
default: break;
} /* switch */
if (!hasFinished()) setActiveEvent( false );
if (handled) e->accept();
if (handled) return true;
}
return AbstractEventDispatcher::eventFilter(watched,e);
} /* EventMouseNavigator::eventFilter */
void EventMouseNavigator::selectionRequested( const QPoint & pos )
{
const bool appendSelection = _selectionMode.testFlag( SelectionMode::MultiSelection );
if (isSignalConnected( QMetaMethod::fromSignal(&EventMouseNavigator::selectionRequest) ))
{
// do the work only in case of slot connections are installed
if (0 != _idConnectionCount)
{
qWarning() << LOGFUNCTION << " graphic layer id list request is still pending!";
return;
}
pickObjects( pos, _selectedIdList, appendSelection, &EventMouseNavigator::selectionRequest );
}
} /* EventMouseNavigator::selectionRequested */
void EventMouseNavigator::pickRequested( const QPoint & pos )
{
if (isSignalConnected( QMetaMethod::fromSignal(&EventMouseNavigator::contextMenuRequest) ))
{
// do the work only in case of slot connections are installed
if (0 != _idConnectionCount)
{
qWarning() << LOGFUNCTION << " graphic layer id list request is still pending!";
return;
}
pickObjects( pos, _selectedIdList, false, &EventMouseNavigator::contextMenuRequest );
}
} /* EventMouseNavigator::pickRequested */
void EventMouseNavigator::pickObjects( const QPoint & pos
, QList<uint> & pickIdList
, bool append
, void (EventMouseNavigator::*pickSignal)(const QList< uint>&,QPoint) )
{
#ifdef NEVER
if (!append) _selectedIdList.clear();
QList<EsriRuntimeQt::Layer*> layerList = _esriMap->layers();
QList<EsriRuntimeQt::Layer*> selectLayerList;
/* ~~~~~~~~~~~~~~~~~~~ first look for all layers in map ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
for (auto layer : layerList)
{
EsriRuntimeQt::MessageGroupLayer* msgGrpLayer = qobject_cast<EsriRuntimeQt::MessageGroupLayer*>(layer);
if (msgGrpLayer)
{
selectLayerList.append( msgGrpLayer->getLayers() );
}
else selectLayerList.append(layer);
}
/* ~~~~~~~~~~~~~~~~~~~ loop over all layers in layer list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
for (auto layer : selectLayerList)
{
EsriRuntimeQt::FeatureLayer* featureLayer = qobject_cast<EsriRuntimeQt::FeatureLayer*>(layer);
if (featureLayer)
{
/*~~~~~~~~~~~~~~~~~~~~~~~ get selected features by direct function call ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
QList<qint64> fidList = featureLayer -> featureIds( pos.x(), pos.y(), _pickTolerance );
featureLayer->selectFeatures( fidList, append );
EsriRuntimeQt::FeatureTable* featureTable = featureLayer->featureTable();
for (auto featureId : fidList)
{
if (featureTable)
{
EsriRuntimeQt::Feature* feature = featureTable->feature( featureId );
if (feature)
{
bool ok;
SituationMap::UniqueMapId id;
id = feature->property( SituationMap::UniqueMapIdProperty ).toUInt( &ok );
if (ok)
{
if (!pickIdList.contains(id))
{
pickIdList += id;
}
}
}
}
} // for
} // if (featureLayer)
EsriRuntimeQt::GraphicsLayer * graphicsLayer = qobject_cast<EsriRuntimeQt::GraphicsLayer*>(layer);
if (graphicsLayer)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* In case of message symbols, in a graphic layer a slot method has to be used to get
* the ids of selected symbols. The slot installed (connected) each time
* EventMouseNavigator::selectionRequested() has been called and will be disconnect itself at
* beginning of slot function. Because the slot methode will be called later, we have to store
* some information like the _selectedIdList as member variable.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* connect here, because the layer in MessageGroupLayer can change:
* do not use QMetaObject:.Connection directly because disconnect will fail.
* See also http://stackoverflow.com/questions/13847507/qt5-new-signal-to-lambda-connections-memory-leak
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
_idConnectionCount++;
auto conn = std::make_shared<QMetaObject::Connection>();
*conn = connect( graphicsLayer, &EsriRuntimeQt::GraphicsLayer::graphicIdsComplete,
this , [conn,pos,&pickIdList,graphicsLayer,pickSignal,this]( const QList<qint64>& gIdList )
{
disconnect( *conn );
for (auto gId : gIdList)
{
QString objectName(QLatin1String(" - no graphic - "));
EsriRuntimeQt::Graphic * graphic = graphicsLayer->graphic(gId);
if (graphic)
objectName = graphic->objectName();
qDebug() << LOGFUNCTION
<< " gId=" << gId
<< " name= " << objectName;
if (graphic)
{
bool ok;
SituationMap::UniqueMapId id;
id = graphic->property( SituationMap::UniqueMapIdProperty ).toUInt( &ok );
if (ok)
{
if (!pickIdList.contains(id))
{
pickIdList += id;
}
}
}
}
// Just emit selectionRequest only once
if (_idConnectionCount <= 1)
{
(this->*pickSignal)( pickIdList, pos );
_idConnectionCount = 0;
}
else _idConnectionCount--;
} ); // end of lambda methode
graphicsLayer->graphicIds( pos.x(), pos.y(), _pickTolerance, 100 );
}
} // for layer
if (_idConnectionCount == 0)
{
(this->*pickSignal)( pickIdList, pos );
}
#endif
} // EventMouseNavigator::pickObjects
} } /* namespace SituationMap::RB */
@@ -0,0 +1,154 @@
/**
**
** @RDE_HEADER@
** Event Dispatcher for Qt5 to handle mouse events navigate on map
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 24.04.2015, JT : first edition
**
** -----------------------------------------------------------------------------------------------
*/
#pragma once
#include <QtCore/QList>
#include "abstract_event_dispatcher.h"
namespace EsriRuntimeQt
{
class Map;
} /* namespace EsriRuntimeQt */
namespace SituationMap { namespace RB
{
/**
@class EventMouseNavigator event_mouse_navigator.h
@brief Event filter that handles mouse events for general map operation like selecting object, zooming and paning the map window
Implements class \c AbstractEventDispatcher to manage event handling for general map operation like selecting object, zooming and
panning the map window. Monitoring the mouse position can be realized by connecting the \c mouseMovedEvent signal. If the user has
clicked to map objects the signal \c selectionRequest is emitted.
Following events are handled:
| Input-Event | Interface Function | Description |
| :--------------------------------------------- | : ----------------- | : --------------------------------------------------------------------------- |
| Mouse move without any modifier | | Move Cursor. |
| Mouse move with pressed left button | | Panning of map if more then 3 pixels moved. |
| Mouse move with pressed middle button | | Panning of map. |
| Mouse wheel | | Redirect to \c Esri map for zooming. |
| Left mouse button release | | Emits signal \c selectionRequest with list of map objects at cursor position. |
@see AbstractEventDispatcher, EventDelegater, EventDispatcher
*/
class EventMouseNavigator : public AbstractEventDispatcher
{
Q_OBJECT
public:
/**
@name Construction & Destruction
@{
*/
EventMouseNavigator(const EventMouseNavigator &) = delete;
EventMouseNavigator & operator = (const EventMouseNavigator &) = delete;
EventMouseNavigator( QWidget * getEventsFrom, EsriRuntimeQt::Map * esriMap );
virtual ~EventMouseNavigator() {}
/** @} */
inline static void setPickTolerance( int value = 20 ) { _pickTolerance = value; }
signals:
/**
Will be emitted if the user clicks to map objects with the left mouse button.
*/
void selectionRequest( const QList< uint > & idList, QPoint viewPortPos );
/**
Will be emitted if the user clicks to the map with the rigth mouse button.
*/
void contextMenuRequest( const QList< uint > & idList, QPoint viewPortPos );
/**
Signal will be emitted if a mouse move is done.
*/
void mouseMovedEvent( int x, int y );
protected:
virtual bool eventFilter(QObject*, QEvent*);
enum SelectionMode
{
NoSelection = 0x00,
SingleSelection = 0x01,
MultiSelection = 0x02,
FrameSelection = 0x04
}; // SelectionMode
Q_DECLARE_FLAGS(SelectionModes,SelectionMode)
EsriRuntimeQt::Map * _esriMap;
QPoint _mouseMoveRefPos;
QCursor _restoreMouseCursor;
static int _pickTolerance;
SelectionModes _selectionMode;
QList<uint> _selectedIdList; // List of selected object-ids. Is completly handled in selectionRequested()
unsigned int _idConnectionCount; // counter to avoid multiple signals selectionRequest, see implementation of selectionRequested()
bool _mousePanningActive; // is panning with mouse active
/**
Find out which map objects are at given mouse position and emits the signal selectionRequest
*/
void selectionRequested( const QPoint & );
/**
Find out which map objects are at given mouse position and emits the signal contextMenuRequest
*/
void pickRequested( const QPoint & );
/**
Helper function to get all map objets at a given position
@param pos position in window coordinates
@param pickIdList List to store uid's of picked map objects. Don't use a local variable here because the picking is a asynchrone function
@param append If true the uid's are appended at end of list. Otherwise the list will be cleared first.
@param pickSignal Function pointer to signal to be emitted at end.
*/
void pickObjects( const QPoint & pos
, QList<uint> & pickIdList
, bool append
, void (EventMouseNavigator::*pickSignal)(const QList< uint>&,QPoint) );
}; /* EventMouseNavigator */
} } /* namespace SituationMap::RB */
+102
View File
@@ -0,0 +1,102 @@
/**
* @RDE_HEADER@
* Declaration/Definition
* $Id$
* $HeadURL$
* $Author$
*/
#include "gestures.h"
#include <QtCore/QDebug>
#include <QtCore/QEvent>
#include <QtWidgets/QWidget>
namespace SituationMap { namespace RB {
// TabGestureRecognizer
ApplyGestureRecognizer::ApplyGestureRecognizer() : QGestureRecognizer()
{
}
ApplyGestureRecognizer::~ApplyGestureRecognizer()
{}
QGesture * ApplyGestureRecognizer::create( QObject * target )
{
qDebug() << "ApplyGesture create";
if (target && target->isWidgetType())
{
((QWidget*)target)->setAttribute(Qt::WA_AcceptTouchEvents);
}
return new ApplyGesture();
} // TabGestureRecognizer::create
QGestureRecognizer::Result ApplyGestureRecognizer::recognize( QGesture * state, QObject* , QEvent * event)
{
ApplyGesture * q = static_cast<ApplyGesture*>(state);
const QTouchEvent * ev = static_cast<const QTouchEvent*>(event);
QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture;
switch (event->type())
{
case QEvent::TouchBegin:
{
qDebug() << "ApplyGesture begin";
q->_position = ev->touchPoints().at(0).pos();
q->setHotSpot(ev->touchPoints().at(0).screenPos());
q->_tripleTouch = (ev->touchPoints().size() == 3);
result = QGestureRecognizer::TriggerGesture;
} break;
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
{
if (q->state() != Qt::NoGesture && ev->touchPoints().size() >= 1 && ev->touchPoints().size() <= 3)
{
if (ev->touchPoints().size() == 3) q->_tripleTouch = true;
qDebug() << "ApplyGesture update _tripleTouch=" << q->_tripleTouch;
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
QPoint delta = p.pos().toPoint() - p.startPos().toPoint();
enum { TapRadius = 40 };
if (delta.manhattanLength() <= TapRadius)
{
if (event->type() == QEvent::TouchEnd)
{
result = (q->_tripleTouch) ? QGestureRecognizer::FinishGesture : QGestureRecognizer::CancelGesture;
}
else result = QGestureRecognizer::TriggerGesture;
}
}
} break;
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
result = QGestureRecognizer::Ignore;
break;
default:
result = QGestureRecognizer::Ignore;
break;
}
return result;
} // TabGestureRecognizer::recognize( QGesture * state, QObject * watched, QEvent * event)
void ApplyGestureRecognizer::reset( QGesture * state )
{
ApplyGesture * q = static_cast<ApplyGesture*>(state);
q->_tripleTouch = false;
} // TabGestureRecognizer::reset( QGesture * gesture )
}} // namspaces
+71
View File
@@ -0,0 +1,71 @@
/**
**
** @RDE_HEADER@
** Gesture recognition
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 09.12.2015, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#pragma once
#include <QtCore/QObject>
#include <QtWidgets/QGesture>
#include <QtWidgets/QGestureRecognizer>
namespace SituationMap { namespace RB
{
class ApplyGestureRecognizer : public QGestureRecognizer
{
public:
ApplyGestureRecognizer();
virtual ~ApplyGestureRecognizer();
QGesture * create( QObject * target ) override;
QGestureRecognizer::Result recognize( QGesture * gesture, QObject * watched, QEvent * event) override;
void reset( QGesture * gesture ) override;
}; // ApplyGestureRecognizer
class ApplyGesture : public QGesture
{
friend class ApplyGestureRecognizer;
public:
ApplyGesture() = default;
~ApplyGesture() = default;
ApplyGesture( const ApplyGesture & ) = delete;
ApplyGesture & operator = ( const ApplyGesture & ) = delete;
QPointF position() const { return _position; }
private:
QPointF _position;
bool _tripleTouch;
}; // ApplyGesture
}} // namespaces
+83
View File
@@ -0,0 +1,83 @@
/**
* @RDE_HEADER@
* Declaration/Definition
* $Id$
* $HeadURL$
* $Author$
*/
#include <QtWidgets/QApplication>
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/QGraphicsView>
#include <QtWidgets/QGraphicsProxyWidget>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QHBoxLayout>
#include "Map.h"
#include "MapGraphicsView.h"
#include "ArcGISLocalTiledLayer.h"
#include "event_mouse_navigator.h"
int main (int argc, char* argv[])
{
QApplication app ( argc, argv );
// under windows for ArcGIS 10.2.6 and higher
#ifdef Q_OS_WIN
QCoreApplication::setAttribute( Qt::AA_UseOpenGLES );
#endif
QApplication::setApplicationName(QString("Esri - Map Touch Test"));
QWidget top;
QHBoxLayout * layout = new QHBoxLayout( &top );
QTextEdit * console = new QTextEdit( &top );
EsriRuntimeQt::Map * map = new EsriRuntimeQt::Map();
EsriRuntimeQt::MapGraphicsView * mapGraphicsView = EsriRuntimeQt::MapGraphicsView::create(map);
QString samplePath = EsriRuntimeQt::ArcGISRuntime::installDirectory();
samplePath.append("/sdk/samples/data/tpks/Topographic.tpk");
samplePath = QDir::toNativeSeparators(samplePath);
if (!QFileInfo::exists(samplePath))
{
qDebug() << "Load map from not existing file" << samplePath;
}
EsriRuntimeQt::ArcGISLocalTiledLayer * geoMapBaseLayer = new EsriRuntimeQt::ArcGISLocalTiledLayer( samplePath, &top );
geoMapBaseLayer -> setName( "Base Map Layer" );
QObject::connect( geoMapBaseLayer, &EsriRuntimeQt::ArcGISLocalTiledLayer::layerCreateError , []() { qDebug() << "Loading map failed!"; } );
QObject::connect( geoMapBaseLayer, &EsriRuntimeQt::ArcGISLocalTiledLayer::layerCreateComplete, []() { qDebug() << "Loading map finished."; } );
map->setAnimationMode( EsriRuntimeQt::AnimationMode::NoAnimation );
map->addLayer(geoMapBaseLayer);
map->setWrapAroundEnabled(true);
map->grid()->setType( EsriRuntimeQt::GridType::Mgrs );
map->grid()->setVisible(false);
mapGraphicsView -> setFixedSize( 600, 400 );
SituationMap::RB::EventMouseNavigator * eventDispatcher = new SituationMap::RB::EventMouseNavigator( mapGraphicsView->viewport(), map );
layout->addWidget( mapGraphicsView );
layout->addWidget( console );
top.show();
QPushButton * button = new QPushButton( QString("Touch or Click me"), nullptr ); // button must be toplevel widget
QGraphicsProxyWidget * widgetProxy = mapGraphicsView->scene()->addWidget( button );
widgetProxy -> setPos( mapGraphicsView->mapToScene(250,200) );
QObject::connect( button, &QPushButton::clicked, [console]() { console->append(QString("Button has been clicked.\n")); });
QObject::connect( button, &QPushButton::pressed, [console]() { console->append(QString("Button has been pressed.\n")); });
return app.exec();
} // main (int argc, char* argv[])
@@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.4)
SET(QT_MIN_VERSION 5.4.0)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
SET(CMAKE_CXX_STANDARD 11)
FILE ( GLOB sourceFiles *.h *.cpp )
FIND_PACKAGE(OpenGL)
FIND_PACKAGE(Qt5 COMPONENTS Core Gui OpenGL Widgets REQUIRED)
INCLUDE_DIRECTORIES ( ${QT_INCLUDE_DIR} )
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
ADD_EXECUTABLE( GraphicsViewTouchTest WIN32 ${sourceFiles} )
target_link_libraries( GraphicsViewTouchTest Qt5::Core Qt5::Gui Qt5::OpenGL Qt5::Widgets )
@@ -0,0 +1,86 @@
/**
* @RDE_HEADER@
* Declaration/Definition
* $Id$
* $HeadURL$
* $Author$
*/
#include <QtWidgets/QApplication>
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/QGraphicsView>
#include <QtWidgets/QGraphicsProxyWidget>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QHBoxLayout>
class View : public QGraphicsView
{
private:
QPushButton * m_button;
QPushButton * m_reset;
QTextEdit * m_console;
public:
View(QGraphicsScene * scene, QTextEdit * console, QWidget * parent = nullptr) : QGraphicsView(scene, parent), m_console(console)
{
setFixedSize( 600, 400 );
QGraphicsProxyWidget * widgetProxy;
m_reset = new QPushButton( "Reset", nullptr ); // button must be toplevel widget
widgetProxy = scene->addWidget( m_reset );
widgetProxy -> setPos( this->mapToScene(150,100) );
connect(m_reset, &QPushButton::clicked, this, [this]()
{
this->m_console->append("Reset cursor.\n");
this->viewport()->setCursor( Qt::CursorShape::CrossCursor );
});
m_button = new QPushButton( "Touch or Click me \n to change cursor.", nullptr ); // button must be toplevel widget
widgetProxy = scene->addWidget( m_button );
widgetProxy -> setPos( this->mapToScene(250,200) );
connect(m_button, &QPushButton::clicked, this, [this]()
{
this->m_console->append("Button has been clicked --> cursor shape changed to cross cursor.\n");
this->viewport()->setCursor( Qt::CursorShape::CrossCursor );
update();
});
connect(m_button, &QPushButton::pressed, this, [this]()
{
this->m_console->append("Button has been pressed.\n");
});
this->viewport()->setCursor( Qt::CursorShape::PointingHandCursor );
} // View( QGraphicsScene * scene, QWidget * parent = nullptr )
}; // class View
int main (int argc, char* argv[])
{
QApplication app ( argc, argv );
QApplication::setApplicationName("QGraphicsView Touch Test");
QGraphicsScene scene;
QWidget top;
QHBoxLayout * layout = new QHBoxLayout( &top );
QTextEdit * console = new QTextEdit( &top );
View * view = new View( &scene, console, &top );
layout->addWidget( view );
layout->addWidget( console );
top.show();
return app.exec();
} // main (int argc, char* argv[])
@@ -0,0 +1,37 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# EXAMPLE
SET(EXAMPLE_SRCS
lineOfSightEvaluation.cpp
)
SET(EXAMPLE_HDRS
)
IF(MSVC)
# Configure the template file
SET(VS_USER_FILE exampleSvgRenderer.vcxproj.user)
configure_file( ../../SituationMap.vcxproj.user.in ${CMAKE_CURRENT_BINARY_DIR}/${VS_USER_FILE} @ONLY)
ENDIF(MSVC)
NGL_ADD_EXECUTABLE(WS NO_TRANSLATION lineOfSightEvaluation ${EXAMPLE_SRCS} ${EXAMPLE_HDRS})
NGL_TARGET_LINK_LIBRARIES(lineOfSightEvaluation
NGLLogger
nglapplication
Qt5::Widgets
Qt5::Core
Qt5::Svg
Qt5::Gui
ArcGIS::ArcGIS
ArcGISQt5Hack
situationMapCommon
situationMapElevationMap
)
@@ -0,0 +1,330 @@
/**
* @RDE_HEADER@
* Interface
* $Id$
* $HeadURL$
* $Author$
*/
#include <QtWidgets/QApplication>
#include <QMainWindow>
#include <QFileInfo>
#include <QTimer>
#include <QElapsedTimer>
#include <nglapplication/nglapplication.h>
#include <Common/situation_map_logging.h>
#include <ElevationMap/elevation_map.h>
#include <arcgis/GeometryEngine.h>
#include <Map/situation_map_types.h>
using namespace SituationMap;
// some helper functions
inline Q_CONSTEXPR double pi() { return M_PI; }
inline Q_CONSTEXPR double deg2rad() { return pi() / 180.; }
inline Q_CONSTEXPR double rad2deg() { return 1. / deg2rad(); }
//----------------------------------------------------------------------------
/*!
\brief Define visibility.
*/
enum class LineOfSightVisibility
{
Undefined, /*!< May be no data? */
Visible,
Obstructed
};
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
class ObserverTargetData
{
public:
explicit ObserverTargetData(const Point3D &oberserver = Point3D(), // z-value: elevation@terrain + observerHeight
const Point3D &target = Point3D()) // z-value: elevation@terrain + targetHeight
: m_oberserver(oberserver),
m_target(target)
{}
const Point3D &observer() const { return m_oberserver; }
const Point3D &target() const { return m_target; }
const Point3D &obstacle() const { return m_obstacle; }
void setObstacle(const Point3D &obstacle) { m_obstacle = obstacle; }
LineOfSightVisibility lineOfSightVisibility() const { return m_visible; }
void setLineOfSightVisibility(const LineOfSightVisibility &visible)
{
m_visible = visible;
}
bool isObserverAndTargetValid()
{
return (!m_oberserver.isNull()) && (!m_target.isNull());
}
private:
Point3D m_oberserver;
Point3D m_target;
Point3D m_obstacle;
LineOfSightVisibility m_visible = LineOfSightVisibility::Undefined;
};
//----------------------------------------------------------------------------
class LineOfSightCalculation
{
public:
explicit LineOfSightCalculation(ElevationMap *elevationMap)
: m_logger(getLogger("LineOfSightCalculation"))
, m_elevationMap(elevationMap)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool calculate(ObserverTargetData &observerTarget, unsigned int sampleIntervallMeter = 5)
{
// same checks:
if (!m_elevationMap || !m_elevationMap->isValid())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no elevationMap configured or not valid";
observerTarget.setLineOfSightVisibility(LineOfSightVisibility::Undefined);
return false;
}
if (!observerTarget.isObserverAndTargetValid())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " observer and/or target not valid";
observerTarget.setLineOfSightVisibility(LineOfSightVisibility::Undefined);
return false;
}
if (observerTarget.observer().toPointF() == observerTarget.target().toPointF())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " observer and target are identical regard x and y";
observerTarget.setLineOfSightVisibility(LineOfSightVisibility::Undefined);
return false;
}
bool success = true;
QElapsedTimer timer;
if (m_logger.isErrorEnabled())
timer.start();
//
//
// consider using ElevationMap::LOSProfile
//
//
// determine how many iterations we need:
double distanceInMeter = distanceMeter(observerTarget.observer(),
observerTarget.target());
ERROR_LOG(m_logger) << LOGFUNCTION << " distanceMeter = " << distanceInMeter;
int maxNumberOfIterations = distanceInMeter / sampleIntervallMeter; // check visibility every ~5m
// maxNumberOfIterations = 1000000;
if (maxNumberOfIterations<=0)
maxNumberOfIterations = 5;
double distanceFromObserverToTargetAsFraction = 0;
int i = 0;
while (i<=maxNumberOfIterations)
{
/*
z-axis (Elevation) pCandidate
|---------- /
| ----------
| ----------
| ----------
| ----------
|------------------------------------------------------------ xy-axis
^ ^ ^ ^ ^ ^ ^ ^ samples (every ~5meters)
^ ^
ObserverPosition TargetPosition
On every sample position, check if directLineElevation (maximum) is
obstructed by elevationMapElevation (real value)
if (elevationMapElevation>directLineElevation) -> obstructed/break
*/
distanceFromObserverToTargetAsFraction = (double)i/maxNumberOfIterations;
const Point3D &pCandidate = movePoint(observerTarget.observer(),
observerTarget.target(),
distanceFromObserverToTargetAsFraction);
// {
// static Point3D oldCandidate;
// double distanceInMeter = distanceMeter(pCandidate, oldCandidate);
// ERROR_LOG(m_logger) << LOGFUNCTION << " distanceMeter = " << distanceInMeter;
// oldCandidate = pCandidate;
// }
// z is the elevation of a *direct* line:
const double directLineElevation = pCandidate.z();
const double elevationMapElevation = m_elevationMap->elevation(pCandidate.x(), pCandidate.y());
// Coord covered by elevationMap?
if (elevationMapElevation <= std::numeric_limits<int>::min())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " Error, coordinate not covered be elevationData. Finish this LineOfSightCalculation."
<< " i=" << i
<< ", pCandidate = " << pCandidate;
// write back data
observerTarget.setObstacle(pCandidate);
observerTarget.setLineOfSightVisibility(LineOfSightVisibility::Undefined);
// finish the loop:
success = false;
break;
}
// analyze / check visibility:
if (elevationMapElevation>directLineElevation)
{
INFO_LOG(m_logger) << LOGFUNCTION << " i=" << i
<< " break - pCandidate = " << pCandidate
<< " -> directLineElevation = " << directLineElevation
<< " -> elevationMapElevation = " << elevationMapElevation;
// write result
observerTarget.setObstacle(pCandidate);
observerTarget.setLineOfSightVisibility(LineOfSightVisibility::Obstructed);
// finish the loop:
break;
}
++i;
} // while
if (m_logger.isErrorEnabled())
{
ERROR_LOG(m_logger) << LOGFUNCTION << " END"
<< ", success = " << success
<< ", " << i << " of "<< maxNumberOfIterations << " iterations"
<< ", distanceFromObserverToTargetAsFraction = " << distanceFromObserverToTargetAsFraction
<< ", pCandidate=" << observerTarget.obstacle()
<< ", lineOfSightVisibility=" << static_cast<int>(observerTarget.lineOfSightVisibility())
<< ", took [ms] " << timer.elapsed();
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << ", success = " << success;
return success;
}
protected:
static Point3D movePoint(const Point3D &oberserver,
const Point3D &target,
double distanceFromObserverToTargetAsFraction) // 0.0 ... 1.0
{
// positions are lon/lat @ rad.
// for evaluation we do that very simple:
// strange, but: using Point3D seems to be faster then using QPointF
const Point3D &dist = target - oberserver;
const Point3D &point = oberserver + (dist * distanceFromObserverToTargetAsFraction);
// FATAL_LOG(m_logger) << LOGFUNCTION << " obs = " << oberserver;
// FATAL_LOG(m_logger) << LOGFUNCTION << " tgt = " << target;
// FATAL_LOG(m_logger) << LOGFUNCTION << " fct = " << distanceFromObserverToTargetInPercent;
// FATAL_LOG(m_logger) << LOGFUNCTION << " mvd = " << point;
return point;
}
static double distanceMeter(const Point3D &oberserver,
const Point3D &target)
{
Esri::ArcGISRuntime::Point geom1(oberserver.x()*rad2deg(), oberserver.y()*rad2deg(), oberserver.z(), Esri::ArcGISRuntime::SpatialReference::wgs84());
Esri::ArcGISRuntime::Point geom2(target.x() *rad2deg(), target.y() *rad2deg(), target.z() , Esri::ArcGISRuntime::SpatialReference::wgs84());
Esri::ArcGISRuntime::GeometryEngine *gEngine = Esri::ArcGISRuntime::GeometryEngine::instance();
Esri::ArcGISRuntime::GeodeticDistanceResult geodeticDistanceResult = gEngine->distanceGeodetic(geom1, geom2,
Esri::ArcGISRuntime::LinearUnitId::Meters,
Esri::ArcGISRuntime::AngularUnitId::Degrees,
Esri::ArcGISRuntime::GeodeticCurveType::Geodesic);
double distance = geodeticDistanceResult.distance();
return distance;
}
private:
LOGGER_T m_logger; ///< Interface of the Logging-Facility
ElevationMap *m_elevationMap = nullptr;
ObserverTargetData m_observerTarget;
};
#include <ElevationMap/elevation_map.h>
int main (int argc, char* argv[])
{
NGLApplication app ( argc, argv );
app.createLogger("lineOfSightEvaluation", "log4cxx_sitmapMain.props");
LOGGER_T m_logger=app.baseLogger();
STARTUP_LOG(m_logger);
QString elevationFileAbs(QLatin1String("/usr/share/arcgis/resources/elevation/srtm_38_02.tif")); // srtm_38_02.tif -> Bremen
QFileInfo fi (elevationFileAbs);
if (!fi.exists(elevationFileAbs))
{
ERROR_LOG(m_logger) << LOGFUNCTION << ", elevationFile '" << elevationFileAbs << "' doesn't exists";
return -1;
}
ElevationMap *elevationMap = new ElevationMap(fi);
elevationMap->waitForInitialization();
ERROR_LOG(m_logger) << LOGFUNCTION << " elevation.isValid() =" << elevationMap->isValid();
//qCritical() << LOGFUNCTION << " elevation.isValid() = " << elevationMap->isValid()
// << " elevation =" << elevationMap->elevation(0.155, 0.926);
LineOfSightCalculation losCalc(elevationMap);
ObserverTargetData obsTgt(Point3D(0.1504, 0.926, 20),
Point3D(0.1530, 0.926, 5));
losCalc.calculate(obsTgt);
int iRet = app.exec();
delete elevationMap;
SHUTDOWN_LOG(m_logger);
return iRet;
}
@@ -0,0 +1,268 @@
/*
**
** @RDE_HEADER@
** Shows a crash when using QGraphicsItems and ESRI-Graphics in same scene
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.7. ArcGISRuntimeQt 100
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 16.01.2017, JT : Initial
**
** -----------------------------------------------------------------------------------------------
*/
#include <QtCore/QDir>
#include <QtCore/QUrl>
#include <QtCore/QDebug>
#include <QtGui/QPainterPath>
#include <QtGui/QSurface>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/QGraphicsPathItem>
#include <QtWidgets/QMainWindow>
#include <arcgis/Map.h>
#include <arcgis/MapGraphicsView.h>
#include <arcgis/Basemap.h>
#include <arcgis/ArcGISTiledLayer.h>
#include <arcgis/Layer.h>
#include <arcgis/GraphicsOverlay.h>
#include <arcgis/PolygonBuilder.h>
#include <arcgis/Point.h>
#include <arcgis/SimpleFillSymbol.h>
#include <arcgis/DictionaryRenderer.h>
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* The class MapWindow creates a tiled base map from an UTM based TPK from Bremen. Loading the map will be done
* by clicking the "Load Map" button. The next 2 buttons creates graphics on top of the map, as follows:
*
* (1) Draw QGraphicsPathItem
* The "Draw QGraphicsPathItem" is creating an QGraphicsItemPath. The QGraphicsItemPath has a blue border line and
* is filled with a tranparent green color. See drawQGraphicPathItem().
*
* (2) Draw Overlay
* The "Draw Overlay" is creating GraphicsOverlay with one simple polygon. See buildSymbol().
*
* All is working as expected when using only one of each button, restart the program and click the other one.
* Each of both drawings are ok. In one case you will see a red filled polygon and in other case a green polygon
* with a border is drawn on the map.
*
* But now restart the program click "Draw QGraphicsPathItem" the green area with
* a blue border is visible now. After that click "Draw Overlay". The red area of GraphicOverlay polygon appears
* on the map. But the green filling of the QGraphicsItemPath has been vanished.
*
* Restart: Next click the buttons in reversed order ( "Draw Overlay" first and next "Draw QGraphicsPathItem"). On Windows
* the behaviour is the same as before - the green polygon filling is not drawn. On Linux a crash in the OpenGl
* Driver appears.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
class MapWindow : public QWidget
{
Esri::ArcGISRuntime::ArcGISTiledLayer * m_tiledLayer;
Esri::ArcGISRuntime::Basemap * m_basemap;
Esri::ArcGISRuntime::Map * m_map;
Esri::ArcGISRuntime::MapGraphicsView * m_mapView;
private:
public:
MapWindow() : QWidget(), m_tiledLayer(nullptr)
{
m_basemap = new Esri::ArcGISRuntime::Basemap(this);
m_map = new Esri::ArcGISRuntime::Map(this);
m_map->setAutoFetchLegendInfos(true);
m_mapView = new Esri::ArcGISRuntime::MapGraphicsView(this);
m_mapView->setObjectName(QLatin1String("EsriMapView"));
m_mapView->setFrameShape(QFrame::NoFrame);
m_mapView->setWrapAroundMode(Esri::ArcGISRuntime::WrapAroundMode::Disabled);
m_mapView->setFixedSize(900,900);
QPushButton * btn1 = new QPushButton(QStringLiteral("Load Map"), this);
QPushButton * btn2 = new QPushButton(QStringLiteral("Draw QGraphicsPathItem"), this);
QPushButton * btn3 = new QPushButton(QStringLiteral("Draw Overlay (Esri primitive)"), this);
btn2->setEnabled(false);
btn3->setEnabled(false);
connect( btn1, &QPushButton::clicked, this, [this](bool) { initMap(); });
connect( btn2, &QPushButton::clicked, this, [this](bool) { drawQGraphicPathItem(); });
connect( btn3, &QPushButton::clicked, this, [this](bool) { buildSymbol(); });
QVBoxLayout * layout = new QVBoxLayout(this);
layout->addWidget(btn1);
layout->addWidget(btn2);
layout->addWidget(btn3);
layout->addWidget(m_mapView,2);
connect(m_map, &Esri::ArcGISRuntime::Map::doneLoading, this, [this,btn2,btn3](Esri::ArcGISRuntime::Error loadError)
{
if (loadError.isEmpty())
{
btn2->setEnabled(true);
btn3->setEnabled(true);
} else {
qCritical() << loadError.message();
qCritical() << loadError.additionalMessage();
// Esri::ArcGISRuntime::ErrorDomainType errorDomain = loadError.domain();
// Esri::ArcGISRuntime::ExtendedErrorType extendedErr = loadError.extendedErrorType();
}
});
} // MapWindow()
void initMap()
{
//m_tiledLayer = new Esri::ArcGISRuntime::ArcGISTiledLayer(QUrl("http://192.168.133.90:6080/arcgis/rest/services/BremenGeoTiffUTM/MapServer"));
Esri::ArcGISRuntime::TileCache * tpkCache = new Esri::ArcGISRuntime::TileCache("/usr/share/arcgis/resources/Topographic.tpk", this);
m_tiledLayer = new Esri::ArcGISRuntime::ArcGISTiledLayer(tpkCache);
m_basemap->baseLayers()->append(m_tiledLayer);
m_map->setBasemap(m_basemap);
Esri::ArcGISRuntime::GraphicsOverlayListModel * graphicsOverlayListModel = m_mapView->graphicsOverlays();
Esri::ArcGISRuntime::GraphicsOverlay * graphicalOverlay = new Esri::ArcGISRuntime::GraphicsOverlay();
graphicalOverlay->setSelectionColor(Qt::magenta);
graphicsOverlayListModel->append(graphicalOverlay);
m_mapView->setMap(m_map);
} // void initMap()
~MapWindow() = default;
void buildSymbol()
{
Esri::ArcGISRuntime::GraphicsOverlay * layer = new Esri::ArcGISRuntime::GraphicsOverlay(this);
m_mapView->graphicsOverlays()->append(layer);
//layer->setRenderingMode(Esri::ArcGISRuntime::GraphicsRenderingMode::Static);
layer->setRenderingMode(Esri::ArcGISRuntime::GraphicsRenderingMode::Dynamic);
Esri::ArcGISRuntime::PolygonBuilder builder( m_map->spatialReference() );
builder.addPoint( Esri::ArcGISRuntime::Point( 0, 0,m_map->spatialReference()) );
builder.addPoint( Esri::ArcGISRuntime::Point( 0,5878900,m_map->spatialReference()) );
builder.addPoint( Esri::ArcGISRuntime::Point(493200,5880900,m_map->spatialReference()) );
builder.addPoint( Esri::ArcGISRuntime::Point(495200, 0,m_map->spatialReference()) );
Esri::ArcGISRuntime::Graphic * graphic = new Esri::ArcGISRuntime::Graphic(this);
Esri::ArcGISRuntime::SimpleFillSymbol * simpleFillSym = new Esri::ArcGISRuntime::SimpleFillSymbol(this);
simpleFillSym->setColor( QColor("red") );
simpleFillSym->setStyle( Esri::ArcGISRuntime::SimpleFillSymbolStyle::Solid );
graphic->setGeometry( builder.toPolygon() );
graphic->setSymbol(simpleFillSym);
//add the graphic to the graphics overlay
layer->graphics()->append(graphic);
} // void buildSymbol()
void drawQGraphicPathItem()
{
QGraphicsScene * scene = m_mapView->scene();
QGraphicsPathItem * pathItem = scene->addPath( QPainterPath() );
QColor drawColor("darkblue");
QColor fillColor("green");
fillColor.setAlphaF( 0.5 );
pathItem -> setFlags( QGraphicsItem::ItemIgnoresTransformations );
pathItem -> setPen ( QPen(drawColor) );
pathItem -> setBrush ( QBrush(fillColor) );
pathItem -> setZValue( 100 );
QPainterPath painterPath;
painterPath.moveTo(QPointF(200,200));
painterPath.lineTo(QPointF(700,200));
painterPath.lineTo(QPointF(450,700));
painterPath.lineTo(QPointF(200,700));
painterPath.closeSubpath();
pathItem -> setPath( painterPath );
} // void drawQGraphicPathItem()
}; // MapWindow
int main(int argc, char* argv[])
{
QApplication app(argc,argv);
// ESRI :
#ifdef Q_OS_WIN
// Force usage of OpenGL ES through ANGLE on Windows
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#endif
// : ESRI
MapWindow * mapWin = new MapWindow();
QDesktopWidget wid;
int width = mapWin->frameGeometry().width();
int height = mapWin->frameGeometry().height();
int screenWidth = wid.screen()->width();
int screenHeight = wid.screen()->height();
mapWin->setGeometry((screenWidth / 2) - (width / 2), (screenHeight / 2) - (height / 2), width, height);
mapWin->show();
app.setQuitOnLastWindowClosed(true);
int retval = app.exec();
delete mapWin;
return retval;
} // main
@@ -0,0 +1,47 @@
#-------------------------------------------------
# Copyright 2015 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.
#-------------------------------------------------
mac {
cache()
}
CONFIG += c++11 esri_runtime_qt100_0_0
QT += core gui opengl xml network positioning sensors
QMAKE_CXXFLAGS += -std=c++0x
# $$(ENVVAR)
# $(ENVVAR)
INCLUDEPATH += /XXX
LIBPATH += /XXX
LIBS += -lEsriCommonQt
LIBS += -lEsriRuntimeQt
LIBS += -lc++
win32:CONFIG += \
embed_manifest_exe
TARGET = QGraphicsItem_FillBug
TEMPLATE = app
SOURCES += \
QGraphicsItem_FillBug.cpp
HEADERS +=
@@ -0,0 +1,32 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# EXAMPLE
SET(EXAMPLE_SRCS
main.cpp
Viewshed.cpp
)
SET(EXAMPLE_HDRS
Viewshed.h
)
IF(MSVC)
# Configure the template file
SET(VS_USER_FILE rdeexample.vcxproj.user)
configure_file( ../../SituationMap.vcxproj.user.in ${CMAKE_CURRENT_BINARY_DIR}/${VS_USER_FILE} @ONLY)
ENDIF(MSVC)
NGL_ADD_EXECUTABLE(WS rdeexample_viewshed ${EXAMPLE_SRCS} ${EXAMPLE_HDRS})
NGL_TARGET_LINK_LIBRARIES(rdeexample_viewshed
NGLLogger
situationMap
ArcGIS::ArcGIS
)
@@ -0,0 +1,556 @@
/**
* @RDE_HEADER@
* Declaration/Definition
* $Id$
* $HeadURL$
* $Author$
*/
#include "Viewshed.h"
// Qt
#include <QDebug>
#include <QDialog>
#include <QPushButton>
#include <QGridLayout>
#include <QLabel>
#include <QMessageBox>
// Esri
#include <arcgis/ArcGISRuntime.h>
#include <arcgis/MapGraphicsView.h>
#include <arcgis/SimpleMarkerSymbol.h>
#include <arcgis/SimpleFillSymbol.h>
#include <arcgis/UserCredentials.h>
#include <arcgis/ProxySetup.h>
// Uncomment if needed
//#include <Graphic.h>
//#include <SimpleMarkerSymbol.h>
//#include <PictureMarkerSymbol.h>
//#include <Point.h>
//#include <Polyline.h>
//#include <MultiPath.h>
//#define USE_SAMPLE_SERVER
EsriRuntimeQt::SpatialReference sr(102100);
mainwindow::mainwindow(QWidget *parent)
: QMainWindow(parent)
{
m_map = new EsriRuntimeQt::Map(this);
connect(m_map, SIGNAL(mapReady()), this, SLOT(onMapReady()));
m_mapGraphicsView = EsriRuntimeQt::MapGraphicsView::create(m_map, this);
setCentralWidget(m_mapGraphicsView);
m_map->setWrapAroundEnabled(false);
// create and add the tiled layer
EsriRuntimeQt::ArcGISTiledMapServiceLayer* mapServiceLayer =
new EsriRuntimeQt::ArcGISTiledMapServiceLayer(QLatin1String("http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"), this);
m_map->addLayer(mapServiceLayer);
QString path = EsriRuntimeQt::ArcGISRuntime::installDirectory();
path.append(QLatin1String("/sdk/samples/data"));
QDir dataDir(path); // using QDir to convert to correct file separator
QString pathSampleData = dataDir.path() + QDir::separator();
qDebug() << " installDirectory='" << path << "'";
QString tiledBaseMapLayer = pathSampleData + QLatin1String("tpks/Topographic.tpk");
qDebug() << " tiledBaseMapLayer='" << tiledBaseMapLayer << "'";
// m_tiledLayer = new EsriRuntimeQt::ArcGISLocalTiledLayer(tiledBaseMapLayer, this);
// m_tiledLayer->setName( QLatin1String("ArcGISLocalTiledLayer") );
// m_map->addLayer(m_tiledLayer);
// Create Graphics Layer
m_graphicsLayer = new EsriRuntimeQt::GraphicsLayer(this);
m_graphicsLayer -> setName(QLatin1String("GraphicsLayer"));
m_map->addLayer(m_graphicsLayer);
// {
// //
// // Create red circle at maps origin
// //
// EsriRuntimeQt::Point nullPoint(0, 0, m_map->spatialReference());
// EsriRuntimeQt::SimpleMarkerSymbol redCircle(Qt::red, 20, EsriRuntimeQt::SimpleMarkerSymbolStyle::Circle);
// EsriRuntimeQt::Graphic* graphic1 = new EsriRuntimeQt::Graphic( nullPoint, redCircle);
// qint64 gId = m_graphicsLayer->addGraphic(graphic1);
// //
// // Get access to graphic and hide: -> Works fine :-)
// //
// EsriRuntimeQt::Graphic* graphicRetrieved = m_graphicsLayer->graphic(gId);
// if (graphicRetrieved)
// {
// graphicRetrieved->setVisible(false);
// } else {
// qWarning() << LOGFUNCTION << "could NOT retrieve graphic" ;
// }
// }
QString url;
#ifdef USE_SAMPLE_SERVER
url = QLatin1String("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Elevation/ESRI_Elevation_World/GPServer/Viewshed");
#else
url = QLatin1String("http://elevation.arcgis.com/arcgis/rest/services/Tools/Elevation/GPServer/Viewshed");
#endif
qDebug() << LOGFUNCTION << " url='" << url << "'";
// create a Geoprocessor that points to the remote geoprocessing service.
EsriRuntimeQt::UserCredentials *ucEsri = new EsriRuntimeQt::UserCredentials;
ucEsri->setUserAccount("norbert.thoden", "RDEESRI7");
m_geoprocessor = new EsriRuntimeQt::Geoprocessor(url,
ucEsri,
this);
connect(m_geoprocessor,
SIGNAL(gpError(const EsriRuntimeQt::ServiceError&)), this,
SLOT(onGpError(const EsriRuntimeQt::ServiceError&)));
#ifdef USE_SAMPLE_SERVER
connect(m_geoprocessor,
SIGNAL(gpExecuteComplete(const QList<EsriRuntimeQt::GPParameter*>&)), this,
SLOT(onGpExecuteComplete(const QList<EsriRuntimeQt::GPParameter*>&)));
#else
connect(m_geoprocessor,
SIGNAL(gpSubmitJobComplete(const EsriRuntimeQt::GPJobResource&)), this,
SLOT(onGpSubmitJobComplete(const EsriRuntimeQt::GPJobResource&)));
// used:
connect(m_geoprocessor,
SIGNAL(gpJobStatusComplete(const EsriRuntimeQt::GPJobResource&)), this,
SLOT(onGpJobStatusComplete(const EsriRuntimeQt::GPJobResource&)));
// used:
connect(m_geoprocessor,
SIGNAL(gpResultComplete(EsriRuntimeQt::GPParameter*)), this,
SLOT(onGpResultComplete(EsriRuntimeQt::GPParameter*)));
// unused!?
connect(m_geoprocessor,
SIGNAL(gpServiceInfoComplete(EsriRuntimeQt::GPServiceInfo)), this,
SLOT(onGpServiceInfoComplete(EsriRuntimeQt::GPServiceInfo)));
// unused!?
connect(m_geoprocessor,
SIGNAL(gpSubmitJobAndGetResultComplete(const EsriRuntimeQt::GPJobResource&, const QList<EsriRuntimeQt::GPParameter*>&)), this,
SLOT(onGpSubmitJobAndGetResultComplete(const EsriRuntimeQt::GPJobResource&, const QList<EsriRuntimeQt::GPParameter*>&)));
// unused!?
connect(m_geoprocessor,
SIGNAL(statusUpdated(const EsriRuntimeQt::GPJobResource&, const QList<EsriRuntimeQt::GPMessage>&)), this,
SLOT(onStatusUpdated(const EsriRuntimeQt::GPJobResource&, const QList<EsriRuntimeQt::GPMessage>&)));
// unused!?
connect(m_geoprocessor,
SIGNAL(gpTaskInfoComplete(EsriRuntimeQt::GPTaskInfo)), this,
SLOT(onGpTaskInfoComplete(const EsriRuntimeQt::GPTaskInfo&)));
#endif
// connect signals
connect(m_map, SIGNAL(mapReady()), this, SLOT(onMapReady()));
connect(m_map, SIGNAL(mousePressRelease(QMouseEvent&)), this, SLOT(onMousePressRelease(QMouseEvent&)));
// // set up progress bar
// m_progressDialog = new QProgressDialog();
// m_progressDialog->setBaseSize(280, 20);
// m_progressDialog->setRange(0, 0);
// m_progressDialog->setValue(0);
// m_progressDialog->setCancelButton(0);
// connect(m_mapGraphicsView->scene(), SIGNAL(sceneRectChanged(QRectF)), this, SLOT(onResizeProgressBar()));
// m_progressDialog->setLabelText("");
// m_progressDialog->setAttribute(Qt::WA_NoBackground);
// m_progressDialog->setAutoFillBackground(false);
// m_progressDialog->setVisible(false);
// WidgetPanel* widget = new WidgetPanel();
// QLabel* instructionsLabel = new QLabel(
// QString("Click on the map to set the viewshed point. The viewshed will be computed ") +
// QString("from the specified buffer area around the viewshed point. "));
// instructionsLabel->setWordWrap(true);
// QFont font;
// font.setPixelSize(11);
// instructionsLabel->setFont(font);
// instructionsLabel->setMargin(5);
// instructionsLabel->setObjectName("instructions");
// instructionsLabel->setStyleSheet("QLabel#instructions { background: rgba(0,0,0, 192); color: #ddd; }");
// instructionsLabel->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding));
//
// QVBoxLayout* layout = new QVBoxLayout();
// layout->setMargin(0);
//// layout->addWidget(instructionsLabel, Qt::AlignLeft);
// QHBoxLayout* horizontalBox = new QHBoxLayout();
// horizontalBox->setMargin(1);
// QFont font;
// font.setPixelSize(12);
// QLabel* distanceLabel = new QLabel("Viewshed Buffer (miles):");
// distanceLabel->setFixedSize(180, 25);
// distanceLabel->setFont(font);
// distanceLabel->setMargin(5);
// horizontalBox->addWidget(distanceLabel, Qt::AlignRight);
// m_textDistanceLineEdit = new QLineEdit("9");
// m_textDistanceLineEdit->setFixedSize(60, 25);
// m_textDistanceLineEdit->setFont(font);
// horizontalBox->addWidget(m_textDistanceLineEdit, Qt::AlignLeft);
// layout->addLayout(horizontalBox);
//// widget->setFixedSize(210, 105);
//// widget->setLayout(layout);
// QGraphicsProxyWidget *proxy = m_mapGraphicsView->scene()->addWidget(widget);
// proxy->setPos(10, 10);
// proxy->setAcceptedMouseButtons(Qt::LeftButton);
// proxy->setFlag(QGraphicsItem::ItemIsFocusable, true);
// proxy->setFlag(QGraphicsItem::ItemIsSelectable, true);
// proxy->setFlag(QGraphicsItem::ItemAcceptsInputMethod, true);
// proxy->setOpacity(0.85);
// m_proxyProgressBar = m_mapGraphicsView->scene()->addWidget(m_progressDialog);
// m_proxyProgressBar->setAcceptedMouseButtons(Qt::NoButton);
// m_proxyProgressBar->setFlag(QGraphicsItem::ItemIsSelectable, false);
// m_viewShed = new
// SituationMap::ViewshedBase(
// m_geoprocessor->url()
// , *m_graphicsLayer,
// this);
// bool init = m_viewShed->init();
// qDebug() << LOGFUNCTION << " init=" << init;
} /* mainwindow::mainwindow */
mainwindow::~mainwindow()
{
}
void mainwindow::onMapReady()
{
qDebug() << LOGFUNCTION << " ready";
// m_map->setExtent(EsriRuntimeQt::Envelope(-10000, -10000, 10000, 10000, sr));
m_map->setExtent(EsriRuntimeQt::Envelope(-13386516, 4516694, -13236394, 4616827, m_map->spatialReference()));
m_srMap = m_map->spatialReference();
}
void mainwindow::onMousePressRelease(QMouseEvent &event)
{
qDebug() << LOGFUNCTION;
if (event.button() != Qt::LeftButton)
return;
if (m_inProgress)
return;
QPoint scenePosition = event.pos();
// // make sure the mouse didn't move - if so it was a pan so do nothing
// QGraphicsItem * graphicsItem = nullptr;
// graphicsItem = itemFromQGraphicsScene(m_mapGraphicsView->scene(), scenePosition);
// if (graphicsItem)
// return; // Clicked item box
// remove viewshed from previous computation
m_graphicsLayer->removeAll();
int inputValue = 10;
// inputValue = m_textDistanceLineEdit->text().toInt();
if (inputValue > 12 || inputValue < 1)
{
if (m_progressDialog)
m_progressDialog->setVisible(false);
QMessageBox::warning(this, "Invalid Distance", "Please enter an integer from 1 to 12.");
return;
}
// the click point is the viewshed point
EsriRuntimeQt::Point viewshedPoint = m_map->toMapPoint(scenePosition.x(), scenePosition.y());
qDebug() << LOGFUNCTION<< " esriViewshedPoint.x=" << viewshedPoint.x()
<< " ;y=" << viewshedPoint.y()
<< " wkid=" << viewshedPoint.spatialReference().wkid()
<< " m_inProgress=" << m_inProgress
;
// make sure it is a point on the map
if (!EsriRuntimeQt::GeometryEngine::within(viewshedPoint, m_map->extent()))
return;
m_inProgress = true;
if (m_progressDialog)
{
m_progressDialog->setLabelText("Computing the viewshed...");
m_progressDialog->setVisible(true);
}
EsriRuntimeQt::Graphic* viewshedPointGraphic = new EsriRuntimeQt::Graphic(viewshedPoint, EsriRuntimeQt::SimpleMarkerSymbol(QColor("Black"), 14, EsriRuntimeQt::SimpleMarkerSymbolStyle::X));
m_graphicsLayer->addGraphic(viewshedPointGraphic);
// initialize the input parameters. refer to help link in the geoprocessing service URL.
m_geoprocessor->setProcessSR(m_srMap);
m_geoprocessor->setOutSR(m_srMap);
QList<EsriRuntimeQt::GPParameter*> gpInputParams;
#ifdef USE_SAMPLE_SERVER
EsriRuntimeQt::GPFeatureRecordSetLayer* gpInputViewshedPoint =
new EsriRuntimeQt::GPFeatureRecordSetLayer("Input_Observation_Point", this);
#else
EsriRuntimeQt::GPFeatureRecordSetLayer* gpInputViewshedPoint =
new EsriRuntimeQt::GPFeatureRecordSetLayer("InputPoints", this);
#endif
gpInputViewshedPoint->setSpatialReference(m_srMap);
gpInputViewshedPoint->addGraphic(qobject_cast<EsriRuntimeQt::Graphic*>(viewshedPointGraphic->clone(this)));
#ifdef USE_SAMPLE_SERVER
EsriRuntimeQt::GPLinearUnit* gpInputViewshedDistance =
new EsriRuntimeQt::GPLinearUnit("Viewshed_Distance", this);
gpInputViewshedDistance->setUnits("esriMiles");
gpInputViewshedDistance->setDistance(inputValue);
gpInputParams.append(gpInputViewshedPoint);
gpInputParams.append(gpInputViewshedDistance);
#else
EsriRuntimeQt::GPDouble* gpInputMaxDistance =
new EsriRuntimeQt::GPDouble("MaximumDistance", this);
gpInputMaxDistance->setValue(inputValue);
EsriRuntimeQt::GPString* gpInputMaxDistanceUnits =
new EsriRuntimeQt::GPString("MaximumDistanceUnits", this);
gpInputMaxDistanceUnits->setValue(QLatin1String("Miles"));
EsriRuntimeQt::GPDouble* gpInputObserverHeight =
new EsriRuntimeQt::GPDouble("ObserverHeight", this);
gpInputObserverHeight->setValue(3000); // [Meter]
EsriRuntimeQt::GPBoolean* gpInputGeneralize =
new EsriRuntimeQt::GPBoolean("GeneralizeViewshedPolygons", this);
gpInputGeneralize->setValue(false);
gpInputParams.append(gpInputViewshedPoint);
gpInputParams.append(gpInputMaxDistance);
gpInputParams.append(gpInputMaxDistanceUnits);
gpInputParams.append(gpInputObserverHeight);
// gpInputParams.append(gpInputGeneralize);
#endif
// execute the geoprocessing request
// -------------------------------------------------------------------------------------
// Option 1 - execute sync
// Client execution will happen in this thread. It will be blocked on server.
// Client side result collection will happen in this thread. It will be blocked on server.
//
// This is ideal for jobs that take less processing time and whose result size is small.
// This will freeze the UI.
// -------------------------------------------------------------------------------------
/*QList<EsriRuntimeQt::GPParameter*> result = m_geoprocessor->execute(gpInputParams);
processResult(result);*/
// -------------------------------------------------------------------------------------
// Option 2 - execute async
// Client execution will happen in a new thread. It will be blocked on server.
// Client side result collection will happen on that thread. It will be blocked on server.
//
// This is ideal for jobs that take relatively more processing time than option 1
// and whose result size is small.
// -------------------------------------------------------------------------------------
// m_geoprocessor->execute(gpInputParams);
m_geoprocessor->setStatusPollingInterval(10);
#ifdef USE_SAMPLE_SERVER
m_geoprocessor->execute( gpInputParams );
#else
m_geoprocessor->submitJob(gpInputParams);
#endif
}
void mainwindow::onGpExecuteComplete(const QList<EsriRuntimeQt::GPParameter *> &result)
{
qDebug() << LOGFUNCTION << " result.size()=" << result.size();
foreach (EsriRuntimeQt::GPParameter* outputParameter, result)
{
if (!outputParameter)
continue;
EsriRuntimeQt::GPFeatureRecordSetLayer* gpLayer = qobject_cast<EsriRuntimeQt::GPFeatureRecordSetLayer*>(outputParameter);
if (gpLayer)
{
qDebug() << LOGFUNCTION << " gpLayer->graphics().size=" << gpLayer->graphics().size();
// get all the graphics and add them to the graphics layer.
foreach (EsriRuntimeQt::Graphic* resultGraphic, gpLayer->graphics())
{
EsriRuntimeQt::Graphic* theGraphic = new EsriRuntimeQt::Graphic(resultGraphic->geometry(), EsriRuntimeQt::SimpleFillSymbol(QColor(255, 0, 0, 80), EsriRuntimeQt::SimpleFillSymbolStyle::Solid, EsriRuntimeQt::SimpleLineSymbol(QColor("Red"), 0.5)));
// add to the graphics layer
m_graphicsLayer->addGraphic(theGraphic);
}
}
outputParameter->deleteLater();
}
if (m_progressDialog)
m_progressDialog->setVisible(false);
m_inProgress = false;
}
void mainwindow::onGpError(const EsriRuntimeQt::ServiceError &error)
{
if (m_progressDialog)
m_progressDialog->setVisible(false);
qWarning() << LOGFUNCTION << QString("Service Error, code: %1, message: %2, details: %3").arg(QString::number(error.code()), error.message(), error.details());
m_inProgress = false;
}
void mainwindow::onGpSubmitJobComplete(const EsriRuntimeQt::GPJobResource &jobResource)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION << " isEmpty=" << jobResource.isEmpty();
qWarning() << LOGFUNCTION << " jobId='" << jobResource.jobId() << "'";
qWarning() << LOGFUNCTION << " jobStatus='" << (int)jobResource.jobStatus() << "'";
qWarning() << LOGFUNCTION << " inputParameters().size()='" << (int)jobResource.inputParameters().size() << "'";
qWarning() << LOGFUNCTION << " outputParameters().size()='" << (int)jobResource.outputParameters().size() << "'";
qWarning() << LOGFUNCTION << " messages().size()='" << (int)jobResource.messages().size() << "'";
delete m_timer;
m_timer = new QTimer;
connect(m_timer, &QTimer::timeout, [=]() {
qWarning() << " jobStatus() ...";
m_geoprocessor->jobStatus();
} );
qWarning() << "\n starting timer...";
m_timer->start(1000);
}
void mainwindow::onGpJobStatusComplete(const EsriRuntimeQt::GPJobResource &jobResource)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION << " isEmpty=" << jobResource.isEmpty();
qWarning() << LOGFUNCTION << " jobId='" << jobResource.jobId() << "'";
qWarning() << LOGFUNCTION << " jobStatus='" << (int)jobResource.jobStatus() << "'";
qWarning() << LOGFUNCTION << " inputParameters().size()='" << (int)jobResource.inputParameters().size() << "'";
qWarning() << LOGFUNCTION << " outputParameters().size()='" << (int)jobResource.outputParameters().size() << "'";
qWarning() << LOGFUNCTION << " messages().size()='" << (int)jobResource.messages().size() << "'";
if (jobResource.jobStatus() == EsriRuntimeQt::JobStatus::Succeeded)
{
qWarning() << " Succeeded :-)";
if (m_timer)
m_timer->stop();
m_geoprocessor->result(jobResource,
QLatin1String("OutputViewshed"),
true); // GetAsImageResult
}
}
void mainwindow::onGpResultComplete(EsriRuntimeQt::GPParameter *outputParameter)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION << " outputParameter=" << outputParameter;
if (outputParameter)
{
EsriRuntimeQt::GPFeatureRecordSetLayer* gpLayer = qobject_cast<EsriRuntimeQt::GPFeatureRecordSetLayer*>(outputParameter);
if (gpLayer)
{
qDebug() << LOGFUNCTION << " gpLayer->graphics().size=" << gpLayer->graphics().size();
// get all the graphics and add them to the graphics layer.
foreach (EsriRuntimeQt::Graphic* resultGraphic, gpLayer->graphics())
{
EsriRuntimeQt::Graphic* theGraphic =
new EsriRuntimeQt::Graphic(resultGraphic->geometry(),
EsriRuntimeQt::SimpleFillSymbol(QColor(0, 255, 0, 80), EsriRuntimeQt::SimpleFillSymbolStyle::Solid,
EsriRuntimeQt::SimpleLineSymbol(QColor("Red"), 0.5)));
// add to the graphics layer
m_graphicsLayer->addGraphic(theGraphic);
}
}
outputParameter->deleteLater();
}
}
void mainwindow::onGpServiceInfoComplete(EsriRuntimeQt::GPServiceInfo serviceInfo)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION ;
}
void mainwindow::onGpSubmitJobAndGetResultComplete(const EsriRuntimeQt::GPJobResource &, const QList<EsriRuntimeQt::GPParameter *> &results)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION ;
}
void mainwindow::onStatusUpdated(const EsriRuntimeQt::GPJobResource &jobResource, const QList<EsriRuntimeQt::GPMessage> &msgList)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION << " isEmpty=" << jobResource.isEmpty();
qWarning() << LOGFUNCTION << " jobId='" << jobResource.jobId() << "'";
qWarning() << LOGFUNCTION << " jobStatus='" << (int)jobResource.jobStatus() << "'";
qWarning() << LOGFUNCTION << " inputParameters().size()='" << (int)jobResource.inputParameters().size() << "'";
qWarning() << LOGFUNCTION << " outputParameters().size()='" << (int)jobResource.outputParameters().size() << "'";
qWarning() << LOGFUNCTION << " messages().size()='" << (int)jobResource.messages().size() << "'";
qWarning() << LOGFUNCTION << " 2 msgList().size()='" << msgList.size() << "'";
m_geoprocessor->jobStatus();
}
void mainwindow::onGpTaskInfoComplete(const EsriRuntimeQt::GPTaskInfo &)
{
qWarning() << "\n";
qWarning() << LOGFUNCTION ;
}
@@ -0,0 +1,87 @@
/**
* @RDE_HEADER@
* Declaration/Definition
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
namespace EsriRuntimeQt
{
class MapGraphicsView;
}
// Esri
#include <arcgis/Map.h>
//Uncommented layer(s) needed
#include <arcgis/ArcGISTiledMapServiceLayer.h>
#include <arcgis/ArcGISLocalTiledLayer.h>
#include <arcgis/GraphicsLayer.h>
#include <arcgis/Geoprocessor.h>
#include <QProgressDialog>
#include <QLineEdit>
#include <QMainWindow>
//#include <MapImpl/viewshed_base.h>
class mainwindow : public QMainWindow
{
Q_OBJECT
public:
mainwindow (QWidget *parent = 0);
~mainwindow ();
public slots:
void onMapReady();
void onMousePressRelease(QMouseEvent& event);
void onGpExecuteComplete(const QList<EsriRuntimeQt::GPParameter*>& result);
void onGpError(const EsriRuntimeQt::ServiceError& error);
void onGpSubmitJobComplete(const EsriRuntimeQt::GPJobResource& jobResource);
void onGpJobStatusComplete(const EsriRuntimeQt::GPJobResource&);
void onGpResultComplete(EsriRuntimeQt::GPParameter* outputParameter);
void onGpServiceInfoComplete(EsriRuntimeQt::GPServiceInfo serviceInfo);
void onGpSubmitJobAndGetResultComplete(const EsriRuntimeQt::GPJobResource&, const QList<EsriRuntimeQt::GPParameter*>& results);
void onStatusUpdated(const EsriRuntimeQt::GPJobResource& jobResource, const QList<EsriRuntimeQt::GPMessage> &msgList);
void onGpTaskInfoComplete(const EsriRuntimeQt::GPTaskInfo&);
private:
EsriRuntimeQt::Map *m_map = nullptr;
EsriRuntimeQt::MapGraphicsView *m_mapGraphicsView = nullptr;
EsriRuntimeQt::ArcGISTiledMapServiceLayer* m_tiledServiceLayer;
EsriRuntimeQt::ArcGISLocalTiledLayer *m_tiledLayer = nullptr;
EsriRuntimeQt::GraphicsLayer *m_graphicsLayer = nullptr;
EsriRuntimeQt::Geoprocessor *m_geoprocessor = nullptr;
EsriRuntimeQt::SpatialReference m_srMap;
QTimer *m_timer = nullptr;
QProgressDialog *m_progressDialog = nullptr;
QLineEdit *m_textDistanceLineEdit = nullptr;
QGraphicsProxyWidget *m_proxyProgressBar = nullptr;
bool m_inProgress = false;
// SituationMap::ViewshedBase *m_viewShed = nullptr;
private slots:
};
+92
View File
@@ -0,0 +1,92 @@
/**
* @RDE_HEADER@
* Declaration/Definition
* $Id$
* $HeadURL$
* $Author$
*/
#include "Viewshed.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
// Esri
#include <arcgis/ArcGISRuntime.h>
#include <arcgis/ProxySetup.h>
// Qt
#include <QApplication>
#include <QPushButton>
#include <QDialog>
#include <QGridLayout>
int main (int argc, char* argv[])
{
QApplication app ( argc, argv );
#ifdef Q_OS_WIN
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#endif
#define USEPROXY
#ifdef USEPROXY
EsriRuntimeQt::ProxySetup::setupProxy("192.168.133.178" // proxy @ mike
, 8080
, QNetworkProxy::HttpProxy);
#endif
#define DO_LIC
#ifdef DO_LIC
// ESRI-Account:
QLatin1String clientId("8UJNp7vsRWT4l9lc"); // 8UJNp7vsRWT4l9lc -> taken from ESRI-Account
EsriRuntimeQt::ArcGISRuntime::setClientId(clientId);
#define OLD_LICENSE
#ifdef OLD_LICENSE
//alter methode (langer String):
QLatin1String licenseCode("runtimestandard,101,rud077222135,none,FAYRMD1AJ42HXH46C167");
#else
// Neue Methode (kurzer String)
QLatin1String licenseCode("RUD077222135"); // RUD077222135 -> taken from mail "ESRI order 2874794"
#endif
EsriRuntimeQt::LicenseStatus status =
EsriRuntimeQt::ArcGISRuntime::License::setLicense(licenseCode);
qDebug() << LOGFUNCTION
<< " clientId='" << clientId << "'"
<< " licenseCode='" << licenseCode << "'"
<< " LicenseStatus=" << static_cast<int>(status)
<< " (LicenseStatusVALID=" << static_cast<int>(EsriRuntimeQt::LicenseStatus::Valid) << ")"
;
// Use this code to check for licensing errors
if (EsriRuntimeQt::ArcGISRuntime::initialize() == false)
{
// QMessageBox msgBox;
// msgBox.setText(EsriRuntimeQt::ArcGISRuntime::error());
// msgBox.exec();
// app.quit();
return 1;
}
#endif // DO_LIC
// Init the logger
NGL::NGLLoggerBootstrap::createNGLRootLogger("log4cxxSituationMapUnitTest.props", true);
mainwindow applicationWindow;
applicationWindow.setMinimumWidth(800);
applicationWindow.setMinimumHeight(600);
applicationWindow.show();
return app.exec();
}
+69
View File
@@ -0,0 +1,69 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# Situation Map Test Application
SET(EXE_SRCS
main.cpp
mainwindow.cpp
nglsettings.cpp
log4cxx_sitMapTestApp.props
mapsettings.ini
)
SET(EXE_HDRS
mainwindow.h
nglsettings.h
)
SET(EXE_UICS
ui/mainwindow.ui
)
NGL_WRAP_UI(EXE_SRCS ${EXE_UICS})
SET(SETTINGS_FILE mapsettings.ini)
SET(LOG4CXX_PROPS_FILE log4cxx_sitMapTestApp.props)
NGL_ADD_EXECUTABLE(WS NO_TRANSLATION sitMapTestApp ${EXE_SRCS} ${EXE_HDRS} ${EXE_UICS})
NGL_TARGET_LINK_LIBRARIES(
sitMapTestApp
NGLLogger
nglapplication
nglwidgets
nglsettings
situationMap
situationMapObjects
situationMapFunctionDialog
ArcGIS::ArcGIS
LtsCoordTrans
)
IF(TARGET sitMapTestApp)
ADD_CUSTOM_COMMAND( TARGET sitMapTestApp POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${LOG4CXX_PROPS_FILE} $<TARGET_FILE_DIR:sitMapTestApp>/${LOG4CXX_PROPS_FILE}
COMMAND ${CMAKE_COMMAND}
ARGS -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${SETTINGS_FILE} $<TARGET_FILE_DIR:sitMapTestApp>/${SETTINGS_FILE}
)
IF (UNIX)
ADD_CUSTOM_COMMAND( TARGET sitMapTestApp POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${SETTINGS_FILE} $ENV{HOME}/${SETTINGS_FILE}
)
ENDIF()
ENDIF()
IF(MSVC)
# Configure the template file
SET(VS_USER_FILE sitMapTestApp.vcxproj.user)
configure_file( ../../SituationMap.vcxproj.user.in ${CMAKE_CURRENT_BINARY_DIR}/${VS_USER_FILE} @ONLY)
ENDIF(MSVC)
NGL_INSTALL_TARGET_DEVEL(sitMapTestApp)
NGL_INSTALL(FILES WS ${LOG4CXX_PROPS_FILE} DESTINATION "bin" COMPONENT Devel)
NGL_INSTALL(FILES WS ${SETTINGS_FILE} DESTINATION "." COMPONENT Devel)
@@ -0,0 +1,165 @@
log4j.reset=true
log4j.rootLogger=WARN, file
# SituationMapTestApp
###########################################################
log4j.logger.SituationMap.SitMapTestApp=DEBUG
# AdvancedSymbology (AdvSymbology)
###########################################################
log4j.logger.AdvSymbology=FATAL
log4j.logger.AdvSymbology.SymbolDictionary=FATAL
log4j.logger.AdvSymbology.SymbolDictionaryImpl=FATAL
log4j.logger.AdvSymbology.Sidc2525Delta=FATAL
# SituationMap
###########################################################
log4j.logger.SituationMap=FATAL
log4j.logger.SituationMap.MapImpl=FATAL
log4j.logger.SituationMap.MapSettings=FATAL
log4j.logger.SituationMap.MapInitializer=FATAL
log4j.logger.SituationMap.LayerFactoryImpl=FATAL
log4j.logger.SituationMap.LayerControl=INFO
log4j.logger.SituationMap.CoordTranslationFunctorImpl=FATAL
log4j.logger.SituationMap.CoordTranslationThread=FATAL
log4j.logger.SituationMap.PositionsTranslated=FATAL
log4j.logger.SituationMap.GridImpl=FATAL
log4j.logger.SituationMap.ObjectFactory=FATAL
log4j.logger.SituationMap.IdGenerator=FATAL
log4j.logger.SituationMap.ObjectContainer=FATAL
log4j.logger.SituationMap.ObjectContainerCTC=FATAL
log4j.logger.SituationMap.OverlayHandlerImpl=FATAL
log4j.logger.SituationMap.ViewshedImpl=FATAL
log4j.logger.SituationMap.ViewshedBase=FATAL
log4j.logger.SituationMap.AbstractMapObjectImpl=FATAL
log4j.logger.SituationMap.AbstractEffectSimulationImpl=FATAL
log4j.logger.SituationMap.OriginTranslated=FATAL
log4j.logger.SituationMap.PositionsTranslated=FATAL
log4j.logger.SituationMap.AbstractMultiPointMapObjectImpl=FATAL
log4j.logger.SituationMap.AbstractSinglePointMapObjectImpl=FATAL
log4j.logger.SituationMap.BasicPathObjectImpl=FATAL
log4j.logger.SituationMap.IndicationContainer=INFO
log4j.logger.SituationMap.PolygonImpl=FATAL
log4j.logger.SituationMap.PolylineImpl=FATAL
log4j.logger.SituationMap.TextImpl=FATAL
log4j.logger.SituationMap.AreaFireImpl=FATAL
log4j.logger.SituationMap.BiologicalAgentImpl=FATAL
log4j.logger.SituationMap.BuildingOutlineImpl=FATAL
log4j.logger.SituationMap.ChemicalAgentImpl=FATAL
log4j.logger.SituationMap.DangerAreaImpl=FATAL
log4j.logger.SituationMap.FunctionalAreaImpl=FATAL
log4j.logger.SituationMap.HitLineImpl=FATAL
log4j.logger.SituationMap.MapObjectIndicatorImpl=FATAL
log4j.logger.SituationMap.MineImpl=FATAL
log4j.logger.SituationMap.MineFieldImpl=FATAL
log4j.logger.SituationMap.NuclearAgentImpl=FATAL
log4j.logger.SituationMap.ParticipantImpl=FATAL
log4j.logger.SituationMap.SingleFireImpl=FATAL
log4j.logger.SituationMap.AbstractGraphicalObject=FATAL
log4j.logger.SituationMap.GraphicalObjectEllipse=FATAL
log4j.logger.SituationMap.GraphicalObjectPath=FATAL
log4j.logger.SituationMap.GraphicalObjectMultiPath=FATAL
log4j.logger.SituationMap.GraphicalObjectPictureMarker=FATAL
log4j.logger.SituationMap.GraphicalObjectRange=FATAL
log4j.logger.SituationMap.GraphicalObjectText=FATAL
log4j.logger.SituationMap.TacticalAppearance=FATAL
log4j.logger.SituationMap.MessageBase=FATAL
log4j.logger.SituationMap.EventDispatcher=FATAL
log4j.logger.SituationMap.Rubberband=FATAL
log4j.logger.SituationMap.RubberbandRectangle=FATAL
log4j.logger.SituationMap.RubberbandDrawablesAndHandles=FATAL
log4j.logger.SituationMap.RubberbandFrameHandle=FATAL
log4j.logger.SituationMap.RubberbandPointHandle=FATAL
log4j.logger.SituationMap.RubberbandStateSelect=FATAL
# SituationMap-SideBar
###########################################################
log4j.logger.SituationMap.SideBar=FATAL
log4j.logger.SituationMap.SideBarItem=FATAL
log4j.logger.SituationMap.SideBarModel=FATAL
# PlanEditor
###########################################################
log4j.logger.SituationMap.PlanEditor=FATAL
log4j.logger.SituationMap.PlanRenderer=FATAL
# Appnd_File
###########################################################
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=9
log4j.appender.file.file=${LOG4QT_LOGDIR}/${LOG4QT_USER}_SituationMapTestApp.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
# Appnd_Console
###########################################################
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= %d %-5p %c{1} |#| %m (%-.30F:%L) %n
#log4j.appender.stdout.layout.ConversionPattern= %d %-5p %-30c |#| %m (%-.30F:%L) %n
# Appnd_Syslog
###########################################################
log4j.appender.syslog=org.apache.log4j.SyslogAppender
log4j.appender.syslog.Threshold=ERROR
log4j.appender.syslog.SysLogHost=localhost
log4j.appender.syslog.Facility=LOCAL7
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
log4j.appender.syslog.LevelRangeFilter.LevelMin=FATAL
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
###########################################################
###########################################################
###########################################################
# 1) Available Levels in LOG4CXX Version 0.10.0:
# TRACE,
# DEBUG,
# INFO,
# WARN,
# ERROR
# FATAL
#
# d = date/time
# p = priority (Level)
# c = category/channel
# m = message
# F = file
# L = line
# n = platform dependent line separator character or characters.
# ....
#
# Examples for console:
# a)
# %d %p %c #%m# (%.50F:%L)%n
# date/time
# priority
# category/channel
# #message#
# (Maximal 50Character des Filename von rechts:Line)
# line separator
#
# b)
# %d (%.15F:%L) %-5p %c |#| %m%n
# date/time
# (Maximal 15Character des Filename von rechts:Line)
# priority, Right pad with spaces if the priority name is less than 5 characters long.
# category/channel
# message
# line separator
#
+68
View File
@@ -0,0 +1,68 @@
/**
* @RDE_HEADER@
* SquishTest
* $Id$
* $HeadURL$
* $Author$
*/
#include <nglapplication/nglapplication.h>
#include <NGLLogger/INGLLogger.h>
#include "mainwindow.h"
#include <QDesktopWidget>
#include <QMessageBox>
// -------------------------------------------------------------------
int main (int argc, char* argv[])
{
NGLApplication app ( argc, argv );
// under windows for ArcGIS 10.2.6 and higher
#ifdef Q_OS_WIN
QCoreApplication::setAttribute( Qt::AA_UseOpenGLES );
#endif
app.createLogger("sitMapTestApp", "log4cxx_sitMapTestApp.props");
TRACE_LOG(app.baseLogger()) << LOGFUNCTION << " START";
STARTUP_LOG(app.baseLogger());
app.setOrganizationName(QLatin1String("Rheinmetall Defence Electronics"));
app.setApplicationName(QLatin1String("Situation Map Test Application"));
MainWindow *mw = new MainWindow();
/*
QDesktopWidget *desktopWidget = QApplication::desktop();
QRect geom;
// DEBUG_LOG(app.baseLogger()) << LOGFUNCTION << " desktopWidget->screenCount() = " << desktopWidget->screenCount();
if (desktopWidget->screenCount() > 1)
geom = desktopWidget->screenGeometry(1);
else
geom = desktopWidget->screenGeometry();
int width = mw->frameGeometry().width();
int height = mw->frameGeometry().height();
int screenWidth = geom.width();
int screenHeight = geom.height();
int screenWidth = 1024;
int screenHeight = 768;
mw->setGeometry((screenWidth/2)-(width/2),(screenHeight/2)-(height/2),width,height);
*/
mw->setGeometry(0,0,1024,768);
// mw->setWindowState(Qt::WindowMaximized);
mw->show();
app.setQuitOnLastWindowClosed(true);
int retval = app.exec();
delete mw;
SHUTDOWN_LOG(app.baseLogger());
return retval;
}
File diff suppressed because it is too large. Load diff
+201
View File
@@ -0,0 +1,201 @@
/**
* @RDE_HEADER@
*
* MainWindow for DDS View
*
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <Common/ref_pointer.h>
#include <nglwidgets/nglmainwindow.h>
#include <Map/map.h>
#include <Map/grid.h>
#include <MapObjects/building_outline.h>
#include <MapObjects/danger_area.h>
#include <MapObjects/hit_line.h>
#include <MapObjects/area_fire.h>
#include <MapObjects/biological_agent.h>
#include <Rubberbands/rubberband_factory.h>
#include "nglsettings.h"
#include <LtsCoordTrans/lts_coord_trans.h>
namespace Ui {
class widgetMain;
}
class MainWindow : public NGLMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void init();
private:
Ui::widgetMain* m_ui;
// map
SituationMap::Map* m_map = nullptr;
// map settings
float m_scale = 500000.0;
int m_wkid = 32632;
QPointF m_objectBasePoint = QPointF(0, 0);
// QPointF m_objectCenterPoint = QPointF(0, 0);
LtsCoordTrans::UtmCoordinate s_basePoint;
// map objects
// buildings
SituationMap::RefPointer<SituationMap::BuildingOutline> m_building;
QMap<int /*buildingId*/, SituationMap::RefPointer<SituationMap::BuildingOutline> > m_buildingMap;
//danger areas
SituationMap::RefPointer<SituationMap::DangerArea> m_dangerArea;
QMap<int /*dangerAreaId*/, SituationMap::RefPointer<SituationMap::DangerArea> > m_dangerAreaMap;
//fire areas
SituationMap::RefPointer<SituationMap::AreaFire> m_fireArea;
QMap<int /*fireAreaId*/, SituationMap::RefPointer<SituationMap::AreaFire> > m_fireAreaMap;
// B agents
SituationMap::RefPointer<SituationMap::BiologicalAgent> m_bAgent;
QMap<int /*bAgentId*/, SituationMap::RefPointer<SituationMap::BiologicalAgent> > m_bAgentMap;
// Fire line
SituationMap::RefPointer<SituationMap::HitLine> m_hitLine;
QMap<int /*hitLineId*/, SituationMap::RefPointer<SituationMap::HitLine> > m_hitLineMap;
//settings
bool m_visibility = true;
bool m_visibilityTechn = true;
bool m_visibilityTact = true;
void setVersionView();
//timer for update buildings
QTimer* m_timer;
SituationMap::LOGGER_T m_logger;
private slots:
void onClose();
// map
void createMap();
void destroyMap();
void onMapReady();
void onExtentChanged();
void onMapObjectClicked( const SituationMap::Map::RefPointerMapObjectList &mapObjList );
void updateMapObjects();
void clearMapObjects();
// buildings
void createBuildings();
void createBuilding(int objId);
void removeBuildings();
void removeBuilding(int objId);
void onBuildingUpdate(int objId);
void hideBuildings();
void hideBuilding(int objId);
//danger areas
void createDangerAreas();
void createDangerArea(int objId);
void removeDangerAreas();
void removeDangerArea(int objId);
void onDangerAreaUpdate(int objId);
void hideDangerAreas();
void hideDangerArea(int objId);
//fire areas
void createFireAreas();
void createFireArea(int objId);
void removeFireAreas();
void removeFireArea(int objId);
void onFireAreaUpdate(int objId);
void hideFireAreas();
void hideFireArea(int objId);
// b agents
void createBAgents();
void createBAgent(int objId);
void removeBAgents();
void removeBAgent(int objId);
void onBAgentUpdate(int objId);
void hideBAgents();
void hideBAgent(int objId);
// fire lines
void createHitLines();
void createHitLine(int objId);
void removeHitLines();
void removeHitLine(int objId);
void onHitLineUpdate(int objId);
void hideHitLines();
void hideHitLine(int objId);
// rubberbands
void rubberbandPointCluster();
void rubberbandMultiPoint();
void rubberbandRectangle();
void rubberbandSquare();
void rubberbandEllipse();
void rubberbandArrow();
void rubberbandCorridorBoundary();
void rubberbandCorridorCenterline();
void rubberbandFilledMultiPoint();
void rubberbandSmoothLine();
void rubberbandFilledSmoothLine();
void rubberbandCreateRectangle(int objId, int noPoints, bool isSquare);
void rubberbandCreateRectangles();
void rubberbandCreateSquares();
void rubberbandCreateEllipse(int objId, int noPoints);
void rubberbandCreateEllipses();
void rubberbandCreatePointClusters();
void rubberbandCreatePointCluster(int objId, int noPoints);
void rubberbandCreateMultiPoints();
void rubberbandCreateMultiPoint(int objId, int noPoints, bool filled = false);
void rubberbandCreateFilledMultiPoints();
void rubberbandCreateSmoothLines();
void rubberbandCreateSmoothLine(int objId, int noPoints, bool filled = false);
void rubberbandCreateFilledSmoothLines();
void rubberbandCreateCorridorBoundaries();
void rubberbandCreateCorridor(int objId, int noPoints, bool bound = false);
void rubberbandCreateCorridorCenterlines();
void rubberbandCreateArrows();
void rubberbandCreateArrow(int objId, int noPoints);
// void onRubberbandApply( SituationMap::RB::Rubberband * rubberband);
void onRubberbandAbort( SituationMap::RB::RubberbandBase * rubberband);
void onRubberbandPointClusterApply(SituationMap::RB::RubberbandBase *rubberband);
void onRubberbandMultiPointApply( SituationMap::RB::RubberbandBase *rubberband);
void onRubberbandRectangleApply( SituationMap::RB::RubberbandBase *rubberband);
void onRubberbandEllipseApply( SituationMap::RB::RubberbandBase *rubberband);
void onRubberbandSmoothLineApply( SituationMap::RB::RubberbandBase *rubberband);
void onRubberbandArrowApply( SituationMap::RB::RubberbandBase *rubberband);
void onRubberbandCorridorApply(SituationMap::RB::RubberbandBase *rubberband);
void endRubberband( SituationMap::RB::RubberbandBase *rubberband);
};
+241
View File
@@ -0,0 +1,241 @@
# $Id$
# $HeadURL$
# $Author$
[Map]
URL = "http://excgeo21.sl.defence-elec.de/arcgis/rest/services/Bremen/BremenHemelingenAerialGeoAmt_32632/MapServer"
URL1 = "http://excgeo21.sl.defence-elec.de/arcgis/rest/services/Norddeutschland/Norddeutschland_32632/MapServer"
Wkid = 32632
BasePoint = "32UMD000000000000" ;# if CoordTrans in not initialized:
Scale = 50000.00
GridType = "MGRS" ;# GridType: NoType, MGRS, UTM, USGN
GridVisible = false
RotationDegree = 0.0
SymbologyType = "MIL2525D"
FunctionDialogVisible = true
[MapObjects]
TextScale = 1.00
[Building_1]
Identifier = "Building_001"
P1 = "93064,78331"
P2 = "93069.9,78337.8"
P3 = "93076.8,78331.8"
P4 = "93070.9,78325"
P11 = "0.155274,0.925975"
P22 = "0.155275,0.925976"
P33 = "0.155277,0.925975"
P44 = "0.155275,0.925974"
TextColor = "red"
TextSize = 20
TextAngle = 0
TextItalic = true
TextAntiAliased = true
Visibility = true
VisibilityTech = true
VisibilityTact = true
LineColor = "red"
LineWidth = 6
LinePattern = "DashDotDot"
FillColor = "yellow"
FillPattern = "DiagonalCross"
TextAngleUpdate = 30
[Building_2]
Identifier = "Building_002"
P1 = "93049,78363"
P2 = "93071,78344"
P3 = "93062,78333"
P4 = "93041,78352"
P11 = "0.155270,0.925980"
P22 = "0.155275,0.925977"
P33 = "0.155273,0.925975"
P44 = "0.155268,0.925978"
TextColor = "blue"
TextSize = 16
TextAngle = -45
TextItalic = true
TextAntiAliased = true
Visibility = true
VisibilityTech = true
VisibilityTact = true
LineColor = "red"
LineWidth = 6
LinePattern = "DashDotDot"
FillColor = "yellow"
FillPattern = "DiagonalCross"
TextAngleUpdate = 0
[DangerArea_1]
Identifier = "DangerArea_001"
Extent = 10000
Offset_X = 60000
Offset_Y = 90000
Visibility = true
VisibilityTech = true
VisibilityTact = true
LineColor = "red"
LineWidth = 6
LinePattern = "DashDotDot"
FillColor = "yellow"
FillPattern = "DiagonalCross"
[BAgent_1]
Identifier = "BAgent_001"
Extent = 10000
Offset_X = 60000
Offset_Y = 60000
Visibility = true
VisibilityTech = true
VisibilityTact = true
TextColor = "magenta"
TextSize = 16
TextBold = true
LineColor = "cyan"
LineWidth = 6
LinePattern = "DashDotDot"
FillColor = "blue"
FillPattern = "DiagonalCross"
[FireArea_1]
Identifier = "FireArea_001"
Extent = 10000
Offset_X = 110000
Offset_Y = 50000
Visibility = true
VisibilityTech = true
VisibilityTact = true
LineColor = "red"
LineWidth = 6
LinePattern = "Solid"
FillColor = "blue"
FillPattern = "null"
[HitLine_1]
Identifier = "HitLine_001"
Extent = 25000
Offset_X = 120000
Offset_Y = 90000
Visibility = true
VisibilityTech = true
VisibilityTact = true
LineColor = "blue"
LineWidth = 3
LinePattern = "Solid"
[RB_PointCluster_1]
Points = 8
P1 = "97748.9,111304"
P2 = "82617,57261.7"
P3 = "62215.9,78203.2"
P4 = "74510.6,99955.4"
P5 = "91128.7,89011.7"
P6 = "120582,105225"
P7 = "59784,94145.8"
P8 = "104639,70096.8"
[RB_PointCluster_2]
Points = 4
P1 = "79509.5,62260.6"
P2 = "103288,77392.5"
P3 = "88156.4,101171"
P4 = "64377.6,86039.4"
[RB_MultiPoint_1]
P1 = "80185.1,94551.1"
P2 = "59243.5,75636.2"
P3 = "80725.5,61720.2"
P4 = "74510.6,77797.9"
P5 = "95046.8,74960.6"
FillColor = "teal"
MaxLength = 100000
MaxSegmentLength = 50000
[RB_SmoothLine_1]
P1 = "64918,92254.3"
P2 = "75726.6,70637.2"
P3 = "118555,79824.5"
P4 = "93425.5,88336.2"
FillColor = "olive"
[RB_Arrow_1]
P1 = "58973.3,102657"
P2 = "115853,82256.4"
P3 = "85454.2,53613.8"
P4 = "69106.3,92794.7"
[RB_Rectangle_1]
// rectangle
P1 = "48570.1,66689.1"
P2 = "122609,66689.1"
P3 = "122609,103438"
P4 = "48570.1,103438"
HandleMargin = 8
[RB_Rectangle_2]
// rotated square
P1 = "64377.6,81783.5"
P2 = "90588.3,63138.8"
P3 = "109233,89349.5"
P4 = "83022.3,107994"
HandleMargin = 8
[RB_Rectangle_3]
// square
P1 = "84238.3,73339.3"
P2 = "97748.9,73339.3"
P3 = "97748.9,86850"
P4 = "84238.3,86850"
HandleMargin = 8
[RB_Ellipse_1]
P1 = "59648.9,66989.3"
P2 = "127337,66989.3"
P3 = "127337,92254.3"
P4 = "59648.9,92254.3"
HandleMargin = 6
[RB_Corridor_1]
P1 = "54109.5,63746.8"
P2 = "107477,69556.4"
P3 = "76942.5,97118.1"
P4 = "77077.6,97118.1"
P5 = "55730.8,79959.6"
FillColor = "orange"
Width = 8000
MinWidth = 5000
MaxWidth = 10000
MaxLength = 1000000
MaxSegmentLength = 200000
MinPointCount = 3
MaxPointCount = 8
+222
View File
@@ -0,0 +1,222 @@
/**
* @RDE_HEADER@
* Settings for sitMapTestApp
* $Id$
* $HeadURL$
* $Author$
*/
#include "nglsettings.h"
#include <QtCore/QSettings>
#include <QPointF>
#include <nglsettings/nglsettings_settings.h>
#include <NGLLogger/INGLLogger.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
using namespace NGL;
//-----------------------------------------------------------------------------------------
namespace MAP
{
class NGLSettingsClass : public NGL::Settings
{
public:
NGLSettingsClass();
~NGLSettingsClass() {}
};
Q_GLOBAL_STATIC ( NGLSettingsClass, s )
NGLSettingsClass::NGLSettingsClass()
: NGL::Settings(QLatin1String("mapsettings.ini"))
{
}
NGL::Settings *Settings::settings()
{
qDebug("%s", s()->settings()->fileName().toStdString().c_str());
return s();
}
//----------------------------------------
QString Settings::basePoint()
{
return s()->getString(QLatin1String("Map/BasePoint"), QLatin1String("32UMD000000000000"));
}
/*
//-----------------------------------------------------------------------------------------
double Settings::mapBasePointX()
{
return s()->getDouble(QLatin1String("Map/BasePoint_X"), 0.0);
}
//----------------------------------------
QString Settings::centerPointMgrs()
{
return s()->getString(QLatin1String("Map/Center"), QLatin1String("32UMD8000085000"));
}
double Settings::mapCenterPointX()
{
return s()->getDouble(QLatin1String("Map/CenterPoint_X"), 0.0);
}
double Settings::mapCenterPointY()
{
return s()->getDouble(QLatin1String("Map/CenterPoint_Y"), 0.0);
}
double Settings::mapBasePointY()
{
return s()->getDouble(QLatin1String("Map/BasePoint_Y"), 0.0);
}
*/
int Settings::mapWkid()
{
return s()->getInteger(QLatin1String("Map/Wkid"), 32632);
}
double Settings::mapObjectsTextScale()
{
return s()->getDouble(QLatin1String("MapObjects/TextScale"), 1.0);
}
double Settings::mapScale()
{
return s()->getDouble(QLatin1String("Map/Scale"), 100000.0);
}
double Settings::mapRotationDegree()
{
return s()->getDouble(QLatin1String("Map/RotationDegree"), 0.0);
}
/*
int Settings::XMin()
{
return s()->getInteger(QLatin1String("Map/XMin"), 0);
}
int Settings::YMin()
{
return s()->getInteger(QLatin1String("Map/YMin"), 0);
}
int Settings::XMax()
{
return s()->getInteger(QLatin1String("Map/XMax"), 0);
}
int Settings::YMax()
{
return s()->getInteger(QLatin1String("Map/YMax"), 0);
}
*/
bool Settings::mapGridVisible()
{
return s()->getBoolean(QLatin1String("Map/GridVisible"), false);
}
bool Settings::mapFunctionDialogVisible()
{
return s()->getBoolean(QLatin1String("Map/FunctionDialogVisible"), false);
}
QString Settings::mapSymbologyType()
{
return s()->getString(QLatin1String("Map/SymbologyType"), QLatin1String("APP6B") );
}
QString Settings::mapGridType()
{
return s()->getString(QLatin1String("Map/GridType"), QLatin1String("MGRS") );
}
QString Settings::mapURL()
{
return s()->getString(QLatin1String("Map/URL"), QString() );
}
// conversion functions
//-------------------------------------------------------------------------------------
SituationMap::LinePattern Settings::getLinePattern(const QString &pattern)
{
SituationMap::LinePattern linePattern = SituationMap::LinePattern::Null;
if (pattern.compare(QLatin1String("Dash")) == 0)
linePattern = SituationMap::LinePattern::Dash;
if (pattern.compare(QLatin1String("DashDot")) == 0)
linePattern = SituationMap::LinePattern::DashDot;
if (pattern.compare(QLatin1String("DashDotDot")) == 0)
linePattern = SituationMap::LinePattern::DashDotDot;
if (pattern.compare(QLatin1String("Dot")) == 0)
linePattern = SituationMap::LinePattern::Dot;
if (pattern.compare(QLatin1String("Solid")) == 0)
linePattern = SituationMap::LinePattern::Solid;
return linePattern;
}
SituationMap::FillPattern Settings::getFillPattern(const QString &pattern)
{
SituationMap::FillPattern fillPattern = SituationMap::FillPattern::Null;
if (pattern.compare(QLatin1String("BackwardDiagonal")) == 0)
fillPattern = SituationMap::FillPattern::BackwardDiagonal;
if (pattern.compare(QLatin1String("Cross")) == 0)
fillPattern = SituationMap::FillPattern::Cross;
if (pattern.compare(QLatin1String("DiagonalCross")) == 0)
fillPattern = SituationMap::FillPattern::DiagonalCross;
if (pattern.compare(QLatin1String("ForwardDiagonal")) == 0)
fillPattern = SituationMap::FillPattern::ForwardDiagonal;
if (pattern.compare(QLatin1String("Solid")) == 0)
fillPattern = SituationMap::FillPattern::Solid;
if (pattern.compare(QLatin1String("Horizontal")) == 0)
fillPattern = SituationMap::FillPattern::Horizontal;
if (pattern.compare(QLatin1String("Vertical")) == 0)
fillPattern = SituationMap::FillPattern::Vertical;
return fillPattern;
}
SituationMap::GridType Settings::getGridType(const QString &pattern)
{
SituationMap::GridType gridType = SituationMap::GridType::MGRS;
if (pattern.compare(QLatin1String("MGRS")) == 0)
gridType = SituationMap::GridType::MGRS;
if (pattern.compare(QLatin1String("UTM")) == 0)
gridType = SituationMap::GridType::UTM;
if (pattern.compare(QLatin1String("USGN")) == 0)
gridType = SituationMap::GridType::USGN;
return gridType;
}
//map objects general functions
//-----------------------------------------------------------------------------------------
QString Settings::objectIdentifier(const QString &prefix, int id)
{
return s()->getString(prefix+QLatin1String("_")+QString::number(id)+QLatin1String("/Identifier"), prefix+QLatin1String("_")+QString::number(id));
}
bool Settings::getObjectBoolAttribute(const QString &prefix, const QString &postfix, int objId, bool defaultValue)
{
return s()->getBoolean(prefix+QLatin1String("_")+QString::number(objId)+QLatin1String("/")+postfix, defaultValue);
}
int Settings::getObjectIntAttribute(const QString &prefix, const QString &postfix, int objId, int defaultValue)
{
return s()->getInteger(prefix+QLatin1String("_")+QString::number(objId)+QLatin1String("/")+postfix, defaultValue);
}
QString Settings::getObjectStringAttribute(const QString &prefix, const QString &postfix, int objId, const QString &defaultValue)
{
return s()->getString(prefix+QLatin1String("_")+QString::number(objId)+QLatin1String("/")+postfix, defaultValue);
}
QPointF Settings::getPoint(const QString &prefix, int objId, int nr )
{
QString strPoint = s()->getString(prefix+QLatin1String("_")+QString::number(objId)+QLatin1String("/P")+QString::number(nr), QLatin1String("0,0"));
double point_x, point_y;
QStringList list = strPoint.split(QLatin1Char(','));
point_x = list[0].toDouble();
point_y = list[1].toDouble();
return QPointF(point_x,point_y);
}
} //namespace
+63
View File
@@ -0,0 +1,63 @@
/**
* @RDE_HEADER@
* Settings for sitMapTestApp
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QString>
#include <nglsettings/nglsettings_settings.h>
#include <Map/text_style.h>
#include <Map/grid.h>
namespace NGL {
class Settings;
}
namespace MAP
{
namespace Settings
{
// read map settings
double mapBasePointX();
double mapBasePointY();
double mapCenterPointX();
double mapCenterPointY();
int mapWkid();
double mapObjectsTextScale();
double mapScale();
bool mapGridVisible();
bool mapFunctionDialogVisible();
QString mapGridType();
double mapRotationDegree();
QString mapSymbologyType();
QString mapURL();
QString centerPointMgrs() ;
QString basePoint();
int XMin();
int YMin();
int XMax();
int YMax();
// general functions for map objects
QString objectIdentifier(const QString &prefix, int id);
bool getObjectBoolAttribute(const QString &prefix, const QString &postfix, int objId, bool defaultValue = false);
int getObjectIntAttribute(const QString &prefix, const QString &postfix, int objId, int defaultValue = 0);
QString getObjectStringAttribute(const QString &prefix, const QString &postfix, int objId, const QString &defaultValue = QString());
QPointF getPoint(const QString &prefix, int objId, int nr );
// conversion functions from strings
SituationMap::LinePattern getLinePattern(const QString &pattern);
SituationMap::FillPattern getFillPattern(const QString &pattern);
SituationMap::GridType getGridType(const QString &pattern);
//!< The real NGL::Settings - object
NGL::Settings *settings();
}
};
@@ -0,0 +1,594 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>widgetMain</class>
<widget class="QMainWindow" name="widgetMain">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>641</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
</property>
<property name="windowTitle">
<string comment="Window title">Situation Map Test Application</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>:/Rde/RdeIcon</normaloff>:/Rde/RdeIcon</iconset>
</property>
<property name="toolTip">
<string>Situation Map Test Application</string>
</property>
<property name="iconSize">
<size>
<width>14</width>
<height>14</height>
</size>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>19</height>
</rect>
</property>
<widget class="QMenu" name="menuMap">
<property name="title">
<string comment="Desktop menu title">&amp;Map</string>
</property>
<addaction name="actionLoadMap"/>
<addaction name="actionRemoveMap"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
<widget class="QMenu" name="menuMap_Objects">
<property name="title">
<string>Map &amp;Objects</string>
</property>
<widget class="QMenu" name="menu_Buildings">
<property name="title">
<string>&amp;Buildings</string>
</property>
<addaction name="actionCreateBuildings"/>
<addaction name="actionRemoveBuildings"/>
<addaction name="actionUpdateBuildings"/>
<addaction name="actionHideBuildings"/>
</widget>
<widget class="QMenu" name="menu_Danger_Areas">
<property name="title">
<string>&amp;Danger Areas</string>
</property>
<addaction name="actionCreateDangerAreas"/>
<addaction name="actionRemoveDangerAreas"/>
<addaction name="actionUpdateDangerAreas"/>
<addaction name="actionHideDangerAreas"/>
</widget>
<widget class="QMenu" name="menuB_Agents">
<property name="title">
<string>B-&amp;Agents</string>
</property>
<addaction name="actionCreateBAgents"/>
<addaction name="actionRemoveBAgents"/>
<addaction name="actionUpdateBAgents"/>
<addaction name="actionHideBAgents"/>
</widget>
<widget class="QMenu" name="menu_Fire_Areas">
<property name="title">
<string>&amp;Fire Areas</string>
</property>
<addaction name="actionCreateFireAreas"/>
<addaction name="actionRemoveFireAreas"/>
<addaction name="actionUpdateFireAreas"/>
<addaction name="actionHideFireAreas"/>
</widget>
<widget class="QMenu" name="menuHit_Lines">
<property name="title">
<string>Hit &amp;Lines</string>
</property>
<addaction name="actionCreateHitLines"/>
<addaction name="actionRemoveHitLines"/>
<addaction name="actionUpdateHitLines"/>
<addaction name="actionHideHitLines"/>
</widget>
<addaction name="menu_Buildings"/>
<addaction name="separator"/>
<addaction name="menu_Danger_Areas"/>
<addaction name="separator"/>
<addaction name="menuB_Agents"/>
<addaction name="separator"/>
<addaction name="menu_Fire_Areas"/>
<addaction name="separator"/>
<addaction name="menuHit_Lines"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menu_Rubberbands">
<property name="title">
<string>&amp;Rubberbands</string>
</property>
<widget class="QMenu" name="menu_Rectangle">
<property name="title">
<string>&amp;Rectangle</string>
</property>
<addaction name="actionCreateRectangle"/>
<addaction name="actionRectangle"/>
</widget>
<widget class="QMenu" name="menuS_quare">
<property name="title">
<string>S&amp;quare</string>
</property>
<addaction name="actionCreateSquare"/>
<addaction name="actionSquare"/>
</widget>
<widget class="QMenu" name="menu_Ellipse">
<property name="title">
<string>&amp;Ellipse</string>
</property>
<addaction name="actionCreateEllipse"/>
<addaction name="actionEllipse"/>
</widget>
<widget class="QMenu" name="menu_Point_Cluster">
<property name="title">
<string>&amp;Point Cluster</string>
</property>
<addaction name="actionCreatePointCluster"/>
<addaction name="actionPointCluster"/>
</widget>
<widget class="QMenu" name="menu_Multipoint">
<property name="title">
<string>&amp;Multipoint</string>
</property>
<addaction name="actionCreateMultiPoint"/>
<addaction name="actionMultiPoint"/>
</widget>
<widget class="QMenu" name="menu_Filled_Multipoint">
<property name="title">
<string>&amp;Filled Multipoint</string>
</property>
<addaction name="actionCreateFilledMultiPoint"/>
<addaction name="actionFilledMultiPoint"/>
</widget>
<widget class="QMenu" name="menu_Smooth_Line">
<property name="title">
<string>&amp;Smooth Line</string>
</property>
<addaction name="actionCreateSmoothLine"/>
<addaction name="actionSmoothLine"/>
</widget>
<widget class="QMenu" name="menuFilled_Smooth_Line">
<property name="title">
<string>Filled Smooth &amp;Line</string>
</property>
<addaction name="actionCreateFilledSmoothLine"/>
<addaction name="actionFilledSmoothLine"/>
</widget>
<widget class="QMenu" name="menuCorridor_Boundary">
<property name="title">
<string>Corridor &amp;Boundary</string>
</property>
<addaction name="actionCreateCorridorBoundary"/>
<addaction name="actionCorridorBoundary"/>
</widget>
<widget class="QMenu" name="menuCorridor_Centerline">
<property name="title">
<string>Corridor &amp;Centerline</string>
</property>
<addaction name="actionCreateCorridorCenterline"/>
<addaction name="actionCorridorCenterline"/>
</widget>
<widget class="QMenu" name="menu_Arrow">
<property name="title">
<string>&amp;Arrow</string>
</property>
<addaction name="actionCreateArrow"/>
<addaction name="actionArrow"/>
</widget>
<addaction name="menu_Point_Cluster"/>
<addaction name="separator"/>
<addaction name="menu_Multipoint"/>
<addaction name="menu_Filled_Multipoint"/>
<addaction name="menu_Smooth_Line"/>
<addaction name="menuFilled_Smooth_Line"/>
<addaction name="menuCorridor_Boundary"/>
<addaction name="menuCorridor_Centerline"/>
<addaction name="menu_Arrow"/>
<addaction name="separator"/>
<addaction name="menu_Rectangle"/>
<addaction name="menuS_quare"/>
<addaction name="menu_Ellipse"/>
</widget>
<addaction name="menuMap"/>
<addaction name="menuMap_Objects"/>
<addaction name="menu_Rubberbands"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionLoadMap">
<property name="text">
<string>&amp;Load Map</string>
</property>
<property name="toolTip">
<string>Load Map</string>
</property>
<property name="statusTip">
<string comment="Auto save action statusTip">Loading default map</string>
</property>
</action>
<action name="actionRemoveMap">
<property name="text">
<string>&amp;Remove Map</string>
</property>
<property name="statusTip">
<string>Removing current map</string>
</property>
</action>
<action name="actionExit">
<property name="text">
<string>E&amp;xit</string>
</property>
<property name="toolTip">
<string>Exit application</string>
</property>
</action>
<action name="actionCreateBuildings">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create Buildings</string>
</property>
</action>
<action name="actionRemoveBuildings">
<property name="text">
<string>&amp;Remove</string>
</property>
<property name="toolTip">
<string>Remove Buildings</string>
</property>
</action>
<action name="actionUpdateBuildings">
<property name="text">
<string>&amp;Update</string>
</property>
<property name="toolTip">
<string>Update Buildings</string>
</property>
</action>
<action name="actionCreateDangerAreas">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create Danger Areas</string>
</property>
</action>
<action name="actionRemoveDangerAreas">
<property name="text">
<string>&amp;Remove</string>
</property>
<property name="toolTip">
<string>Remove Danger Areas</string>
</property>
</action>
<action name="actionUpdateDangerAreas">
<property name="text">
<string>&amp;Update</string>
</property>
<property name="toolTip">
<string>Update Danger Areas</string>
</property>
</action>
<action name="actionCreateBAgents">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create B Agents</string>
</property>
</action>
<action name="actionRemoveBAgents">
<property name="text">
<string>&amp;Remove</string>
</property>
<property name="toolTip">
<string>Remove B Agents</string>
</property>
</action>
<action name="actionUpdateBAgents">
<property name="text">
<string>&amp;Update</string>
</property>
<property name="toolTip">
<string>Update B Agents</string>
</property>
</action>
<action name="actionCreateFireAreas">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create Fire Areas</string>
</property>
</action>
<action name="actionRemoveFireAreas">
<property name="text">
<string>&amp;Remove</string>
</property>
<property name="toolTip">
<string>RemoveFireAreas</string>
</property>
</action>
<action name="actionUpdateFireAreas">
<property name="text">
<string>&amp;Update</string>
</property>
<property name="toolTip">
<string>Update Fire Areas</string>
</property>
</action>
<action name="actionCreateHitLines">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create Fire Lines</string>
</property>
</action>
<action name="actionRemoveHitLines">
<property name="text">
<string>&amp;Remove</string>
</property>
<property name="toolTip">
<string>Remove Fire Lines</string>
</property>
</action>
<action name="actionUpdateHitLines">
<property name="text">
<string>&amp;Update</string>
</property>
<property name="toolTip">
<string>Update Hit Lines</string>
</property>
</action>
<action name="actionRubberbands">
<property name="text">
<string>&amp;Rubberbands</string>
</property>
</action>
<action name="actionCreateRectangle">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB Rectangle</string>
</property>
</action>
<action name="actionRectangle">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Create RB Rectangle Free Hand</string>
</property>
</action>
<action name="actionCreateSquare">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB Square</string>
</property>
</action>
<action name="actionSquare">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Create RB Square Free Hand</string>
</property>
</action>
<action name="actionCreateEllipse">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB Ellipse</string>
</property>
</action>
<action name="actionEllipse">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Draw RB Ellipse</string>
</property>
</action>
<action name="actionCreatePointCluster">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB PointCluster</string>
</property>
</action>
<action name="actionPointCluster">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Draw RB PointCluster</string>
</property>
</action>
<action name="actionCreateMultiPoint">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB MultiPoint</string>
</property>
</action>
<action name="actionMultiPoint">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Draw RB MultiPoint</string>
</property>
</action>
<action name="actionCreateFilledMultiPoint">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB Filled MultiPoint</string>
</property>
</action>
<action name="actionFilledMultiPoint">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Draw RB FilledMultiPoint</string>
</property>
</action>
<action name="actionCreateSmoothLine">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB SmoothLine</string>
</property>
</action>
<action name="actionSmoothLine">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Draw RB SmoothLine</string>
</property>
</action>
<action name="actionCreateFilledSmoothLine">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB FilledSmoothLine</string>
</property>
</action>
<action name="actionFilledSmoothLine">
<property name="text">
<string>Draw</string>
</property>
<property name="toolTip">
<string>Draw RB FilledSmoothLine</string>
</property>
</action>
<action name="actionCreateCorridorBoundary">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB Corridor Boundary</string>
</property>
</action>
<action name="actionCorridorBoundary">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Draw RB Corridor Boundary</string>
</property>
</action>
<action name="actionCreateCorridorCenterline">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB Corridor Centerline</string>
</property>
</action>
<action name="actionCorridorCenterline">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Draw RB Corridor Centerline</string>
</property>
</action>
<action name="actionCreateArrow">
<property name="text">
<string>&amp;Create</string>
</property>
<property name="toolTip">
<string>Create RB Arrow</string>
</property>
</action>
<action name="actionArrow">
<property name="text">
<string>&amp;Draw</string>
</property>
<property name="toolTip">
<string>Draw RB Arrow</string>
</property>
</action>
<action name="actionHideBuildings">
<property name="text">
<string>&amp;Hide/Show</string>
</property>
<property name="toolTip">
<string>Toggle Hide/Show Buildings</string>
</property>
</action>
<action name="actionHideDangerAreas">
<property name="text">
<string>&amp;Hide/Show</string>
</property>
<property name="toolTip">
<string>Toggle Hide/Show Danger Areas</string>
</property>
</action>
<action name="actionHideBAgents">
<property name="text">
<string>&amp;Hide/Show</string>
</property>
<property name="toolTip">
<string>Toggle Hide/Show B-Agents</string>
</property>
</action>
<action name="actionHideFireAreas">
<property name="text">
<string>&amp;Hide/Show</string>
</property>
<property name="toolTip">
<string>Toggle Hide/Show Fire Areas</string>
</property>
</action>
<action name="actionHideHitLines">
<property name="text">
<string>&amp;Hide/Show</string>
</property>
<property name="toolTip">
<string>Toggle Hide/Show Hit Lines</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>
+53
View File
@@ -0,0 +1,53 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# SIT_MAP
SET(SIT_MAP_EXE_SRCS
sit_map_main.cpp
sit_map.cpp
sit_map.h
log4cxx_sitmapMain.props
)
NGL_ADD_EXECUTABLE(WS NO_TRANSLATION sitMapExample ${SIT_MAP_EXE_SRCS})
NGL_TARGET_LINK_LIBRARIES(sitMapExample
Qt5::Network
NGLLogger
nglapplication
LtsPluginManager
LtsPluginLoader
situationMap
situationMapObjects
situationMapFunctionDialog
situationMapSideBar
advancedSymbologyGui
ArcGIS::ArcGIS
ArcGISQt5Hack
# situationMapSideBar
)
# Copy on LIBchanges:
IF(TARGET sitMapExample)
SET(LOG4CXX_PROPS_FILE log4cxx_sitmapMain.props)
ADD_CUSTOM_COMMAND(TARGET sitMapExample POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${LOG4CXX_PROPS_FILE} $<TARGET_FILE_DIR:sitMapExample>/${LOG4CXX_PROPS_FILE}
)
ENDIF()
IF(MSVC)
# Configure the template file
SET(VS_USER_FILE sitMapExample.vcxproj.user)
configure_file( ../../SituationMap.vcxproj.user.in ${CMAKE_CURRENT_BINARY_DIR}/${VS_USER_FILE} @ONLY)
ENDIF(MSVC)
NGL_INSTALL_TARGET(sitMapExample)
NGL_INSTALL(FILES WS ${CMAKE_CURRENT_SOURCE_DIR}/${LOG4CXX_PROPS_FILE} DESTINATION "bin")
@@ -0,0 +1,175 @@
log4j.reset=true
log4j.rootLogger=INFO, file, stdout
# SitMap
###########################################################
log4j.logger.SituationMap.sitmapMain=INFO
log4j.logger.SituationMap.SitMap=INFO
# AdvancedSymbology (AdvSymbology)
###########################################################
#log4j.logger.AdvSymbology.SymbolDictionary=INFO
#log4j.logger.AdvSymbology.SymbolDictionaryImpl=INFO
#log4j.logger.AdvSymbology.EsriDictionaryProcessor=INFO
#log4j.logger.AdvSymbology.SymbolResult=INFO
#log4j.logger.AdvSymbology.Sidc2525Delta=INFO
# SituationMap
###########################################################
#log4j.logger.SituationMap.INFO
#log4j.logger.SituationMap.MapImpl=INFO
#log4j.logger.SituationMap.MapSettings=INFO
#log4j.logger.SituationMap.MapInitializer=INFO
#log4j.logger.SituationMap.JumpPoints=INFO
#log4j.logger.SituationMap.LayerFactoryImpl=INFO
#log4j.logger.SituationMap.LogicalLayer=INFO
#log4j.logger.SituationMap.LayerControl=INFO
#log4j.logger.SituationMap.CoordTranslationFunctorImpl=INFO
#log4j.logger.SituationMap.CoordTranslationThread=INFO
#log4j.logger.SituationMap.PositionsTranslated=INFO
#log4j.logger.SituationMap.GridImpl=INFO
#log4j.logger.SituationMap.ObjectFactory=INFO
#log4j.logger.SituationMap.IdGenerator=INFO
#log4j.logger.SituationMap.ObjectContainer=INFO
#log4j.logger.SituationMap.ObjectContainerCTC=INFO
#log4j.logger.SituationMap.OverlayHandlerImpl=INFO
#log4j.logger.SituationMap.OverviewMapHandlerImpl=INFO
#log4j.logger.SituationMap.OverviewMap=INFO
log4j.logger.SituationMap.LocationDisplayImpl=TRACE
log4j.logger.SituationMap.ViewshedImpl=TRACE
log4j.logger.SituationMap.ViewshedBase=TRACE
log4j.logger.SituationMap.AbstractMapObjectImpl=INFO
log4j.logger.SituationMap.AbstractEffectSimulationImpl=INFO
log4j.logger.SituationMap.OriginTranslated=INFO
log4j.logger.SituationMap.PositionsTranslated=INFO
log4j.logger.SituationMap.AbstractMultiPointMapObjectImpl=INFO
log4j.logger.SituationMap.AbstractSinglePointMapObjectImpl=INFO
log4j.logger.SituationMap.BasicPathObjectImpl=INFO
log4j.logger.SituationMap.IndicationContainer=INFO
log4j.logger.SituationMap.PolygonImpl=INFO
log4j.logger.SituationMap.PolylineImpl=INFO
log4j.logger.SituationMap.TextImpl=INFO
log4j.logger.SituationMap.AreaFireImpl=INFO
log4j.logger.SituationMap.BiologicalAgentImpl=INFO
log4j.logger.SituationMap.BuildingOutlineImpl=INFO
log4j.logger.SituationMap.ChemicalAgentImpl=INFO
log4j.logger.SituationMap.DangerAreaImpl=INFO
log4j.logger.SituationMap.FunctionalAreaImpl=INFO
log4j.logger.SituationMap.GeoImageImpl=INFO
log4j.logger.SituationMap.HitLineImpl=INFO
log4j.logger.SituationMap.MapObjectIndicatorImpl=INFO
log4j.logger.SituationMap.MineImpl=INFO
log4j.logger.SituationMap.MineFieldImpl=INFO
log4j.logger.SituationMap.NuclearAgentImpl=INFO
log4j.logger.SituationMap.ParticipantImpl=INFO
log4j.logger.SituationMap.SingleFireImpl=INFO
log4j.logger.SituationMap.AbstractGraphicalObject=INFO
log4j.logger.SituationMap.GraphicalObjectEllipse=INFO
log4j.logger.SituationMap.GraphicalObjectPath=INFO
log4j.logger.SituationMap.GraphicalObjectMultiPath=INFO
log4j.logger.SituationMap.GraphicalObjectPictureMarker=INFO
log4j.logger.SituationMap.GraphicalObjectRange=INFO
log4j.logger.SituationMap.GraphicalObjectText=INFO
log4j.logger.SituationMap.TacticalAppearance=INFO
log4j.logger.SituationMap.EventDispatcher=INFO
log4j.logger.SituationMap.Rubberband=DEBUG
log4j.logger.SituationMap.RubberbandRectangle=INFO
log4j.logger.SituationMap.RubberbandDrawablesAndHandles=INFO
log4j.logger.SituationMap.RubberbandFrameHandle=INFO
log4j.logger.SituationMap.RubberbandPointHandle=INFO
log4j.logger.SituationMap.RubberbandStateSelect=INFO
log4j.logger.SituationMap.ObjectIndicatorImpl=INFO
# SituationMap-SideBar
###########################################################
log4j.logger.SituationMap.SideBar=INFO
log4j.logger.SituationMap.SideBarItem=INFO
log4j.logger.SituationMap.SideBarModel=INFO
# PlanEditor
###########################################################
log4j.logger.SituationMap.PlanEditor=TRACE
log4j.logger.SituationMap.PlanRenderer=TRACE
# Appnd_File
###########################################################
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=9
log4j.appender.file.file=${LOG4QT_LOGDIR}/${LOG4QT_USER}_SituationMap.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
# Appnd_Console
###########################################################
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= %d %-5p %c{1} |#| %m (%-.30F:%L) %n
#log4j.appender.stdout.layout.ConversionPattern= %d %-5p %-30c |#| %m (%-.30F:%L) %n
# Appnd_Syslog
###########################################################
log4j.appender.syslog=org.apache.log4j.SyslogAppender
log4j.appender.syslog.Threshold=ERROR
log4j.appender.syslog.SysLogHost=localhost
log4j.appender.syslog.Facility=LOCAL7
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
###########################################################
###########################################################
###########################################################
# 1) Available Levels in LOG4CXX Version 0.10.0:
# TRACE,
# DEBUG,
# INFO,
# WARN,
# ERROR
# FATAL
#
# d = date/time
# p = priority (Level)
# c = category/channel
# m = message
# F = file
# L = line
# n = platform dependent line separator character or characters.
# ....
#
# Examples for console:
# a)
# %d %p %c #%m# (%.50F:%L)%n
# date/time
# priority
# category/channel
# #message#
# (Maximal 50Character des Filename von rechts:Line)
# line separator
#
# b)
# %d (%.15F:%L) %-5p %c |#| %m%n
# date/time
# (Maximal 15Character des Filename von rechts:Line)
# priority, Right pad with spaces if the priority name is less than 5 characters long.
# category/channel
# message
# line separator
#
+688
View File
@@ -0,0 +1,688 @@
/**
* @RDE_HEADER@
* Interface
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "sit_map.h"
#include <ngltools/ngltools_filesystem.h>
#include <Map/grid.h>
#include <Map/situation_map_utils.h>
#include <Symbology/symbol_dictionary.h>
#include <Map/map_initializer.h>
#include <Map/object_factory.h>
#include <Map/camera.h>
#include <MapObjectsImpl/polygon_impl.h>
#include <MapObjectsImpl/polyline_impl.h>
#include <MapObjectsImpl/text_impl.h>
#include <MapObjectsImpl/area_fire_impl.h>
#include <MapObjectsImpl/biological_agent_impl.h>
#include <MapObjectsImpl/chemical_agent_impl.h>
#include <MapObjectsImpl/cube_impl.h>
#include <MapObjectsImpl/building_outline_impl.h>
#include <MapObjectsImpl/danger_area_impl.h>
#include <MapObjectsImpl/functional_area_impl.h>
#include <MapObjectsImpl/geo_image_impl.h>
#include <MapObjectsImpl/hit_line_impl.h>
#include <MapObjectsImpl/line_of_sight_impl.h>
#include <MapObjectsImpl/map_object_attributes_impl.h>
#include <MapObjectsImpl/map_object_indicator_impl.h>
#include <MapObjectsImpl/mine_impl.h>
#include <MapObjectsImpl/mine_field_impl.h>
#include <MapObjectsImpl/nuclear_agent_impl.h>
#include <MapObjectsImpl/participant_impl.h>
#include <MapObjectsImpl/single_fire_impl.h>
//#include <MapObjectsImpl/single_fire_central_impl.h>
#include <MapObjectsImpl/sound_area_impl.h>
#include <MapImpl/sidc_symbol_impl.h>
#include <MapImpl/sight_fan_impl.h>
#include <Map/camera.h>
#include <Map/viewshed.h>
#include <FunctionDialog/function_dialog.h>
#include <QStackedLayout>
#include <SideBar/side_bar.h>
#include <Map/party_id_to_color_functor.h>
// PlanModel:
#include <GeometryModel/geometry_model_factory.h>
#include <GeometryModel/geometry_model.h>
#include <Map/geometry_model_renderer.h>
// Qt
#include <QApplication>
#include <QTimer>
#include <QPushButton>
#include <QComboBox>
#include <QGridLayout>
#include <QSharedPointer>
#include <QGraphicsView>
#include <QGraphicsProxyWidget>
#include <QMenu>
#include <QFileDialog>
#include <QDir>
//-----------------------------------------------------------------------------
class myMapInitializer : public SituationMap::MapInitializer
{
Q_OBJECT
using BaseClass = SituationMap::MapInitializer;
public:
explicit myMapInitializer(SituationMap::Map &map
, SituationMap::MapSettings &mapSettings
, const QString &debugName)
: SituationMap::MapInitializer(map, mapSettings, debugName)
{}
bool initializeObjectFactory() override
{
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::MapObjectIndicator), new SituationMap::GenericObjectFactory<SituationMap::MapObjectIndicatorImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::Cube), new SituationMap::GenericObjectFactory<SituationMap::CubeImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::Polygon), new SituationMap::GenericObjectFactory<SituationMap::PolygonImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::Polyline), new SituationMap::GenericObjectFactory<SituationMap::PolylineImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::Text), new SituationMap::GenericObjectFactory<SituationMap::TextImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::Participant), new SituationMap::GenericObjectFactory<SituationMap::ParticipantImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::AreaFire), new SituationMap::GenericObjectFactory<SituationMap::AreaFireImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::BiologicalAgent), new SituationMap::GenericObjectFactory<SituationMap::BiologicalAgentImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::ChemicalAgent), new SituationMap::GenericObjectFactory<SituationMap::ChemicalAgentImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::BuildingOutline), new SituationMap::GenericObjectFactory<SituationMap::BuildingOutlineImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::DangerArea), new SituationMap::GenericObjectFactory<SituationMap::DangerAreaImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::FunctionalArea), new SituationMap::GenericObjectFactory<SituationMap::FunctionalAreaImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::GeoImage), new SituationMap::GenericObjectFactory<SituationMap::GeoImageImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::HitLine), new SituationMap::GenericObjectFactory<SituationMap::HitLineImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::LineOfSight), new SituationMap::GenericObjectFactory<SituationMap::LineOfSightImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::MapObjectAttributes), new SituationMap::GenericObjectFactory<SituationMap::MapObjectAttributesImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::Mine), new SituationMap::GenericObjectFactory<SituationMap::MineImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::MineField), new SituationMap::GenericObjectFactory<SituationMap::MineFieldImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::NuclearAgent), new SituationMap::GenericObjectFactory<SituationMap::NuclearAgentImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::SingleFire), new SituationMap::GenericObjectFactory<SituationMap::SingleFireImpl>() );
// SituationMap::ObjectFactory::registerMe(typeid(SituationMap::SingleFireCentral), new SituationMap::GenericObjectFactory<SituationMap::SingleFireCentralImpl>());
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::SoundArea), new SituationMap::GenericObjectFactory<SituationMap::SoundAreaImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::SidcSymbol), new SituationMap::GenericObjectFactory<SituationMap::SidcSymbolImpl>() );
SituationMap::ObjectFactory::registerMe(typeid(SituationMap::SightFan), new SituationMap::GenericObjectFactory<SituationMap::SightFanImpl>());
return true;
} // initializeObjectFactory()
AdvancedSymbology::SymbologyType symbologyType() const override
{
return m_symbologyType;
} // symbologyType
void setSymbologyType(AdvancedSymbology::SymbologyType symbologyType)
{
m_symbologyType = symbologyType;
}
protected:
AdvancedSymbology::SymbologyType m_symbologyType = AdvancedSymbology::SymbologyType::APP6B;
};
//-----------------------------------------------------------------------------
class SitMap::Private
{
public:
Private() = default;
~Private() = default;
// map
QPointer<SituationMap::Map> m_map = nullptr;
bool m_demoMode = false;
QStackedLayout* m_stackedLayout = nullptr;
QSharedPointer<SituationMap::MapSettings> m_mapSettings;
QSharedPointer<myMapInitializer> m_mapInitializer;
// admin
QGridLayout* m_mainLayout = nullptr;
QPushButton* m_pbDestroyMap = nullptr;
QPushButton* m_pbToggleMode = nullptr;
SituationMap::Viewpoint2D m_viewpoint4Toggle;
QPushButton* m_pbQuit = nullptr;
QComboBox* m_cbIniFile = nullptr;
QString m_initFilePath;
QComboBox* m_cb2D3D = nullptr;
QComboBox* m_cbSymbologyType = nullptr;
int symbologyType() const
{
if (m_cbSymbologyType)
{
return m_cbSymbologyType->currentData().toInt();
}
return -1;
}
QPushButton* m_pbPlan = nullptr;
QMenu* m_popupMenu = nullptr;
QTimer* m_getRotationTimer = nullptr;
}; // class SitMap::Private
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//SitMap
//-----------------------------------------------------------------------------
SitMap::SitMap(bool demoMode, QWidget *parent)
: QDialog(parent)
, m_logger(SituationMap::getLogger("SitMap"))
, d(new Private)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
this->setObjectName( QLatin1String("SitMapExample-Widget") );
d->m_mainLayout = new QGridLayout(this);
d->m_mainLayout->setObjectName( QLatin1String("SitMapExample-MainLayoutGrid") );
//-----------------------------------
// Buttons
//-----------------------------------
QVariant data;
QGridLayout* topLayout = new QGridLayout();
topLayout->setObjectName( QLatin1String("SitMapExample-TopLayoutGrid") );
d->m_mainLayout->addLayout(topLayout, 0, 0);
d->m_cbIniFile = new QComboBox();
d->m_cbIniFile->setObjectName( QLatin1String("SitMapExample-IniFileComboBox") );
topLayout->addWidget(d->m_cbIniFile, 0, 0);
d->m_cbIniFile->addItem(QStringLiteral("situation_map_defaults.ini"), QLatin1String("situation_map_defaults.ini"));
d->m_cbIniFile->addItem(QStringLiteral("situation_map_ahtc.ini"), QLatin1String("situation_map_ahtc.ini"));
d->m_cbIniFile->addItem(QStringLiteral("situation_map_demo_center.ini"), QLatin1String("situation_map_demo_center.ini"));
d->m_cbIniFile->addItem(QStringLiteral("situation_map_guez.ini"), QLatin1String("situation_map_guez.ini"));
d->m_cbIniFile->addItem(QStringLiteral("situation_map_land400.ini"), QLatin1String("situation_map_land400.ini"));
d->m_cbIniFile->addItem(QStringLiteral("situation_map_qatar.ini"), QLatin1String("situation_map_qatar.ini"));
d->m_cbIniFile->addItem(QStringLiteral("situation_map_luxemburg.ini"), QLatin1String("situation_map_luxemburg.ini"));
d->m_cbIniFile->addItem(QStringLiteral("select"), QString());
onIniFileActivated(d->m_cbIniFile->currentText());
connect(d->m_cbIniFile, QOverload<const QString&>::of(&QComboBox::activated),
this, &SitMap::onIniFileActivated);
d->m_cbSymbologyType = new QComboBox();
d->m_cbSymbologyType->setObjectName( QLatin1String("SitMapExample-SymbologyComboBox") );
topLayout->addWidget(d->m_cbSymbologyType, 0, 1);
// debugging :
if (0)
{
// highlighted -> UserInteraction
connect(d->m_cbSymbologyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::highlighted), this, [](int idx){
qCritical() << " called: highlighted(int) " << idx;
});
// currentIndexChanged -> programmatically & UserInteraction
connect(d->m_cbSymbologyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [](int idx){
qCritical() << " called: currentIndexChanged(int) " << idx;
});
// activated -> UserInteraction
connect(d->m_cbSymbologyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, [](int idx)
{
qCritical() << " called: activated(int) " << idx;
});
} //
// : debugging
d->m_cb2D3D = new QComboBox();
d->m_cb2D3D->setObjectName( QLatin1String("SitMapExample-cb2D3D") );
data.setValue(SituationMap::Mode::Mode_2D);
d->m_cb2D3D->addItem(QStringLiteral("2D"), data);
data.setValue(SituationMap::Mode::Mode_3D);
d->m_cb2D3D->addItem(QStringLiteral("3D"), data);
topLayout->addWidget(d->m_cb2D3D, 0, 2);
d->m_pbDestroyMap = new QPushButton( QLatin1String("Create Map") );
d->m_pbDestroyMap->setObjectName( QLatin1String("SitMapExample-CreateDestroyMapButton") );
topLayout->addWidget(d->m_pbDestroyMap, 0, 3);
connect(d->m_pbDestroyMap, &QPushButton::clicked, this, &SitMap::onCreateDestroyClicked);
d->m_pbToggleMode = new QPushButton( QLatin1String("Toggle Mode") );
d->m_pbToggleMode->setObjectName( QLatin1String("SitMapExample-ToggleModeButton") );
topLayout->addWidget(d->m_pbToggleMode, 0, 4);
connect(d->m_pbToggleMode, &QPushButton::clicked, this, &SitMap::onToggleModeClicked);
d->m_pbToggleMode->setDisabled(true);
AdvancedSymbology::SymbologyType symType;
symType = AdvancedSymbology::SymbologyType::MIL2525D;
data.setValue(symType); d->m_cbSymbologyType->addItem(AdvancedSymbology::toString(symType), data);
symType = AdvancedSymbology::SymbologyType::MIL2525C;
data.setValue(symType); d->m_cbSymbologyType->addItem(AdvancedSymbology::toString(symType), data);
symType = AdvancedSymbology::SymbologyType::APP6B;
data.setValue(symType); d->m_cbSymbologyType->addItem(AdvancedSymbology::toString(symType), data);
symType = AdvancedSymbology::SymbologyType::APP6D;
data.setValue(symType); d->m_cbSymbologyType->addItem(AdvancedSymbology::toString(symType), data);
symType = AdvancedSymbology::SymbologyType::None;
data.setValue(symType); d->m_cbSymbologyType->addItem(AdvancedSymbology::toString(symType), data);
d->m_cbSymbologyType->setCurrentText(AdvancedSymbology::toString(AdvancedSymbology::SymbologyType::APP6D));
//-----------------------------------
// Map
//-----------------------------------
// createMap();
{
QGridLayout* bottomLayout = new QGridLayout();
bottomLayout->setObjectName( QLatin1String("SitMapExample-TopBottomLayoutGrid") );
d->m_mainLayout->addLayout(bottomLayout, 2, 0);
d->m_pbPlan = new QPushButton( QLatin1String("Plan") );
d->m_pbPlan->setObjectName( QLatin1String("SitMapExample-Plan") );
connect(d->m_pbPlan, &QPushButton::clicked, this, &SitMap::onPlanClicked);
bottomLayout->addWidget(d->m_pbPlan, 0, 0);
d->m_pbQuit = new QPushButton( QLatin1String("Quit") );
d->m_pbQuit->setObjectName( QLatin1String("SitMapExample-Quit") );
bottomLayout->addWidget(d->m_pbQuit, 1, 0);
connect(d->m_pbQuit, &QPushButton::clicked, []() {
QCoreApplication::quit();
});
// tbc
}
if (demoMode)
{
// topLayout
d->m_cbSymbologyType->hide();
d->m_cb2D3D->hide();
d->m_pbDestroyMap->hide();
// bottomLayout
d->m_pbPlan->hide();
// createMap:
onCreateDestroyClicked();
} // if (demoMode)
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
SitMap::~SitMap()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
delete d;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
SituationMap::Map *SitMap::map()
{
return d->m_map;
}
void SitMap::onCreateDestroyClicked()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
static bool destroy = true;
destroy = !destroy;
if (destroy)
{
d->m_cbIniFile->setEnabled(true);
d->m_cbSymbologyType->setEnabled(true);
d->m_cb2D3D->setEnabled(true);
d->m_pbDestroyMap->setText( QLatin1String("Create Map") );
if (d->m_getRotationTimer)
d->m_getRotationTimer->stop(); // to avoid slot being called
delete d->m_map;
} else {
d->m_cbIniFile->setEnabled(false);
d->m_cbSymbologyType->setEnabled(false);
d->m_cb2D3D->setEnabled(false);
d->m_pbDestroyMap->setText( QLatin1String("Destroy Map") );
createMap();
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
void SitMap::onToggleModeClicked()
{
NOTICE_LOG(m_logger) << LOGFUNCTION << " START" << " curMode=" << d->m_cb2D3D->currentText();
d->m_pbToggleMode->setDisabled(true);
d->m_viewpoint4Toggle = d->m_map->viewpoint2D();
qCritical() << " save last d->m_viewpoint4Toggle=" << d->m_viewpoint4Toggle.toString();
// toogle mode:
SituationMap::Mode newMapMode = SituationMap::toggleMode(d->m_map->mode());
// destroy:
onCreateDestroyClicked();
// rebuild
QVariant data;
data.setValue(newMapMode);
int idx = d->m_cb2D3D->findData(data);
d->m_cb2D3D->setCurrentIndex(idx);
// create
onCreateDestroyClicked();
}
void SitMap::createMap()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
d->m_map = SituationMap::Map::create(this);
d->m_map->setObjectName(QLatin1String("SitMapExample-Map"));
// d->m_mainLayout->addWidget(d->m_map, 1, 0);
if (!d->m_stackedLayout)
d->m_stackedLayout = new QStackedLayout();
d->m_stackedLayout->setStackingMode(QStackedLayout::StackAll);
d->m_mainLayout->addLayout(d->m_stackedLayout, 1, 0);
d->m_stackedLayout->addWidget(d->m_map);
NOTICE_LOG(m_logger) << LOGFUNCTION << " iniFile = '" << d->m_initFilePath << "'";
d->m_mapSettings = QSharedPointer<SituationMap::MapSettings> ( new SituationMap::MapSettings(d->m_initFilePath) );
d->m_mapInitializer = QSharedPointer<myMapInitializer>
( new myMapInitializer(*d->m_map, *d->m_mapSettings, QLatin1String("SitMapExample")) );
// toggle?
if (! d->m_viewpoint4Toggle.isNull())
d->m_mapInitializer->setViewPoint(d->m_viewpoint4Toggle);
// Take SymbologyType from UI and not from ini file:
int symbologyTypeInt = d->symbologyType();
if (symbologyTypeInt == -1)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " Error retrieving symbologyType";
abort();
}
AdvancedSymbology::SymbologyType symbologyTypeUI =
static_cast<AdvancedSymbology::SymbologyType>(symbologyTypeInt);
d->m_mapInitializer->setSymbologyType(symbologyTypeUI);
if (d->m_mapInitializer->hasErrors())
{
FATAL_LOG(m_logger) << LOGFUNCTION << " MapInitializer-filename='" << d->m_mapInitializer->filename()
<< "'' has following errors: "
<< " exists = " << d->m_mapInitializer->exists()
<< " accessError = " << d->m_mapInitializer->accessError()
<< " formatError = " << d->m_mapInitializer->formatError();
return;
} else {
const SituationMap::Mode mapMode = d->m_cb2D3D->currentData().value<SituationMap::Mode>();
if (d->m_mapInitializer->initMap(mapMode) )
{
INFO_LOG(m_logger) << LOGFUNCTION << " MapInitializer::initMap() ok";
} else {
ERROR_LOG(m_logger) << LOGFUNCTION << " MapInitializer::initMap() failed";
return;
}
}
// 50. turn over to application (if required):
d->m_map->setTimeString(QStringLiteral("#"));
// connect (d->m_map.data(), &SituationMap::Map::mapObjectsClicked, this, &SitMap::onMapObjectClicked);
connect( d->m_map.data()
, &SituationMap::Map::contextMenuClicked
, this
, &SitMap::onMapContextClicked );
if (d->m_map->isReady())
d->m_pbToggleMode->setEnabled(true);
else
connect(d->m_map.data(), &SituationMap::Map::mapReady, this, [this]() {
d->m_pbToggleMode->setEnabled(true);
});
// Create FunctionDialog:
SituationMap::FunctionDialog::addButtonToMap(d->m_map);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
} // SitMap::createMap
static QVector<SituationMap::RefPointer<SituationMap::Participant>>& participantMap()
{
static QVector<SituationMap::RefPointer<SituationMap::Participant>> s_participantCont;
return s_participantCont;
}
void SitMap::onPlanClicked()
{
if (!d->m_map || !d->m_map->isReady())
return;
const SituationMap::PartyIdToColorFunctor::PartyData pData1(QStringLiteral("P1"),
AdvancedSymbology::Role::Friend,
Qt::blue, Qt::blue);
const SituationMap::PartyIdToColorFunctor::PartyData pData2(QStringLiteral("P2"),
AdvancedSymbology::Role::HostileFaker,
Qt::red, Qt::red);
d->m_map->partyIdToColorFunctor().setParty(1, pData1);
d->m_map->partyIdToColorFunctor().setParty(2, pData2);
const QSize windowSize = this->size();
const QSize offset(50, 50);
SituationMap::LayerFactory &layerFac = d->m_map->layerFactory();
QStringList layernames = layerFac.layernames(SituationMap::LayerType::Operational);
QString layername = layernames[0];
layername = QStringLiteral("Participants");
SituationMap::ObjectFactory &objFac = d->m_map->objectFactory();
SituationMap::RefPointer<SituationMap::Participant> participant;
int counter = 0;
int partyId = 1;
for (int x = offset.width(); x<windowSize.width()-offset.width(); x+=offset.width())
{
for (int y = offset.height(); y<windowSize.height()-offset.height(); y+=offset.height())
{
++counter;
QString debugName = QString(QStringLiteral("ModuleTestId1 cnt=%1")).arg(counter);
QPointF geoCoord = d->m_map->viewPortWindowPointToGeoCoordinate(QPointF(x,y));
SituationMap::SymbolData symData;
symData.sidc = QStringLiteral("AP6D|CMPL|10031000111205000000");
symData.color = Qt::cyan; // Will be overwritten via partyId.
participant = objFac.create<SituationMap::Participant>(layername, debugName);
participantMap().append(participant);
participant->setOrigin(SituationMap::Point3D::fromQPointF(geoCoord));
participant->setSymbol(symData);
if (partyId == 2)
partyId = 1;
else
partyId = 2;
participant->setPartyId(partyId);
if (!participant->updateView())
{
qCritical() << "updateView failed: debugName='" << debugName << "'";
abort();
}
} // for
} // for
QTimer *timer = new QTimer(this);
timer->setInterval(150);
static int s_partyId = 1;
static int s_finishCounter=0;
connect(timer, &QTimer::timeout, this, [timer]() {
qCritical() << " new partyId= " << s_partyId << " count=" << participantMap().size() << ")";
++s_finishCounter;
if (s_finishCounter>10)
timer->stop();
int counter = rand()%5;
for(auto participant : qAsConst(participantMap()))
{
int curPartyId = participant->partyId();
if (curPartyId == 2)
curPartyId = 1;
else
curPartyId = 2;
participant->setPartyId(curPartyId);
SituationMap::SymbolData symData = participant->symbol();
int mod = ((++counter)%9);
switch (mod)
{
case 0: symData.sidc = QStringLiteral("AP6D|CMPL|10031000111205000000"); break;
case 1: symData.sidc = QStringLiteral("AP6D|CMPL|10031500001202000000"); break;
case 2: symData.sidc = QStringLiteral("AP6D|CMPL|10031500001302000000"); break;
case 3: symData.sidc = QStringLiteral("AP6D|CMPL|10031500001402000000"); break;
case 4: symData.sidc = QStringLiteral("AP6D|CMPL|10031500001502000000"); break;
case 5: symData.sidc = QStringLiteral("AP6D|CMPL|10031500001602000000"); break;
case 6: symData.sidc = QStringLiteral("AP6D|CMPL|10031500001702000000"); break;
case 7: symData.sidc = QStringLiteral("AP6D|CMPL|10031500001802000000"); break;
case 8: symData.sidc = QStringLiteral("AP6D|CMPL|10031500001902000000"); break;
}
participant->setSymbol(symData);
if (!participant->updateView())
{
qCritical() << "updateView failed:";
abort();
}
}
});
timer->start();
}
void SitMap::onMapObjectClicked(const SituationMap::Map::RefPointerMapObjectList & mapObjList, const QPointF &viewportPosition)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << "START onMapObjectClicked"
<< " viewportPosition=" << viewportPosition
<< " mapObjList.size()=" << mapObjList.size();
for (auto mapObj : mapObjList)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " id=" << mapObj->uniqueMapId()
<< " object-debugInfo=" << mapObj->debugInfo()
<< " object-identifier=" << mapObj->identifier();
// Selection:
if (mapObj->pickable())
{
mapObj->setSelected(!mapObj->selected());
mapObj->updateView();
DEBUG_LOG(m_logger) << LOGFUNCTION << (mapObj->selected() ? " is selected" : " is not selected");
}
}
DEBUG_LOG(m_logger) << LOGFUNCTION << "END onMapObjectClicked";
}
void SitMap::onMapContextClicked(const SituationMap::Map::RefPointerMapObjectList & mapObjList, const QPointF & pos)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << "START onMapContextClicked window pos x=" << pos.x() << " y=" << pos.y()
<< " mapObjList.size()=" << mapObjList.size();
return;
// delete d->m_popupMenu;
// d->m_popupMenu = new QMenu( d->m_map );
// d->m_popupMenu->addSection( QLatin1String("Object at mouse position") );
// for (auto mapObj : mapObjList)
// {
// DEBUG_LOG(m_logger) << LOGFUNCTION << " id=" << mapObj->uniqueMapId()
// << "object-debugInfo=" << mapObj->debugInfo()
// << "object-identifier=" << mapObj->identifier();
// d->m_popupMenu->addAction( mapObj->identifier() );
// }
// d->m_popupMenu->addSeparator();
// // d->m_popupMenu->popup(d->m_map->getQGraphicsView()->mapToGlobal(pos.toPoint()));
// d->m_popupMenu->popup( QPoint(100, 100) );
// DEBUG_LOG(m_logger) << LOGFUNCTION << "END onMapContextClicked";
}
void SitMap::onIniFileActivated(const QString &text)
{
if (text.compare(QLatin1String("select")) == 0)
{
d->m_initFilePath = QFileDialog::getOpenFileName(this,
QLatin1String("get ini file"),
QLatin1String(""),
QLatin1String("Ini files (*.ini)"));
} else {
// e.g. TDS-build/share/Lts/situation_map/situation_map_defaults.ini
d->m_initFilePath = NGL::findFile(NGL::FileType::ConfigFile, text);
}
NOTICE_LOG(m_logger) << LOGFUNCTION << "selected filename= '" << d->m_initFilePath << "'";
}
// SitMap::onMapContextClicked(const SituationMap::Map::RefPointerMapObjectList & mapObjList, const QPoint &)
#include "sit_map.moc"
+50
View File
@@ -0,0 +1,50 @@
/**
* @RDE_HEADER@
* Interface
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
// Qwn
#include <Common/ref_pointer.h>
#include <Common/situation_map_logging.h>
#include <Map/abstract_map_object.h>
#include <Map/map.h>
// Qt
#include <QDialog>
class SitMap : public QDialog
{
Q_OBJECT
public:
explicit SitMap(bool demoMode, QWidget *parent = nullptr);
virtual ~SitMap ();
SituationMap::Map *map();
public slots:
void onCreateDestroyClicked();
void onToggleModeClicked();
void createMap();
void onPlanClicked();
void onMapObjectClicked (const SituationMap::Map::RefPointerMapObjectList & mapObjList, const QPointF &viewportPosition);
void onMapContextClicked( const SituationMap::Map::RefPointerMapObjectList & mapObjList, const QPointF &pos);
protected slots:
void onIniFileActivated(const QString &text);
private:
SituationMap::LOGGER_T m_logger; ///< Interface of the Logging-Facility
class Private;
Private* d = nullptr;
};
+119
View File
@@ -0,0 +1,119 @@
/**
* @RDE_HEADER@
* Interface
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "sit_map.h"
#include <SideBar/side_bar.h>
#include <LtsPluginManager/lts_plugin_loader.h>
#include <PluginInterfaces/style_plugin_interface.h>
#include <PluginInterfaces/project_plugin_interface.h>
#include <nglapplication/nglapplication.h>
#include <NGLLogger/INGLLogger.h>
// Qt
#include <QMessageBox>
#include <QDir>
#include <QNetworkProxy>
#include <QSurface>
// ESRI
//#include <arcgis/ProxySetup.h>
int main (int argc, char* argv[])
{
NGLApplication app ( argc, argv );
// ESRI :
#ifdef Q_OS_WIN
// Force usage of OpenGL ES through ANGLE on Windows
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#endif
// : ESRI
app.createLogger("sitmapMain", "log4cxx_sitmapMain.props");
STARTUP_LOG( app.baseLogger() );
// TODO: load style plugin
//QApplication::setStyle(QLatin1String("rde"));
//QDir::setSearchPaths(QLatin1String("icon"), QStringList(QLatin1String(":/icons/light")));
app.setOrganizationName( QLatin1String( "Rheinmetall Defence Electronics" ) );
app.setApplicationName( QLatin1String( "SituationMap Example Application" ) );
LtsPluginManager::LtsPluginLoader *pluginLoader = LtsPluginManager::LtsPluginLoader::getInstance();
pluginLoader->loadPlugins(LtsPluginManager::PluginType::STYLE, nullptr,
QStringList() << QStringLiteral("rme.light"));
pluginLoader->loadPlugins(LtsPluginManager::PluginType::PROJECT, nullptr,
QStringList() << QStringLiteral("legatus"));
// .. to keep some compatibility to old resource structure TODO: rm !
QDir::setSearchPaths( QLatin1String( "icon" ), QStringList( QLatin1String( ":/style/icons/" ) ) );
QDir::setSearchPaths( QLatin1String( "icon" ), QStringList( QLatin1String( ":/style/" ) ) ); // FIXME: does qt check for recursion ??
if(0)
{
INFO_LOG(app.baseLogger()) << LOGFUNCTION << " set PROXY PROXY PROXY PROXY PROXY PROXY PROXY";
QNetworkProxy proxy;
proxy.setType(QNetworkProxy::HttpProxy);
proxy.setHostName(QLatin1String("213.61.254.67")); // proxy-rde > 213.61.254.67
proxy.setUser(QLatin1String("Norbert Thoden/RH-UBD-BC"));
proxy.setPassword(QLatin1String("RDEWWW11"));
proxy.setPort(8080);
QNetworkProxy::setApplicationProxy(proxy);
} else {
NOTICE_LOG(app.baseLogger()) << LOGFUNCTION << " reset !!! QNETWORKPROXY QNETWORKPROXY QNETWORKPROXY QNETWORKPROXY QNETWORKPROXY !!!";
QNetworkProxy::setApplicationProxy(QNetworkProxy());
}
//QNetworkProxy proxy;
//proxy.setType(QNetworkProxy::HttpProxy);
//proxy.setHostName(QStringLiteral("proxy-rde"));
//proxy.setPort(8080);
//proxy.setUser(QStringLiteral("norbert.thoden@rheinmetall.com"));
//proxy.setPassword(QStringLiteral("RDEWWW11"));
//QNetworkProxy::setApplicationProxy(proxy);
bool demoMode = false;
if (argc == 2)
demoMode = true;
SitMap* sitMap= new SitMap(demoMode);
sitMap->setMinimumWidth(200);
sitMap->setMinimumHeight(200);
sitMap->resize(800, 600);
sitMap->show();
int ret = app.exec();
delete sitMap;
SHUTDOWN_LOG(app.baseLogger());
return ret;
}
@@ -0,0 +1,31 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# EXAMPLE
SET(EXAMPLE_SRCS
exampleMain.cpp
)
SET(EXAMPLE_HDRS
)
IF(MSVC)
# Configure the template file
SET(VS_USER_FILE exampleSvgRenderer.vcxproj.user)
configure_file( ../../SituationMap.vcxproj.user.in ${CMAKE_CURRENT_BINARY_DIR}/${VS_USER_FILE} @ONLY)
ENDIF(MSVC)
NGL_ADD_EXECUTABLE(WS NO_TRANSLATION exampleSvgRenderer ${EXAMPLE_SRCS} ${EXAMPLE_HDRS})
NGL_TARGET_LINK_LIBRARIES(exampleSvgRenderer
NGLLogger
Qt5::Widgets
Qt5::Core
Qt5::Svg
Qt5::Gui
)
@@ -0,0 +1,108 @@
/**
* @RDE_HEADER@
* Interface
* $Id$
* $HeadURL$
* $Author$
*/
#include <QtWidgets/QApplication>
#include <QMainWindow>
#include <QPainter>
#include <QImage>
#include <QSvgGenerator>
#include <QSvgRenderer>
void renderImpactSymbol(QPainter& painter)
{
// From SymbolDictionaryExtendedImpl::renderImpactSymbol
QColor color = Qt::red;
int size = 100;
bool filled = false;
QPen pen(color);
pen.setWidth(2);
painter.setPen(pen);
const int sizeHalf = size/2.0;
QPointF center(sizeHalf, sizeHalf);
// circle
if (filled)
painter.setBrush( color );
painter.drawEllipse(center, sizeHalf*0.5, sizeHalf*0.5);
// // lines
// QLine newLine(0, sizeHalf, size, sizeHalf);
// painter.drawLine(newLine);
// QTransform trans;
// trans.translate(sizeHalf, sizeHalf);
// trans.rotate(45);
// trans.translate(-sizeHalf, -sizeHalf);
// newLine = trans.map(newLine);
// painter.drawLine(newLine);
// newLine = trans.map(newLine);
// painter.drawLine(newLine);
// newLine = trans.map(newLine);
// painter.drawLine(newLine);
}
int main (int argc, char* argv[])
{
QApplication app ( argc, argv );
// under windows for ArcGIS 10.2.6 and higher
#ifdef Q_OS_WIN
QCoreApplication::setAttribute( Qt::AA_UseOpenGLES );
#endif
int fullSize = 100;
QImage image(fullSize, fullSize, QImage::Format_ARGB32);
image.fill(qRgba(0,0,0,0));
{
// Image:
QPainter painterI(&image);
renderImpactSymbol(painterI);
painterI.end();
image.save(QLatin1String("dummy.png"));
// SaveSvg:
QSvgGenerator generator;
generator.setFileName(QLatin1String("dummy.svg"));
generator.setSize(QSize(100, 100));
generator.setViewBox(QRect(0, 0, 100, 100));
generator.setTitle(QLatin1String("SVG Generator Example Drawing"));
generator.setDescription(QLatin1String("An SVG drawing created by the SVG Generator"));
QPainter painterSvg;
painterSvg.begin(&generator);
renderImpactSymbol(painterSvg);
painterSvg.end();
}
{
QSvgRenderer svgRenderer;
QImage image(fullSize, fullSize, QImage::Format_ARGB32);
image.fill(qRgba(0,0,0,0));
QPainter painter(&image);
svgRenderer.load(QLatin1String("manualDummy.svg"));
svgRenderer.render(&painter);
painter.end();
image.save(QLatin1String("manualDummy.png"));
}
return app.exec();
}