I. Preface
The function of offline map has only been completed recently. Many people have asked if there is any function of offline map for a long time ago. They have also roughly learned how to make offline map before. In fact, the core is not the code, but how to get free offline map files. Most of the offline map downloaders are charged online, and it seems that they are not cheap. After finding many, they finally find out A simple and available one can be downloaded in a designated city. Most of the offline maps are Baidu or Goude. In fact, if you are proficient in using online maps, those methods are completely the same. In theory, the api interface made by the manufacturer will also be unified. The only difference is that the js file introduced is different, and the use method and processing flow are completely different In the same way, I spent some time reorganizing and encapsulating a Baidu map class, and supported both online map and offline map modes.
Map function features:
- Both online map and offline map are supported.
- It also supports webkit kernel, webengine kernel and IE kernel.
- It supports setting multiple annotation points, including name, address, longitude and latitude.
- You can set whether the map can be clicked, dragged, and zoomed by the mouse wheel.
- You can set the protocol version, secret key, theme style, center coordinate, center city, geocoding location, etc.
- The zoom scale and level of the map can be set, and the thumbnail, scale bar, traffic information and other controls can be visible.
- Support map interaction, such as mouse click to obtain the latitude and longitude of the corresponding position.
- It supports query of routes, and can set start position, end position, route mode, route mode, route scheme (minimum time, minimum transfer, minimum walking, no subway, minimum distance, avoiding high-speed).
- It can display point, line and surface tools, and can directly draw lines, points, rectangles, circles, etc. on the map.
- Administrative divisions can be set up, a certain city area drawing layer can be specified, and online map can automatically output boundary points of administrative divisions to js file for offline map.
- Multiple coverings can be added. Support points, polylines, polygons, rectangles, circles, arcs, etc.
- Function interface is friendly and unified, easy to use, just one class.
- Support any Qt version, any system, any compiler.
Open source address of video control: https://gitee.com/feiyangqingyun/QWidgetDemo https://github.com/feiyangqingyun/QWidgetDemo File name: Video widget
Experience address: https://gitee.com/feiyangqingyun/QWidgetExe https://github.com/feiyangqingyun/QWidgetExe File name: Bin video system.zip
2, Functional features
- Support 16 screen switching, full screen switching, etc., including 1 + 4 + 6 + 8 + 9 + 13 + 16 screen switching.
- Support alt+enter full screen, esc exit full screen.
- Custom message box + error box + inquiry box + prompt box at the bottom right corner.
- 17 sets of skin styles are changed at will, all styles are unified, including menu, etc.
- Move the mouse on the dashboard of the platform to highlight and identify eight directions accurately.
- The bottom screen toolbar (screen segmentation switch + screenshot sound and other settings) is moved up to highlight.
- You can change the logo + Chinese software name + English software name in the upper left corner of the configuration file.
- Package Baidu map, three-dimensional switching, equipment point, mouse click to get latitude and longitude.
- Stack form, each form is a separate qwidget, convenient to write their own code.
- The top right mouse button menu can dynamically control the display and hide of time CPU + upper left corner panel + lower left corner panel + upper right corner panel + lower right corner panel, and support to restore the default layout.
- The toolbar can place multiple small icons and close icons.
- The left and right sides can be dragged and stretched, and the width and height positions can be memorized automatically, which can be recovered after restart.
- Double click the camera node to automatically play the video, double-click the node to automatically add the video in turn, and it will automatically jump to the next one, double-click the parent node to automatically add all the videos under the node.
- The camera node can be dragged to the corresponding form to play the video, and the local file can be dragged to play directly.
- The video window supports drag switching and instant response.
- Double click the node + drag the node + drag the form exchange location, and the url.txt will be updated automatically.
- It supports loading 16 channels of video from url.txt to play, automatically remembering the corresponding video of the last channel, and automatically opening and playing after the software is started.
- The volume bar control in the lower right corner automatically hides when the focus is lost, and the volume bar mute icon.
- Integrated with Baidu map, you can add the corresponding location of the device, automatically generate the map, support zoom and 3D map, and provide the choice of map style, a total of 12 styles.
- Drag the video outside the channel form to automatically delete the video.
- Right click to delete current + all videos, screenshot current + all videos.
- VCR management, camera management, can add, delete, modify, import, export and print information, apply new device information to generate tree list immediately, without restart.
- Whether to load the map can be opened freely in pro file.
- Four kinds of cores can be selected for video playback, vlc+ffmpeg+easyplayer + Haikang sdk, which can be set in pro.
- 1 + 4 + 9 + 16 screen polling can be set, polling interval and polling code stream type can be set. Click the start polling button directly on the right side of the toolbar at the bottom of the main interface, and then click stop polling again.
- The mouse pointer is not automatically hidden by default for more than 10 seconds.
- Support the onvif search equipment, support any onvif camera, including but not limited to the Huawei of Haikang Dahua Yushi Tiandi Weiye, etc., and support the onvif PTZ control.
- Highly customizable, users can easily derive their own functions on this basis, supporting linux system.
3, Renderings
4, Core code
#include "frmmaplocal.h" #include "frmmapweb.h" #include "ui_frmmaplocal.h" #include "quiwidget.h" #include "iconfont.h" #include "mapbaidu.h" frmMapLocal::frmMapLocal(QWidget *parent) : QWidget(parent), ui(new Ui::frmMapLocal) { ui->setupUi(this); this->initForm(); this->initTree(); this->initMap(); } frmMapLocal::~frmMapLocal() { delete ui; } void frmMapLocal::showEvent(QShowEvent *) { static bool isShow = false; if (!isShow) { isShow = true; QTimer::singleShot(100, this, SLOT(loadMap())); } } void frmMapLocal::initForm() { connect(AppEvent::Instance(), SIGNAL(saveIpcInfo()), this, SLOT(loadMap())); ui->widgetRight->setFixedWidth(App::RightWidth); ui->navTitle1->setText("Information setup"); ui->navTitle2->setText("Layer management"); ui->navTitle1->setLeftIcon(0xf041); ui->navTitle2->setLeftIcon(0xf1b2); ui->navTitle2->setRightIcon5(0xf1f8); } void frmMapLocal::initTree() { ui->treeWidget->clear(); ui->treeWidget->setAnimated(false); ui->treeWidget->setHeaderHidden(true); //ui->treeWidget->setIndentation(0); QStringList texts; texts << "A" << "B" << "C" << "D"; for (int i = 0; i < texts.count(); i++) { //Add parent node QTreeWidgetItem *itemParent = new QTreeWidgetItem(ui->treeWidget); itemParent->setText(0, QString("layer%1").arg(texts.at(i))); //Loop add child for (int j = 0; j < 5; j++) { QTreeWidgetItem *itemChild = new QTreeWidgetItem(itemParent); itemChild->setText(0, QString("%1%2").arg((j % 2 == 0) ? "terrain" : "Mountain range").arg(j + 1)); QPixmap iconNormal = IconFont::Instance()->getPixmap(QUIConfig::TextColor, (j % 2 == 0) ? 0xe6f2 : 0xe6ed, 18, 20, 20); itemChild->setIcon(0, iconNormal); } } ui->treeWidget->expandAll(); } void frmMapLocal::initMap() { #ifdef webkit QWebSettings *webSetting = QWebSettings::globalSettings(); webSetting->setAttribute(QWebSettings::JavascriptEnabled, true); webSetting->setAttribute(QWebSettings::PluginsEnabled, true); webSetting->setAttribute(QWebSettings::JavascriptCanOpenWindows, true); webView = new QWebView; ui->layout->addWidget(webView); connect(webView->page(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); #elif webengine QWebEngineSettings *webSetting = QWebEngineSettings::globalSettings(); webSetting->setAttribute(QWebEngineSettings::JavascriptEnabled, true); webSetting->setAttribute(QWebEngineSettings::PluginsEnabled, true); webSetting->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); webView = new QWebEngineView; ui->layout->addWidget(webView); QWebChannel *channel = new QWebChannel(this); channel->registerObject("objName", MapData::Instance()); webView->page()->setWebChannel(channel); connect(MapData::Instance(), SIGNAL(receiveDataFromJs(QVariant)), this, SLOT(receiveData(QVariant))); connect(webView->page(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); #elif webie webView = new QAxWidget; ui->layout->addWidget(webView); webView->setControl("{8856F961-340A-11D0-A96B-00C04FD705A2}"); #endif } void frmMapLocal::loadMap() { QString fileName = QUIHelper::appPath() + "/config/deviceall.html"; QString url = "file:///" + fileName; MapBaiDu::Instance()->reset(); MapBaiDu::Instance()->setFileName(fileName); MapBaiDu::Instance()->setSaveFile(false); MapBaiDu::Instance()->setMapLocal(true); MapBaiDu::Instance()->setShowOverlayTool(true); MapBaiDu::Instance()->setEnableClickPoint(true); //Set the default center point coordinate. It is recommended to use the center point coordinate method MapBaiDu::Instance()->setMapCenterPoint("121.414,31.1828"); //Set the default central city. Online map can be set //Mapbaidu:: instance() - > setmapcentercity ("Shanghai"); #ifndef webie MapBaiDu::Instance()->setCallFun(QString("%1.receiveData").arg("objName")); #endif QStringList deviceNames, deviceAddrs, devicePoints; #if 0 for (int i = 1; i <= 100; i++) { deviceNames << QString("Camera%1").arg(i); deviceAddrs << QString("Test address%1").arg(i); devicePoints << QString("121.%1,31.%2").arg(qrand() % 1000000).arg(qrand() % 1000000); } #elif 0 deviceNames << "Camera 1" << "Camera 2" << "Camera 3" << "Camera 4" << "Camera 5"; deviceAddrs << "Building 1, Lane 533, Anbo Road" << "8 Beixin Road" << "1200 Kangqiao Road, Kangqiao town(Yuqing Road)" << "JiZhai South Road, Zhuzhai Town, Minhang District" << "1080 Guanglan Road, Pudong New Area(Crape myrtle junction)"; devicePoints << "121.534942,31.307706" << "121.572075,31.188825" << "121.57987,31.155795" << "121.292628,31.215278" << "121.626992,31.211056"; #else //Load from database deviceNames = DBData::IpcInfo_IpcName; deviceAddrs = DBData::IpcInfo_IpcAddr; devicePoints = DBData::IpcInfo_IpcPosition; #endif MapBaiDu::Instance()->setShowTrafficControl(true); MapBaiDu::Instance()->setShowNavigationControl(true); MapBaiDu::Instance()->setMarkerInfo(deviceNames, deviceAddrs, devicePoints); QString content = MapBaiDu::Instance()->newMap(); //Here are two ways to load a web page. If the content is empty, load the web page file. Otherwise, load the content //Generally, it is recommended to load content for confidentiality, so that the generated web page file cannot be seen //Maybe webkit kernel on linux needs to be loaded by load if (MapBaiDu::Instance()->getSaveFile()) { #ifdef webkit webView->load(QUrl(url)); #elif webengine webView->load(QUrl(url)); #elif webie webView->dynamicCall("Navigate(const QString&)", url); #endif } else { QUrl baseUrl(QString("%1/config/").arg(QUIHelper::appPath())); #ifdef webkit webView->setHtml(content, baseUrl); #elif webengine webView->setHtml(content, baseUrl); #endif } } void frmMapLocal::receiveData(const QVariant &data) { //Show me how to get the latitude and longitude from the marked points on the map if (!data.isNull()) { QStringList list = data.toString().split(","); double longitude = list.at(0).toDouble(); double latitude = list.at(1).toDouble(); //Take 6 decimal places QString strLongitude = QString::number(longitude, 'f', 6); QString strLatitude = QString::number(latitude, 'f', 6); ui->txtLongitude->setText(strLongitude); ui->txtLatitude->setText(strLatitude); } } void frmMapLocal::loadFinished() { #ifdef webkit webView->page()->mainFrame()->addToJavaScriptWindowObject("objName", this); #endif }