|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
|
#include <cmath>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
class GoogleTile
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
// 构造函数
|
|
|
|
|
GoogleTile(int zoom, int x, int y, cv::Mat content = cv::Mat())
|
|
|
|
|
{
|
|
|
|
|
_zoom = zoom;
|
|
|
|
|
_x = x;
|
|
|
|
|
_y = y;
|
|
|
|
|
_content = content.clone();
|
|
|
|
|
_isValid = !content.empty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取缩放级别
|
|
|
|
|
int getZoom() const
|
|
|
|
|
{
|
|
|
|
|
return _zoom;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取X坐标
|
|
|
|
|
int getX() const
|
|
|
|
|
{
|
|
|
|
|
return _x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取Y坐标
|
|
|
|
|
int getY() const
|
|
|
|
|
{
|
|
|
|
|
return _y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取瓦片内容
|
|
|
|
|
cv::Mat getContent() const
|
|
|
|
|
{
|
|
|
|
|
return _content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置瓦片内容
|
|
|
|
|
void setContent(cv::Mat content)
|
|
|
|
|
{
|
|
|
|
|
_content = content.clone();
|
|
|
|
|
_isValid = !content.empty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查瓦片是否有效
|
|
|
|
|
bool isValid() const
|
|
|
|
|
{
|
|
|
|
|
return _isValid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取相邻瓦片坐标
|
|
|
|
|
GoogleTile getLeftTile() const
|
|
|
|
|
{
|
|
|
|
|
int newX = (_x - 1 + (1 << _zoom)) % (1 << _zoom);
|
|
|
|
|
return GoogleTile(_zoom, newX, _y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GoogleTile getRightTile() const
|
|
|
|
|
{
|
|
|
|
|
int newX = (_x + 1) % (1 << _zoom);
|
|
|
|
|
return GoogleTile(_zoom, newX, _y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GoogleTile getTopTile() const
|
|
|
|
|
{
|
|
|
|
|
int newY = (_y - 1 + (1 << _zoom)) % (1 << _zoom);
|
|
|
|
|
return GoogleTile(_zoom, _x, newY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GoogleTile getBottomTile() const
|
|
|
|
|
{
|
|
|
|
|
int newY = (_y + 1) % (1 << _zoom);
|
|
|
|
|
return GoogleTile(_zoom, _x, newY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将瓦片坐标转换为经纬度
|
|
|
|
|
void tileToLatLon(double& lat, double& lon) const
|
|
|
|
|
{
|
|
|
|
|
double n = M_PI - 2.0 * M_PI * _y / (1 << _zoom);
|
|
|
|
|
lat = 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n)));
|
|
|
|
|
lon = _x / (double)(1 << _zoom) * 360.0 - 180.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将经纬度转换为瓦片坐标
|
|
|
|
|
static void latLonToTile(double lat, double lon, int zoom, int& x, int& y)
|
|
|
|
|
{
|
|
|
|
|
double lat_rad = lat * M_PI / 180.0;
|
|
|
|
|
double n = 1 << zoom;
|
|
|
|
|
x = static_cast<int>((lon + 180.0) / 360.0 * n);
|
|
|
|
|
y = static_cast<int>((1.0 - log(tan(lat_rad) + 1.0 / cos(lat_rad)) / M_PI) / 2.0 * n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取瓦片URL(根据谷歌地图规范)
|
|
|
|
|
std::string getUrl() const
|
|
|
|
|
{
|
|
|
|
|
std::stringstream ss;
|
|
|
|
|
ss << "https://mt.google.com/vt/lyrs=s&x=" << _x << "&y=" << _y << "&z=" << _zoom;
|
|
|
|
|
return ss.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
int _zoom; // 缩放级别 (0-21)
|
|
|
|
|
int _x; // 瓦片X坐标
|
|
|
|
|
int _y; // 瓦片Y坐标
|
|
|
|
|
cv::Mat _content; // 瓦片图像数据
|
|
|
|
|
bool _isValid; // 瓦片是否有效
|
|
|
|
|
};
|