前文链接:QGraphicsView实现简易地图10『自适应窗口大小』
提供一个地图初始化函数,指定地图显示的中心点和地图缩放层级
能够让地图显示某一层级的瓦片,并将中心点坐标显示在视图中心。
1、动态演示效果
7级地图-大连-老虎滩 定位到 8级地图-台湾-台北
2、指定层级-定位坐标的代码
注:WHMapView继承自MapView
void WHMapView::centerAndZoom(const GeoCoord&geoCenter, int zoom)
{
m_geoCoord = geoCenter;
m_curLevel = zoom - 1;
MapDataManager::instance()->setMapLevel(m_curLevel);
double len = MapUtility::sceneSize(m_curLevel);
setSceneRect(QRect(0, 0, len, len));
// 经纬度坐标转场景坐标、视图定位到中心点
QPointF offsetPos = QPointF(viewport()->width() / 2.0, viewport()->height() / 2.0);
QPointF scenePos = MapUtility::sceneCoordFromGeoCoord(m_geoCoord, m_curLevel);
horizontalScrollBar()->setValue(scenePos.x() - offsetPos.x());
verticalScrollBar()->setValue(scenePos.y() - offsetPos.y());
scaleScene();
updateOtherItemPos();
}
void MapView::scaleScene()
{
// 前面省略与计算无关的代码...
// 视口宽度和高度
int w = viewport()->width();
int h = viewport()->height();
// 瓦片像素点坐标、视口坐标
QPointF scenePos = MapUtility::sceneCoordFromGeoCoord(m_geoCoord, m_curLevel);
QPointF pixelPos = MapUtility::tilePixelCoordFromScene(scenePos, m_curLevel);
QPoint viewportPos = mapFromScene(scenePos);
// 鼠标所在瓦片的四边 与 视口四边的距离
int lPixel = viewportPos.x() - pixelPos.x();
int rPixel = w - (viewportPos.x() + PIXMAP_SIZE - pixelPos.x());
int tPixel = viewportPos.y() - pixelPos.y();
int bPixel = h - (viewportPos.y() + PIXMAP_SIZE - pixelPos.y());
// 计算鼠标所在瓦片的四边应该填充的完整图片数量、是否存在剩余像素
int leftPixmapCount = lPixel / PIXMAP_SIZE;
bool remainLeftPixel = lPixel % PIXMAP_SIZE;
int rightPixmapCount = rPixel / PIXMAP_SIZE;
bool remainRightPixel = rPixel % PIXMAP_SIZE;
int topPixmapCount = tPixel / PIXMAP_SIZE;
bool remainTopPixel = tPixel % PIXMAP_SIZE;
int bottomPixmapCount = bPixel / PIXMAP_SIZE;
bool remainBottomPixel = bPixel % PIXMAP_SIZE;
// 计算呈现的瓦片地图左上角的瓦片坐标
m_curTileCoord = MapUtility::tileCoordFromGeoCoord(m_geoCoord, m_curLevel);
m_topLeftTileCoord.x = qMax(m_curTileCoord.x - leftPixmapCount, 0);
m_topLeftTileCoord.y = qMax(m_curTileCoord.y - topPixmapCount, 0);
if (remainLeftPixel && m_topLeftTileCoord.x > 0)
m_topLeftTileCoord.x -= 1;
if (remainTopPixel && m_topLeftTileCoord.y > 0)
m_topLeftTileCoord.y -= 1;
// 计算呈现的瓦片地图右下角的瓦片坐标
int mapSideCount = MapUtility::mapSideCount(m_curLevel);
m_bottomRightTileCoord.x = qMin(m_curTileCoord.x + rightPixmapCount, mapSideCount - 1);
m_bottomRightTileCoord.y = qMin(m_curTileCoord.y + bottomPixmapCount, mapSideCount - 1);
if (remainRightPixel && m_bottomRightTileCoord.x < mapSideCount - 1)
m_bottomRightTileCoord.x += 1;
if (remainBottomPixel && m_bottomRightTileCoord.y < mapSideCount - 1)
m_bottomRightTileCoord.y += 1;
// 计算瓦片集合,视口最小瓦片集合+周边瓦片集合
vector<TileCoord> vecTileCoord;
m_viewAndAroundTileRect = CommonUtility::getViewAndAroundTileCoords(m_topLeftTileCoord.y, m_topLeftTileCoord.x, m_bottomRightTileCoord.y, m_bottomRightTileCoord.x, m_curLevel, vecTileCoord);
//showTileCoord();
showGraticules();
// 上方即为计算瓦片索引的核心代码,省略下方加载瓦片的代码...
// 加载瓦片代码...
}