修复了高德地图不显示的问题

Release-dev
chenzenghui 2025-05-02 13:19:00 +08:00
parent fa8395cdf2
commit 25c5a65f4b
17 changed files with 258 additions and 362 deletions

View File

@ -40,29 +40,17 @@ namespace LAMPMainWidget {
mUi->setupUi(dynamic_cast<QMainWindow*>(this));
setupWindow();
setupTaskWindow();
setupShowMessage();
this->show();// 强制显示窗口
setupLayers();
setupStatusBar();
setupActions();
setRightToolbox();
mUi->panAction->trigger();
mUi->layerList->setCurrentItem(mLayerList.first());
this->show();// 强制显示窗口
// 绑定消息显示
RasterMessageShow::RasterWidgetMessageShow* messageshow = RasterMessageShow::RasterWidgetMessageShow::getInstance(this);
messageshow->bandingTextBrowserMessage(this->mUi->textBrowserMessage);
connect(mUi->actioncloseAllRasterFile, SIGNAL(triggered()), this, SLOT(onactioncloseAllRasterFile_triggered()));
this->mUi->toolBar->hide();
this->mUi->dockWidget_Map->hide();
this->mUi->dockWidget->hide();
this->mUi->statusbar->hide();
this->mUi->dockWidget_2->hide();
this->mUi->dockWidget_3->hide();
}
RasterMainWidget::~RasterMainWidget() {
@ -74,8 +62,7 @@ namespace LAMPMainWidget {
delete mCenterLabel;
}
void
RasterMainWidget::setupTaskWindow() {
void RasterMainWidget::setupTaskWindow() {
mUi->taskTable->setColumnCount(5);
mUi->taskTable->setHorizontalHeaderLabels(QStringList{
"名称", "范围", "zoom值", "数据源", "进度"
@ -83,8 +70,7 @@ namespace LAMPMainWidget {
mUi->taskTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
}
void
RasterMainWidget::setupActions() {
void RasterMainWidget::setupActions() {
mMapActionGroup->addAction(mUi->panAction);
mMapActionGroup->addAction(mUi->zoomInAction);
mMapActionGroup->addAction(mUi->zoomOutAction);
@ -157,11 +143,10 @@ namespace LAMPMainWidget {
}
}
void
RasterMainWidget::initMaps() {
if (false&&mMaps.isEmpty()) {
void RasterMainWidget::initMaps() {
if (mMaps.isEmpty()) {
mMaps = QHash<QString, MapLayer*>{
{"Openstreet地图", new TmsLayer(OSTNormalMap, "ostnormalmap", mMapConvas)},
//{"Openstreet地图", new TmsLayer(OSTNormalMap, "ostnormalmap", mMapConvas)},
{"高德地图", new TmsLayer(GaodeNormapMap, "gaodenormalmap", mMapConvas)}
};
}
@ -188,6 +173,16 @@ namespace LAMPMainWidget {
}
void RasterMainWidget::setupShowMessage()
{
// 绑定消息显示
RasterMessageShow::RasterWidgetMessageShow* messageshow = RasterMessageShow::RasterWidgetMessageShow::getInstance(this);
messageshow->bandingTextBrowserMessage(this->mUi->textBrowserMessage);
connect(mUi->actioncloseAllRasterFile, SIGNAL(triggered()), this, SLOT(onactioncloseAllRasterFile_triggered()));
}
QWidget* RasterMainWidget::spacerWiget(int width) const {
auto spacer = new QWidget{};
spacer->setHidden(true);
@ -197,18 +192,15 @@ namespace LAMPMainWidget {
return spacer;
}
void
RasterMainWidget::panHandle(bool checked) {
void RasterMainWidget::panHandle(bool checked) {
mMapConvas->selectTool(QString{ "pan_tool" });
}
void
RasterMainWidget::zoomInHandle(bool checked) {
void RasterMainWidget::zoomInHandle(bool checked) {
mMapConvas->selectTool(QString{ "zoomin_tool" });
}
void
RasterMainWidget::zoomOutHandle(bool checked) {
void RasterMainWidget::zoomOutHandle(bool checked) {
mMapConvas->selectTool(QString{ "zoomout_tool" });
}
@ -219,36 +211,30 @@ namespace LAMPMainWidget {
void
RasterMainWidget::sponsorHandle(bool checked) {
void RasterMainWidget::sponsorHandle(bool checked) {
auto* window = new SponsorWindow(dynamic_cast<QWidget*>(this));
window->exec();
window->deleteLater();
}
void
RasterMainWidget::refreshHandle(bool checked) {
void RasterMainWidget::refreshHandle(bool checked) {
mMapConvas->refreshMap();
}
void
RasterMainWidget::selectHandle(bool checked) {
void RasterMainWidget::selectHandle(bool checked) {
mMapConvas->selectTool(QString{ "select_tool" });
}
void
RasterMainWidget::centerChangedHandle(LAMPMainWidget::PointXY pos) {
void RasterMainWidget::centerChangedHandle(LAMPMainWidget::PointXY pos) {
mCenterText->setText(QString("lon:%1, lat:%2").arg(pos.x()).arg(pos.y()));
}
void
RasterMainWidget::zoomChangedHandle(int zoom) {
void RasterMainWidget::zoomChangedHandle(int zoom) {
mZoomText->setText(QString("%1").arg(zoom));
mScaleText->setText(QString("1cm:%1m").arg(this->mMapConvas->scale()));
}
void
RasterMainWidget::clickedHandle(LAMPMainWidget::PointXY pos) {
void RasterMainWidget::clickedHandle(LAMPMainWidget::PointXY pos) {
QString posText = QString("%1, %2").arg(pos.x()).arg(pos.y());
if (mSetLeftTop) {
mUi->leftTopText->setText(posText);
@ -260,23 +246,20 @@ namespace LAMPMainWidget {
}
}
void
RasterMainWidget::leftTopClickedHandle() {
void RasterMainWidget::leftTopClickedHandle() {
mSetLeftTop = true;
mUi->selectAction->trigger();
}
void
RasterMainWidget::rightBottomClickedHandle() {
void RasterMainWidget::rightBottomClickedHandle() {
mSetLeftTop = false;
mUi->selectAction->trigger();
}
void
RasterMainWidget::layerChanged(QListWidgetItem* current, QListWidgetItem* previous) {
void RasterMainWidget::layerChanged(QListWidgetItem* current, QListWidgetItem* previous) {
auto mapName = current->text();
if (!mMaps.contains(mapName)) {
qDebug() << mapName << "不支持";
qDebug() << mapName << u8"不支持";
return;
}
@ -284,7 +267,7 @@ namespace LAMPMainWidget {
auto i = mMaps.begin();
for (; i != mMaps.end(); ++i) {
if (i.key() == mapName) {
i.value()->setVisiblity(true);
i.value()->setVisiblity(true); // 切换图层为显示模式
qDebug() << i.key() << i.value()->isVisible();
continue;
}
@ -292,23 +275,21 @@ namespace LAMPMainWidget {
i.value()->setVisiblity(false);
}
mMapConvas->addLayer(layer);
mMapConvas->addLayer(layer);//图层开始显示
mMapConvas->setCurrentLayer(layer->id());
mMapConvas->refreshMap();
mMapConvas->refreshMap();//刷新地图
zoomChangedHandle(mMapConvas->zoomValue());
centerChangedHandle(mMapConvas->mapCenter());
zoomChangedHandle(mMapConvas->zoomValue());// 更新zoom值
centerChangedHandle(mMapConvas->mapCenter());// 更新中心坐标
}
void
RasterMainWidget::createDownloadTask() {
void RasterMainWidget::createDownloadTask() {
auto taskWindow = new TaskWindow(dynamic_cast<QWidget*>(this));
taskWindow->exec();
taskWindow->deleteLater();
}
void
RasterMainWidget::changeTaskTable(int row, int col, QString text) {
void RasterMainWidget::changeTaskTable(int row, int col, QString text) {
mUi->taskTable->takeItem(row, col);
mUi->taskTable->setItem(row, col, new QTableWidgetItem(text));
}

View File

@ -44,7 +44,7 @@ namespace LAMPMainWidget {
void initMaps();
void setRightToolbox();
void initToolbox();
void setupShowMessage();
protected:
/// 各处处理函数
@ -75,7 +75,7 @@ namespace LAMPMainWidget {
void onactioncloseAllRasterFile_triggered();
private:
Ui::RasterMainWidget* mUi;
MapCanvas* mMapConvas;
MapCanvas* mMapConvas;//地图容器
QLineEdit* mScaleText;
QLabel* mScaleLabel;
QLineEdit* mCenterText;

View File

@ -12,8 +12,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>898</width>
<height>580</height>
<width>906</width>
<height>609</height>
</rect>
</property>
<property name="sizePolicy">
@ -84,8 +84,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>898</width>
<height>22</height>
<width>906</width>
<height>23</height>
</rect>
</property>
<widget class="QMenu" name="projectMenu">
@ -117,11 +117,15 @@
<property name="title">
<string>工具</string>
</property>
<addaction name="actioncloseAllRasterFile"/>
</widget>
<widget class="QMenu" name="helpMenu">
<property name="title">
<string>帮助</string>
</property>
<addaction name="tutorialAction"/>
<addaction name="srcAction"/>
<addaction name="separator"/>
</widget>
<addaction name="projectMenu"/>
@ -134,9 +138,6 @@
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
<property name="enabled">
<bool>false</bool>
</property>
<property name="windowTitle">
<string>toolBar</string>
</property>
@ -378,85 +379,11 @@ p, li { white-space: pre-wrap; }
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_Map">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
<action name="actioncloseAllRasterFile">
<property name="text">
<string>释放影像文件</string>
</property>
<property name="windowTitle">
<string>地图窗口</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_5">
<widget class="QTabWidget" name="tabWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>0</y>
<width>502</width>
<height>274</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="mapTab">
<attribute name="title">
<string>地图</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="mapCanvasLayout"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="taskTab">
<attribute name="title">
<string>任务</string>
</attribute>
<widget class="QWidget" name="gridLayoutWidget_5">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1431</width>
<height>871</height>
</rect>
</property>
<layout class="QGridLayout" name="taskLayout">
<item row="0" column="0">
<widget class="QTableWidget" name="taskTable"/>
</item>
</layout>
</widget>
</widget>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>906</width>
<height>23</height>
</rect>
</property>
<widget class="QMenu" name="toolsMenu">
<property name="title">
<string>工具</string>
</property>
<addaction name="actioncloseAllRasterFile"/>
</widget>
<addaction name="toolsMenu"/>
</widget>
</action>
<action name="tutorialAction">
<property name="text">
<string>使用教程</string>
@ -593,11 +520,6 @@ p, li { white-space: pre-wrap; }
<string>飞机</string>
</property>
</action>
<action name="actioncloseAllRasterFile">
<property name="text">
<string>释放影像文件</string>
</property>
</action>
</widget>
<resources>
<include location="../RasterMainWidgetGUI.qrc"/>

View File

@ -9,8 +9,7 @@ namespace LAMPMainWidget {
initCache();
}
QString
GaodeNormalProvider::tileUrl(const LAMPMainWidget::PointXY& pos, int zoom) const {
QString GaodeNormalProvider::tileUrl(const LAMPMainWidget::PointXY& pos, int zoom) const {
QString urlFmt = { R"(http://wprd01.is.autonavi.com/appmaptile?style=6&x=%1&y=%2&z=%3)" };
return QString(urlFmt).arg(pos.x()).arg(pos.y()).arg(zoom);

View File

@ -84,8 +84,7 @@ namespace LAMPMainWidget {
setZoomValue(zoom);
}
void
MapCanvas::resizeEvent(QResizeEvent* event) {
void MapCanvas::resizeEvent(QResizeEvent* event) {
updateViewExtent(true);
}
@ -97,19 +96,17 @@ namespace LAMPMainWidget {
QGraphicsView::mouseMoveEvent(event);
}
void
MapCanvas::refreshMap() {
void MapCanvas::refreshMap() {
QMapIterator<QString, MapLayer*> iterator(mLayers);
while (iterator.hasNext()) {
iterator.next();
iterator.value()->map()->setViewExtent(mViewExtent);
iterator.value()->update();
iterator.value()->map()->setViewExtent(mViewExtent);//设置当前图层的可视范围
iterator.value()->update();//更新当前图层的显示内容
}
mScene->update();
}
void
MapCanvas::addLayer(MapLayer* const layer) {
void MapCanvas::addLayer(MapLayer* const layer) {
if (!layer)
return;
@ -119,15 +116,14 @@ namespace LAMPMainWidget {
}
mLayers.insert(layer->id(), layer);
if (mLayers.count() == 1) {
if (mLayers.count() == 1) {//判断是否是第唯一个图层
setCurrentLayer(layer->id());
}
mScene->addItem(layer->map());
mScene->addItem(layer->map());//将当前图层添加到场景中
refreshMap();
}
void
MapCanvas::setZoomValue(const int zoom) {
void MapCanvas::setZoomValue(const int zoom) {
mZoomValue = normalizeZoom(zoom);
zoomChanged(mZoomValue);
@ -142,8 +138,7 @@ namespace LAMPMainWidget {
updateViewExtent(true);
}
void
MapCanvas::updateViewExtent(bool reset) {
void MapCanvas::updateViewExtent(bool reset) {
if (!mCurrentLayer) {
qDebug() << "未设置当前图层,视图区域无法更新";
return;
@ -178,33 +173,29 @@ namespace LAMPMainWidget {
refreshMap();
}
void
MapCanvas::setCrs(const CRS* const crs) {
void MapCanvas::setCrs(const CRS* const crs) {
mCrs = crs;
crsChanged();
updateViewExtent(true);
}
void
MapCanvas::setCurrentLayer(const QString& id) {
void MapCanvas::setCurrentLayer(const QString& id) {
if (!mLayers.contains(id)) {
qWarning() << "未添加图层=>" << id;
return;
}
mCurrentLayer = mLayers[id];
if (!mCrs) {
setCrs(&mCurrentLayer->crs());
setCrs(&mCurrentLayer->crs());//设置当前图层的坐标系,后期考虑继续拆分
}
updateViewExtent(true);
updateViewExtent(true);// 更新视图区域
}
double
MapCanvas::scale() const {
double MapCanvas::scale() const {
return logicalDpiX() * resolution() * 39.37 / 100;;
}
double
MapCanvas::resolution() const {
double MapCanvas::resolution() const {
if (!mCurrentLayer) {
qWarning() << "未设置当前图层,无法获取分辨率";
return 0;
@ -213,8 +204,7 @@ namespace LAMPMainWidget {
return mCurrentLayer->resolution();
}
int
MapCanvas::zoomValue() const {
int MapCanvas::zoomValue() const {
if (!mCurrentLayer) {
qWarning() << "未设置当前图层默认返回zoom值为0";
return 0;
@ -223,8 +213,7 @@ namespace LAMPMainWidget {
return mCurrentLayer->zoomValue();
}
int
MapCanvas::normalizeZoom(const int zoom) const {
int MapCanvas::normalizeZoom(const int zoom) const {
int z{};
if (zoom <= kMinZoomValue) {
z = kMinZoomValue;
@ -239,8 +228,7 @@ namespace LAMPMainWidget {
return z;
}
PointXY
MapCanvas::pixel2Lonlat(const QPointF& point) const {
PointXY MapCanvas::pixel2Lonlat(const QPointF& point) const {
QPointF scenePoint = mapToScene(QPoint{ static_cast<int>(point.x()), static_cast<int>(point.y()) });
QPointF mapPoint{ scenePoint.x() * resolution(), scenePoint.y() * resolution() };
PointXY crsPoint = mCrs->inverse(PointXY{ mapPoint });
@ -248,8 +236,7 @@ namespace LAMPMainWidget {
return crsPoint;
}
bool
MapCanvas::selectTool(const QString& tool) {
bool MapCanvas::selectTool(const QString& tool) {
if (!mMapTools.contains(tool)) {
qWarning() << QString("%1工具不存在").arg(tool);
return false;
@ -274,8 +261,7 @@ namespace LAMPMainWidget {
}
}
void
MapCanvas::setupTools() {
void MapCanvas::setupTools() {
auto panTool = new MapToolPan(this);
mMapTools.insert(panTool->id(), panTool);

View File

@ -162,7 +162,7 @@ namespace LAMPMainWidget {
void mouseMoveEvent(QMouseEvent* event) override;
protected:
QGraphicsScene* mScene;
QGraphicsScene* mScene; // 场景对象
QRectF mMapExtent;
QRectF mViewExtent;
QRectF mDragRect;

View File

@ -10,16 +10,20 @@
namespace LAMPMainWidget {
void
MapCanvasMap::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
/// <summary>
/// 重写paint函数绘制图层的内容
/// </summary>
/// <param name="painter"></param>
/// <param name="option"></param>
/// <param name="widget"></param>
void MapCanvasMap::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
if (!mLayer->provider().hasContent()) {
return;
}
painter->drawImage(mViewExtent.topLeft(), mLayer->provider().preparedImage());
}
QRectF
MapCanvasMap::boundingRect() const {
QRectF MapCanvasMap::boundingRect() const {
auto width = mViewExtent.size().width();
auto height = mViewExtent.size().height();
return mViewExtent + QMarginsF(1024, 1024, 1024, 1024);

View File

@ -16,7 +16,7 @@ class MapCanvasMap : public QGraphicsItem {
~MapCanvasMap() override = default;
public:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; //图层绘制函数
QRectF boundingRect() const override;

View File

@ -5,8 +5,7 @@
namespace LAMPMainWidget {
size_t
writeData(void *content, size_t size, size_t nmemb, void *userp) {
size_t writeData(void* content, size_t size, size_t nmemb, void* userp) {
size_t realSize{ size * nmemb };
auto userRes = static_cast<QByteArray*>(userp);
if (!userRes) {
@ -20,8 +19,7 @@ writeData(void *content, size_t size, size_t nmemb, void *userp) {
const QString Network::kUserAgent{ "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0" };
QByteArray
Network::httpRequest(const QString &url) {
QByteArray Network::httpRequest(const QString& url) {
QByteArray result{};
if (url.isEmpty()) {
qDebug() << QString("url为空");
@ -50,17 +48,16 @@ Network::httpRequest(const QString &url) {
return result;
}
QByteArray
Network::httpsRequest(const QString &url) {
QByteArray Network::httpsRequest(const QString& url) {
QByteArray result{};
if (url.isEmpty()) {
qDebug() << QString("url为空");
qDebug() << QString(u8"url为空");
return result;
}
CURL* curl = curl_easy_init();
if (!curl) {
qDebug() << "无法初始化curl句柄";
qDebug() << u8"无法初始化curl句柄";
return result;
}
@ -73,7 +70,7 @@ Network::httpsRequest(const QString &url) {
CURLcode res = curl_easy_perform(curl);
if (CURLE_OK != res) {
qDebug() << QString("%1 =>请求异常, %2").arg(url).arg(curl_easy_strerror(res));
qDebug() << QString(u8"%1 =>请求异常, %2").arg(url).arg(curl_easy_strerror(res));
result.clear(); // 请求失败时,清空接受到的数据
}

View File

@ -17,8 +17,7 @@
namespace LAMPMainWidget
{
void
DownloadTask::run()
void DownloadTask::run()
{
auto currentLayer = dynamic_cast<const TmsLayer*>(mTaskInfo.layer);
auto provider = dynamic_cast<const TmsProvider*>(&currentLayer->provider());
@ -59,8 +58,7 @@ namespace LAMPMainWidget
}
}
void
DownloadTask::generateCommonRow()
void DownloadTask::generateCommonRow()
{
auto provider = dynamic_cast<const TmsProvider*>(&mTaskInfo.layer->provider());
mRowId = mTaskInfo.display->rowCount();
@ -71,24 +69,21 @@ namespace LAMPMainWidget
mTaskInfo.display->setItem(mRowId, 3, new QTableWidgetItem(provider->id()));
}
void
DownloadTask::generateErrorRow()
void DownloadTask::generateErrorRow()
{
generateCommonRow();
mTaskInfo.display->setItem(mRowId, 4, new QTableWidgetItem("任务新建失败"));
mTaskInfo.display->resizeColumnsToContents();
}
void
DownloadTask::generateSuccessRow()
void DownloadTask::generateSuccessRow()
{
generateCommonRow();
mTaskInfo.display->setItem(mRowId, 4, new QTableWidgetItem("0.0%"));
mTaskInfo.display->resizeColumnsToContents();
}
QString
DownloadTask::getExtentStr()
QString DownloadTask::getExtentStr()
{
auto leftTop = mTaskInfo.extent.topLeft();
auto rightBottom = mTaskInfo.extent.bottomRight();
@ -112,8 +107,7 @@ namespace LAMPMainWidget
delete mUi;
}
void
TaskWindow::setupWindow()
void TaskWindow::setupWindow()
{
setFixedSize(size());
auto currentLayer = dynamic_cast<const TmsLayer*>(mParent->mMapConvas->currentLayer());
@ -129,8 +123,7 @@ namespace LAMPMainWidget
QString("%1, %2").arg(mParent->mRightBottom.x()).arg(mParent->mRightBottom.y()));
}
void
TaskWindow::setupAction()
void TaskWindow::setupAction()
{
QObject::connect(mUi->exitBtn, &QPushButton::clicked, this, &TaskWindow::close);
QObject::connect(mUi->createBtn, &QPushButton::clicked, this, &TaskWindow::createTask);
@ -140,8 +133,7 @@ namespace LAMPMainWidget
this, &TaskWindow::setupZoomValue);
}
void
TaskWindow::createTask()
void TaskWindow::createTask()
{
if (!taskInfoCheck()) {
return;
@ -162,12 +154,11 @@ namespace LAMPMainWidget
close();
}
void
TaskWindow::setupSaveDir()
void TaskWindow::setupSaveDir()
{
auto saveDir = QFileDialog::getExistingDirectory(dynamic_cast<QWidget*>(this), "存储路径选择");
if (saveDir.isEmpty()) {
qWarning() << "未选择存储路径";
qWarning() << u8"未选择存储路径";
return;
}
@ -175,15 +166,13 @@ namespace LAMPMainWidget
mUi->saveDirText->setText(mSavePath);
}
void
TaskWindow::setupTaskName(const QString& text)
void TaskWindow::setupTaskName(const QString& text)
{
qDebug() << "任务名=>" << text;
qWarning() << u8"任务名=>" << text;
mTaskName = text;
}
bool
TaskWindow::taskInfoCheck()
bool TaskWindow::taskInfoCheck()
{
if (mTaskName.isEmpty()) {
QMessageBox::critical(dynamic_cast<QWidget*>(this), "错误", "任务名称为空");
@ -198,11 +187,10 @@ namespace LAMPMainWidget
return true;
}
void
TaskWindow::setupZoomValue(int index)
void TaskWindow::setupZoomValue(int index)
{
auto zoom = mUi->zoomValueCbx->itemData(index).toInt();
qDebug() << "设置下载任务zoom值=>" << zoom;
qWarning() << u8"设置下载任务zoom值=>" << zoom;
mZoomValue = zoom;
}
}

View File

@ -18,8 +18,7 @@ namespace LAMPMainWidget {
setProvider(TmsProviderFactory::create(provider));
}
double
TmsLayer::resolution() const {
double TmsLayer::resolution() const {
auto pd = dynamic_cast<const TmsProvider*>(&provider());
auto sz = pd->tileSize();
double length = crs().extent().width();
@ -32,8 +31,7 @@ namespace LAMPMainWidget {
return result;
}
QRectF
TmsLayer::extent() const {
QRectF TmsLayer::extent() const {
auto pd = dynamic_cast<const TmsProvider*>(&provider());
QSize sz = pd->tileSize();
@ -41,14 +39,13 @@ namespace LAMPMainWidget {
int height = power2(zoomValue()) * sz.height();
//#ifdef DEBUG
// qDebug() << "layer extent=>{width:" << width << ", height:" << height << "}";
qDebug() << "layer extent=>{width:" << width << ", height:" << height << "}";
//#endif
return { 0, 0, static_cast<qreal>(width), static_cast<qreal>(height) };
}
void
TmsLayer::setZoomValue(int zoom) {
void TmsLayer::setZoomValue(int zoom) {
int zoomValue{};
if (zoom <= minZoom()) {
zoomValue = minZoom();
@ -63,8 +60,7 @@ namespace LAMPMainWidget {
mZoomValue = zoomValue;
}
bool
TmsLayer::parseTiles(const QRectF& rect, int zoom, QHash<QPoint, QString>& tiles, QSize& size) const {
bool TmsLayer::parseTiles(const QRectF& rect, int zoom, QHash<QPoint, QString>& tiles, QSize& size) const {
auto pd = dynamic_cast<const TmsProvider*>(&provider());
auto tileSize = pd->tileSize();
@ -80,7 +76,7 @@ namespace LAMPMainWidget {
auto yMin = qFloor(mapLeftTop.y() / tileSize.height());
auto yMax = qFloor(mapRightBottom.y() / tileSize.height());
if ((xMin > xMax) || (yMin > yMax)) {
qDebug() << "下载区边界错误";
qDebug() << u8"下载区边界错误";
return false;
}

View File

@ -4,26 +4,32 @@
#include <QDir>
#include <QSqlQuery>
#include <QSqlError>
#include <QPointer>
#include <tmsprovider.h>
#include <network.h>
#include <iostream>
#pragma execution_character_set("utf-8")
namespace LAMPMainWidget
{
TileDownloadTask::TileDownloadTask(TileInfo tile, QObject* parent)
TileDownloadTask::TileDownloadTask(TileInfo tile, tileReadyCallback cb, QObject* parent)
: QObject(parent),
mTile(std::move(tile))
mTile(std::move(tile)),
mCallback(cb)
{
// 程序初始化时注册如main函数或类构造函数
qRegisterMetaType<TileInfo>("TileInfo");
}
void
TileDownloadTask::run()
void TileDownloadTask::run()
{
Network web{};
QByteArray data = web.httpsRequest(mTile.url);
mTile.data = data;
tileReady(mTile);
if (mCallback) {
mCallback(mTile);
}
else {}
}
TmsProvider::TmsProvider(QObject* parent)
@ -42,13 +48,12 @@ namespace LAMPMainWidget
delete mImage;
}
bool
TmsProvider::initCache()
bool TmsProvider::initCache()
{
mDbConn = QSqlDatabase::addDatabase("QSQLITE", id());
mDbConn.setDatabaseName(mDbName);
if (!mDbConn.open()) {
qCritical() << "缓存数据库打开失败";
std::cout << u8"缓存数据库打开失败";
return false;
}
@ -71,8 +76,7 @@ namespace LAMPMainWidget
return true;
}
QByteArray
TmsProvider::getCache(const QPoint& pos, int zoom)
QByteArray TmsProvider::getCache(const QPoint& pos, int zoom)
{
QByteArray res{};
mDbConn.open();
@ -87,7 +91,7 @@ namespace LAMPMainWidget
select.bindValue(":zoom", zoom);
select.bindValue(":position", QString("%1:%2").arg(pos.x()).arg(pos.y()));
if (!select.exec()) {
qDebug() << pos << "查询失败=>" << select.lastError().text();
std::cout << pos.x()<<","<<pos.y() << "查询失败=>" << select.lastError().text().toUtf8().constData() << std::endl;
mDbConn.close();
return res;
}
@ -101,11 +105,10 @@ namespace LAMPMainWidget
return res;
}
bool
TmsProvider::addCache(const QPoint& pos, int zoom, QByteArray data)
bool TmsProvider::addCache(const QPoint& pos, int zoom, QByteArray data)
{
if (data.isEmpty()) {
qWarning() << "瓦片数据为空";
std::cout << "瓦片数据为空";
return false;
}
mDbConn.open();
@ -121,7 +124,7 @@ namespace LAMPMainWidget
sql.bindValue(":data", data);
if (!sql.exec()) {
qCritical() << pos << "=>" << sql.lastError().text();
std::cout << pos.x() << "," << pos.y() << "=>" << sql.lastError().text().toUtf8().constData() << std::endl;
mDbConn.close();
return false;
}
@ -130,15 +133,13 @@ namespace LAMPMainWidget
return true;
}
bool
TmsProvider::cacheContains(const QPoint& pos, int zoom)
bool TmsProvider::cacheContains(const QPoint& pos, int zoom)
{
QByteArray res = getCache(pos, zoom);
return !res.isEmpty();
}
void
TmsProvider::createTask(const QRectF& rect, int zoom)
void TmsProvider::createTask(const QRectF& rect, int zoom)
{
newImage(rect);
@ -164,16 +165,30 @@ namespace LAMPMainWidget
tileReady(tile);
continue;
}
/* 原始写法遇到了跨线程信号槽失效问题,这里修改为回调函数方式
auto* task = new TileDownloadTask(tile);
QObject::connect(task, &TileDownloadTask::tileReady, this, &TmsProvider::tileReady);
if (!QObject::connect(task, SIGNAL(tileReady(TileInfo)), this, SLOT(tileReady(TileInfo)))) {
qDebug() << "连接失败:" << QObject::tr(qPrintable(Q_FUNC_INFO));
}
QThreadPool::globalInstance()->start(task);
*/
// 回调函数版本
QPointer<TmsProvider> safeThis(this);
auto* task = new TileDownloadTask(tile, [safeThis]( TileInfo info) {
if (safeThis) { // 自动检测对象是否存活
QMetaObject::invokeMethod(safeThis.data(), [safeThis, info] {
safeThis->tileReady(info);
}, Qt::QueuedConnection); // 强制主线程执行[6](@ref)
}
});
QThreadPool::globalInstance()->start(task);
}
}
}
void
TmsProvider::tileReady(TileInfo tile)
void TmsProvider::tileReady(TileInfo tile)
{
if (!cacheContains(tile.position, tile.zoom)) {
addCache(tile.position, tile.zoom, tile.data);
@ -190,8 +205,7 @@ namespace LAMPMainWidget
painter.drawImage(QPointF(xPos, yPos), img);
}
void
TmsProvider::newImage(const QRectF& rect)
void TmsProvider::newImage(const QRectF& rect)
{
QSize imgSize{ int(rect.width()), int(rect.height()) };
if (!mImage || imgSize != mImage->size()) {

View File

@ -27,7 +27,8 @@ namespace LAMPMainWidget
QString url;
QByteArray data;
};
// 在结构体定义后声明
Q_DECLARE_METATYPE(TileInfo);
/*
*
*/
@ -39,7 +40,9 @@ namespace LAMPMainWidget
void tileReady(TileInfo tile);
public:
explicit TileDownloadTask(TileInfo tile, QObject* parent = nullptr);
using tileReadyCallback = std::function<void( TileInfo )>;
explicit TileDownloadTask(TileInfo tile, tileReadyCallback=nullptr, QObject* parent = nullptr);
TileDownloadTask(const TileDownloadTask& other) = delete;
TileDownloadTask(TileDownloadTask&& other) = delete;
TileDownloadTask& operator=(const TileDownloadTask& other) = delete;
@ -47,11 +50,15 @@ namespace LAMPMainWidget
~TileDownloadTask() override = default;
public:
void run() override;
protected:
TileInfo mTile;
private:
tileReadyCallback mCallback;
};
class TmsProvider : public LayerProvider

View File

@ -4,8 +4,7 @@
namespace LAMPMainWidget
{
PointXY
WebMercator::forward(const LAMPMainWidget::PointXY& point) const
PointXY WebMercator::forward(const LAMPMainWidget::PointXY& point) const
{
PointXY result{};
PointXY originXy = CRS::forward(point);
@ -17,8 +16,7 @@ namespace LAMPMainWidget
return result;
}
PointXY
WebMercator::inverse(const LAMPMainWidget::PointXY& point) const
PointXY WebMercator::inverse(const LAMPMainWidget::PointXY& point) const
{
PointXY originXy{};
QSizeF sz = extent().size();
@ -29,14 +27,12 @@ namespace LAMPMainWidget
return CRS::inverse(originXy);
}
QString
WebMercator::proj4Cvt() const
QString WebMercator::proj4Cvt() const
{
return QString{"+proj=webmerc +datum=WGS84"};
}
QString
WebMercator::wktDef() const
QString WebMercator::wktDef() const
{
return QString{
R"(

View File

@ -24,6 +24,12 @@
<Filter Include="RasterLayer">
<UniqueIdentifier>{1a65f538-c16c-4824-895f-105eb2fc502e}</UniqueIdentifier>
</Filter>
<Filter Include="gaodelayer">
<UniqueIdentifier>{7c9ae80d-da53-409c-805d-a3cc2c821574}</UniqueIdentifier>
</Filter>
<Filter Include="OpenstreetLayer">
<UniqueIdentifier>{bce9c1c4-57d0-42e5-bd9e-681fe17e9f00}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<QtRcc Include="RasterMainWidgetGUI.qrc">
@ -37,9 +43,6 @@
<ClCompile Include="RasterMainWidget\crs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RasterMainWidget\gaodenormalprovider.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RasterMainWidget\imgwriter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -91,9 +94,6 @@
<ClCompile Include="RasterMainWidget\network.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RasterMainWidget\ostnormalprovider.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RasterMainWidget\pointxy.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -124,20 +124,17 @@
<ClCompile Include="PrintMessage_C.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RasterMainWidget\gaodenormalprovider.cpp">
<Filter>gaodelayer</Filter>
</ClCompile>
<ClCompile Include="RasterMainWidget\ostnormalprovider.cpp">
<Filter>OpenstreetLayer</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="RasterMainWidget\crs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RasterMainWidget\gaodesatelliteprovider.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RasterMainWidget\googlechinanormalprovider.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RasterMainWidget\googlechinasatelliteprovider.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RasterMainWidget\imgwriter.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -213,20 +210,23 @@
<ClInclude Include="RasterMainWidgetGUICFunAPI.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RasterMainWidget\gaodesatelliteprovider.h">
<Filter>gaodelayer</Filter>
</ClInclude>
<ClInclude Include="RasterMainWidget\googlechinanormalprovider.h">
<Filter>gaodelayer</Filter>
</ClInclude>
<ClInclude Include="RasterMainWidget\googlechinasatelliteprovider.h">
<Filter>gaodelayer</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtMoc Include="RasterMainWidget\gaodenormalprovider.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="RasterMainWidget\layerprovider.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="RasterMainWidget\mapcanvas.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="RasterMainWidget\ostnormalprovider.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="RasterMainWidget\RasterMainWidget.h">
<Filter>Header Files</Filter>
</QtMoc>
@ -242,6 +242,12 @@
<QtMoc Include="RasterWidgetMessageShow.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="RasterMainWidget\gaodenormalprovider.h">
<Filter>gaodelayer</Filter>
</QtMoc>
<QtMoc Include="RasterMainWidget\ostnormalprovider.h">
<Filter>OpenstreetLayer</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<None Include="RasterMainWidget\proj.db" />

BIN
图像结构.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB