网站建设未来趋势,天津市建设教育培训网,淄博网站推广,wordpress切换语言 语言包前文链接#xff1a;QGraphicsView实现简易地图4『局部加载-地图漫游』 由于GCJ02 Web 墨卡托投影 纬度并不随像素等分#xff0c;且两极跨度较大#xff0c;因此本次演示采用的经纬网等分逻辑为等分像素。同等像素跨度之间#xff0c;两级纬度变化较小#xff0c;越靠近赤…前文链接QGraphicsView实现简易地图4『局部加载-地图漫游』 由于GCJ02 Web 墨卡托投影 纬度并不随像素等分且两极跨度较大因此本次演示采用的经纬网等分逻辑为等分像素。同等像素跨度之间两级纬度变化较小越靠近赤道附近纬度变化越大。以下将提供实现此需求的核心代码。 1、动态演示效果 2、静态展示图片
核心代码
void MapView::showGraticules()
{// 计算等分像素后的经纬度步长int gridCount MapUtility::graticulesGridCount(m_curLevel);int mapSideCount apUtility::mapSideCount(m_curLevel);double perLon PIXMAP_SIZE * mapSideCount * 1.0 / gridCount;double perLat perLon;// 计算呈现的瓦片地图左上角和右下角的场景坐标QPoint topLeftScenePos(m_topLeftTileCoord.x * PIXMAP_SIZE, m_topLeftTileCoord.y * PIXMAP_SIZE);QPoint bottomRightScenePos((m_bottomRightTileCoord.x 1) * PIXMAP_SIZE, (m_bottomRightTileCoord.y 1) * PIXMAP_SIZE);// 计算经纬线覆盖范围此处采用的逻辑是经纬网覆盖区域呈现的瓦片地图区域int leftGridIndex qFloor(topLeftScenePos.x() / perLon);int rightGridIndex qCeil(bottomRightScenePos.x() / perLon);int topGridIndex qFloor(topLeftScenePos.y() / perLat);int bottomGridIndex qCeil(bottomRightScenePos.y() / perLat);if (leftGridIndex 0)leftGridIndex 0;if (rightGridIndex gridCount)rightGridIndex gridCount;if (topGridIndex 0)topGridIndex 0;if (bottomGridIndex gridCount)bottomGridIndex gridCount;// 视口宽度和高度int vw viewport()-width();int vh viewport()-height();// 场景宽度和高度int sw MapUtility::sceneSize(m_curLevel);int sh sw;// 视口右下角对应场景坐标QPointF bottomRightViewToScenePos mapToScene(viewport()-rect().bottomRight());// 经纬网线条颜色、文本颜色QColor gridLineColor(255, 163, 70);QColor textColor(Qt::white);// 绘制经纬网纬度线for (int row topGridIndex; row bottomGridIndex; row){ // 纬度线double sceneY row * perLat;QGraphicsLineItem *item m_scene-addLine(topLeftScenePos.x(), sceneY, bottomRightScenePos.x(), sceneY);item-setPen(QPen(gridLineColor, 1, Qt::DotLine));item-setZValue(50);m_vecGraticulesItems.append(item);// 纬度文本double lat MapUtility::latFromSceneY(sceneY, m_curLevel);QGraphicsTextItem *textItem m_scene-addText(CommonUtility::convertToDMSLatSymbol(lat));textItem-setDefaultTextColor(Qt::white);QFont font textItem-font();font.setFamily(微软雅黑);textItem-setFont(font);// 调整文本位置QRectF textBoundingRect textItem-boundingRect();int sceneX sw vw ? bottomRightScenePos.x() : bottomRightViewToScenePos.x();textItem-setPos(sceneX - textItem-boundingRect().width(), sceneY - textBoundingRect.height() / 2);m_vecGraticulesTextItems.append(textItem);}// 绘制经纬网经度线for (int col leftGridIndex; col rightGridIndex; col){// 经度线double sceneX col * perLon;QGraphicsLineItem *item m_scene-addLine(sceneX, topLeftScenePos.y(), sceneX, bottomRightScenePos.y());item-setPen(QPen(gridLineColor, 1, Qt::DotLine));item-setZValue(50);m_vecGraticulesItems.append(item);// 经度文本double lon MapUtility::lonFromSceneX(sceneX, m_curLevel);QGraphicsTextItem *textItem m_scene-addText(CommonUtility::convertToDMSLonSymbol(lon));textItem-setDefaultTextColor(Qt::white);QFont font textItem-font();font.setFamily(微软雅黑);textItem-setFont(font);// 调整文本位置QRectF textBoundingRect textItem-boundingRect();int sceneY sh vh ? bottomRightScenePos.y() : bottomRightViewToScenePos.y();textItem-setPos(sceneX - textBoundingRect.width() / 2, sceneY - textItem-boundingRect().height());m_vecGraticulesTextItems.append(textItem);}
}辅助代码
void CommonUtility::convertToDMS(double value, int d, int m, int s)
{d (int)(value); m (int)((value - d) * 60);s (int)(((value - d) * 60 - m) * 60);// 四舍五入float e ((value - d) * 60 - m) * 60 - s;if (5 (int)(e * 10))s 1;// 秒进位if (60 s){s 0;m 1;}// 分进位if (60 m){m 0;d 1;}
}QString CommonUtility::convertToDMS(double value)
{int d, m, s;convertToDMS(value, d, m, s);QString strM QString::number(m).rightJustified(2, 0);QString strS QString::number(s).rightJustified(2, 0);return QString(%1°%2′%3″).arg(d).arg(strM).arg(strS);
}QString CommonUtility::convertToDMSLonSymbol(double value)
{return QString(%1%2).arg(convertToDMS(fabs(value))).arg(value 0 ? E : (value 0 ? W : ));
}QString CommonUtility::convertToDMSLatSymbol(double value)
{return QString(%1%2).arg(convertToDMS(fabs(value))).arg(value 0 ? N : (value ! 0 ? S : ));
}