Files
fmviewer3/project/fm_viewer/ui/rm_dialog_map.cpp
2026-02-21 17:11:31 +09:00

596 lines
16 KiB
C++

#if !(DO_NOT_USE_MAP)
#if !(USE_WEBVIEW2)
#include "rm_dialog_map.h"
#include "../rm_include.h"
#include "../fm_dimensions.h"
#include "../rm_app.h"
#include "title_widget.h"
#include "rm_widget_drag.h"
#include "rm_widget_map.h"
#include "fm_layer.h"
#include "fm_button.h"
#include <QMainWindow>
#include <QFile>
#include <QDir>
#include "../data/rm_video_item_2ch.h"
#include "../data/rm_sensordata.h"
#include "../core/rm_player.h"
#include "../core/fm_strings.h"
#if (KMH_MPH_TOGGLE)
#include "rm_gps_position.h"
#include "rm_speed_label.h"
#endif
#if (USE_RM_KEYBOARD_EVENT)
#include "../core/rm_key_event.h"
#endif
RMDialogMap::RMDialogMap(QWidget *parent) : QDialog(parent)
{
//qInfo() << "parent:" << parent;
_bHTMLLoaded = false;
_hideOnFullScreen = false;
this->setWindowFlags(this->windowFlags() | Qt::FramelessWindowHint);
this->setWindowModality(Qt::NonModal);
// 시작시 표시 및 처리되지 않도록 시작
#if !(TOGGLE_PLAYER)
this->setAttribute(Qt::WA_DontShowOnScreen,true);
this->setAttribute(Qt::WA_ShowWithoutActivating,true);
#endif
//setFocusPolicy(Qt::NoFocus);
#if (TOGGLE_PLAYER)
this->setFixedSize(RIGHT_FRAME_WIDTH,RIGHT_SUB_HEIGHT);
#else
#if (MAP_SINGLE_PATH)
this->setFixedSize(403,493-48);
#else
this->setFixedSize(403,493);
#endif
#endif
#if (MODEL_BBVIEWER)
this->setFixedSize(628,500);
#endif
_layout = new QVBoxLayout(this);
ZERO_LAYOUT(_layout);
// 地図, マップを見る(MODEL_WATEX)
#if !(TOGGLE_PLAYER)
_title = new TitleWidget(this,FMS::txt("map"),"",true);
_layout->addWidget(_title);
connect(_title->closeButton,SIGNAL(clicked()),this,SLOT(onClose()));
#endif
_map = new RMWidgetMap(this);
//_map->setHidden(true);
#if (TOGGLE_PLAYER)
// 392 x 274
_map->setFixedSize(RIGHT_FRAME_WIDTH,RIGHT_SUB_HEIGHT);
#else
_map->setFixedSize(403,406);
#endif
_layout->addWidget(_map);
#if !(TOGGLE_PLAYER)
#if !(MAP_SINGLE_PATH)
// FD500 도 표시함
QWidget* speedWidget = new QWidget(this);
speedWidget->setObjectName("bg_widget");
speedWidget->setFixedHeight(48);
_layout->addWidget(speedWidget);
FMWidgetBackground(speedWidget,"map",0x4f4f4f);
QVBoxLayout* speedLayout = new QVBoxLayout(speedWidget);
speedLayout->setMargin(0);
speedLayout->setSpacing(0);
speedLayout->setAlignment(Qt::AlignCenter);
QLabel* speedBar = new QLabel(speedWidget);
speedBar->setPixmap( QPixmap(":/image/speed_bar.png") );
speedBar->setFixedSize(392,22);
speedBar->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
speedLayout->addWidget(speedBar);
QWidget* speedLabelWidget = new QWidget(speedWidget);
//speedLabelWidget->setFixedHeight(51);
speedLayout->addWidget(speedLabelWidget);
QGridLayout* speedLabeLayout = new QGridLayout(speedLabelWidget);
speedLabeLayout->setMargin(3);
speedLabeLayout->setSpacing(0);
// 低速
lowLable = new QLabel(speedLabelWidget);
lowLable->setObjectName("text");
lowLable->setText(FMS::txt("low_speed"));
//#if(LIVE_LANGUAGE_CHANGE)
// RMLanguage::instance()->append(RMLanguage::LANGUAGE_JP,RMLanguage::TITLE_TEXT,lowLable,MKU8("\xe4\xbd\x8e\xe9\x80\x9f"));
//#if !(LANGUAGE_REMOVE_ENG) // WATEX
// RMLanguage::instance()->append(RMLanguage::LANGUAGE_EN,RMLanguage::TITLE_TEXT,lowLable,QString("Low speed"));
//#endif // #if (LANGUAGE_REMOVE_ENG) // WATEX
//#endif
// 高速 ( 130 Km/h 以上 )
highLable = new QLabel(speedLabelWidget);
highLable->setObjectName("text");
highLable->setText(FMS::txt("high_speed"));
#if (MODEL_BBVIEWER)
connect(speedLabel,SIGNAL(speedUnitChange()),SLOT(onSpeedUnitChange()));
refreshSpeedBarUnit();
#endif
#if (LIVE_LANGUAGE_CHANGE)
connect(RMLanguage::instance(),SIGNAL(languageChange(RMLanguage::LANGUAGE_TYPE)),SLOT(onLanguageChange(RMLanguage::LANGUAGE_TYPE)));
#endif
speedLabeLayout->addWidget(lowLable,0,0,Qt::AlignLeft);
speedLabeLayout->addWidget(highLable,0,0,Qt::AlignRight);
#endif // #if !(MAP_SINGLE_PATH)
_drag = new RMWidgetDrag(this,POPUP_TITLE_BAR_HEIGHT);
#endif // TOGGLE_PLAYER
connect(RMApp::instance(),SIGNAL(appEvent(RMApp::Event,int)),this,SLOT(onAppEvent(RMApp::Event,int)));
sensor = NULL;
lonX = -9999;
latY = -9999;
speed = -9999;
connect(RMPlayer::instance(),SIGNAL(positionChanged(qint64,qint64)),SLOT(onPositionChanged(qint64,qint64)));
connect(RMPlayer::instance(),SIGNAL(playEvent(PLAY_EVENT,RMVideoItem*)),SLOT(onPlayEvent(PLAY_EVENT,RMVideoItem*)));
#if (TEST_MAP_MOVE_THREAD)
connect(&updater,SIGNAL(moveTo(double, double, double, bool)),SLOT(onMoveToProcess(double,double,double,bool)),Qt::BlockingQueuedConnection);
#endif
//setHidden(true);
_bFirst = true;
#if (LIVE_LANGUAGE_CHANGE && MODEL_STANDARD)
refreshLanguage();
#endif
connect(RMLanguage::instance(),SIGNAL(languageChange(RMLanguage::LANGUAGE_TYPE)),SLOT(onLanguageChange(RMLanguage::LANGUAGE_TYPE)));
}
#if (TOGGLE_PLAYER)
void RMDialogMap::snapTo(QWidget* target)
{
if(target != NULL) {
snapTarget = target;
}
QPoint lt = snapTarget->mapToGlobal(QPoint(0,0));
//qInfo() << lt;
move(lt);
//setGeometry(lt.x(),lt.y(),354,226);
//target->installEventFilter(this);
}
#endif // TOGGLE_PLAYER
#if (KMH_MPH_TOGGLE)
void RMDialogMap::onSpeedUnitChange()
{
refreshSpeedBarUnit();
}
void RMDialogMap::refreshSpeedBarUnit()
{
QString speed = "";
//#if (MODEL_BBVIEWER)
// if(speedLabel->isMPH) 이거 왜 에러남?
//#else
if(RMApp::isMPH)
//#endif
{
speed = "80 mph";
}
else
{
speed = "130 km/h";
}
if(RMLanguage::isJP())
{
// // 高速 ( 130 Km/h 以上 )
highLable->setText(MKU8("\xe9\xab\x98\xe9\x80\x9f") + QString(" ( ") + speed + MKU8(" \xe4\xbb\xa5\xe4\xb8\x8a \x29"));
}
else
{
highLable->setText(QString("High speed ( up to ") + speed + QString(" )"));
}
}
#endif
#if (LIVE_LANGUAGE_CHANGE)
void RMDialogMap::onLanguageChange(RMLanguage::LANGUAGE_TYPE language)
{
Q_UNUSED(language)
#if (MODEL_BBVIEWER)
refreshSpeedBarUnit();
#else
refreshLanguage();
#endif
}
#endif
#if (LIVE_LANGUAGE_CHANGE && MODEL_STANDARD)
void RMDialogMap::refreshLanguage()
{
#if (LIVE_LANGUAGE2)
_title->titleLabel->setText(FMS::txt("map"));
#endif
// bool isJP = RMLanguage::isJP();
// _title->titleLabel->setText(isJP ? MKU8("\xe5\x9c\xb0\xe5\x9b\xb3") : "MAP");
// lowLable->setText(isJP ? MKU8("\xe4\xbd\x8e\xe9\x80\x9f") : "Low speed");
// highLable->setText(isJP ? MKU8("\xe9\xab\x98\xe9\x80\x9f \x28 \x31\x33\x30 \x4b\x6d\x2f\x68 \xe4\xbb\xa5\xe4\xb8\x8a \x29") : "High speed (up to 130km/h)");
// _title->closeButton->setToolTip(isJP ? MKU8("\xe9\x96\x89\xe3\x81\x98\xe3\x82\x8b") : "Exit");
}
#endif
void RMDialogMap::runScript(QString script)
{
if(_map != NULL) {
_map->runScript(script);
}
}
#if (USE_RM_KEYBOARD_EVENT)
// @TODO -> MAP
void RMDialogMap::keyPressEvent(QKeyEvent *event)
{
if(event->isAutoRepeat() == false) {
RMKeyEvent::instance()->pressed(event->key());
}
}
void RMDialogMap::keyReleaseEvent(QKeyEvent *event)
{
if(event->isAutoRepeat() == false) {
RMKeyEvent::instance()->released(event->key());
}
}
#endif
bool RMDialogMap::isGPSExist()
{
return (sensor != NULL && sensor->getGPSCount() > 0);
}
#if (USE_HTML_MAP)
void RMDialogMap::removeHtml()
{
_map->removePage();
}
#endif // USE_HTML_MAP
RMDialogMap* RMDialogMap::instance(QWidget* parent)
{
static RMDialogMap * _instance = NULL;
if ( _instance == NULL )
{
_instance = new RMDialogMap(parent);
_instance->initHtml();
}
return _instance;
}
void RMDialogMap::initHtml()
{
// 로딩완료 처리
connect(_map->_ax, SIGNAL(signal(const QString&, int, void*)),SLOT(activexEventHandler(const QString&, int, void*)));
#if (USE_HTML_MAP)
_map->loadFirstPage();
#else
_map->navigate("");
#endif
// navigate 종료 후 HTML 로딩
// _map->navigate("https://www.whatismybrowser.com/");
}
// 초기 로딩 완료 여부 확인
void RMDialogMap::activexEventHandler(const QString &name, int argc, void *argv)
{
Q_UNUSED(argc)
Q_UNUSED(argv)
if(name == QString("NavigateComplete(QString)"))
{
//qInfo() << "NavigateComplete";
//_map->setHidden(false);
_bHTMLLoaded = true;
disconnect(_map->_ax,SIGNAL(signal(const QString&, int, void*)),this,SLOT(activexEventHandler(const QString&, int, void*)));
#if !(USE_HTML_MAP)
_map->load();
#endif
}
}
bool RMDialogMap::isHiddenReal()
{
#if !(TOGGLE_PLAYER)
if(testAttribute(Qt::WA_DontShowOnScreen))
{
setAttribute(Qt::WA_DontShowOnScreen,false);
setAttribute(Qt::WA_ShowWithoutActivating,false);
setHidden(true);
return true;
}
#endif
return isHidden();
}
void RMDialogMap::onClose()
{
_hideOnFullScreen = false;
setHidden(true);
close();
RMApp::instance()->pMainWindow->setFocus();
}
#if (TEST_MAP_MOVE_THREAD)
void RMDialogMap::moveTo(double lon, double lat,double speed, bool drawLine)
{
updater.runMove(new RMMapMove(lon,lat,speed,drawLine));
}
void RMDialogMap::onMoveToProcess(double lon, double lat,double speed, bool drawLine)
#else
void RMDialogMap::moveTo(double lon, double lat,double speed, bool drawLine)
#endif
{
if(_bHTMLLoaded == false) {
return;
}
#if !(TEST_DO_NOT_UPDATE_MAP)
QString script = "setLatLag(";
script.append(QString::number(lat,'f', 6));
script.append(",");
script.append(QString::number(lon,'f', 6));
script.append(",");
int color = MAX(MIN((int)((double)speed / 13.0),13),0);
script.append(QString::number(color));
if(_bFirst == true)
{
script.append(",1,1);");
_bFirst = false;
}
else
{
if(drawLine)
{
script.append(",0,0);");
//lineCount++;
//qInfo() << "LINE COUNT:" << lineCount;
}
else
{
// FIRST, DISTANCE
script.append(",0,1);");
}
}
_map->runScript(script);
#endif
}
void RMDialogMap::onPlayEvent(PLAY_EVENT event,RMVideoItem* item)
{
// 사용자 STOP 일 경우 PLAY ITEM CLEAR
if(event == PLAY_DID_LOADED) {
if(item->getSensorData() != NULL && item->getSensorData()->getGPSCount() > 0)
{
sensor = item->getSensorData();
#if (MAP_SINGLE_PATH)
QString arg = "drawPaths([";
int pointCount = 0;
const NMEA_INFO* nmea = item->getSensorData()->getGPS();
bool bStart = false;
int pathCount = 0;
for(uint32_t i=0;i<item->getSensorData()->getGPSCount();i++) {
#if (CHECK_GPS_LOCATION)
if( nmea[i].nStatus != 0 && IS_VALID_LOCATION(nmea[i].Longitude,nmea[i].Latitude)) //
#else
if(nmea[i].nStatus != 0)
#endif
{
// 시작되지 않은 경우 시작
if(bStart == false) {
pointCount = 0;
bStart = true;
if(pathCount > 0) {
arg.append(",");
}
pathCount += 1;
arg.append("[");
}
if(pointCount > 0)
{
arg.append(",");
}
arg.append("{lat:" + QString::number(nmea[i].Latitude,'f', 6)
+ ", lng:" + QString::number(nmea[i].Longitude,'f', 6) + "}");
pointCount++;
}
else if (bStart) { // 중단된 경우 닫기
bStart = false;
pointCount = 0;
arg.append("]");
}
}
// 마지막까지 데이터가 정상일 경우 닫기
if(bStart) {
arg.append("]");
}
arg.append("]);");
//qInfo() << arg;
runScript(arg);
#endif
}
else
{
_lastPosition = -1;
lonX = -9999;
latY = -9999;
speed = -9999;
sensor = NULL;
#if (MAP_SINGLE_PATH)
runScript("clearPath();");
#endif
}
}
else if (event == PLAY_DID_CLEARED)
{
_lastPosition = -1;
sensor = NULL;
// lonX = -9999;
// latY = -9999;
// speed = -9999;
#if (MAP_SINGLE_PATH)
runScript("clearPath();");
#endif
}
}
QString RMDialogMap::_packLine(double lon1, double lat1, double lon2, double lat2)
{
int32_t o1 = (int32_t)(lon1 * 1000000.0);
int32_t a1 = (int32_t)(lat1 * 1000000.0);
int32_t o2 = (int32_t)(lon2 * 1000000.0);
int32_t a2 = (int32_t)(lat2 * 1000000.0);
return QString().sprintf("%X_%X_%X_%X",o1,a1,o2,a2);
}
void RMDialogMap::onPositionChanged(qint64 position,qint64 duration)
{
if(sensor != NULL)
{
#if !(MAP_SINGLE_PATH)
// 뒤로 이동
bool isFirstLine = (_lastPosition == -1);
bool drawLine = true;
if(_lastPosition > position)
{
drawLine = false;
}
else if (position > _lastPosition + 2000)
{
drawLine = false;
}
_lastPosition = position;
#endif
double ratio = ((double)position) / ((double)duration);
// 처리 속도를 줄이기 위해
double x,y,s;
if(sensor->getGPSPosition(ratio,&x,&y,&s))
{
if(x != lonX || y != latY || s != speed)
{
#if !(MAP_SINGLE_PATH)
// 시속 200 KM 의 경우 1초당 55.5 m 주행 가능
//qInfo() << "DIST:" << RMDialogMap::distance(y,x,latY,lonX);
if(drawLine == false && isFirstLine)
{
drawLine = true;
}
if(drawLine == true && RMDialogMap::distance(y,x,latY,lonX) > (55*3)) // 버퍼 3초
{
drawLine = false;
}
#endif // MAP_SINGLE_PATH
//qInfo() << "LON:" << lonX << " LAT:" << latY << " SPEED:" << s << " DRAW:" << drawLine;
// Status 는 getGPSPosition 에서 처리하지만 잘못된 경우가 있음
#if (FORCE_VALID_LOCATION)
if(true)
#else
if(IS_VALID_LOCATION(x,y))
#endif
{
#if !(MAP_SINGLE_PATH)
if(drawLine == true)
{
QString key = _packLine(lonX,latY,x,y);
if(_drawList.contains(key) == true)
{
drawLine = false;
}
else
{
_drawList.insert(key,true);
}
}
#endif
lonX = x;
latY = y;
speed = s;
#if !(MAP_SINGLE_PATH)
moveTo(lonX,latY,speed,drawLine);
#else
runScript(QString().sprintf("moveToMap(%.6f,%.6f);",latY,lonX));
#endif
}
else {
#if (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || RM_MODEL == RM_MODEL_TYPE_MBJ5010 || RM_MODEL == RM_MODEL_TYPE_FC_DR232W)
runScript("clearCarMarker();");
#endif
}
}
}
else {
#if (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || RM_MODEL == RM_MODEL_TYPE_MBJ5010 || RM_MODEL == RM_MODEL_TYPE_FC_DR232W)
runScript("clearCarMarker();");
#endif
}
}
}
void RMDialogMap::onAppEvent(RMApp::Event event,int param)
{
if(event == RMApp::WillFullScreen && isHidden() == false)
{
// MAXIMIZE 모드
if(param == 1) {
}
else {
_hideOnFullScreen = true;
setHidden(true);
}
}
else if (_hideOnFullScreen == true && event == RMApp::WillNormalScreen && isHidden() == true)
{
// MAXIMIZE 모드
if(param == 1) {
} else {
_hideOnFullScreen = false;
setHidden(false);
}
}
else if (event == RMApp::WillCloseApplication)
{
// clearHtml();
}
}
#endif // #if !(USE_WEBVIEW2)
#endif // #if !(DO_NOT_USE_MAP)