452 строки
15 KiB
C++
452 строки
15 KiB
C++
/*
|
|
Copyright (c) 2024 SWD Embedded Systems, Ltd. <http://www.kpda.ru>
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
software and associated documentation files (the "Software"), to deal in the Software
|
|
without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
|
to whom the Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all copies or
|
|
substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM,
|
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
|
|
#ifndef MAPWIDGET_H
|
|
#define MAPWIDGET_H
|
|
|
|
#include <QDebug>
|
|
#include <QGestureEvent>
|
|
#include <QGridLayout>
|
|
#include <QLabel>
|
|
#include <QMessageBox>
|
|
#include <QPanGesture>
|
|
#include <QPinchGesture>
|
|
#include <QPointer>
|
|
#include <QPushButton>
|
|
#include <QSwipeGesture>
|
|
|
|
#include <gis/gishelper.h>
|
|
#include <gis/gisrender.h>
|
|
|
|
#include "distancemeter.h"
|
|
#include "objectinfo.h"
|
|
#include "userdialog.h"
|
|
|
|
#define DEBUG_TOUCH
|
|
#define MAPWIDGET_PREFIX const_cast<char*>("[MapWidget] ")
|
|
|
|
|
|
class MapWidget : public QWidget,
|
|
public SMCallbacks,
|
|
public DBCallbacks
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
friend class MapTabWidget;
|
|
|
|
explicit MapWidget( gis_core_connection_t *connection, int idx,
|
|
QWidget *parent = 0 );
|
|
~MapWidget();
|
|
|
|
void initialize();
|
|
|
|
void databufferValidityChangedCallback( bool isValid )
|
|
{
|
|
if ( !isValid )
|
|
gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, MAPWIDGET_PREFIX,
|
|
"Databuffer is invalid [%s()]", __FUNCTION__ );
|
|
else
|
|
gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, MAPWIDGET_PREFIX,
|
|
"Databuffer is valid [%s()]", __FUNCTION__ );
|
|
}
|
|
|
|
void errorCallback( int err_code )
|
|
{
|
|
switch ( err_code )
|
|
{
|
|
case ETIME:
|
|
{
|
|
gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, MAPWIDGET_PREFIX,
|
|
"Too long drawing [%s()]", __FUNCTION__ );
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void surfaceCompleteCallback( int32_t surface_z_idx )
|
|
{
|
|
Q_UNUSED( surface_z_idx );
|
|
update();
|
|
}
|
|
|
|
void mapLayerCompleteCallback( int32_t rsc_key, int32_t layer_number )
|
|
{
|
|
Q_UNUSED( rsc_key );
|
|
Q_UNUSED( layer_number );
|
|
update();
|
|
}
|
|
|
|
bool mapLayerRequiredCallback( int32_t classifier_key, int32_t layer_number )
|
|
{
|
|
for ( size_t idx = 0; idx < classifiers.size(); idx++ )
|
|
{
|
|
ClassifierInfo &info = classifiers[idx];
|
|
if ( info.idx == classifier_key )
|
|
{
|
|
for ( size_t layer_idx = 0; layer_idx < classifiers[idx].layers.size(); layer_idx++ )
|
|
{
|
|
if ( layer_number == classifiers[idx].layers[layer_idx].layerNumber )
|
|
return info.layers[layer_idx].layerIsActive;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool mapClassRequiredCallback( int32_t classifier_key, gis_core_class_code_t class_code )
|
|
{
|
|
Q_UNUSED( classifier_key );
|
|
Q_UNUSED( class_code );
|
|
return true;
|
|
}
|
|
|
|
void updateProjectionParameters();
|
|
void updateScreenParameters();
|
|
|
|
void setIndex( int index );
|
|
int getIndex();
|
|
|
|
gis_render_sm_context_t getSurfacemanagerContext();
|
|
|
|
float brightness = 0;
|
|
float contrast = 0;
|
|
|
|
uint32_t invalidRasterHeightColor;
|
|
double maxRasterHeight;
|
|
double minRasterHeight;
|
|
|
|
bool isAliasingEnabled;
|
|
bool isConstScalingEnabled;
|
|
bool centerOnScaling;
|
|
bool rescaleByWheel;
|
|
bool autoRasterHeightLimits;
|
|
bool rasterDiscretePalette;
|
|
bool rasterInvalidHeightMode;
|
|
|
|
QVector <uint32_t> colorMap;
|
|
|
|
QVector <LayerInfo> layer_list;
|
|
std::vector <ClassifierInfo> classifiers;
|
|
std::vector <MapInfo> maps;
|
|
|
|
QLabel *positionLabel;
|
|
uint32_t wgt_width;
|
|
uint32_t wgt_height;
|
|
|
|
private:
|
|
int index;
|
|
|
|
gis_map_projection_t proj_params;
|
|
gis_data_engine_context_t data_engine_ctx;
|
|
gis_render_sm_context_t sm_ctx;
|
|
gis_core_connection_t *connection;
|
|
|
|
uint32_t offscreen_ext_px;
|
|
float blit_region_rate;
|
|
double_point_t geo_center;
|
|
double_point_t pinned_position;
|
|
uint32_t pinned_scale;
|
|
uint32_t map_widget_scale;
|
|
bool allocInRam;
|
|
int smMode;
|
|
int minimal_size;
|
|
QVector<int> scale_values;
|
|
int buttonBorderOffset;
|
|
int objectSearchSideSizePx;
|
|
int iconSideSizePx;
|
|
int minimumWidgetHeight;
|
|
int minimumWidgetWidth;
|
|
int maximumWidgetHeight;
|
|
int maximumWidgetWidth;
|
|
|
|
|
|
bool pin;
|
|
bool dont_save_to_config;
|
|
bool initialized;
|
|
int idx_scale;
|
|
uint32_t scale_value;
|
|
int32_point_t viewport_pos;
|
|
QPoint last_position;
|
|
bool update_scaling_center;
|
|
|
|
QLabel *scaleLabel;
|
|
QPushButton *increaseButton;
|
|
QPushButton *decreaseButton;
|
|
QPushButton *closeButton;
|
|
QPushButton *meterButton;
|
|
QPushButton *savePinButton;
|
|
QPushButton *showPinButton;
|
|
|
|
bool userFormBlockingFlag;
|
|
gis_userobject_t obj;
|
|
|
|
QPointer <UserDialog> userForm;
|
|
QPointer <DistanceMeter> distance_meter;
|
|
QPointer <ObjectInfo> objInfo;
|
|
|
|
int loadSettings();
|
|
void saveSettings();
|
|
|
|
void setScaleValue( uint32_t value )
|
|
{
|
|
scale_value = value;
|
|
emit scaleValueChanged( scale_value );
|
|
}
|
|
|
|
bool event(QEvent *event);
|
|
void fillClassifierInfo();
|
|
bool gestureEvent( QGestureEvent *event );
|
|
void mousePressEvent( QMouseEvent *event );
|
|
void mouseReleaseEvent( QMouseEvent *event );
|
|
void mouseMoveEvent( QMouseEvent *event );
|
|
void mouseDoubleClickEvent(QMouseEvent *event);
|
|
virtual void paintEvent(QPaintEvent * event);
|
|
void resizeEvent( QResizeEvent *event );
|
|
void closeEvent( QCloseEvent *event );
|
|
|
|
void panTriggered( QPanGesture *gesture );
|
|
void pinchTriggered( QPinchGesture *gesture );
|
|
void swipeTriggered( QSwipeGesture *gesture );
|
|
void syncHeightLimits();
|
|
void wheelEvent(QWheelEvent *event);
|
|
|
|
#ifdef DEBUG_TOUCH
|
|
void grabGestures(const QList<Qt::GestureType> &gestures);
|
|
qreal scaleFactor;
|
|
qreal currentStepScaleFactor;
|
|
#endif
|
|
|
|
bool hasChildWidgets;
|
|
public slots:
|
|
void setTabBlockingFlag( bool blocked )
|
|
{
|
|
hasChildWidgets = blocked;
|
|
emit hasLockingWidgets( hasChildWidgets );
|
|
}
|
|
|
|
void fillLayerTypeList();
|
|
void showMeter();
|
|
void savePin();
|
|
void showPin();
|
|
void showUserForm();
|
|
void updateDatabufferDescriptor();
|
|
void showObjectInfo( QPoint px_click );
|
|
void showObjectInfoWindow( gis_object_t current_object );
|
|
void sync();
|
|
void updateMapDrawing();
|
|
|
|
void setDiscretePalette( bool enabled );
|
|
void setRasterInvalidHeightMode( bool show );
|
|
|
|
void setCenterOnScaling( bool enabled ) { centerOnScaling = enabled; }
|
|
void setRescaleByWheel( bool enabled ) { rescaleByWheel = enabled; }
|
|
|
|
void setAutoRasterHeightLimits( bool enabled )
|
|
{
|
|
autoRasterHeightLimits = enabled;
|
|
gis_mdp_t dp = gis_data_engine_get_display_parameters( data_engine_ctx );
|
|
gis_mdp_set_raster_height_mode( dp, autoRasterHeightLimits );
|
|
if ( autoRasterHeightLimits )
|
|
{
|
|
minRasterHeight = gis_mdp_get_raster_lower_height_limit( dp );
|
|
maxRasterHeight = gis_mdp_get_raster_upper_height_limit( dp );
|
|
}
|
|
}
|
|
|
|
void setInvalidHeightMode( bool enabled ) { rasterInvalidHeightMode = enabled; }
|
|
|
|
void setConstScalingMode( bool enabled );
|
|
void setAliasingMode( bool enable );
|
|
void setRasterHeightLimits( double new_min, double new_max );
|
|
void setMapWidgetCenterAtPoint( double_point_t object_center );
|
|
void updateBrightnessContrast( float br, float cn );
|
|
void updateLayerOrder( int index, gis_render_sm_layer_type_t type );
|
|
void updateDataSourcesForLayer( gis_render_sm_layer_type_t layer_type,
|
|
int num_of_data_sources,
|
|
gis_core_map_data_source_t *data_sources );
|
|
|
|
private slots:
|
|
|
|
void increaseScale();
|
|
void decreaseScale();
|
|
|
|
void updatePositionLabel( QPoint );
|
|
void updateScaleLabel( uint32_t );
|
|
|
|
void setRasterPalette();
|
|
|
|
signals:
|
|
void hasLockingWidgets( bool );
|
|
void eraseList();
|
|
void getNewMeterPoint( QPoint );
|
|
void getNewUserObjPoint( QPoint );
|
|
void getMouseRelease( QPoint );
|
|
void positionLabelChanged( int, QString );
|
|
void scaleValueChanged( uint32_t );
|
|
void showList();
|
|
void shutdownButtonPressed();
|
|
void sizeChanged();
|
|
void widgetIsReady();
|
|
|
|
};
|
|
|
|
|
|
|
|
class MapTabWidget : public QTabWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit MapTabWidget( QWidget *parent = 0 ) : QTabWidget( parent ),
|
|
lock_tab_idx( -1 ),
|
|
is_tab_locked( false )
|
|
{
|
|
setTabsClosable( true );
|
|
|
|
connect( this->tabBar(), SIGNAL( tabCloseRequested( int ) ),
|
|
this, SLOT( closeTab( int ) ) );
|
|
}
|
|
|
|
MapWidget* currentMapWidget() { return static_cast<MapWidget*>( currentWidget() ); }
|
|
|
|
void addMapWidget( gis_core_connection_t *connection )
|
|
{
|
|
MapWidget *mw = nullptr;
|
|
try
|
|
{
|
|
mw = new MapWidget( connection, count(), this );
|
|
}
|
|
catch( const std::bad_alloc & )
|
|
{
|
|
qDebug () << "Failed to allocate memory for MapWidget";
|
|
exit( 1 );
|
|
}
|
|
|
|
connect( mw, SIGNAL( positionLabelChanged( int, QString ) ),
|
|
this, SLOT( updateTabText( int, QString ) ) );
|
|
connect( mw, SIGNAL( hasLockingWidgets( bool ) ),
|
|
this, SLOT( setCurrentTabLocked( bool ) ) );
|
|
|
|
addTab( mw, "-" );
|
|
|
|
mw->initialize();
|
|
if ( count() == 1 )
|
|
{
|
|
emit firstTabAdded(0);
|
|
}
|
|
}
|
|
|
|
bool checkLock( int tab_idx )
|
|
{
|
|
Q_UNUSED( tab_idx );
|
|
if ( is_tab_locked )
|
|
setCurrentIndex( lock_tab_idx );
|
|
return is_tab_locked;
|
|
}
|
|
|
|
protected:
|
|
void tabInserted(int index)
|
|
{
|
|
emit tabInsert(index);
|
|
}
|
|
private:
|
|
int lock_tab_idx;
|
|
bool is_tab_locked;
|
|
signals:
|
|
void tabInsert(int index);
|
|
void firstTabAdded(int);
|
|
|
|
public slots:
|
|
|
|
void closeEvent( QCloseEvent *event )
|
|
{
|
|
for( int i = 0; i < this->count(); ++i )
|
|
{
|
|
MapWidget *map_w = qobject_cast<MapWidget *>( this->widget( i ) );
|
|
|
|
map_w->userForm->close();
|
|
map_w->distance_meter->close();
|
|
map_w->objInfo->close();
|
|
}
|
|
}
|
|
|
|
void closeTab( int index )
|
|
{
|
|
QWidget *map_widget = this->widget( index );
|
|
removeTab( index );
|
|
map_widget->close();
|
|
|
|
for( int i = index; i < this->count(); ++i )
|
|
{
|
|
qobject_cast<MapWidget *>(this->widget( i ))->setIndex( i );
|
|
}
|
|
}
|
|
|
|
void setCurrentTabLocked( bool locked )
|
|
{
|
|
if ( locked ) {
|
|
lock_tab_idx = currentIndex();
|
|
is_tab_locked = true;
|
|
} else {
|
|
is_tab_locked = false;
|
|
}
|
|
}
|
|
|
|
void refreshMapData()
|
|
{
|
|
for ( int i = 0; i < count(); ++i )
|
|
{
|
|
qobject_cast<MapWidget*>( widget(i) )->updateDatabufferDescriptor();
|
|
}
|
|
}
|
|
void setAliasingMode( bool enabled ) { currentMapWidget()->setAliasingMode( enabled ); }
|
|
void setCenterAtCursor( bool enabled ) { currentMapWidget()->setCenterOnScaling( enabled ); }
|
|
void setRescaleByWheel( bool enabled ) { currentMapWidget()->setRescaleByWheel( enabled ); }
|
|
void setConstScalingMode( bool enabled ) { currentMapWidget()->setConstScalingMode( enabled ); }
|
|
void setDiscretePaletteEnabled( bool enabled ) { currentMapWidget()->setDiscretePalette( enabled ); }
|
|
void setRasterAutoHeightMode( bool enabled )
|
|
{
|
|
currentMapWidget()->setAutoRasterHeightLimits( enabled );
|
|
|
|
}
|
|
void setRasterInvalidHeightMode( bool enabled ) { currentMapWidget()->setRasterInvalidHeightMode( enabled ); }
|
|
|
|
void showMeter() { currentMapWidget()->showMeter(); }
|
|
void showProjectionDialog() { currentMapWidget()->updateProjectionParameters(); }
|
|
void showScreenParametersDialog() { currentMapWidget()->updateScreenParameters(); }
|
|
void showUserForm() { currentMapWidget()->showUserForm(); }
|
|
void syncCurrentTab() { currentMapWidget()->sync(); }
|
|
void updateCurrentTabMap() { currentMapWidget()->updateMapDrawing(); }
|
|
|
|
void updateBrightnessContrast( float br, float cn ) { currentMapWidget()->updateBrightnessContrast( br, cn ); }
|
|
void updateLayerOrder( int idx, gis_render_sm_layer_type_t type ) { currentMapWidget()->updateLayerOrder( idx, type ); }
|
|
void updateTabText( int idx, QString str ) { setTabText( idx, str ); }
|
|
void updateDataSourcesForLayer( gis_render_sm_layer_type_t layer_type,
|
|
int num_of_data_sources,
|
|
gis_core_map_data_source_t *data_sources )
|
|
{
|
|
currentMapWidget()->updateDataSourcesForLayer( layer_type, num_of_data_sources, data_sources );
|
|
}
|
|
};
|
|
|
|
#endif
|